当前位置:   article > 正文

社交网络群体精准识别定位_怎么识别社交媒体平台社群

怎么识别社交媒体平台社群

1. louvain算法

Louvain算法是一种常用的社区发现算法,可以将网络中的节点划分为若干个社区。对于给定的网络,Louvain算法通过最大化社区内部连接和最小化社区之间连接来优化社区结构。

1.1模块度

模块度(modularity)用于衡量一种社区划分是否比随机划分更好。具体而言,它是一个表示划分质量的指标,用于评估网络中节点之间的紧密程度

通常,将网络划分为若干个社区,每个社区中的节点在结构上具有较高的相似性。模块度的计算可以将网络中节点的分布情况与一个随机分布的节点分布进行比较。如果节点更倾向于聚集在一起,模块度会得到一个更高的值,表示社区结构更加明显。

模块度计算的步骤

  1. 计算整个网络的边权和 w w w,以及每个节点的度数 k i k_i ki

  2. 计算网络中每个社区的边权和 w c w_c wc,以及社区内节点的度数之和 k i c k_{ic} kic

  3. 计算社区结构的期望值,即若节点随机分布在网络上时,每个社区的边权和 和节点的度数之和的期望值 e ( w c ) e(w_c) e(wc) e ( k i c ) e(k_{ic}) e(kic)

  4. 计算模块度 Q Q Q,用来度量网络中社区结构的优越程度。模块度计算公式如下:

    Q = 1 2 w ∑ i , j ( A i j − k i k j 2 w ) δ ( c i , c j ) Q = \frac{1}{2w} \sum_{i,j} (A_{ij} - \frac{k_i k_j}{2w})\delta(c_i,c_j) Q=2w1i,j(Aij2wkikj)δ(ci,cj)

2w是总的度数(当边权为1的时候)
k j 2 ∗ w \frac{k_j}{ 2 * w} 2wkj 表示的是随机的情况下,j这个点连接到其他的任意的一个点的概率。
k j ∗ k i 2 ∗ w \frac{k_j * k_i}{ 2 * w} 2wkjki 就表示随机的情况下,i和j连接的边的数量
最优解是为了找到一个划分:使得该划分得到的结果中,模块度达到最大化。
对于i这个点来说,和它直接相连在同一个社区的节点的数量 - 随机情况下和它相连的节点的数量。

其中, A i j A_{ij} Aij表示节点 i i i和节点 j j j之间的边权 k i k_i ki k j k_j kj表示节点 i i i和节点 j j j的度数之和, w w w表示网络的边权和, c i c_i ci c j c_j cj表示节点 i i i和节点 j j j所属的社区。 δ ( c i , c j ) \delta(c_i,c_j) δ(ci,cj)表示两个节点所属的社区是否相同。如果相同,取值为 1 1 1,否则取值为 0 0 0

注意:例如,如果节点 i i i 和节点 j j j 的度数都比较大,那么在一个随机图中,它们之间的期望边权重就会比较大,而如果它们的度数都比较小,那么它们之间的期望边权重就会比较小。模块度的定义就是将实际边权重和期望边权重之间的差距作为网络社区划分的优劣度量。

公式中, k i k j 2 w \frac{k_i k_j}{2w} 2wkikj表示节点 i i i和节点 j j j之间边权的期望值, ( A i j − k i k j 2 w ) (A_{ij} - \frac{k_i k_j}{2w}) (Aij2wkikj)表示节点 i i i和节点 j j j之间边权与期望值的差 δ ( c i , c j ) \delta(c_i,c_j) δ(ci,cj)表示两个节点所属的社区是否相同,如果相同,则节点 i i i和节点 j j j之间的差值会被计入到社区内,否则被计入到社区外。

因此,模块度 Q Q Q表示了社区内边权之和边权期望值之差所有边权之和的比例。模块度的值越大,说明网络中的社区结构越明显

1.2 louvain社区发现流程

Louvain社区发现算法是一种基于贪心策略的层次聚类算法,其流程如下:

