分析与可视化Twitter网络
构建Twitter网络
现在我们开始构建Twitter网络。为了介绍一种构建和运行R脚本的替代方法,我们将把代码编写成一个可以在命令行运行的shell脚本。在此之前,我们通常是在R控制台中编写和运行代码,这可能也是大家使用R语言的主要方式。不过,有时候你可能需要多次运行同一个任务或程序,但每次的输入不同。这种情况下,编写一个能在命令行运行并从标准输入获取参数的程序会更方便。我们可以使用R安装包自带的Rscript命令行程序来实现这一点。在运行代码之前,我们先详细了解一下代码的功能。
需要注意的是,由于Google SocialGraph API的变更,我们现在无法再生成新的Twitter网络数据。所以在接下来的内容中,我们将使用之前收集的John(@johnmyleswhite)的Twitter网络数据。
为了能为不同的用户构建Twitter网络,我们的程序应该能够接受不同的用户名作为输入,并根据需要生成相应的数据。在内存中构建好网络对象后,我们将对其进行一些基本的网络分析,以确定潜在的社区结构,将这些信息添加到图对象中,最后将网络数据保存为文件到磁盘上。
首先,我们需要加载igraph库以及上一节编写的函数,这些函数保存在google_sg.R文件中。以下是相应的代码:
library(igraph)
source('google_sg.R')
user <- 'johnmyleswhite'
user.net <- read.graph(paste("data/",user, "/", user, "_net.graphml", sep = ""), format = "graphml")
我们将再次使用igraph库来构建和操作Twitter图对象。使用source函数加载上一节编写的函数。由于在这个案例中我们不会生成新的数据,所以通过加载johnmyleswhite文件夹中的数据来获取之前为John的Twitter网络抓取的数据。
Windows用户请注意:你可能无法在DOS shell中运行这个脚本。这种情况下,你可以直接将user变量设置为你想要构建网络的Twitter用户,然后像之前一样运行这个脚本。这一点在twitter_net.R文件中也有提及。
在上一节构建好所有必要的支持函数后,我们只需将种子用户传递给twitter.snowball函数。在这个例子中,我们想要构建种子用户的自我中心网络(ego-network),所以雪球抽样只进行两轮。稍后,我们会将网络文件加载到图可视化软件Gephi中,它可以帮助我们创建漂亮的数据可视化效果。
Gephi有一些用于可视化的保留变量名,其中一个是Label变量,用于在图中标记节点。默认情况下,igraph将标签信息存储为name顶点属性,所以我们需要创建一个名为Label的新顶点属性,复制name属性的信息。我们可以使用set.vertex.attribute函数来实现这一点,代码如下:
user.net <- set.vertex.attribute(user.net, "Label",
value = get.vertex.attribute(user.net, "name"))
Gephi是一个开源的、跨平台的图可视化和操作平台。R和igraph内置的网络可视化工具虽然有用,但可能无法满足我们的需求。Gephi专门为网络可视化设计,包含许多创建高质量网络图形的有用功能。如果你还没有安装Gephi或者使用的是旧版本,强烈建议你从http://gephi.org/ 下载并安装最新版本。
分析网络以发现局部社区结构
构建好图对象后,我们将对其进行一些基本的网络分析,以降低其复杂度并发现局部社区结构。
提取核心子图
分析过程的第一步是提取图的核心元素。我们需要从完整的user.net对象中提取两个有用的子图。
首先,我们进行k-core分析,提取图的2-core。k-core分析是根据节点的连通性对图进行分解。为了确定图的“核心度”,我们需要知道有多少节点具有特定的度。k-core中的k表示分解的度,所以图的2-core是由度大于等于2的节点组成的子图。我们提取2-core的原因是,在雪球抽样过程中,网络外部会出现很多悬挂节点,这些节点对网络结构的有用信息贡献很少,我们希望将它们移除。
需要注意的是,Twitter图是有向图,节点有入度和出度。为了找到与分析更相关的节点,我们使用graph.coreness函数,通过设置mode=”in”参数,根据节点的入度计算每个节点的核心度。我们这样做是因为我们希望保留那些至少有两条入边的节点,而不是有两条出边的节点。雪球抽样中捕获的悬挂节点可能与网络有连接,但没有从网络发出的连接,所以我们使用入度来筛选它们。以下是相应的代码:
user.cores <- graph.coreness(user.net, mode="in")
user.clean <- subgraph(user.net, which(user.cores>1)-1)
subgraph函数接受一个图对象和一组节点作为输入,并返回由这些节点在传入图上诱导的子图。为了提取user.net图的2-core,我们使用R的which函数找到入度核心度大于1的节点。
另外,我们还需要提取种子用户的自我中心网络(ego-network)。自我中心网络是由种子用户的邻居节点诱导的子图。幸运的是,igraph提供了一个方便的neighbors函数来识别这些节点。但要注意Twitter图的有向结构,节点的邻居可以是入邻居或出邻居,所以我们需要告诉neighbors函数我们想要的是哪种邻居。在这个例子中,我们将分析由出度邻居(即种子用户关注的Twitter用户)诱导的自我中心网络,而不是关注种子用户的用户。从分析的角度来看,研究一个人关注的用户可能更有趣,特别是当你分析自己的数据时。当然,研究入度邻居也可能很有意思,大家可以重新运行代码来查看入度邻居的情况。以下是提取自我中心网络的代码:
user.ego <- subgraph(user.net, c(0, neighbors(user.net, user, mode = "out")))
需要注意的是,使用igraph时一个比较容易出错的地方是,igraph对节点使用零索引,而R是从1开始索引的。在2-core的例子中,你会看到我们从which函数返回的向量中减去了1,以避免出现“偏移一位”的错误。
在接下来的内容中,我们将重点分析自我中心网络,以发现局部社区结构。不过,2-core对于其他网络分析也非常有用,所以我们会将其作为数据提取的一部分保存下来。
确定社区成员
为了分析自我中心网络的局部社区结构,我们将使用一种最基本的方法:基于节点距离的层次聚类。虽然这个概念听起来有点复杂,但实际上很简单。我们假设节点(这里指Twitter用户)之间的连接越紧密,即它们之间的跳数越少,就越相似。这在实际中是有道理的,因为我们可以认为有共同兴趣的人会在Twitter上相互关注,所以他们之间的距离更短。有趣的是,不同用户的自我中心网络中可能存在多个不同的社区。
以下是进行层次聚类分析的步骤:
1.
测量节点之间的距离
:使用shortest.paths函数测量图中所有节点之间的距离,该函数返回一个N×N的矩阵,其中N是图中节点的数量,矩阵中每个位置的元素表示每对节点之间的最短距离。
user.sp <- shortest.paths(user.ego)
- 计算距离矩阵 :使用dist函数将上一步得到的距离矩阵转换为适合hclust函数处理的格式。
- 进行层次聚类 :使用hclust函数进行层次聚类,该函数返回一个包含所有聚类信息的特殊对象。
user.hc <- hclust(dist(user.sp))
完成层次聚类后,一个有用的操作是查看聚类的树状图(dendrogram)。树状图是一种树状图,它展示了随着层次的深入,聚类是如何分离的。这可以让我们初步了解自我中心网络的社区结构。以下是查看John的Twitter自我中心网络树状图的代码:
user.ego <- read.graph('data/johnmyleswhite/johnmyleswhite_ego.graphml', format = 'graphml')
user.sp <- shortest.paths(user.ego)
user.hc <- hclust(dist(user.sp))
plot(user.hc)
从John的Twitter网络树状图中,我们可以看到一些有趣的社区结构。似乎有两个高层次的社区有比较明显的划分,每个社区内部又有许多紧密相连的小团体。当然,每个人的数据都不同,你看到的社区数量很大程度上取决于Twitter自我中心网络的大小和密度。
虽然从学术角度来看,通过树状图查看聚类很有趣,但我们更希望在网络中直观地看到这些社区。为了实现这一点,我们需要将聚类分区数据添加到节点上。我们可以使用一个简单的循环将前10个非平凡分区添加到我们的网络中。这里的非平凡分区是指跳过第一个分区,因为第一个分区将所有节点分配到同一个组,虽然它在整体层次结构中很重要,但不能提供局部社区结构的信息。以下是相应的代码:
for(i in 2:10) {
user.cluster <- as.character(cutree(user.hc, k=i))
user.cluster[1] <- "0"
user.ego <- set.vertex.attribute(user.ego, name=paste("HC",i,sep=""),
value=user.cluster)
}
cutree函数返回层次结构中每个元素在给定层次的分区分配,即“切割树”。聚类算法并不知道我们提供的是一个以单个节点为中心的自我中心网络,所以在每个聚类层次上,它都会将种子用户与其他节点分组在一起。为了在可视化时更容易识别种子用户,我们将其分配到自己的聚类中,标记为”0”。最后,我们再次使用set.vertex.attributes函数将这些信息添加到图对象中。现在,我们的图对象包含了Twitter用户名和前10个聚类分区的信息。
在使用Gephi可视化结果之前,我们需要将图对象保存为文件。我们可以使用write.graph函数将数据导出为GraphML文件。GraphML是一种基于XML的网络文件格式,它很适合我们的需求,因为我们的图对象包含很多元数据,如节点标签和聚类分区。但和大多数基于XML的格式一样,GraphML文件可能会很快变得很大,不太适合单纯存储关系数据。关于GraphML的更多信息,可以查看http://graphml.graphdrawing.org/ 。以下是保存图对象的代码:
write.graph(user.net, paste("data/", user, "/", user, "_net.graphml", sep=""), format="graphml")
write.graph(user.clean, paste("data/", user, "/", user, "_clean.graphml", sep=""), format="graphml")
write.graph(user.ego, paste("data/", user, "/", user, "_ego.graphml", sep=""), format="graphml")
我们保存了在这个过程中生成的三个图对象。接下来,我们将使用Gephi对这些结果进行可视化。
使用Gephi可视化聚类后的Twitter网络
我们将使用Gephi程序来直观地探索我们的网络数据。如果你已经下载并安装了Gephi,首先要做的是打开应用程序并加载Twitter数据。在这个例子中,我们将使用Drew的Twitter自我中心网络数据,这些数据位于code/data/drewconway/目录下。如果你自己生成了Twitter数据,也可以使用自己的数据。
需要注意的是,这里并不是对Gephi进行全面详尽的介绍,本节仅解释如何直观地探索Twitter自我中心网络数据的局部社区结构。Gephi是一个强大的网络可视化程序,有很多分析数据的选项。在本节中,我们只会使用其中很少的一部分功能,建议大家多尝试这个程序,探索它的各种选项。可以从Gephi的快速入门教程开始,教程链接为:http://gephi.org/2010/quick-start-tutorial/ 。
以下是使用Gephi可视化数据的具体步骤:
1.
加载网络数据
:打开Gephi后,在菜单栏中选择File→Open,导航到drewconway目录,打开drewconway_ego.graphml文件。加载图后,Gephi会报告一些关于刚加载的网络文件的基本信息,包括节点数量(263)和边的数量(6,945)。点击窗口中的Report标签,你还可以看到我们添加到这个网络中的所有属性数据。特别值得关注的是节点属性HC
,它们是前10个非平凡分区的层次聚类分区标签。
2.
调整节点布局
*:Gephi加载网络时,节点会随机分布,形成一个混乱的“网络毛球”。为了更好地展示网络中的社区结构信息,我们需要更合理地排列这些节点。在大型复杂网络中,节点布局的方法和算法有很多种。我们希望让连接更紧密的节点靠得更近,因为我们的聚类方法就是基于节点之间的距离进行分组的。
一种常用的节点布局方法是“力导向”算法。这种算法模拟了在网络上施加吸引力和排斥力时节点的分布情况。可以想象,Gephi当前显示的节点之间杂乱的边就像橡皮筋,节点就像可以带有磁性电荷的滚珠轴承。力导向算法会计算滚珠轴承节点如何因电荷相互排斥,但又会被橡皮筋拉回来。最终的结果是根据局部社区结构将节点整齐地排列在一起。
Gephi提供了很多力导向布局的示例。在Layout面板的下拉菜单中有很多不同的选项,其中一些是力导向的。我们选择Yifan Hu Proportional算法并使用默认设置。选择该算法后,点击Run按钮,你会看到Gephi以力导向的方式重新排列节点。根据网络的大小和你使用的硬件,这个过程可能需要一些时间。当节点停止移动时,算法就完成了节点位置的优化,我们可以进行下一步操作。
3.
调整节点大小
:为了更方便地识别网络中的局部社区及其成员,我们将调整节点的大小和颜色。由于这是一个有向的自我中心网络,我们将节点大小设置为节点入度的函数。这样,种子节点会是最大的,因为网络中的几乎每个成员都关注了种子节点,同时也会增大自我中心网络中其他重要用户的节点大小。在Rankings面板中,点击Nodes标签,从下拉菜单中选择InDegree,点击红色钻石图标设置大小,你可以将最小和最大大小设置为你想要的值。在Drew的网络中,我们分别选择了2和16,但其他设置可能更适合你的数据。设置好值后,点击Apply按钮调整节点大小。
4.
为节点上色
:最后一步是根据社区分区为节点上色。在Rankings面板上方的Partition面板中,你会看到一个有两个相反箭头的图标,点击它刷新这个图的分区列表。之后,下拉菜单中会包含我们为这些分区添加的节点属性数据。我们选择HC8(即第八个分区),它包含了Drew(drewconway)和他的自我中心网络中的其他七个节点的分区信息。再次点击Apply按钮,节点就会根据分区上色。
通过以上步骤,我们可以立即看到网络的底层结构!一种很好的观察特定网络如何分裂成更小的子社区的方法是逐步查看层次聚类的分区。我们建议在Gephi中通过迭代地根据更细粒度的分区为节点重新上色来进行这个操作。从HC2开始,逐步到HC10,每次为节点重新上色,观察较大的组如何分裂。这将让你深入了解网络的底层结构。
以Drew的自我中心网络为例,当根据HC8分区上色时,可以清晰地看到他的Twitter网络的局部社区结构。Drew似乎有四个主要的子社区。Drew本人在中心以青色显示,他左边有两个紧密相连的组,分别是红色和紫色;右边有另外两个连接相对较松散的子组,分别是蓝色和绿色。当然,还有其他橙色、粉色和浅绿色的组,但我们主要关注这四个主要组。
在网络的左侧,集中了Drew关注的数据领域的用户。其中,像Tim O’Reilly(timoreilly)和Nathan Yau(flowingdata)这样的知名数据专家被标记为浅绿色,他们在数据领域有独特的地位。紫色和红色的组也很有意思,它们都包含数据黑客,但有一个关键区别:紫色组中的Drew的朋友是数据社区的重要成员,如Hilary Mason(hmason)、Pete Skomoroch(peteskomoroch)和Jake Hofman(jakehofman),但他们都不是R社区的活跃成员;而红色组中的节点是R社区的活跃成员,包括Hadley Wickham(hadleywickham)、David Smith(revodavid)和Gary King(kinggary)。力导向算法成功地将这些成员紧密排列在一起,并将处于两个社区之间的节点放在边缘位置。例如,John(johnmyleswhite)被标记为紫色,但与很多红色节点靠在一起,这是因为John在两个社区中都很突出,数据也反映了这一点。其他类似的例子还包括JD Long(cmastication)和Josh Reich(i2pi)。
除了数据社区,Drew还使用Twitter与满足他其他兴趣的社区进行互动,特别是他的学术生涯,专注于国家安全技术和政策。网络的右侧包含了来自这些社区的成员,同样分为两个子组,分别是蓝色和绿色。和数据爱好者组的例子一样,分区颜色和节点的位置可以很好地说明它们在网络中的角色。
通过以上的分析和可视化过程,我们可以深入了解Twitter用户的社交网络结构,发现不同用户之间的关系和社区划分。这对于研究社交行为、信息传播等方面都有很大的帮助。大家可以根据自己的需求,尝试不同的参数和算法,进一步挖掘Twitter网络数据的价值。
以下是整个分析和可视化过程的流程图:
graph LR
A[加载必要的库和数据] --> B[提取子图(2-core和ego-network)]
B --> C[进行层次聚类分析]
C --> D[查看聚类树状图]
D --> E[添加聚类分区信息到图对象]
E --> F[保存图对象为GraphML文件]
F --> G[使用Gephi加载网络数据]
G --> H[调整节点布局]
H --> I[调整节点大小]
I --> J[为节点上色]
J --> K[观察和分析社区结构]
通过这个流程图,我们可以清晰地看到从数据加载到最终可视化分析的整个过程。希望大家可以按照这些步骤,对自己的Twitter网络数据进行深入分析和可视化展示。
分析与可视化Twitter网络
深入理解与拓展分析
在完成了对Drew的Twitter自我中心网络的可视化分析后,我们可以进一步深入理解网络结构,并探讨一些拓展分析的方法。
社区结构的深入分析
通过Gephi的可视化,我们已经看到了Drew的Twitter网络中存在多个子社区。这些子社区的形成可能与多种因素有关,例如用户的兴趣爱好、职业领域、社交圈子等。我们可以进一步分析这些子社区的特征,以更好地理解用户的社交行为。
- 子社区的规模和密度 :不同子社区的规模和密度可能会有所不同。规模较大的子社区可能代表着更广泛的兴趣群体,而密度较高的子社区可能表示成员之间的互动更为频繁。我们可以通过计算子社区的节点数量和边的数量来评估其规模和密度。
- 子社区的中心节点 :每个子社区可能都有一些中心节点,这些节点在子社区中具有较高的连接度和影响力。通过识别这些中心节点,我们可以了解子社区的核心成员,并进一步分析他们的社交行为和影响力。
- 子社区之间的关系 :子社区之间可能存在着不同程度的联系。有些子社区可能相互独立,而有些子社区可能存在重叠或相互影响的关系。我们可以通过分析子社区之间的边的数量和方向来了解它们之间的关系。
拓展分析方法
除了上述的基本分析方法外,我们还可以尝试一些拓展分析方法,以更深入地挖掘Twitter网络数据的价值。
- 动态分析 :Twitter网络是一个动态的系统,用户的关注关系和互动行为会随着时间的推移而发生变化。我们可以通过收集不同时间点的网络数据,分析网络的动态变化,例如社区的形成、发展和消失,以及用户的社交行为的演变。
- 多网络分析 :除了Twitter网络外,用户可能还在其他社交平台上有活跃的社交行为。我们可以将不同社交平台的网络数据进行整合,进行多网络分析,以更全面地了解用户的社交行为和社交圈子。
- 文本分析 :Twitter上的用户发布的推文包含了丰富的文本信息。我们可以对这些推文进行文本分析,例如情感分析、主题分析等,以了解用户的兴趣爱好和情感状态,并进一步分析这些因素与网络结构的关系。
总结与展望
通过对Twitter网络的分析和可视化,我们可以深入了解用户的社交行为和社交圈子,发现不同用户之间的关系和社区划分。这对于研究社交行为、信息传播、市场营销等方面都有很大的帮助。
在实际应用中,我们可以根据自己的需求和目标,选择合适的分析方法和工具。例如,如果我们关注的是用户的兴趣爱好和社交圈子,我们可以重点分析网络的社区结构;如果我们关注的是信息的传播和扩散,我们可以重点分析网络的传播路径和影响力。
同时,我们也可以不断尝试新的分析方法和技术,以更深入地挖掘Twitter网络数据的价值。例如,随着人工智能和机器学习技术的发展,我们可以利用这些技术对Twitter网络数据进行更复杂的分析和预测。
总之,Twitter网络分析是一个充满挑战和机遇的领域。通过不断地学习和实践,我们可以更好地理解和利用Twitter网络数据,为我们的研究和应用提供有力的支持。
以下是一个总结表格,展示了本文中涉及的主要分析步骤和方法:
| 步骤 | 方法 | 代码示例 |
| — | — | — |
| 构建网络 | 加载必要的库和数据,提取子图 |
library(igraph); source('google_sg.R'); user.net <- read.graph(...); user.clean <- subgraph(...); user.ego <- subgraph(...)
|
| 分析社区结构 | 层次聚类分析,查看树状图,添加分区信息 |
user.sp <- shortest.paths(user.ego); user.hc <- hclust(dist(user.sp)); plot(user.hc); for(i in 2:10) {...}
|
| 可视化网络 | 使用Gephi加载数据,调整布局、大小和颜色 | 打开Gephi,选择File→Open加载数据;在Layout面板选择Yifan Hu Proportional算法;在Rankings面板调整节点大小;在Partition面板为节点上色 |
| 深入分析 | 分析子社区的规模、密度、中心节点和关系,尝试动态分析、多网络分析和文本分析 | 无 |
通过这个表格,我们可以清晰地看到整个分析过程的主要步骤和方法,以及相应的代码示例。希望这个表格能够帮助你更好地理解和应用本文中介绍的分析方法。
最后,为了更清晰地展示整个分析过程的逻辑关系,我们再次给出一个mermaid格式的流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(构建网络):::process
B --> C(分析社区结构):::process
C --> D(可视化网络):::process
D --> E(深入分析):::process
E --> F([结束]):::startend
这个流程图展示了从开始到结束的整个分析过程,包括构建网络、分析社区结构、可视化网络和深入分析等步骤。通过这个流程图,我们可以更直观地理解整个分析过程的逻辑关系。
希望本文能够帮助你更好地理解和应用Twitter网络分析的方法和技术。如果你有任何问题或建议,欢迎随时交流和讨论。
超级会员免费看
22

被折叠的 条评论
为什么被折叠?



