En este artículo, no nos detendremos en los aspectos legales de las notificaciones enviadas sobre un CFC, sobre la participación en un CFC, consideraremos el aspecto técnico del problema.
Sin duda, si el holding en cuestión se presenta como estructuras simples del tipo LLC-> KIK-> Ruso, entonces no es práctico construir algo aquí con la participación de una máquina, es otra cuestión si la estructura se bifurca, se duplica y no hay número de estos entretejidos.
Echemos un vistazo a varias soluciones gráficas existentes que simplificarán su trabajo.
Para facilitar la visualización, se utilizarán el cuaderno jupyter y el entorno de python.
Networkx
Esta solución es la más antigua de las presentadas y no puede presumir de su interactividad. Existe el mismo artículo antiguo sobre este paquete en Habré.
Sin embargo, lo antiguo no significa malo, y esta opción es una de las más acertadas tanto a nivel de dibujo como de computación.
Instale e importe el módulo a través de jupyter:
!pip install networkx
import networkx as nx
También importamos otros complementos. módulos que te ayudarán a dibujar formas:
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams.update({
'figure.figsize': (7.5, 7.5),
'axes.spines.right': False,
'axes.spines.left': False,
'axes.spines.top': False,
'axes.spines.bottom': False})
Construyamos la primera red usando networkx:
from pathlib import Path
data_dir = Path('.') / 'data'
# Read edge list
G = nx.read_edgelist('example.edgelist')
# Draw network
#pos = nx.spring_layout(G)
pos = nx.spectral_layout(G)
#pos = nx.planar_layout(G)
nx.draw_networkx(G, pos)
plt.gca().margins(0.15, 0.15)
Esto es lo que sucedió:
como puede ver, Ivanov posee dos CFC, que, a su vez, poseen entidades legales rusas. por personas.
Analicemos el código de arriba.
Importamos el módulo y especificamos desde dónde leeremos los datos en el disco:
from pathlib import Path
data_dir = Path('.') / 'data'
El directorio actual se consideró 'example.edgelist':
G = nx.read_edgelist('example.edgelist')
* example.edgelist es un archivo de texto sin formato como este:
# source target
1
2
1 2
1 _
2 _
Los valores los registra alguien con un espacio entre ellos.
A continuación, determinamos cómo se verá la red:
pos = nx.spectral_layout(G)
Si cambiamos a pos = nx.spring_layout (G), entonces tomará la forma:
Y esta disposición, por extraño que parezca, es la más adecuada para estructuras más grandes.
Finalmente, dibujamos la red, marcando las sangrías:
nx.draw_networkx(G, pos)
plt.gca().margins(0.15, 0.15)
Es fácil guardar una imagen:
plt.savefig('plot.png')
Cómo dibujar un segmento en networkx
#
H = G.subgraph(['', '1', '_'])
plt.subplot(212)
print(":")
nx.draw_networkx(H)
No
sangramos aquí, y los nombres "se fueron": Networkx opera con los conceptos de nodos y enlaces entre ellos. En nuestra situación, los nodos son Ivanov, KIK1, KIK2, Romashka_OOO, Bucket_AO. Y los enlaces son los que se encuentran en el archivo example.edgelist.
Puede ver ambos simplemente consultando los métodos G.nodes y G.edges:
Gráfico dirigido en networkx (lista de bordes dirigidos)
Aclaremos un poco la red construida, agreguemos flechas:
# Read edge list
G = nx.read_edgelist(
str('example.edgelist'),
create_using=nx.DiGraph)
pos = nx.spectral_layout(G)
# Draw network
nx.draw_networkx(G, pos, arrowsize=20)
plt.gca().margins(0.15, 0.15)
Pequeños cambios hicieron posible pintar una imagen más clara de quién es dueño de quién:
En el código, como puede ver, los cambios son mínimos.
El siguiente paso es crear un gráfico donde se verá el tamaño de los paquetes de propiedad.
Para hacer esto, necesita familiarizarse con el concepto de peso (peso) es el tercer parámetro principal con el que networkx puede trabajar. Para incluirlo en el trabajo, debe agregar estos mismos pesos a un archivo de texto, por ejemplo:
# source target
1 100
2 100
1 2 50
1 _ 100
2 _ 100
Ahora reconstruyamos la red usando los pesos y designémoslos en el gráfico:
# Read edge list
G = nx.read_weighted_edgelist(
str('example2.edgelist'))
# Extract weights
weights = [d['weight'] for s, t, d in G.edges(data=True)]
nx.draw_networkx(G,pos)
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
plt.gca().margins(0.15, 0.15)
* example2.edgelist es el archivo que se genera arriba con pesos.
Obtenemos la siguiente imagen:
Quién es el propietario de quién y cómo, networkx
Ahora nosotros, como abogados-programadores, necesitamos entender en qué secuencia y en qué cantidad Ivanov posee, por ejemplo, la empresa Bucket_AO y si es de su propiedad. Esto es necesario para determinar el hecho de la propiedad en la explotación ramificada y todas las cadenas a la LLC objetivo (JSC), para que posteriormente estas cadenas puedan registrarse en la notificación CFC.
Con networkx, puede hacer esto de la siguiente manera:
list(nx.all_simple_paths(G,'', '_'))
El primer argumento es el nodo propietario, el segundo es el nodo al que construiremos las rutas.
Con este método, puede ver que Bucket_AO de Ivanov pertenece a las siguientes cadenas:
[['', '1', '2', '_'], ['', '2', '_']]
Esto se confirma gráficamente.
Puede averiguar la participación en la propiedad multiplicando los pesos entre los nodos correspondientes: 1 * 0.5 * 1 = 0.5, 1 * 1 = 1. Proporción de más del 25%, se debe enviar una notificación.
En el código, la multiplicación se realiza con las siguientes muletas (aún no se ha encontrado un método más elegante):
x=0
b=0
c=[]
for i in list(nx.all_simple_paths(G,'', '_')):
for a in i:
if x>len(i)-2:
pass
else:
b=int(nx.bidirectional_dijkstra(G, i[x],i[x+1])[0])#
x+=1
c.append(b/100)
print(c)
import numpy as np
print(np.prod(c))
x=0
b=0
c=[]
for i in list(nx.all_shortest_paths(G,'', '_')):
for a in i:
if x>len(i)-2:
pass
else:
b=int(nx.bidirectional_dijkstra(G, i[x],i[x+1])[0])#
x+=1
c.append(b/100)
print(c)
import numpy as np
print(np.prod(c))
En el primer caso mostrará una fracción de 0,5, en el segundo 1.
¿Qué otras opciones de visualización están disponibles? Por ejemplo, Netwulf.
Netwulf
La documentación está aquí .
La red en sí es interactiva, esta es su principal ventaja. Después de instalar el paquete de Python, construyamos la red:
import netwulf as nw
plt.figure(figsize=(200,200))
G = nx.read_weighted_edgelist(str('example2.edgelist'),create_using=nx.DiGraph)
pos = nx.spring_layout(G)
nw.visualize(G)
Después de ejecutar el código, jupyter se congela, y en una ventana adicional del navegador que se abre, puede ver el resultado:
En el lado derecho del panel, puede ver las opciones, cambiando las que afectan la red construida en línea.
La desventaja de este paquete es que aún no es posible mostrar los pesos y flechas entre los nodos, pero los autores prometieron refinarlo.
* para volver a jupyter, debe hacer clic en la opción "publicar en python":
Otra buena opción para una visualización de este tipo para python es el proyecto young webweb.
Webweb
La documentación está aquí .
La red está construida de manera similar:
from webweb import Web
web = Web(title='kitchen_sink')
web.display.networkName = 'tree'
web.display.networkLayer = 2
web.display.colorBy = 'ring'
web.display.sizeBy = 'degree'
web.display.gravity = .3
web.display.charge = 30
web.display.linkLength = 15
web.display.colorPalette = 'Greens'
web.display.scaleLinkOpacity = False
web.display.scaleLinkWidth = True
from pathlib import Path
data_dir = Path('.') / 'data'
# Read edge list
G = nx.read_edgelist('example.edgelist',create_using=nx.DiGraph)
plt.figure(figsize=(200,200))
# Draw network
pos = nx.spring_layout(G)
Web(list(G.edges)).show()
De las claras ventajas sobre netwulf: la capacidad de resaltar nodos clave con color, búsqueda de texto para nodos resaltados en la red: en
resumen, podemos decir que los descendientes en desarrollo de networkx: netwulf y webweb son buenos para construir una imagen rápida de la estructura de una pequeña explotación. Ambos módulos tienen un modo de congelación para congelar los nodos que se pegan juntos en una pila debido a la interactividad del gráfico. Sin embargo, incluso usándolos, no es fácil trabajar con estructuras a gran escala, donde el número de nodos es más de 200.
"Pedestal" del Ministerio de Finanzas, propiedad de cruz y anillo
Todo estaría muy bien a la hora de construir tales estructuras, si no fuera por una cosa que estropea todo el panorama. Sin embargo, esto radica en el hecho de que las participaciones de la empresa se poseen a través de otras entidades legales. caras y esto se llama propiedad cruzada o en anillo.
En las imágenes de las cartas del Ministerio de Finanzas (por ejemplo, del 02.07.2013 -4-13 / 11912) se ve así.
Propiedad cruzada: en forma de anillo
:
veamos cómo networkx define los vínculos para el esquema de propiedad cruzada de la participación de D en B.
Creemos un edgelist con vínculos:
# source target
D B 45
B A 40
A B 55
E A 60
Habiendo construido una red con pesos, puede ver que la retroalimentación entre A y B no se refleja:
se puede ver si construye una red sin pesos, con flechas:
¿Qué pasa con los cálculos? ¿Cuál es la participación acumulada de D en B?
Todo parece transparente aquí, 45%
Y networkx se rinde con la lista de comandos (nx.all_simple_paths (G, 'D', 'B')):
[['D', 'B']]
Pero no todo es tan simple.
El Ministerio de Finanzas dice que la participación total de D en B está determinada por la fórmula:
Y será 57.69%.
¿Qué hacer? networkx es impotente?
En absoluto, networkx revelará tales situaciones, pero la fórmula de cálculo será diferente, según la “letra de la ley”.
El problema se puede resolver parcialmente agregando entradas
AA
BB al edgelist
Además, con la lista de comandos (nx.nodes_with_selfloops (G)), puede ver los nodos con participación en sí mismos, pero esto aún no se tiene en cuenta al determinar las rutas de D a B.
Descarga del cuaderno jupyter - aquí .