Fork me on GitHub

Graph Embedding| Node2Vec

Graph Embedding 

什么是Graph Embedding 

Graph Embedding场景:

  • 社交网络,生物信息,用户行为序列(购物,浏览)都存在着大量的关系图谱
  • Graph Embedding是一种Embedding降维技术,可以有效的挖掘图网络中的节点特征表示
  • 在推荐系统、计算广告领域中的热点模型
  • word2vec等Embedding技术的延伸

 

Graph Embedding的作用:

帮助我们从图网络中进行特征提取,将图网络中的点用低维的向量表示,并且这些向量要能反应原有网络的特性,比如原网络中两个点的结构类似,那么这两个点表示的向量也应该类似

主要方法:

  • factorization methods (图因式分解机)
  • random walk techniques(随机游走)
  • deep learning(深度学习)

 

Deep Walk 

Deep Walk算法:

  • DeepWalk Online Learning of Social Representations, 2014 KDD
  • https://classes.cs.uoregon.edu/17S/cis607bddl/papers/Perozzi.pdf
  • 输入是一张图网络,输出为网络中顶点的向量表示
  • 通过截断随机游走(truncated random walk)学习出一个网络的社会表示(social representation),在网络标注顶点很少的情况也能得到比较好的效果
  • 具有可扩展的优点,能够适应网络的变化

115个平权的顶点,假如一个顶点可以产生5个句子,遍历每个顶点,找到它的邻居顶点,random随机选择,限制句子最大长度10;

一共会产生多少个句子,115*5=575个,575*10; 把图变成多个一维数组;

 

  • 借助NLP中的word2vec,也就是word embedding(词嵌入)
  • word embedding的基本元素是word,在Graph中表示的就是Node,
  • word embedding是对构成一个句子中单词序列进行分析,在Graph Network中Node构成的序列就是Random Walk
  • random walk,即随机游走,指的是从某个特定的端点开始,游走的每一步都从与当前节点相连的边中随机选择一条,沿着选定的边移动到下一个顶点,不断重复这个过程

 

Deep Walk算法:

  • DeepWalk = Random Walk + Skip-gram
  • Step1,给定当前访问起始节点,从其邻居中随机采样节点作为下一个访问节点,重复此过程,直到访问序列长度满足预设条件,产生大量词序列(句子)
  • Step2,将这些词序列作为训练样本输入word2vec,用Skip-gram + Hierarchical softmax进行训练,得到词的embedding

 

Deep Walk算法:

  • DeepWalk = Random Walk + Skip-gram

用户行为中如何对物品进行Embedding:

  • 基于用户行为序列构建了物品相关图,物品A,B之间存在边是因为用户U1先后购买了物品A和物品B,所以产生了A => B的有向边。
  • 如果后续产生了多条相同的有向边,则有向边的权重被加强。将所有用户行为序列都转换成物品相关图中的边之后,全局的物品相关图就建立起来了
  • 采用随机游走的方式随机选择起始点,重新产生物品序列
  • 最终将这些物品序列输入word2vec模型,生成最终的物品Embedding向量

用户u1,u2,u3,假设用户u1点击了D A B,虚线是时间间隔大于30min (以session作为划分),把它转化为图;

D->A->B;

B->E;  D->E->F;

E->C->B;B->A;

通过random walk generation,生成如图c,限制最大长度为5个;

最后通过skip-gram,一个学习向量化表达,得到商品的embedding;

 

Deep Walk算法

随机游走的跳转概率,也就是到达节点vi后,下一步遍历vi的临接点vj的概率

如果物品的相关图是有向有权图,那么从节点vi跳转到节点vj的概率定义为

N+(vi)是节点vi所有的出边集合,Mij是节点vi到节点vj边的权重。

如果物品相关图是无相无权重图,那么跳转概率将是上面公式的一个特例,即权重Mij将为常数1,且N+(vi)应是节点vi所有“边”的集合,而不是所有“出边”的集合

 

Project美国大学生足球队Embedding

复制代码
import networkx as nx
# 数据加载,构造图
G = nx.read_gml('football.gml')
#球队总数
print(len(G)) 
#都有哪些球队
print(G.nodes()) 
#都有哪些比赛
print(G.edges()) 