初始化:将每个节点视为一个单独的社区。
第一轮迭代:
2.1 对于每个节点,计算其与邻居节点所在的社区合并后,整个网络的模块度提升值。
2.2 将该节点移动到使(整个网络)模块度提升值最大的社区中。
2.3 如果所有节点都已经被遍历过,停止第一轮迭代。
将所有节点所在的社区视为一个新的节点,构建一个新的网络,其中节点为第二步中的社区,边权为两个社区之间的边权和。
重复第二步和第三步,直到模块度不再提升为止。
返回所有社区。

其中,模块度是用来衡量社区结构的指标,社区结构越明显,模块度越高。在Louvain算法中,模块度提升值是用来选择最优社区的关键。在每一轮迭代中,将每个节点移动到模块度提升值最大的社区中,可以最大化模块度的提升,从而找到最优的社区划分方案。

1.3 louvain社区发现算法实现

import networkx as nx
import itertools

def modularity(G, communities):
    """
    计算图的模块度

    :param G: 网络图,用 NetworkX 实现
    :param communities: 由社区构成的列表,每个社区是一个节点 ID 列表
    :return: 模块度
    """
    m = G.number_of_edges()
    Q = 0.0
    for community in communities:
        # 计算社区内部的边权重之和(计算社区内部的边的权重,这里表示的是边的数量)
        intra_edges = G.subgraph(community).number_of_edges()
        # 计算社区内部的度数之和
        degree_sum = sum(dict(G.degree(community)).values())
        # 计算社区对网络整体的贡献
        Q += (intra_edges / m) - ((degree_sum / (2 * m)) ** 2)
    return Q

def louvain(G):
    """
    Louvain 社区发现算法实现

    :param G: 网络图,用 NetworkX 实现
    :return: 一个由社区构成的列表,每个社区是一个节点 ID 列表
    """
    # 初始化
    communities = [[n] for n in G.nodes()]
    Q = modularity(G, communities)
    print("当前网络的模块度为:",Q)
    # 不断迭代,直到模块度不再增加
    while True:
        # 遍历每个节点
        for node in G.nodes():
            # 计算将该节点移到其他社区时,对模块度的贡献
            best_community = None
            best_delta_Q = 0.0
            node_community = None
            for i, community in enumerate(communities):
                if node in community:
                    node_community = i
                    break
            # 当前节点node所在的社区编号为node_community
            for i, community in enumerate(communities):
                delta_Q = 0.0
                if i == node_community:
                    continue
                # 计算该节点移到当前社区时对模块度的贡献
                to_community = community + [node]
                from_community = [n for n in communities[node_community] if n != node]
                delta_Q += modularity(G, [to_community, from_community]) - Q
                if delta_Q > best_delta_Q:
                    best_delta_Q = delta_Q
                    best_community = i
            # 如果将该节点移到其他社区会使模块度增加,则移动该节点
            if best_delta_Q > 0:
                communities[best_community].append(node)
                communities[node_community].remove(node)
                Q += best_delta_Q
        # 如果模块度不再增加,则结束迭代
        new_Q = modularity(G, communities)
        if new_Q == Q:
            break
        Q = new_Q
    # 返回最终的各个社区
    return communities

# 测试数据
G = nx.Graph()
G.add_edge(1, 2)
G.add_edge(1, 3)
G.add_edge(2, 3)
G.add_edge(2, 4)
G.add_edge(3, 4)
G.add_edge(4, 5)
G.add_edge(4, 6)
G.add_edge(5, 6)
print(louvain(G))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

2. networkx 库

networkx 是一个用于创建、操作和研究复杂网络的 Python 库。它提供了一系列简单而强大的工具来处理网络结构,包括节点的添加、删除、修改、查询,边的添加、删除、修改、查询,网络的遍历、复制、读写等等。同时,它还提供了许多算法,如最短路径算法、最大流算法、社区发现算法等,方便了网络分析和研究。

2.1 创建图

nx.Graph(): 创建一个空的无向图或有向图,可以选择创建无向图nx.Graph()、有向图nx.DiGraph()、有向无环图nx.DiGraph()。

import networkx as nx
G = nx.Graph()  # 创建一个空的无向图
  • 1
  • 2

2.2 添加节点

G.add_node(): 添加节点到图中,第一个参数是节点的名称,可以是任意可哈希类型的数据,第二个参数是节点的属性字典。

G.add_node(1)
G.add_node('apple', weight=1)

  • 1
  • 2
  • 3

2.3 添加边

