RuntimeError фильтрует ребра с весом ниже порога - Networkx - PullRequest
1 голос
/ 26 марта 2020

Я работаю с Python и networkx, и это мой первый проект с этим инструментом. Я хотел бы сделать график для анализа сходства между некоторыми строками. К вашему сведению, я использовал косинусное сходство для вычисления сходства между строками.

Ниже приведен код, который я использовал до сих пор:

skills=[]

for i in data['skills']:
    skills.append(i)


def clean_string(text):
    text = ''.join([word for word in text if word not in string.punctuation])
    text = text.lower()
    text = ' '.join([word for word in text.split() if word not in stop_words])
    return text

cleaned = list(map(clean_string, skills))
# print(cleaned)

vectorizer = CountVectorizer().fit_transform(cleaned)
vectors = vectorizer.toarray()
# print(vectors)

csim = cosine_similarity(vectors)

Я хочу, чтобы сходство косинусов было вес ребер в моей сети.

G = nx.from_numpy_matrix(np.matrix(csim), create_using=nx.DiGraph)

Затем я пытаюсь отфильтровать ребра, вес которых превышает порог 0,2.

def slice_network(G, T, data = True):
    """ Remove all edges with weight<T from G or its copy. """
    F = G.copy() if copy else G
    F.remove_edges_from((n1, n2) for n1, n2, w in F.edges(data="weight") if w < T)
    return G

F = slice_network(G, 0.2)
print(F.edges())

Однако выдает ошибку:

RuntimeError: размер словаря изменился во время итерации

Может ли кто-нибудь мне помочь?

1 Ответ

1 голос
/ 26 марта 2020

Вам просто нужно добавить [] к вашему remove_edges_from вызову (и вы должны вернуть F вместо G. Из вашего другого вопроса я создал минимальный воспроизводимый пример:

import networkx as nx
import numpy as np
import matplotlib.pyplot as plt


simple_weights = [[1., 0.51639778, 0., 0., 0., 0.],
                  [0.51639778, 1., 0., 0., 0., 0.25819889],
                  [0., 0., 1., 0., 0., 0.33333333],
                  [0., 0., 0., 1., 0.65465367, 0.],
                  [0., 0., 0., 0.65465367, 1., 0.],
                  [0., 0.25819889, 0.33333333, 0., 0., 1.]]


G = nx.from_numpy_matrix(np.array(simple_weights), create_using=nx.DiGraph)
nx.draw(G)
plt.show()

F = G.copy()
threshold = 0.4
F.remove_edges_from([(n1, n2) for n1, n2, w in F.edges(data="weight") if w < threshold])
nx.draw(F)
plt.show()

или как ваша функция (вы не определили copy в своем коде выше)

def slice_network(G, T, data = True):
    """ Remove all edges with weight<T from G or its copy. """
    F = G.copy() if copy else G
    F.remove_edges_from([(n1, n2) for n1, n2, w in F.edges(data="weight") if w < T])
    return F

или как фильтр перед созданием

threshold = 0.4
simple_weights = np.array(simple_weights)
simple_weights[simple_weights<threshold] = 0
...