标签传播算法(llgc 或 lgc)

动手实践标签传播算法

初始化算法

载入一些必备的库:

from IPython.display import set_matplotlib_formats
%matplotlib inline
#set_matplotlib_formats(‘svg‘, ‘pdf‘)

import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist
from sklearn.datasets import make_moons

save_dir = ‘../data/images‘

创建一个简单的数据集

利用 make_moons 生成一个半月形数据集。

n = 800   # 样本数
n_labeled = 10 # 有标签样本数
X, Y = make_moons(n, shuffle=True, noise=0.1, random_state=1000)

X.shape, Y.shape
((800, 2), (800,))
def one_hot(Y, n_classes):
    ‘‘‘
    对标签做 one_hot 编码

    参数
    =====
    Y: 从 0 开始的标签
    n_classes: 类别数
    ‘‘‘
    out = Y[:, None] == np.arange(n_classes)
    return out.astype(float)
color = [‘red‘ if l == 0 else ‘blue‘ for l in Y]
plt.scatter(X[:, 0], X[:, 1], color=color)
plt.savefig(f"{save_dir}/bi_classification.pdf", format=‘pdf‘)
plt.show()

Y_input = np.concatenate((one_hot(Y[:n_labeled], 2), np.zeros((n-n_labeled, 2))))

算法过程:

Step 1: 创建相似度矩阵 W

def rbf(x, sigma):
    return np.exp((-x)/(2* sigma**2))
sigma = 0.2
dm = cdist(X, X, ‘euclidean‘)
vfunc = np.vectorize(rbf)
vfunc = np.vectorize(rbf)
W = vfunc(dm, sigma)
np.fill_diagonal(W, 0)   # 对角线全为 0

Step 2: 计算 S

\[
S = D^{-\frac{1}{2}} W D^{-\frac{1}{2}}
\]

向量化编程:

def calculate_S(W):
    d = np.sum(W, axis=1)
    D_ = np.sqrt(d*d[:, np.newaxis]) # D_ 是 np.sqrt(np.dot(diag(D),diag(D)^T))
    return np.divide(W, D_, where=D_ != 0)

S = calculate_S(W)

迭代一次的结果

alpha = 0.99
F = np.dot(S, Y_input)*alpha + (1-alpha)*Y_input

Y_result = np.zeros_like(F)
Y_result[np.arange(len(F)), F.argmax(1)] = 1

Y_v = [1 if x == 0 else 0 for x in Y_result[0:,0]]

color = [‘red‘ if l == 0 else ‘blue‘ for l in Y_v]
plt.scatter(X[0:,0], X[0:,1], color=color)
#plt.savefig("iter_1.pdf", format=‘pdf‘)
plt.show()

Step 3: 迭代 F "n_iter" 次直到收敛

n_iter = 150
F = Y_input
for t in range(n_iter):
    F = np.dot(S, F)*alpha + (1-alpha)*Y_input

Step 4: 画出最终结果

Y_result = np.zeros_like(F)
Y_result[np.arange(len(F)), F.argmax(1)] = 1

Y_v = [1 if x == 0 else 0 for x in Y_result[0:,0]]

color = [‘red‘ if l == 0 else ‘blue‘ for l in Y_v]
plt.scatter(X[0:,0], X[0:,1], color=color)
#plt.savefig("iter_n.pdf", format=‘pdf‘)
plt.show()

from sklearn import metrics

print(metrics.classification_report(Y, F.argmax(1)))

acc = metrics.accuracy_score(Y, F.argmax(1))
print(‘准确度为‘,acc)
              precision    recall  f1-score   support

           0       1.00      0.86      0.92       400
           1       0.88      1.00      0.93       400

   micro avg       0.93      0.93      0.93       800
   macro avg       0.94      0.93      0.93       800
weighted avg       0.94      0.93      0.93       800

准确度为 0.92875

sklearn 实现 lgc

参考:https://scikit-learn.org/stable/modules/label_propagation.html

在 sklearn 里提供了两个 lgc 模型:LabelPropagationLabelSpreading,其中后者是前者的正则化形式。\(W\) 的计算方式提供了 rbfknn

  • rbf 核由参数 gamma控制(\(\gamma=\frac{1}{2{\sigma}^2}\))
  • knn 核 由参数 n_neighbors(近邻数)控制
def pred_lgc(X, Y, F, numLabels):
    from sklearn import preprocessing
    from sklearn.semi_supervised import LabelSpreading
    cls = LabelSpreading(max_iter=150, kernel=‘rbf‘, gamma=0.003, alpha=.99)
    # X.astype(float) 为了防止报错 "Numerical issues were encountered "
    cls.fit(preprocessing.scale(X.astype(float)), F)
    ind_unlabeled = np.arange(numLabels, len(X))
    y_pred = cls.transduction_[ind_unlabeled]
    y_true = Y[numLabels:].astype(y_pred.dtype)
    return y_true, y_pred