G.add_edge(): 添加边到图中,第一个参数和第二个参数是节点的名称,第三个参数是边的权重。

G.add_edge(1, 2)
G.add_edge('apple', 'banana', weight=0.5)

  • 1
  • 2
  • 3

2.4 计算节点度数

nx.degree(): 返回节点的度数,可以选择返回入度或出度,第二个参数可以选择返回哪种度数,默认为节点的度数。

degree = nx.degree(G)  # 返回节点的度数
in_degree = nx.degree(G, weight='weight')  # 返回节点的入度
out_degree = nx.degree(G, weight='weight', incoming=False)  # 返回节点的出度
  • 1
  • 2
  • 3

返回图中节点的度数的字典:

图对象(Graph object).degree()方法用于计算图中每个节点的度数(degree),即与该节点相连的边数。

degree() 方法返回的是一个视图对象(View),而不是一个普通的列表或字典对象。视图对象是一种类似于生成器的可迭代对象,可以用于遍历网络图中所有节点的度(degree)信息,包括节点和对应的度数。视图对象的类型为 DegreeView,可以通过调用 type() 函数来查看返回的对象类型。这种设计可以有效地减少内存消耗,特别是对于大型网络图而言。如果需要将度信息存储为一个字典对象,可以使用 dict() 函数将视图对象转换为字典。

import networkx as nx

# 创建一个简单的图
G = nx.Graph()
G.add_edges_from([(1,2), (1,3), (2,3), (3,4), (4,5), (4,6)])

# 计算各个节点的度数
degrees = G.degree()

# 打印结果
print(degrees)
# {1: 2, 2: 2, 3: 3, 4: 3, 5: 1, 6: 1}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

可以看到,这个字典对象的键是图中的节点,对应的值是该节点的度数。例如,节点1和节点2的度数均为2,节点3和节点4的度数均为3,而节点5和节点6的度数均为1。

2.5 两个点的最短路径

nx.shortest_path(): 计算最短路径,返回最短路径上的节点列表。

# 计算从节点 'appple' 到节点 'banana' 的最短路径上的节点列表
shortest_path = nx.shortest_path(G, 'apple', 'banana')
  • 1
  • 2

nx.draw(): 画出图形,可以选择不同的布局方式,如随机布局、圆形布局、Kamada-Kawai布局等。

2.6 计算边

G.number_of_edges() 是 NetworkX 库中用于计算一个图 G 中边的数量的函数。

具体来说,该函数可以接受一个图对象 G 作为输入,然后返回这个图中所有边的数量。

下面是一个简单的例子:

import networkx as nx

# 创建一个简单的无向图
G = nx.Graph()
G.add_edge(1, 2)
G.add_edge(2, 3)
G.add_edge(3, 4)
# 计算边的数量
num_edges = G.number_of_edges()
print(num_edges) # 输出:3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这个例子中,我们创建了一个简单的无向图,然后调用 G.number_of_edges() 函数计算边的数量。最终,输出结果为 3,表示该图中共有 3 条边。

2.7 生成子图

在 NetworkX 中,G.subgraph(nodes) 函数可以用来返回包含给定节点列表的子图。该函数可以传入一个节点列表作为参数,也可以传入一个生成器对象。返回的是一个新的图对象,其包含指定的节点和相应的边。原始图对象 G 不会被修改。
下面是一个使用 G.subgraph() 函数的示例:

import networkx as nx

# 创建一个有向图
G = nx.DiGraph()

# 添加一些节点和边
G.add_edges_from([(1,2), (2,3), (3,1), (3,4), (4,5)])

# 打印原始图的边数
print(G.number_of_edges())  # 输出 5

# 获取节点 1、3 和 4 的子图
nodes = [1, 3, 4]
subgraph = G.subgraph(nodes)

# 打印子图的边数
print(subgraph.number_of_edges())  # 输出 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在上面的示例中,我们首先创建了一个有向图 G,然后添加了一些节点和边。接着,我们使用 G.subgraph() 函数获取节点 1、3 和 4 的子图,并打印了子图的边数。

2.8 从文件中读入图

read_edgelist()是NetworkX中用于读取边列表的函数。边列表是一种常用的存储图数据的格式,可以将图的每个节点表示为一个唯一的字符串或数字,并将图的边用一个或多个文件中的元组列表表示。

