作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
胡安·曼努埃尔·奥尔蒂斯·德·萨拉特的头像

胡安·曼纽尔·奥尔蒂斯·德·萨拉特

Juan是一名开发人员, data scientist, 他是布宜诺斯艾利斯大学研究社交网络的博士研究员, AI, and NLP. Juan拥有十多年的数据科学经验,并在ML会议上发表过论文, 包括SPIRE和ICCS.

Previously At

布宜诺斯艾利斯大学
Share

本文是关于使用R和Twitter聚类分析的三部分系列文章的第二部分 Gephi. Part one 奠定基础 for the example we dive deeper into below; part three uses cluster analysis 从关于美国政治的两极分化的帖子中得出结论.

社交网络中心性

为了实现我们的目标,首先我们需要引入的概念 centrality. 在网络科学中,中心性是指对网络有较大影响的节点. Influence is an ambiguous concept; it can be understood in many ways. 有很多边的节点比有更少但更“重要”边的节点更有影响力吗? 社交网络的重要优势是什么?

为了解决这些歧义,网络科学家开发了许多中心性的测量方法. 在这里,我们讨论四种常用的度量方法 many more are available.

Degree

最常见和最直观的度量是度中心性. 度中心性背后的思想很简单:通过节点的度来衡量影响. It can have variants if the graph is directed; in that case, 您可以测量度和度-第一个被称为枢纽得分,第二个被称为权威得分.

在本系列的第一部分中,我们使用了无向方法. 这一次,我们关注的是渐进式方法. 通过强调被他人转发的用户,而不是仅仅频繁转发的用户,可以进行更准确的分析.

Eigenvector

The eigenvector 度量建立在度中心性的基础上. 有影响力的节点指向的节点越多,该节点的得分就越高. We start with an adjacency matrix, 行和列在哪里表示节点, 我们使用1或0来表示给定行和列的对应节点是否连接. 主要计算估计矩阵的特征向量. 主特征向量将包含我们想要的中心性度量,其中位置 i 会保存节点的中心性评分吗 i.

PageRank

PageRank是特征向量测度的变体,是Google的核心. 谷歌使用的具体方法尚不清楚, 但一般的想法是,每个节点以1分开始, 然后将分数等分地分配给每条边. For example, 如果一个节点有三条边从它延伸出来, 它通过每条边“发送”三分之一的分数. 与此同时,指向该节点的边使该节点变得更加重要. 这就得到了一个可解的系统 N equations with N unknowns.

Betweenness

第四项措施, betweenness使用了一种非常不同的方法. 在这里,如果一个节点包含在其他节点之间的许多短路径中,则称其具有影响力. 也就是说,它负责与许多其他节点进行通信,连接“不同的世界”.”

For example, 在社会网络分析中, 这些节点可以被理解为帮助别人找到新工作或建立新关系的人——他们是通往以前未知社交圈的大门.

我该用哪个呢??

适当的中心性度量取决于您的分析目标. 你想知道哪些用户在数量上经常被别人挑出来吗? 度中心性可能是你最好的选择. 或者你更喜欢考虑质量的中心性度量? 在这种情况下,特征向量或PageRank将产生更好的结果. 如果您想知道哪些用户最有效地充当不同社区之间的桥梁, 中间是你最好的选择.

当使用多个相似的度量时,e.g.,特征向量和PageRank,你可以估计它们,看看它们是否产生相同的排名. If not, 你可以加深对差异的分析,或者结合他们的分数生成一个新的衡量标准.

另一种方法使用 主成分分析 要估计哪个度量可以提供有关节点对网络的实际影响的更多信息.

动手中心性计算

让我们看看如何计算这些度量 using R and RStudio. (他们也可以用Gephi.)

首先,我们需要加载将在本文中使用的所有库:

library("plyr")
library(igraph)
库(tidyverse)
library(NLP)
library("tm")
库(RColorBrewer)
库(wordcloud)
库(topicmodels)
库(SnowballC)
库(“textmineR”)

接下来,我们将从数据中删除孤立的节点 we used before,因为它们对这个分析没有用处. 然后,我们将使用 igraph functions betweenness, centr_eigen, page_rank, and degree 估计中心性度量. 最后,我们将把分数存储在 igraph 对象和数据框架,以查看哪些用户是最中心的.