# 随机游走,input: 将节点和被遍历的路径的长度作为输入,output: 返回遍历节点的顺序:
def get_randomwalk(node, path_length):
    random_walk = [node]
    for i in range(path_length-1):
        temp = list(G.neighbors(node))
        temp = list(set(temp) - set(random_walk))    
        if len(temp) == 0:
            break
        random_node = random.choice(temp)
        random_walk.append(random_node)
        node = random_node        
    return random_walk
print(get_randomwalk('EastCarolina', 10))


# 从图获取所有节点的列表
all_nodes = list(G.nodes())
# 捕获数据集中所有节点的随机游走序列
random_walks = []
for n in tqdm(all_nodes):
    # 每个节点游走5次,每次最长距离为10
    for i in range(5):
        random_walks.append(get_randomwalk(n,10))
# 输出随机游走序列,及序列个数
print(random_walks)
print(len(random_walks))


## 一共115支球队,每支球队游走5次,一共115*5=575个word sequence


# 使用skip-gram,提取模型学习到的权重
from gensim.models import Word2Vec
# 训练skip-gram (word2vec)模型
model = Word2Vec(window = 4, sg = 1, hs = 0,
                 negative = 10, # 负采样
                 alpha=0.03, min_alpha=0.0007,
                 seed = 14)
# 从random_walks中创建词汇表
model.build_vocab(random_walks, progress_per=2)
model.train(random_walks, total_examples = model.corpus_count, epochs=20, report_delay=1)
print(model)
# 输出和EastCarolina相似的球队
print(model.similar_by_word('EastCarolina'))



# 在二维空间中绘制所选节点的向量
def plot_nodes(word_list):
    X = model[word_list]
    #print(type(X))
    # 将100维向量减少到2维
    pca = PCA(n_components=2)
    result = pca.fit_transform(X) 
    #print(result)
    # 绘制节点向量
    plt.figure(figsize=(12,9))
    # 创建一个散点图的投影
    plt.scatter(result[:, 0], result[:, 1])
    for i, word in enumerate(word_list):
        plt.annotate(word, xy=(result[i, 0], result[i, 1]))        
    plt.show()
# 将所有的球队embedding进行绘制
plot_nodes(model.wv.vocab)
复制代码

Word2Vec工具

gensim.models.word2vec.Word2Vec(sentences=None,size=100,alpha=0.025,window=5, min_count=5, sample=0.001,seed=1, orkers=3,min_alpha=0.0001, sg=0, hs=0, negative=5, iter=5, trim_rule=None)

  • sentences,可以是一个list
  • size,特征向量的维度,默认为100,更大的 size 值需要更多的训练数据,但也同时可以得到更准确的模型。合理的取值范围是几十到几百
  • alpha,初始的学习速率,在训练过程中会线性地递减到min_alpha。
  • window,窗口大小,表示当前词与预测词在一个句子中的最大距离
  • min_count,可以对字典做截断,词频少于min_count次数的单词会被丢弃掉, 默认值为5
  • max_vocab_size,设置词向量构建期间的RAM限制,设置成None则没有限制
  • sample,高频词汇的随机降采样的配置阈值,默认为1e-3,范围是(0,1e-5)
  • seed,随机数种子
  • workers,训练的并行线程数
  • min_alpha,学习率的最小值
  • sg,指定训练算法,默认为0,CBOW算法,sg=1采用skip-gram算法
  • hs,如果为1则会采用hierarchica softmax。如果设置为0(默认),则使用negative sampling
  • negative,如果>0,采用negative sampling,用于设置多少个noise words(一般是5-20)
  • iter,迭代次数,默认为5
  • trim_rule,用于设置词汇表的整理规则,指定那些单词要留下,哪些要被删除。可以设置为None(min_count会被使用)

 

  • 从一系列句子中创建词汇表
    • build_vocab(sentences, update=False, progress_per=10000, keep_raw_vocab=False, trim_rule=None, **kwargs)
  • 训练,从一系列句子更新模型的神经权重
    • train(sentences, total_words=None, word_count=0, total_examples=None, queue_factor=2, report_delay=1.0)
    • 如果想要支持从(初始)alpha到min_alpha的线性学习速率的衰减,需要提供total_examples(句子数)
  • 模型保存
    • model.save('mymodel')
  • 模型载入
    • new_model = gensim.models.Word2Vec.load('mymodel')
  • 查询词向量
    • model['computer'] 
    • 结果:array([-0.00449447, -0.00310097, 0.02421786, ...], dtype=float32)
  • 相似度任务
    • model.most_similar(positive=['woman', 'king'], negative=['man'], topn=1)     #woman + king - man = queen 
    • 结果:[('queen', 0.50882536)]
    • model.similarity('woman', 'man')
    • 结果:0.73723527