该函数的语法如下:

read_edgelist(path, comments='#', delimiter=None, create_using=None, nodetype=None, data=True, edgetype=None, encoding='utf-8')
  • 1

path:包含边列表的文件路径。

例如,假设有如下的边列表文件example.edgelist:

1 2
1 3
2 3
  • 1
  • 2
  • 3

则可以通过以下代码读取:

import networkx as nx
G = nx.read_edgelist('example.edgelist')
  • 1
  • 2

这样就可以将边列表中的边读入到NetworkX图对象G中。

2.9 画图

2.9.1 nx.draw

nx.draw是networkx中最基本的绘图函数之一,用于绘制无向或有向图形。它提供了许多参数来自定义绘图,例如节点颜色、节点大小、边的宽度和颜色等。

以下是常用的参数:

G:一个networkx图对象
pos:节点的位置,可以是一个字典,指定每个节点的坐标
node_color:节点的颜色
node_size:节点的大小
alpha:节点和边的透明度
with_labels:节点是否显示标签
labels:标签的字典,字典的键是节点,值是标签
font_size:标签的字体大小
font_color:标签的颜色
edge_color:边的颜色
width:边的宽度
style:边的线型
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

以下是一个例子:

import networkx as nx
import matplotlib.pyplot as plt

# 创建一个图
G = nx.Graph()

# 添加节点
G.add_nodes_from([1, 2, 3, 4, 5])

# 添加边
G.add_edges_from([(1, 2), (1, 3), (2, 3), (3, 4), (4, 5), (3, 5)])

# 绘图
pos = nx.spring_layout(G)
nx.draw(G, pos, node_color='lightblue', node_size=500, with_labels=True, font_size=16, font_color='black', edge_color='gray', width=2, style='dashed')

# 显示图形
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这个例子创建了一个无向图,添加了一些节点和边,使用Spring Layout算法进行布局,并绘制了节点和边。

2.9.2 draw_networkx_nodes函数和draw_networkx_edges函数

举例说明:

import networkx as nx
import matplotlib.pyplot as plt

# 创建简单图
G = nx.Graph()
G.add_edges_from([(1,2), (2,3), (3,4), (4,5), (5,1)])

# 计算节点的度数
degrees = dict(G.degree())
node_colors = [degrees[node] for node in G.nodes()]

# 绘制图形
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos, node_size=500, node_color=node_colors, cmap=plt.cm.Blues)
nx.draw_networkx_edges(G, pos, width=1.0, alpha=0.5)
nx.draw_networkx_labels(G, pos, font_size=12, font_family="sans-serif")
plt.axis("off")
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这个例子中,我们首先创建了一个简单的5个节点的无向图。然后使用dict(G.degree())计算了每个节点的度数,并将其存储在一个字典中。在绘制节点的时候,我们将节点的颜色设为其度数,使用了cmap=plt.cm.Blues参数表示颜色使用蓝色系。最后绘制出来的图形中,颜色越深的节点表示其度数越大。

3. anaconda和PyTorch安装

anaconda清华镜像源
下载anaconda的时候,一切都默认,然后选择要安装的路径即可。

下载完之后:

  1. 进入 anaconda prompt窗口
  2. conda create -n PyTorch python=3.8 创建虚拟环境 名字为:PyTorch
  3. 列出当前所有的虚拟环境:conda info --envs
  4. 进入虚拟环境:conda activate PyTorch
  5. 到PyTorch的官网:PyTorch下载地址
  6. 选择对应版本,然后复制下载的指令,在虚拟环境中安装。conda install pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia(CUDA)
    conda install pytorch torchvision torchaudio cpuonly -c pytorch (CPU)
  7. 测试:在虚拟环境中,进入python,然后
import torch
torch.cuda.is_available()
# 返回True说明下载成功!
  • 1
  • 2
  • 3
  1. 删除虚拟环境PyTorch:conda remove -n PyTorch --all