Y_input = np.concatenate((Y[:n_labeled], -np.ones(n-n_labeled)))
y_true, y_pred = pred_lgc(X, Y, Y_input, n_labeled)
print(metrics.classification_report(Y, F.argmax(1)))
              precision    recall  f1-score   support

           0       1.00      0.86      0.92       400
           1       0.88      1.00      0.93       400

   micro avg       0.93      0.93      0.93       800
   macro avg       0.94      0.93      0.93       800
weighted avg       0.94      0.93      0.93       800

networkx 实现 lgc

先谈谈 networkx 的 graph 与其他数据格式转换(参考:https://www.cnblogs.com/wushaogui/p/9240941.html) :

从字典生成图

import networkx as nx
from networkx.algorithms import node_classification
dod = {0: {1: {‘weight‘: 1}}}
G = nx.from_dict_of_dicts(dod)  #或G=nx.Graph(dpl)
plt.subplots(1,1,figsize=(6,3))
nx.draw(G)
plt.axis(‘on‘)
plt.xticks([])
plt.yticks([])
plt.show() 

#图转换为字典
print(nx.to_dict_of_dicts(G))

{0: {1: {‘weight‘: 1}}, 1: {0: {‘weight‘: 1}}}

从列表中创建graph

dol = {0: [1, 2, 3]}
edgelist = [(0, 1), (0, 3), (2, 3)]

G1 = nx.from_dict_of_lists(dol)  # 或G=nx.Graph(dol)
G2 = nx.from_edgelist(edgelist)

# 显示graph
plt.subplots(1, 2, figsize=(5, 3))
plt.subplot(121)
nx.draw(G1, with_labels=True, font_weight=‘bold‘)
plt.axis(‘on‘)
plt.xticks([])
plt.yticks([])
plt.subplot(122)
nx.draw(G2, with_labels=True, font_weight=‘bold‘)
plt.axis(‘on‘)
plt.xticks([])
plt.yticks([])
plt.show()

# graph转list
print(nx.to_dict_of_lists(G1))
print(nx.to_edgelist(G1))

{0: [1, 2, 3], 1: [0], 2: [0], 3: [0]}
[(0, 1, {}), (0, 2, {}), (0, 3, {})]

graph 与 numpy

#从numpy创建graph
import numpy as np
a = np.reshape(np.random.random_integers(0, 1, size=100), (10, 10))
D = nx.DiGraph(a)
nx.draw(D, with_labels=True, font_weight=‘bold‘)
plt.axis(‘on‘)
plt.xticks([])
plt.yticks([])
plt.show() 

#graph返回numpy
G=nx.Graph()
G.add_edge(1, 2, weight=7.0, cost=5)
A1 = nx.to_numpy_matrix(G)
A2 = nx.to_numpy_recarray(G, dtype=[(‘weight‘, float), (‘cost‘, int)])
print(A1,A2) 

[[0. 7.]
 [7. 0.]] [[(0., 0) (7., 5)]
 [(7., 5) (0., 0)]]

从 scipy 创建 graph

#从scipy创建graph
G.clear()
import scipy as sp
A = sp.sparse.eye(2, 2, 1)
G = nx.from_scipy_sparse_matrix(A)
nx.draw(D, with_labels=True, font_weight=‘bold‘)
plt.axis(‘on‘)
plt.xticks([])
plt.yticks([])
plt.show() 

#graph返回scipy
A = nx.to_scipy_sparse_matrix(G)
print(A.todense())

[[0. 1.]
 [1. 0.]]

graph 与 Pandas

#从pandas创建graph
G.clear()
import pandas as pd
df = pd.DataFrame([[1, 1], [2, 1]])
G = nx.from_pandas_adjacency(df)
nx.draw(D, with_labels=True, font_weight=‘bold‘)
plt.axis(‘on‘)
plt.xticks([])
plt.yticks([])
plt.show() 

#graph返回scipy
df = nx.to_pandas_adjacency(G)
print(df)

     0    1
0  1.0  2.0
1  2.0  1.0

参考:networkx.algorithms.node_classification.lgc.local_and_global_consistency 具体的细节,我还没有研究!先放一个简单的例子:

G = nx.path_graph(4)
G.node[0][‘label‘] = ‘A‘
G.node[3][‘label‘] = ‘B‘
G.nodes(data=True)

G.edges()

predicted = node_classification.local_and_global_consistency(G)
predicted
[‘A‘, ‘A‘, ‘B‘, ‘B‘]

更多精彩内容见:DecodePaper 觉得有用,记得给个 star !(@DecodePaper)

原文地址:https://www.cnblogs.com/q735613050/p/10402835.html

时间: 2024-10-25 12:03:19

标签传播算法(llgc 或 lgc)的相关文章

UCI标签传播算法

半监督学习 顾名思义是介于分类(监督学习)与聚类(无监督学习)之间的一种学习范式.给定很少一部分样本的类标签,怎么样利用少部分具有类标签的数据来提高聚类的准确率是其研究主题.其中基于图的标签传播(Label Propagation)算法是有影响的算法之一. UCI机器学习数据库:http://archive.ics.uci.edu/ml/ 原理:某个测试用例的对象的标签(类别)和它附近的对象的标签相同,我们可以根据距离或者相似性来为两个对象设定一个权重.如果a和b的距离越小或者相似性越大的,则a

标签传播算法

参考文献:http://blog.csdn.net/cleverlzc/article/details/39494957Gephi 是一款网络分析领域的可视化处理软件,可以用于数据分析,链接分析,社交网络分析等.标签传播算法LPA(Label Propagation Algorithm)最早是针对社区发现问题提出时的一种解决方案.主要优点有:时间复杂度(近似线性),不需要事先知道社区数量.主要算法流程:首先为每个节点设置唯一标签,接着迭代依次更新各个节点,针对每个节点,通过统计节点邻居的标签,选

Label Propagation Algorithm LPA 标签传播算法解析及matlab代码实现

LPA算法的思路: 首先每个节点有一个自己特有的标签,节点会选择自己邻居中出现次数最多的标签,如果每个标签出现次数一样多,那么就随机选择一个标签替换自己原始的标签,如此往复,直到每个节点标签不再发生变化,那么持有相同标签的节点就归为一个社区. 算法优点:思路简单,时间复杂度低,适合大型复杂网络. 算法缺点:众所周知,划分结果不稳定,随机性强是这个算法致命的缺点. 体现在:(1)更新顺序.节点标签更新顺序随机,但是很明显,越重要的节点越早更新会加速收敛过程 (2)随机选择.如果一个节点的出现次数最

lpa标签传播算法讲解及代码实现

package lpa; import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class LPA { public static float sigma = 1; public static int tag_num = 2; public static void main(String[] args) { float[][] data = { {1,1}, {1,2}, {2,1}, {2

lpa标签传播算法解说及代码实现

package lpa; import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class LPA { public static float sigma = 1; public static int tag_num = 2; public static void main(String[] args) { float[][] data = { {1,1}, {1,2}, {2,1}, {2

神经网络训练中的Tricks之高效BP(反向传播算法)

神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) [email protected] http://blog.csdn.net/zouxy09 Tricks!这是一个让人听了充满神秘和好奇的词.对于我们这些所谓的尝试应用机器学习技术解决某些问题的人,更是如此.曾记得,我们绞尽脑汁,搓手顿足,大喊“为什么我跑的模型不work?”,“为什么我实现的效果那么差?”,“为什么我复现的结果没有他论文里面说的那么好?”.有人会和你说“你不懂调参!

神经网络的正反向传播算法推导

1 正向传播 1.1 浅层神经网络 为简单起见,先给出如下所示的简单神经网络: 该网络只有一个隐藏层,隐藏层里有四个单元,并且只输入一个样本,该样本表示成一个三维向量,分别为为\(x_1\),\(x_2\)和\(x_3\).网络的输出为一个标量,用\(\hat{y}\)表示.考虑该神经网络解决的问题是一个二分类的问题,把网络的输出解释为正样本的概率.比方说输入的是一张图片(当然图片不可能只用三维向量就可以表示,这里只是举个例子),该神经网络去判断图片里面是否有猫,则\(\hat{y}\)代表该图

[2] TensorFlow 向前传播算法(forward-propagation)与反向传播算法(back-propagation)

TensorFlow Playground http://playground.tensorflow.org 帮助更好的理解,游乐场Playground可以实现可视化训练过程的工具 TensorFlow Playground的左侧提供了不同的数据集来测试神经网络.默认的数据为左上角被框出来的那个.被选中的数据也会显示在最右边的 “OUTPUT”栏下.在这个数据中,可以看到一个二维平面上有红色或者蓝色的点,每一个小点代表了一个样例,而点的颜色代表了样例的标签.因为点的颜色只有两种,所以这是 一个二

反向传播算法简介

<!doctype html> 反向传播算法html {overflow-x: initial !important;}:root { --bg-color:#ffffff; --text-color:#333333; --select-text-bg-color:#B5D6FC; --select-text-font-color:auto; --monospace:"Lucida Console",Consolas,"Courier",monospac