负载(“art1_tweets.RData")
隔离=哪(度(净)==0)
Net_clean = delete.顶点(净、隔离)

cent<-data.框架(打赌=中间性(net_clean),eig = centr_eigen (net_clean)美元向量,恶作剧= (page_rank (net_clean)美元向量),degr = (net_clean程度, mode="in"))
cent <- cbind(account = rownames(cent), cent)

现在我们可以通过每项措施检查10个最核心的用户:

Degree
top_n(cent,10,degr)%>% arrange(desc(degr))%>% select(degr)
Eigenvector
top_n(cent,10,eig)%>% arrange(desc(eig))%>% select(eig)
PageRank
top_n(cent,10,prank)%>% arrange(desc(prank))%>% select(prank)
Betweenness
top_n(cent,10,bet)%>% arrange(desc(bet))%>% select(bet)

The results:

DegreeEigenvectorPageRankBetweenness
ESPNFC5892PSG_inside1mundodabola0.037viewsdey77704
TrollFootball5755CrewsMat190.51AleLiparoti0.026EdmundOris76425
PSG_inside5194eh011959910.4PSG_inside0.017ba*****lla63799
CrewsMat194344mohammad1356800.37RoyNemer0.016FranciscoGaius63081
brfootball4054ActuFoot_0.34TrollFootball0.013Yemihazan62534
PSG_espanol3616marttvall0.34ESPNFC0.01hashtag2weet61123
IbaiOut3258ESPNFC0.3PSG_espanol0.007Angela_FCB60991
ActuFoot_3175brfootball0.25lnstantFoot0.007Zyyon_57269
FootyHumour2976SaylorMoonArmy0.22IbaiOut0.006CrewsMat1953758
mundodabola2778JohnsvillPat0.22010MisterChip0.006MdeenOlawale49572

我们可以看到,前三个度量共享许多用户, 比如PSG_inside, ESPNFC, CrewsMat19, 和TrollFootball. 我们可以假设他们对讨论有很大的影响. 中间度测量中心性的方法不同,因此与其他技术没有太多的重叠.

Note: 本文中提到的Twitter账户所表达的观点不代表Toptal或作者的观点.

在下面的图片中,您可以看到我们原始的带有两个用户标签覆盖的彩色网络图. In the first, 节点通过其PageRank分数突出显示, 在第二个, 根据他们的中间值:

这张图片显示了一个彩色的PageRank图,突出显示了前10名用户和他们的网络. 最大的三个用户是PSG_inside、TrollFootball和ESPNFC. ESPNFC位于图的左侧,颜色为紫色, 而PSG_inside则放在它的右边, colored red. TrollFootball位于更高的位置,在他们的右边, between green-, blue-, 橙色的用户.
梅西与前10名PageRank用户的讨论突出显示

显示彩色间度图的图像, 前10名用户和他们的网络被标记并突出显示. 所有前10名用户, 哪些比之前的图片尺寸更相似, 是否位于图像的左下角, 它是紫色的. 他们紧密地组合在一起.
梅西与十大人气用户讨论突出

Gephi可以用来复制这些图像. 您可以使用统计面板中的网络直径按钮来估计间隔或PageRank分数. Then, 可以使用属性显示节点名称,如本系列第1部分所示.

文本分析:R和LDA

我们还可以分析社交网络讨论,以确定用户一直在谈论什么. 有多种方法可以做到这一点. 我们将通过 潜在狄利克雷分配 (LDA), 一种无监督的机器学习技术,可以让我们估计哪组单词倾向于一起出现. 然后,通过这组单词,我们可以推断出正在讨论的话题.

第一步是整理文本. 为此,我们定义了以下函数:

#此函数通过删除twitter相关的术语和嘈杂字符来规范化文本
sanitize_text <- function(text) {
  #转换为ASCII以删除重音字符:
  text <- iconv(text, to = "ASCII", sub = " ")
  #移动到小写并删除RT单词(这是Twitter添加的)
  text <- gsub("rt", " ", tolower(text))
  #删除链接和用户名
  text <- gsub("@\\w+", " ", gsub("http.+ |http.+$", " ", text))
  删除制表符和标点符号
  text <- gsub("[ |\t]{2,}", " ", gsub("[[:punct:]]", " ", text))
  text <- gsub("amp", " ", text)  # Remove HTML special character
  #删除前导和滞后空白:
  text <- gsub("^ ", "", gsub(" $", "", text))
  text <- gsub(" +", " ", text) # Delete extra spaces
  return(text)
}

我们还需要移除 stop words、重复项和空项. 接下来,我们必须将文本转换为a document-term matrix 由LDA处理.

在这个数据集中,我们有使用多种语言(英语、西班牙语、法语等)的用户.). 如果我们专注于单一语言,LDA效果最好. 我们将把它应用于本系列第一部分中检测到的最大社区的用户, 主要由英语用户组成的账户.