Node2Vec算法模型

Node2Vec算法:

  • node2vec: Scalable Feature Learning for Networks, 2016 KDD
  • https://arxiv.org/abs/1607.00653
  • 在DeepWalk基础上进行改进,可以控制进行BFS,DFS随机游走(带偏置的random walk策略)
  • BFS,Breadth-first Sampling,倾向于在初始节点的周围游走,反映出一个节点的邻居的微观特性  (广度优先,邻居、周边 微观)
  • DFS,Depth-first Sampling,倾向于跑得离初始节点越来越远,反映出一个节点邻居的宏观特性 (深度优先,跑到远处  宏观)

 

Node2Vec算法:

  • 从节点t跳转到节点v后,下一步从节点v跳转到周围各点的跳转概率 πVX  = αpq (t, x).wvx
    • 其中πVX代表边vx的权重, αpq (t, x) 称为Search bias,有3种情况: (下一个节点到上一个节点的距离有多少种可能性? (x1, x2, x3, t) 到t 的距离 

                    

        dtx 代表节点t 到节点x 的距离;

 

 

p和q用来调节Node2Vec算法的参数

  • p, return parameter(返回概率):

    Thinking 如果 p>max(q,1), 往回走的概率高 or 低?

    尽量不往回走,即下一个节点是上一个访问的节点t的概率低

    如果 p< min(q,1), 那么采样会更倾向于返回上一个节点,也就是一直在起始点周围某些节点来回转来转去

  • q, in-out parameter(出入参数):

    Thinking 如果 q>1 ,游走于起始点周围 or 跑出去?

    游走会倾向于在起始点周围的节点之间跑,可以反映出一个节点的BFS特性

    如果 q<1 ,那么游走会倾向于往远处跑,反映出DFS特性

    当p=1,q=1时,游走方式就等同于DeepWalk中的随机游走

 

Node2Vec算法:

  • 通过调节p, q参数,可以调节BFS, DFS
  • 挖掘网络中的同质性(homophily) 和 结构性(structural equivalence)
  • 同质性,指的是距离相近节点的embedding应该尽量近似,节点u与相连的节点s1、s2、s3、s4的embedding表达应该是接近的 => 同质性
  • 结构性,指的是结构上相似的节点的embedding应该相似,节点u和节点s6都是各自局域网络的中心节点,embedding表达相近 => 结构性

 

Node2Vec算法步骤:

  • Step1,转移概率矩阵可以提前算好
  • Step2,对图中的每个节点,进行r次随机游走得到r个长为l的walk,可以理解成每个给每个节点造句,r个l长的句子,全部节点的游走合起来就得到了这个网络的语料库
  • Step3,经过类似skip-gram的训练可得节点的Embedding

 

Node2Vec实验结果

  • 除了谱聚类,其他的算法都使用了Embedding这种连续的特征表示,实验结果一致的好于谱聚类。使用Embedding不仅可以应用于NLP,还可以用于网络特征表达
  • 网络中每个节点的邻居集如何选择会很大程度的影响Embedding的效果。Node2Vec的创新之处就在于提出了一种灵活的选择节点邻居的方法,实验证明比其他的方法更有效

 

 

Node2Vec工具

Node2Vec工具:

  • https://github.com/eliorc/node2vec
  • Node2Vec(graph, dimensions=64, walk_length=30, num_walks=200, workers=4) 
  • dimensions, embedding维数,默认为128
  • walk_length,节点随机游走的步长,默认为80
  • num_walks,每个节点随机游走次数,默认为10
  • p,返回概率参数,默认为1
  • q,出入概率参数,默认为1
  • workers,并行线程,默认为1
  • quiet,是否打印计算过程,默认为False,即输出计算过程

Node2Vec.fit(window=4, iter=20)

  1. window,窗口大小,表示当前词与预测词在一个句子中的最大距离
  2. iter,迭代次数

数据探索EDA 

 Project A:美国大学生足球队Embedding 

复制代码
# 数据加载,构造图
G = nx.read_gml('football.gml')
# 初始化Node2Vec模型
model = Node2Vec(G, walk_length = 10, num_walks = 5, p = 0.25, q = 4, workers = 1)
# 模型训练
result = model.fit(window=4, iter=20)
# 得到节点的embedding
print(result.wv.most_similar('EastCarolina'))
embeddings = result.wv

# 在二维空间中绘制所选节点的向量
def plot_nodes(word_list):
    X = []
    for item in word_list:
        X.append(embeddings[item])
    # 将100维向量减少到2维
    pca = PCA(n_components=2)
    result = pca.fit_transform(X) 
    # 绘制节点向量
    plt.figure(figsize=(12,9))
    # 创建一个散点图的投影
    plt.scatter(result[:, 0], result[:, 1])
    for i, word in enumerate(list(word_list)):
        plt.annotate(word, xy=(result[i, 0], result[i, 1]))        
    plt.show()
plot_nodes(result.wv.vocab)
复制代码

Graph Embedding工具:

  • https://github.com/shenweichen/GraphEmbedding (同样是DeepCTR作者)
  • 包括多种Graph Embedding算法,Deep Walk, Node2Vec等
  • DeepWalk
    • from graphembedding.ge.models import DeepWalk
  • Node2Vec
    • from graphembedding.ge.models import Node2Vec

                        

 Project A:美国大学生足球队Embedding(DeepWalk)

复制代码
from graphembedding.ge.models import DeepWalk
# 数据加载,构造图
G = nx.read_gml('football.gml')
# 初始化DeepWalk模型
model = DeepWalk(G, walk_length=10, num_walks=5, workers=1)
# 模型训练
model.train(window_size=4, iter=20)
# 得到节点的embedding
embeddings = model.get_embeddings()

# 在二维空间中绘制所选节点的向量
def plot_nodes(word_list):
……

plot_nodes(model.w2v_model.wv.vocab)
复制代码

Project A:美国大学生足球队Embedding(Node2Vec)

复制代码
from graphembedding.ge.models import Node2Vec
# 数据加载,构造图
G = nx.read_gml('football.gml')
# 需要将Graph转换为DiGraph
DG = nx.DiGraph()
DG.add_nodes_from(G.nodes())
DG.add_edges_from(G.edges())
print(type(G))
print(type(DG))
print(len(DG))

# 初始化Node2Vec模型
model = Node2Vec(DG, walk_length = 10, num_walks = 5, p = 0.25, q = 4, workers = 1)
# 模型训练
model.train(window_size=4, iter=20)
# 得到节点的embedding
embeddings = model.get_embeddings()

# 在二维空间中绘制所选节点的向量
def plot_nodes(word_list):
……

plot_nodes(model.w2v_model.wv.vocab)
复制代码

Summary 

Graph Embedding主要方法:

  • factorization methods (图因式分解机)
  • random walk techniques(随机游走)
  • deep learning(深度学习)
  • DeepWalk = Random Walk + Skip-gram
  • Node2Vec,在DeepWalk基础上,通过超参数p和q条件节点周边的微观特性,宏观特性获取
  • BFS,Breadth-first Sampling,倾向于在初始节点的周围游走,反映出一个节点的邻居的微观特性
  • DFS,Depth-first Sampling,倾向于跑得离初始节点越来越远,反映出一个节点邻居的宏观特性

 

工具使用

  • Networkx
  • Word2Vec
  • RandomWalk + Word2Vec
  • Node2Vec
  • Graph Embedding

 

Project:移动推荐系统

移动推荐系统

https://tianchi.aliyun.com/competition/entrance/231522/information

在真实的业务场景下,需要对所有商品的一个子集构建个性化推荐模型。在这个任务中,不仅需要利用用户在这个商品子集上的行为数据,还需要利用更丰富的用户行为数据:

目标是使用D来构造U中用户对P中商品的推荐模型

 

移动推荐系统

  • 2万用户的完整行为数据以及百万级的商品信息
  • 训练数据包含了抽样出来的一定量用户在一个月时间(11.18~12.18)之内的移动端行为数据(D),对应数据表tianchi_fresh_comp_train_user.csv

  • 商品子集(P),数据表为tianchi_fresh_comp_train_item.csv

  • 评分数据是用户在一个月之后的一天(12.19)对商品子集(P)的购买数据

 

移动推荐系统

  • 使用训练数据建立推荐模型,并输出用户在接下来一天(12月19日)对商品子集(P)购买行为的预测结果
  • 输出结果:tianchi_mobile_recommendation_predict.csv
  • 评估指标(F1值)

    精确度(两者之间的交集/ 预测的指标)

                       

                召回率

                     

                  F1值 (既考虑了Precision又考虑了Recall)

                      

    PredictionSet为算法预测的购买数据集合

    ReferenceSet为真实的答案购买数据集合

    以F1值作为最终的唯一评测标准

 

 

数据预处理

  • 用户购买行对于购买的影响会随着时间逐渐减弱,可以设置test day考察日一周以内的特征数据
  • 可以将数据切分成多组
    • train1: 11.22~11.27 -> 11.28
    • train2: 11.29~12.04 -> 12.05
    • train3: 12.06~12.10 -> 12.12
    • train4: 12.13~12.18 -> 12.19

  Thinking:为什么要考察12.19,12.12,12.05,11.28

  • 因为12月19日是周五,所以我们test day也需要为周五
  • 因为train3包括了双12(异常期,大促),可以将train3省略
  • 最终将数据集划分为3组,分别进行训练和测试
    • train1: 11.22~11.27 -> 11.28
    • train2: 11.29~12.04 -> 12.05
    • train3: 12.13~12.18 -> 12.19

 

 

chunksize使用:

  • pandas使用chunksize分块处理大型csv文件
  • chunksize,单个IO大小,设置越大站占用内存高,需要的iteration少,速度快
复制代码
# 设置解析
dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m-%d %H')
for df in pd.read_csv(open(file_name, 'r'), 
parse_dates=['time'], 
index_col = ['time'], 
date_parser = dateparse,
chunksize = 100000):

# 如果想要追加文件的话,设置mode=a
train1.to_csv(train1_file, columns=['user_id','item_id','behavior_type','item_category'], header=False, mode='a')

基于简单规则:
用户总是先放到购物车,然后进行购买
对应behavior_type = 3 到 behavior_type = 4
观察user_id, item_id, time_3, time_4

计算delta_hour = time_4 - time_3
可视化delta_hour
复制代码

 

基于简单规则:

  • Thinking:想要预测2014-12-19的购买情况,可以根据哪天的购物车来进行预测?
  • To do:使用rule-based,及2014-12-18放到购物车里,还没有完成购物的,假设会在2014-12-19完成购物,提交结果

 

Summary 

  • 对于图像、语音、文本信息,这种一维、二维的矩阵表示的数据,有天然的维度对齐特性,即使不同的数据也可以对齐到同样的特征尺度和矩阵维度 => CNN 或者 RNN
  • 现实世界有大量的非结构化数据,比如社交网络,知识图谱等,是非欧几里得数据,即每个节点可能有不一样的连接方式
  • Embedding 是深度学习中的“基本操作”(包括 NLP/CV,搜索排序,推荐系统)
  • Embedding 指的是用一个低维度向量表示一个实体,可以是一个词(Word2Vec),可以是一个物品(Item2Vec),也可以是网络关系中的节点(Graph Embedding)
  • DeepWalk是Graph Embedding领域的开山之作,NodeVec在此基础上进行改进

Node2Vec在工业界很成功

  • Facebook:广告领域定制化受众
  • Tencent:微信朋友圈广告(Lookalike)策略
  • Lookalike,相似人群扩展
  • DMP是Look-alike技术的核心基础

 

Thinking1:什么是Graph Embedding,都有哪些算法模型

Thinking2:如何使用Graph Embedding在推荐系统,比如NetFlix 电影推荐,请说明简要的思路

Thinking3:数据探索EDA都有哪些常用的方法和工具

  Action1:seealsology是个针对Wikipidea页面的语义分析工具,可以找到与指定页面相关的Wikipidea

seealsology-data.tsv 文件存储了Wikipidea页面的关系(Source, Target, Depth)

使用Graph Embedding对节点(Wikipidea)进行Embedding(DeepWalk或Node2Vec模型)

对Embedding进行可视化(使用PCA呈现在二维平面上)

找到和critical illness insurance相关的页面

 

posted @   kris12  阅读(464)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
历史上的今天:
2020-06-14 数据结构-05 |散列表-① | 映射| 集合
2020-06-14 数据结构-04 |栈 |队列
levels of contents
点击右上角即可分享
微信分享提示