GraphGists

在社交网络中寻找影响者

引言

在此 Graph Gist 中,我将分析社交网络(如 Twitter 或 Facebook)用户之间的互动。

许多使用社交网络的示例都侧重于朋友和推荐,我将转而关注人们如何使用网络,并尝试建立不同类型的行为模式和寻找影响者。作为社交网络的所有者,了解哪些是核心用户非常重要;作为用户,了解哪些人值得关注也非常重要。您还可以利用此功能识别电子商务网站上通过评论具有影响力的购物者。

模型

我的图模型如下所示

social model
图 1. Alice 有多受欢迎?

节点

User:社交网络的用户。

Message:消息在 User` 之间 `SENT`(发送),并与其他 `Message` 之间存在 `FORWARD`(转发)和 `REPLY_TO`(回复)关系。

关系

FOLLOWSUser 关注其他 User

SENTUser 向其他 User 发送 Message

FORWARD:一个 Message 可能是另一个 Message 的转发版本。

REPLY_TO:一个 Message 可能是对另一个 Message 的回复。

设置

用例:列出所有用户和消息

为了进行分析,我们先从简单入手,列出所有的 UserMessage

MATCH path=(User)-[:SENT]->(Message)
RETURN path

正如您所见,从这个视图很难发现任何模式。

用例:查找用户计数

记住我们的目标是找到网络中的影响者,我们可以从最简单的衡量标准开始,即关注某个用户的人数。

MATCH (follower:User)-[:FOLLOWS]->(targetUser:User)-[:FOLLOWS]->(following:User)
RETURN targetUser AS User, COUNT(distinct follower) AS Followers, COUNT(distinct following) AS Following

为了获取更多信息,我们可以提供所有关注者的姓名

MATCH (p:User)-[f:FOLLOWS]->(p1:User)
RETURN p.id AS User, COLLECT(p1.id) AS Following

虽然这很有趣,但它并没有告诉我们太多关于用户行为的信息。用户可能不活跃,或者他们可能每天发送多条消息。

我们可以通过以下查询轻松查看用户的活跃程度

MATCH (p:User)-[:SENT]->(tweet:Message)
RETURN p.id AS User, COUNT(tweet) AS Tweets

现在我们可以了解用户的活跃程度,但让我们深入探讨,看看他们有哪些类型的活动。

用例:将转发的消息作为影响力的衡量标准

衡量影响力的一个标准是用户的消息在整个网络中被转发的频率,因此让我们找出被转发最多的消息

MATCH (retweet:Message)-[r:FORWARD]->(tweet:Message)
RETURN tweet, COUNT(r)
ORDER BY COUNT(r) DESC

我们可以通过限制查看的消息来限定在某一天

MATCH (retweet:Message)-[r:FORWARD]->(tweet:Message {day_sent:'Monday'})
RETURN tweet, COUNT(r)
ORDER BY COUNT(r) DESC

记住我们正在尝试寻找影响者,所以我们需要知道是谁发送了这些消息

MATCH (retweet:Message)-[r:FORWARD]->(tweet:Message)<-[:SENT]-(p:User)
RETURN p.id AS User, COUNT(r) AS `Messages Retweeted`
ORDER BY COUNT(r)
DESC LIMIT 5

由此我们可以看到,Bridget 的许多消息都被转发了,但 Mark 的消息获得了更多的转发。

如果您是 Twitter 或类似社交网络的用户,您会意识到 Twitter 上有很多只是简单转发消息的机器人。我们希望从分析中排除这些机器人。

MATCH (p:User)-[s:SENT]->(tweet:Message)-[retweet:FORWARD]->(tweet1:Message), (p:User)-[s2:SENT]->(tweet2:Message)
WITH p, COUNT(DISTINCT tweet) AS forwards, COUNT(DISTINCT tweet2) AS messages
WHERE (forwards*1.00)/messages > 0.8
RETURN p.id AS `Potential Bot`, (forwards*1.00)/messages*100 AS `Percent Retweeted`
ORDER BY `Percent Retweeted` DESC

正如您所见,Doug 只转发消息,所以很可能是一个机器人。为了更好地了解影响力,我们需要从分析中排除他和任何其他机器人。

MATCH (p:User)-[s:SENT]->(tweet:Message)-[retweet:FORWARD]->(tweet1:Message), (p:User)-[s2:SENT]->(tweet2:Message)
WITH p, COUNT(DISTINCT tweet) AS forwards, COUNT(DISTINCT tweet2) AS messages
WHERE (forwards*1.00)/messages < 0.8
WITH p
MATCH (p)-[s:SENT]->(tweet:Message)-[rt:FORWARD]->(tweet1:Message)<-[:SENT]-(p1:User)
RETURN p1.id as User, COUNT(tweet) as `Retweeted Messages`
ORDER BY COUNT(tweet)
DESC LIMIT 15

请注意,我们现在寻找转发量 LESS THAN 80% 的用户。

正如您所见,这显示了一个略有不同的情况,因为 Mark 的消息只被机器人转发。我希望从分析中排除转发者的原因在于,人类转发会进行一些筛选,只会转发他们喜欢的内容。

我们现在有几种衡量影响力的方法,基于关注者数量和用户获得的转发量。

我想探讨的第三种衡量标准是用户在 Twitter 上以及在多少人中发起对话或讨论的频率。

用例:将对话作为影响力的衡量标准?

找到对话是衡量影响力的一个好方法,因为它表明人们愿意与该用户互动。

为了开始这项分析,我们首先获取对话列表,请注意我已经限制了对话路径的长度,您可能需要根据您的用例考虑扩展。

MATCH p=(tweet:Message)-[:REPLY_TO*1..10]->(conversation:Message)
RETURN p

我们可以将此限定为单个对话

MATCH (tweet:Message {id:'20'})<-[:REPLY_TO*0..10]-(conversation:Message)
RETURN DISTINCT(conversation) AS Conversation
ORDER BY conversation.day_sent

注意 DISTINCT(conversation),这将确保我们在响应中只获取每条消息的一个实例。

现在我们有了对话列表,让我们深入探讨。

获取开始对话的消息列表,即有人回复过的消息

MATCH (tweet:Message)-[r:REPLY_TO]->(conversation:Message)
WHERE NOT (conversation)-[:REPLY_TO]->()
RETURN DISTINCT conversation

并找出发送这些开启对话消息的人

MATCH (tweet:Message)-[:REPLY_TO]->(conversation:Message)<-[s:SENT]-(p:User)
WHERE NOT (conversation)-[:REPLY_TO]->()
RETURN DISTINCT conversation, p.id AS `Conversation Starter`

在此基础上,获取用户愿意互动和回复的用户列表,因为这表明关系不仅仅是浅层的“关注”。

MATCH conv=(b:User)-[:SENT]->(tweet:Message)-[:REPLY_TO]->(tweet1:Message)<-[:SENT]-(a:User)-[:SENT]->(tweet2:Message)-[:REPLY_TO]->(tweet)
RETURN a.id AS `Conversationalist 1`, b.id AS `Conversationalist 2`, COUNT(DISTINCT conv) AS Conversations
ORDER BY a.id ASC

我们还想了解对话的规模有多大以及有多少人参与其中,涉及很多人参与的长对话比只有几个人的短对话更能体现影响力。

MATCH (tweet:Message)-[r:REPLY_TO]->(conversation:Message)<-[s:SENT]-(p:User)
WHERE NOT (conversation)-[:REPLY_TO]->()
WITH DISTINCT conversation,p
MATCH conv=(participant:User)-[:SENT]->(tweet:Message)-[:REPLY_TO*0..10]->(conversation)
RETURN conversation, p, COUNT(DISTINCT participant) AS `Distinct Participants`

最后再次修改查询,添加用户发起的对话数量。

MATCH (tweet:Message)-[r:REPLY_TO]->(conversation:Message)<-[s:SENT]-(p:User)
WHERE NOT (conversation)-[:REPLY_TO]->()
WITH DISTINCT conversation,p
MATCH conv=(participant:User)-[:SENT]->(tweet:Message)-[:REPLY_TO*0..10]->(conversation)
WITH conversation, p, COUNT(DISTINCT tweet) AS messageCount, COUNT(DISTINCT participant) AS participantCount
WHERE participantCount > 2
RETURN p.id, COUNT(p) AS `Conversations`, AVG(messageCount) AS `Average Length`, AVG(participantCount) AS `Average Participants`

正如您所见,Alice 发起了更多对话,但 Mark 发起的对话参与度更高。您需要自己判断哪种情况在您的网络中具有更大的影响力。

结论

正如您所见,Neo4j 是一个强大的社交网络分析工具,您可以使用上述一些值来观察您网络中的影响者是谁。

© . All rights reserved.