4. GCN算法实现

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
from torch_geometric.datasets import Planetoid
import time
# Load Cora dataset
dataset = Planetoid(root='data/Cora', name='Cora')
data = dataset[0]
data
'''
Data(x=[2708, 1433], edge_index=[2, 10556], y=[2708], train_mask=[2708], val_mask=[2708], test_mask=[2708])
'''
# Define GCN model
class GCN(nn.Module):
    # 接受三个参数:输入特征的维度input_dim,隐藏层特征的维度hidden_dim,以及输出特征的维度output_dim
    def __init__(self, input_dim, hidden_dim, output_dim):
        # super()函数调用了父类的构造函数,即nn.Module的构造函数。
        super(GCN, self).__init__()
        # 定义了两个GCNConv层,分别是从输入层到隐藏层的GCNConv(self.conv1)和从隐藏层到输出层的GCNConv(self.conv2)。
        self.conv1 = GCNConv(input_dim, hidden_dim)
        self.conv2 = GCNConv(hidden_dim, output_dim)

    # 定义了GCN类的前向传播函数forward()
    # 它接受两个参数:节点特征矩阵x和邻接矩阵edge_index。
    def forward(self, x, edge_index):    
        x = self.conv1(x, edge_index)    # 首先使用self.conv1对输入的节点特征矩阵x和邻接矩阵edge_index进行卷积操作,得到隐藏层特征
        x = F.relu(x)                    # 然后使用ReLU激活函数对隐藏层特征进行激活
        x = self.conv2(x, edge_index)    # 最后再使用self.conv2对激活后的特征进行卷积操作,得到输出特征
        return F.log_softmax(x, dim=1)   # 最后,我们使用log_softmax函数对输出特征进行softmax操作并返回结果。
     
    
# Initialize model, loss and optimizer
# 定义了一个 GCN 模型对象,使用输入特征的维度 input_dim、隐藏层维度 hidden_dim、输出维度 output_dim 进行初始化。
model = GCN(input_dim=data.x.size()[1], hidden_dim=32, output_dim=dataset.num_classes)
criterion = nn.NLLLoss()            # 定义了一个负对数似然损失函数对象,用于衡量模型预测和真实标签之间的误差。
optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # 定义了一个 Adam 优化器对象,用于更新模型的参数,其中 model.parameters() 表示将模型中所有可学习的参数传递给优化器进行更新,lr 参数表示学习率。

# Train model
model.train()
for epoch in range(200):
    optimizer.zero_grad()   # 将模型的所有梯度设置为0,防止梯度累加影响模型的训练效果
    out = model(data.x, data.edge_index)           # 进行一次前向传播,将节点特征和邻接矩阵作为输入,得到模型的输出结果out
    loss = criterion(out[data.train_mask], data.y[data.train_mask]) # 计算模型输出结果和标签之间的损失函数值,这里使用的是负对数似然损失函数(NLLLoss),只对训练集中的样本计算损失函数
    loss.backward()     # 根据损失函数值反向传播计算梯度
    optimizer.step()        # 使用优化器更新模型的参数,将学习率 lr 作为参数传递给优化器


# Evaluate model
model.eval()              # 将模型设置为评估模式
_, pred = model(data.x, data.edge_index).max(dim=1)  # 使用经过训练的模型对测试数据进行预测,返回的是预测值的张量和每个预测值对应的标签张量。
# pred是一个张量,保存的是所有的节点的标签的预测值
correct = float(pred[data.test_mask].eq(data.y[data.test_mask]).sum().item()) # 对预测结果进行评估,计算预测正确的数量。
accuracy = correct / data.test_mask.sum().item()    # 计算测试集上的准确率。
print(f'Test accuracy: {accuracy:.4f}')         # 打印测试集准确率。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

5.GCN算法的讲解

GCN是Graph Convolutional Network(图卷积网络)的缩写,它是一种深度学习模型,用于处理图数据。

算法的思想:

  • 它将图中节点的特征向量组成的矩阵视为输入,并将图的连接方式编码成邻接矩阵,然后利用卷积神经网络的思想进行计算。

思路:
GCN的基本思路是利用邻接矩阵节点特征矩阵相乘,然后将结果送入一个非线性变换中(我们需要对这个新的特征矩阵进行一个非线性变换,以便更好地抓取节点之间的复杂关系。通常我们使用激活函数(如ReLU)作为非线性变换,将其作用于新特征矩阵中的每个元素,从而得到激活后的特征矩阵,即下一层节点的特征矩阵。)得到下一层节点的特征矩阵。

5.1GCN算法举例说明

