把有关系节点的余弦相似度保存在一块,再把没有关系节点的余弦相似度保存在一块,最后绘图
程序:
#zhouzhichao
#25年5月29日
#统计图中节点的余弦相似度import h5py
import random
import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity, euclidean_distancessnr = 0
# mode = "cosine"
mode = "euclidean"base_dir = "D:\\无线通信网络认知\\论文1\\experiment\\直推式拓扑推理实验\\拓扑生成\\200样本"data_dir = base_dir+'\\30_nodes_dataset_snr-'+str(snr)+'_M_3000.mat'# 加载.mat文件
mat_file = h5py.File(data_dir, 'r')
# 获取数据集
Signals = mat_file["Signals"][()]
Tp = mat_file["Tp"][()]
Tp_list = mat_file["Tp_list"][()]
# 关闭文件
mat_file.close()# 初始化空列表
list_1 = []
list_0 = []# 2. 基于阈值相似性图的方法
def similarity_threshold_method(signals, tp):# 计算余弦相似度# 统计有关系的节点和没关系的节点余弦相似度signals = np.swapaxes(signals,0,1)if mode=="cosine":similarity = cosine_similarity(signals)if mode == "euclidean":similarity = euclidean_distances(signals)N = tp.shape[0]# 根据阈值判断节点关系for i in range(N):for j in range(N):if tp[i, j] == 1:list_1.append(similarity[i][j])else:list_0.append(similarity[i][j])for k in range(200):print("k: ",k)# 获取当前样本的信号和tp矩阵signal = Signals[:, :, k] # (1890, 30) - 对应当前样本的信号矩阵tp = Tp[:, :, k] # (30, 30) - 对应当前样本的tp矩阵similarity_threshold_method(signal, tp)minlength = min(len(list_1),len(list_0))# list_0 = random.sample(list_0, minlength)list_1 = random.sample(list_1, 1000)
list_0 = random.sample(list_0, 1000)# data = {
# 'list_1': list_1,
# 'list_0': list_0
# }value = list_1 + list_0
large_class = list(np.full(len(value), snr))
small_class = list(np.full(len(list_1), 1)) + list(np.full(len(list_0), 0))# data = {
# 'list_1': list_1,
# 'list_0': list_0
# }data = {'large_class': large_class,'small_class': small_class,'value': value
}# 创建一个 DataFrame
df = pd.DataFrame(data)
#
# # 保存到 Excel 文件
file_path = 'D:\无线通信网络认知\论文1\大修意见\图聚类、阈值相似性图实验补充\\'+mode+'_similarity_'+str(snr)+'db.xlsx'
df.to_excel(file_path, index=False)
求余弦值的话
mode = "cosine"
求欧式距离的话
mode = "euclidean"
输入:
输出:
保存成这种形式是方便Origin绘图,第一列是大类,第二列是小类
绘图效果:
还有一种更高级的统计方式,就是不直接对原始图节点特征进行统计,而是表示学习后在高维空间进行统计,例如图卷积神经网络GCN
高维图节点特征统计程序:
#作者:zhouzhichao
#创建时间:25年5月29日
#内容:统计图中有关系节点和无关系节点的GCN特征欧式距离import sys
import torch
import random
import numpy as np
import pandas as pd
from torch_geometric.nn import GCNConv
from sklearn.metrics import roc_auc_score
sys.path.append('D:\无线通信网络认知\论文1\experiment\直推式拓扑推理实验\GCN推理')
from gcn_dataset import graph_data
print(torch.__version__)
print(torch.cuda.is_available())mode = "gcn"class Net(torch.nn.Module):def __init__(self):super().__init__()self.conv1 = GCNConv(Input_L, 1000)self.conv2 = GCNConv(1000, 20)# self.conv3 = GCNConv(2000, 256)# self.conv4 = GCNConv(256, 128)def encode(self, x, edge_index):x1 = self.conv1(x, edge_index)x1_1 = x1.relu()x2 = self.conv2(x1_1, edge_index)x2_2 = x2.relu()# x = self.conv3(x, edge_index).relu()# x = self.conv4(x, edge_index).relu()return x2_2def decode(self, z, edge_label_index):# 节点和边都是矩阵,不同的计算方法致使:节点->节点,节点->边# nodes_relation = (z[edge_label_index[0]] * z[edge_label_index[1]]).sum(dim=-1)# distances = torch.norm(z[edge_label_index[0]] - z[edge_label_index[1]], dim=-1)distance_squared = torch.sum((z[edge_label_index[0]] - z[edge_label_index[1]]) ** 2, dim=-1)# print("distance_squared: ",distance_squared)return distance_squareddef decode_all(self, z):prob_adj = z @ z.t() # 得到所有边概率矩阵return (prob_adj > 0).nonzero(as_tuple=False).t() # 返回概率大于0的边,以edge_index的形式@torch.no_grad()def test(self,input_data):model.eval()z = model.encode(input_data.x, input_data.edge_index)out = model.decode(z, input_data.edge_label_index).view(-1)out = 1 - outN = 30
train_n = 31
M = 3000
# snr = -20
# for train_n in range(1,51):
# for M in range(3000, 499, -100):
for snr in [0,20,40]:# M = 10000# print("train_n: ", train_n)# gcn_data = graph_data("gcn_data")# print("M: ", M)print("snr: ", snr)for I in range(10):root = "gcn_data-"+str(I)+"_N_"+str(N)+"_snr_"+str(snr)+"_train_n_"+str(train_n)+"_M_"+str(M)gcn_data = graph_data(root)Input_L = gcn_data.x.shape[1]model = Net()# model = Net().to(device)optimizer = torch.optim.Adam(params=model.parameters(), lr=0.01)criterion = torch.nn.BCEWithLogitsLoss()def train():model.train()optimizer.zero_grad()z = model.encode(gcn_data.x, gcn_data.edge_index)# out = model.decode(z, train_data.edge_label_index).view(-1).sigmoid()out = model.decode(z, gcn_data.edge_label_index).view(-1)out = 1 - outloss = criterion(out, gcn_data.edge_label)loss.backward()optimizer.step()return lossmin_loss = 99999count = 0#早停for epoch in range(10000):loss = train()if loss<min_loss:min_loss = losscount = 0count = count + 1if count>100:breakprint("epoch: ",epoch," loss: ",round(loss.item(),2), " min_loss: ",round(min_loss.item(),2))z = model.encode(gcn_data.x, gcn_data.edge_index)out = model.decode(z, gcn_data.edge_label_index).view(-1)list_0 = []list_1 = []for i in range(len(gcn_data.edge_label)):true_label = gcn_data.edge_label[i].item()euclidean_distance_value = out[i].item()if true_label==1:list_1.append(euclidean_distance_value)if true_label==0:list_0.append(euclidean_distance_value)minlength = min(len(list_1), len(list_0))list_1 = random.sample(list_1, minlength)list_0 = random.sample(list_0, minlength)value = list_1 + list_0large_class = list(np.full(len(value), snr))small_class = list(np.full(len(list_1), 1)) + list(np.full(len(list_0), 0))data = {'large_class': large_class,'small_class': small_class,'value': value}# 创建一个 DataFramedf = pd.DataFrame(data)## # 保存到 Excel 文件file_path = 'D:\无线通信网络认知\论文1\大修意见\图聚类、阈值相似性图实验补充\\' + mode + '_similarity_' + str(snr) + 'db_'+str(I)+'.xlsx'df.to_excel(file_path, index=False)
保存结果:
重点在这:
z = model.encode(gcn_data.x, gcn_data.edge_index)
out = model.decode(z, gcn_data.edge_label_index).view(-1)list_0 = []
list_1 = []for i in range(len(gcn_data.edge_label)):true_label = gcn_data.edge_label[i].item()euclidean_distance_value = out[i].item()if true_label==1:list_1.append(euclidean_distance_value)if true_label==0:list_0.append(euclidean_distance_value)
画出来后长这个样子,可以看出表示学习后,有关系和没关系的节点之间的特征距离区分度更明显了