#检测社区:
my.com.fast <-cluster_louvain(as.无向(简化(净)))
largestCommunities <- order(sizes(my.com.快),减少= TRUE) [1:3]
#保存最大社区的用户名:
community1 <- names(which(membership(my.com.== largestCommunities[1]))

#净化最大社区用户的文本:
text <- unique(sanitize_text(tweets.df[which(tweets.Df $screen_name %in% community1),]$text))
text = text[text!= "] #删除空条目
Stopwords_regex = paste(stopwords('es'), collapse = '\\b|\\b')
Stopwords_regex = paste0('\\b', Stopwords_regex, '\\b')
删除英文停顿词:
Text = stringr::str_replace_all(Text, stopwords_regex, ")
创建文档术语矩阵:
dtm <- CreateDtm(text,
                 Doc_names = seq(1:length(text)),
                 Ngram_window = c(1,2))

主题计数和连贯分数

我们需要在LDA中定义的主要超参数是数字 (k) 我们想要估计的主题. 然而,我们怎么能事先知道呢? 一种常见的方法是在不同的域上训练LDA模型 k 价值和测量 coherence of each one. 我们会这样做 k 从3到20的值,因为超出这个范围的值不值得检查,以我的经验:

tf <- TermDocFreq(dtm = dtm)
删除不常用的单词:
tf_trimmed = tf$term[ tf$term_freq > 1 & tf$doc_freq < nrow(dtm) / 2 ]

创建一个文件夹来存储训练过的模型:
model_dir <- paste0("models_", digest::digest(tf_trimmed, algo = "sha1"))
if (!dir.存在(model_dir)) dir.create(model_dir)

定义一个函数来推断LDA主题:
train_lda_model <- function(number_of_topics){
    filename = file.路径(model_dir, paste0(number_of_topics,“_topics”).rda"))
    #检查模型是否已经存在:
    if (!file.存在(文件名)){
        为了每次运行得到完全相同的输出,使用一个常量种子:
        set.seed(12345)
        lda_model = FitLdaModel(dtm = dtm, k = number_of_topics, iterations = 500)
        Lda_model $k = number_of_topics
        lda_model$coherence = CalcProbCoherence(phi = lda_model$phi, dtm = dtm, M = 5)
        保存(lda_model, file = filename)
    } else {
        load(filename)
    }
    
    lda_model
}
我们将在每次LDA训练中推断的主题数量:
Topic_count = seq(3,20, by = 1)
#通过TmParallelApply函数进行训练
models = TmParallelApply(X = topic_count,
                         FUN = train_lda_model;
                         导出= c("dtm", "model_dir"))

接下来,我们绘制每个相干值的图:

Coherence_by_topics_quantity = data.frame(
Topic_number = sapply(models, function(model_instance) nrow(model_instance$phi)),
     Score_coherence = sapply(models,
函数(model_instance)意味着(model_instance相干美元)),
     stringsAsFactors = FALSE)
Ggplot (coherence_by_topics_quantity, aes(x = topic_number, y = score_coherence)) +
  geom_point() +
  Geom_line (group = 1) +
  ggtitle("Coherence by Topic") + theme_minimal() +
  scale_x_continuous(break = seq(1,20,1)) + ylab(“连贯分数”)+ xlab(“主题数”)

连贯性值越高,就越能将文本分割成主题:

图表显示了不同主题的连贯得分. 连贯性得分从略高于0.6 - 7个题目是05分,3 - 12个题目的分数都在0分以下.065. 分数突然在0左右达到峰值.13个题目105分. 然后小于0.06为17个课题,高达近0.有19个科目是09分,最终成绩略高于0分.07 for 20 topics.

我们达到了连贯的最高分数 k = 13,所以我们将使用经过13个主题训练的LDA模型. Through the GetTopTerms function, 我们可以看到每个主题的10个主要词,并通过它们来估计主题的语义:

best_model <- models[which.Max (coherence_by_topics_quantity$score_coherence)][[1]]

#按主题划分的最重要术语:
best_model$top_terms <- GetTopTerms(phi = best_model$phi, M = 20)
top10 <- as.data.框架(best_model top_terms美元)
top10

下表详细介绍了检测到的五个最重要的主题以及代表它们的10个主要单词:

 t_1t_2t_3t_4t_5
1messimessimessimessimessi
2lionelinstagramleagueestpsg
3lionel_messipostwinilleo
4psgmilliongoalsauleo_messi
5madridlikeschpourahora
6realspoionspascompa
7barcelonagoatch_ionsavecva
8parispsguclduser
9real_madridbarballonquijugador
10mbappbiggerworldjemejor

虽然这个社区的大多数用户都是英语使用者, 仍然有一些法语和西班牙语使用者(表中t_4和t_5). 我们可以推断第一个话题与 Messi’s 前效力球队(巴塞罗那足球俱乐部), 第二个话题是关于梅西在Instagram上的帖子, 第三个主题是梅西的成就.

现在我们有了话题,我们可以预测哪一个是讨论最多的. 要做到这一点,我们将首先连接用户的tweet(同样,来自最大的社区):

tweets.df.com1 = tweets.df[which(tweets.Df $screen_name %in% community1),]
users_text <- ddply(tweets.df.com1,
                    ~screen_name,
                    summarise,
                    Text = paste(Text, collapse = " "))

然后,我们像以前一样清理文本并创建DTM. 之后,我们称之为 predict 函数使用我们的LDA模型和DTM作为参数. 同样,我们将方法设置为 Gibbs 为了提高计算时间,因为我们有很多文本要分析:

users_text$text <- sanitize_text(users_text$text) # Get rid of duplicates
Stopwords_regex = paste(stopwords('en'), collapse = '\\b|\\b')
Stopwords_regex = paste0('\\b', Stopwords_regex, '\\b')
Users_text $text = stringr::str_replace_all(Users_text $text, stopwords_regex, ")

dtm.users.com1 <- CreateDtm(users_text$text,
                 Doc_names = users_text$screen_name,
                 Ngram_window = c(1,2))
com1.users.主题=预测(best_model, DTM).users.Com1, method="gibbs", iterations=100)

Now, in the com1.users.topics 数据框,我们看到每个用户谈论了多少话题:

Accountt_1t_2t_3t_4t_5[…]
___99th0.027160490.866666660.002469130.002469130.00246913 
Boss__0.051851850.841975300.002469130.002469130.00246913 
Memphis0.003278680.003278680.036065570.003278680.00327868 
___Alex10.009523800.009523800.009523800.009523800.00952380 
[…]      

Finally, 有了这些信息, 我们可以在节点图上创建一个新属性,以定义哪个用户谈论最多的主题. 然后我们可以创建一个新的GML文件,在Gephi中可视化它:

获取第一个社区的子图:
net.Com1 = induced_subgraph(net,community1)
#用每个用户的最高分估计主题:
com1.users.Maxtopic = cbind(users_text$screen_name,
                            colnames(com1.users.(com1主题)[适用.users.topics,
                                                              1,
                                                              which.max)])
#根据用户在图中的顺序对用户主题数据框进行排序:
com1.users.maxtopic = com1.users.maxtopic[匹配(V(净.com1)$name,
                                          com1.users.maxtopic[,1]),]
#根据每个用户讨论次数最多的主题创建一个新属性
V(net.$topic = Com1.users.maxtopic[,2]
创建一个新图表:
write_graph(简化(净.messi_graph_topics com1)。.Gml ", format = " Gml ")

使用Gephi生成的彩色节点图, 显示espn是PageRank中心性最高的用户. ESPNFC位于图像的底部附近,它下面有许多紫色的节点.
最大的梅西讨论社区,按主题着色,并通过PageRank中心突出用户

用图表中使用的每种颜色高亮显示用户百分比的图像, 紫色“t 6”是最常用的颜色(40).(占图表中所有用户的53%),其次是绿色的“t 13”(11).02%,蓝色/青色“t 10”为9.68%. 一个灰色的“NA”,在这11个列表中倒数第二的位置,构成2.25%.
主题标签和图形中使用的每种颜色的用户百分比

推断重要话题及应用社会网络中心性

在本系列的第一部分中,我们学习了如何从 Twitter,创建交互图,通过Gephi绘制它,并检测社区和重要用户. 在本期中, 我们通过演示使用其他标准来检测有影响力的用户,对这一分析进行了扩展. 我们还演示了如何检测和推断用户在谈论什么,并将其绘制到网络中.

在下一篇文章中, 我们将通过展示用户如何探索聚集的社交媒体数据来继续深化这一分析.

本系列还包括:

了解基本知识

  • 网络分析中的中心性是什么?

    中心性是一种度量, 在社会网络分析的背景下, 能帮我们发现网络上有影响力的用户吗.

  • 什么是社会网络分析中的度中心性?

    度中心性通过用户拥有的边的数量来度量用户的影响.

  • 特征向量中心性是用来干什么的?

    特征向量中心性通过用户拥有的边的数量和质量来衡量用户的影响.

  • 中间中心性是什么意思?

    中间性中心性通过有多少用户通过他们进行连接来衡量用户的影响力.

  • RStudio是用来做什么的?

    RStudio是一个用于R语言编程的集成开发环境(IDE).

  • R可以做文本分析吗?

    R是一种功能强大的编程语言,用于执行文本分析. 它有许多用于经典文本分析任务的库,例如用于主题建模的情感分析.

聘请Toptal这方面的专家.
Hire Now
胡安·曼努埃尔·奥尔蒂斯·德·萨拉特的头像

Located in 布宜诺斯艾利斯城,阿根廷布宜诺斯艾利斯

Member since November 6, 2019

About the author

Juan是一名开发人员, data scientist, 他是布宜诺斯艾利斯大学研究社交网络的博士研究员, AI, and NLP. Juan拥有十多年的数据科学经验,并在ML会议上发表过论文, 包括SPIRE和ICCS.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Previously At

布宜诺斯艾利斯大学

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

Toptal开发者

Join the Toptal® community.