假设我们的无向图如下所示:

    (1)
    / \
   /   \
 (2)---(3)
   |   |
   |   |
 (4)   (5)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

每个节点的特征向量分别为:

node 1: [0.5, 0.7]
node 2: [0.3, 0.2]
node 3: [0.8, 0.6]
node 4: [0.1, 0.9]
node 5: [0.4, 0.5]
  • 1
  • 2
  • 3
  • 4
  • 5

我们要对每个节点进行分类,即将它们分为蓝色和红色两类。假设我们已经知道节点 1 和节点 2 是蓝色节点,节点 3、节点 4 和节点 5 是红色节点,现在我们要用 GCN 算法对其它节点进行分类。

首先,我们需要建立邻接矩阵。根据图中的连接关系,邻接矩阵可以表示为:

A = [[0, 1, 1, 0, 0],
     [1, 0, 1, 1, 0],
     [1, 1, 0, 0, 1],
     [0, 1, 0, 0, 0],
     [0, 0, 1, 0, 0]]
  • 1
  • 2
  • 3
  • 4
  • 5

接下来,我们需要对邻接矩阵进行归一化处理,得到:

D = [[2, 0, 0, 0, 0],
     [0, 3, 0, 0, 0],
     [0, 0, 3, 0, 0],
     [0, 0, 0, 1, 0],
     [0, 0, 0, 0, 1]]

# D^{-1/2}
# 先求对角矩阵的逆矩阵,由于是对角矩阵,因此可以直接将里面的所有数都取逆得到D^{-1}
D_inv_sqrt = [[0.7071, 0,      0,      0,      0     ],
              [0,      0.5774, 0,      0,      0     ],
              [0,      0,      0.5774, 0,      0     ],
              [0,      0,      0,      1,      0     ],
              [0,      0,      0,      0,      1     ]]
# D 是度矩阵,D_inv_sqrt 是度矩阵的负平方根.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

然后,我们需要构建邻接矩阵。这里我们使用对称归一化的邻接矩阵,其计算方式为:
D i i = ∑ j = 1 n A i j D_{ii} = \sum_{j=1}^{n}A_{ij} Dii=j=1nAij

A ~ = D − 1 2 A D − 1 2 \tilde{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}} A~=D21AD21

其中, A A A为邻接矩阵, D D D为度数矩阵。

计算过程:

import numpy as np
A = np.array([[0, 1, 1, 0, 0],
    [1, 0, 1, 1, 0],
    [1, 1, 0, 0, 1],
    [0, 1, 0, 0, 0],
    [0, 0, 1, 0, 0]])
D = np.array([[0.7071, 0,      0,      0,      0     ],
              [0,      0.5774, 0,      0,      0     ],
              [0,      0,      0.5774, 0,      0     ],
              [0,      0,      0,      1,      0     ],
              [0,      0,      0,      0,      1     ]])
A_ = np.dot(D, A)
A_ = np.dot(A_,D)
print(A_)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
# 得到临界矩阵的标准化矩阵:
D^{-1/2}AD^{-1/2} =	[[0.         0.40827954 0.40827954 0.        0.        ]
 					[0.40827954 0.         0.33339076 0.5774     0.        ]
					[0.40827954 0.33339076 0.         0.         0.5774    ]
 					[0.         0.5774     0.         0.         0.        ]
 					[0.         0.         0.5774     0.         0.        ]]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5.2 模型前向传播

模型前向传播(forward propagation)是指通过神经网络模型将输入数据传递至输出的过程,也可以称为“模型推理”或“模型预测”。在训练过程中,前向传播是指在给定输入的情况下,通过神经网络模型计算出输出,并将其与真实标签进行比较以计算误差,以便更新模型的参数。

在训练过程中,每次迭代(或称为“epoch”)都会进行多次前向传播和反向传播(backpropagation)以更新模型参数,以最小化误差。而在测试阶段,我们可以使用训练好的模型进行前向传播以预测新的数据样本的标签。

在上述的GCN模型中,模型前向传播指的是将输入数据和邻接矩阵输入到模型中,经过多层GCN变换后,最终输出节点的表示向量。这一过程中,每一层GCN都会进行前向传播,即将上一层的节点表示向量乘以W矩阵并计算新的节点表示向量,最终输出每个节点的表示向量

