I am trying to create a classification algorithm using Graph Neural Networks (GNNs) in Python, but I am encountering an error that I can’t resolve.
I have already tried removing NaN values from my dataframe, but the issue persists. Below is the code I am using.
If anyone could help me, I would greatly appreciate it!
Here is the function I use to create a graph from a dataframe row:
# Função para criar um grafo a partir de uma linha do dataframe
def criar_grafo_passe(row, index):
G = nx.Graph()
passer = f"Player_PP" # Identificador único para o jogador que passa a bola
receiver = f"Player_PR" # Identificador único para o jogador que recebe a bola em t0
receiver_t1 = f"Player_PRt1" # Identificador único para o jogador que recebe a bola em t1
opponent_pp = f"Opponent_PP" # Identificador único para o oponente mais próximo do passador
opponent_pr = f"Opponent_PR" # Identificador único para o oponente mais próximo do receptor em t0
opponent_pr_t1 = f"Opponent_PRt1" # Identificador único para o oponente mais próximo do receptor em t1
distance = row['Passing distance'] # Distância do passe
# Adiciona nós para passador, receptor, receptor em t1 e oponentes mais próximos
G.add_node(passer, role='passer')
G.add_node(receiver, role='receiver')
G.add_node(receiver_t1, role='receiver_t1')
G.add_node(opponent_pp, role='opponent')
G.add_node(opponent_pr, role='opponent')
G.add_node(opponent_pr_t1, role='opponent')
# Adiciona arestas entre passador e receptor
G.add_edge(passer, receiver, weight=distance)
# Adiciona arestas entre passador e oponente mais próximo
G.add_edge(passer, opponent_pp, weight=row['Nearest opp. PPt0'])
# Adiciona arestas entre receptor e oponente mais próximo em t0 e t1
G.add_edge(receiver, opponent_pr, weight=row['Nearest opp. PRt0'])
G.add_edge(receiver_t1, opponent_pr_t1, weight=row['Nearest opp. PRt1'])
# Adiciona aresta entre receptor em t0 e t1
G.add_edge(receiver, receiver_t1, weight=row['Displacement PR'])
# Adiciona atributos aos nós do passador
G.nodes[passer].update({
'Foot or not': row['Foot or not'],
'Nearest opp. PPt0': row['Nearest opp. PPt0'],
'Velocity nearest opp. PPt0': row['Velocity nearest opp. PPt0'],
'Opponet angle': row['Opponet angle'],
'Density PPt0': [row['Density PPt0 (1m)'], row['Density PPt0 (2m)'], row['Density PPt0 (5m)'], row['Density PPt0 (10m)']],
'Velocity PPt0': row['Velocity PPt0'],
'Distance PPt0 to target': row['Distance PPt0 to target']
})
# Adiciona atributos aos nós do receptor em t0
G.nodes[receiver].update({
'Nearest opp. PRt0': row['Nearest opp. PRt0'],
'Density PRt0': [row['Density PRt0 (1m)'], row['Density PRt0 (2m)'], row['Density PRt0 (5m)'], row['Density PRt0 (10m)']],
'Velocity PRt0': row['Velocity PRt0'],
'Distance PRt0 to target': row['Distance PRt0 to target']
})
# Adiciona atributos aos nós do receptor em t1
G.nodes[receiver_t1].update({
'Nearest opp. PRt1': row['Nearest opp. PRt1'],
'Density PRt1': [row['Density PRt1 (1m)'], row['Density PRt1 (2m)'], row['Density PRt1 (5m)'], row['Density PRt1 (10m)']],
'Velocity PRt1': row['Velocity PRt1'],
'Distance PRt1 to target': row['Distance PRt1 to target'],
'Out ball angle': row['Out ball angle']
})
# Adiciona atributos aos nós dos oponentes mais próximos
G.nodes[opponent_pp].update({
'role': 'opponent',
'distance to passer': row['Nearest opp. PPt0']
})
G.nodes[opponent_pr].update({
'role': 'opponent',
'distance to receiver t0': row['Nearest opp. PRt0']
})
G.nodes[opponent_pr_t1].update({
'role': 'opponent',
'distance to receiver t1': row['Nearest opp. PRt1']
})
# Adiciona atributos à aresta entre passador e receptor
G[passer][receiver].update({
'Passing distance': row['Passing distance'],
'Ball velocity': row['Ball velocity'],
'Passing angle': row['Passing angle'],
'Ball progression': row['Ball progression'],
'Outplayed opp. ': row['Outplayed opp. '],
'Opp. btw PRt1 and target': row['Opp. btw PRt1 and target'],
'Accuracy': row['Accuracy'],
'One touth': row['One touth']
})
return G
# Remover valores NaN ou infinitos do dataframe
df.dropna(inplace=True)
df.replace([np.inf, -np.inf], np.nan, inplace=True)
df.dropna(inplace=True)
# Criar uma lista de grafos, um para cada passe
grafos_passes = [criar_grafo_passe(row, index) for index, row in df.iterrows()]
# Treinar o algoritmo Node2Vec em cada grafo
embeddings = []
for G in grafos_passes:
# Verificar e remover qualquer peso não finito do grafo
for u, v, data in G.edges(data=True):
if not np.isfinite(data.get("weight", 1.0)):
G.remove_edge(u, v)
# Configurar e treinar o modelo Node2Vec
node2vec = Node2Vec(G, dimensions=64, walk_length=30, num_walks=200, workers=4)
model = node2vec.fit(window=10, min_count=1)
# Obter os embeddings dos nós
node_embeddings = {node: model.wv[node] for node in G.nodes}
embeddings.append(node_embeddings)
# Converter os embeddings em um dataframe
df_embeddings = pd.DataFrame(embeddings)
# Separar os dados em recursos (X) e rótulos (y)
X = df_embeddings.values
y = df['Difficulty'].values # Substitua 'Difficulty' pelo nome da coluna que contém os rótulos de dificuldade
# Dividir os dados em conjuntos de treinamento e teste
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Treinar o classificador Random Forest
clf = RandomForestClassifier()
clf.fit(X_train, y_train)
# Fazer previsões
y_pred = clf.predict(X_test)
# Avaliar o desempenho do classificador
accuracy = accuracy_score(y_test, y_pred)
print("Acurácia do Random Forest:", accuracy)
I have checked and cleaned the data to remove NaNs and infinite values. I also reviewed the graph construction logic and the attributes for nodes and edges. Despite this, I encounter problems when training the Node2Vec model and using the embeddings to train a Random Forest classifier.
Any suggestions on how to debug or fix this issue?
Thank you!
Val Secco is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.