5.3 模型的反向传播

模型的反向传播指的是在训练神经网络模型时,通过梯度下降算法计算每个参数对损失函数的梯度,并将这些梯度反向传播到神经网络的每一层,用于调整每个参数的值,从而最小化损失函数。

具体来说,反向传播算法通过使用链式法则,将输出误差向后传递并计算每个参数的梯度,然后使用梯度下降法或其它优化算法来更新模型参数,使得损失函数最小化。

反向传播是深度学习中最常用的训练算法之一,它能够高效地计算参数梯度,从而在大规模数据上训练高效的神经网络模型。

举例说明:
模型的反向传播指的是在训练神经网络模型时,通过梯度下降算法计算每个参数对损失函数的梯度,并将这些梯度 反向传播到神经网络的每一层,用于调整每个参数的值,从而最小化损失函数

具体来说,反向传播的过程是将损失函数对模型输出的偏导数通过链式法则,逐层向前计算出每个参数的偏导数。假设有一个三层神经网络,其中第一层的输入为 x x x,第二层的输出为 h h h,第三层的输出为 y y y,损失函数为 L L L。则反向传播的过程如下:

1.计算损失函数对输出的偏导数: ∂ L ∂ y \frac{\partial L}{\partial y} yL

2.根据链式法则计算损失函数对第三层输出的偏导数: ∂ L ∂ y ∗ ∂ y ∂ h \frac{\partial L}{\partial y} * \frac{\partial y}{\partial h} yLhy

3.将第二层的偏导数传播回第一层: ( ∂ L ∂ y ∗ ∂ y ∂ h ) ∗ ∂ h ∂ x (\frac{\partial L}{\partial y} * \frac{\partial y}{\partial h}) * \frac{\partial h}{\partial x} (yLhy)xh

4.使用得到的偏导数更新网络中的参数,以最小化损失函数。

以上是一个简单的例子,实际的神经网络可能会更加复杂,但是反向传播的过程都是类似的。

5.4 损失函数

损失函数(loss function)是指在机器学习和深度学习中用来衡量模型预测结果与实际结果之间差异的函数,通常也被称为误差函数(error function)或代价函数(cost function)。它的值越小,则说明模型的预测结果越接近实际结果。

举个例子,比如在分类问题中,我们用模型预测每个样本属于每个类别的概率分布,通常使用交叉熵损失函数(cross-entropy loss)来度量模型的预测与实际标签之间的差异。其公式为:

L = − 1 N ∑ i = 1 N ∑ j = 1 M y i j log ⁡ ( p i j ) L = -\frac{1}{N}\sum_{i=1}^N\sum_{j=1}^My_{ij}\log(p_{ij}) L=N1i=1Nj=1Myijlog(pij)

其中, N N N表示样本总数, M M M表示类别数, y i j y_{ij} yij表示第 i i i个样本是否属于第 j j j个类别的标签, p i j p_{ij} pij表示模型预测第 i i i个样本属于第 j j j个类别的概率。我们希望通过最小化交叉熵损失函数来优化模型的参数,使得模型的预测结果与实际标签之间的差异尽可能小。

6.用户的兴趣

热点兴趣:体育、电视剧、财经、游戏、音乐、星座、旅游、情感、美食和房产

社交网络群体发现中的基本概念

社交网络群体定义为:基于社交媒体平台的结构上紧密连接而且用户节点属性特征较为相似的用户节点以及这些节点属性的集合。

社区是一些节点的集合,每个社区内部的节点间的联系比较紧密,各个社区之间的连接对比社区内部更加稀疏。社区仅考虑网络节点间的拓扑结构,而没有考虑节点自身的属性特征,具有相似属性的节点更有可能属于同一个群体。

特定群体指的是包含特定属性信息的群体或者包含指定用户节点的群体
特定群体的含义随着领域的变化有一些细微的差别,比如在公共安全领域,特定群体指包含特定成员的犯罪组织,符合指定描述特征的传销组织等。在网络营销领域,特定群体指的是与代表性用户有着相似需求和兴趣的用户群体或者是商家特定产品受众的群体。在网络管控领域,特定群体指的是受某些意见领袖影响的群体,符合特征的谣言传播群体等。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/71072
推荐阅读
相关标签
  

闽ICP备14008679号