☰
微博数据三件套:用户信息、好友关系、转发关系实战分析
2026/10/3 3:37:26 网站建设 项目流程

简介:这份微博社交网络数据集面向数据科学、社交网络分析与信息传播方向的研究者及学生,提供用户信息、好友关注与转发关系三类核心数据,可用于用户画像、网络结构挖掘与舆情传播建模等场景。压缩包共2个文件,以SQL数据库脚本与Markdown说明文档为主,整体约22.26MB,其中SQL文件承载建表与数据记录,便于导入数据库后直接查询统计,说明文档则交代数据格式与使用许可。已有168人学习下载。借助用户属性可分析性别比、地域分布与影响力,通过关注关系能考察连通性、中心性与社区结构,转发数据则支撑传播路径与扩散模式研究,适合开展定量分析与模式识别,为推荐系统、精准营销和舆情监控提供数据基础。

1. 微博数据三件套:用户信息、好友关系、转发关系到底能跑出什么

如果你正在做社交网络分析、传播路径建模或者用户画像,大概率绕不开微博这个数据源。但真正动手时你会发现,单独一份用户表或者单独一份转发记录,能跑出来的结论非常有限——用户属性没有行为轨迹支撑,转发关系没有用户画像锚定,分析做到一半就卡住了。这份「微博数据(用户信息,好友关系,转发关系).zip」解决的就是这个问题:它把三类数据打包在一起,用户信息提供节点属性,好友关系提供关注网络的边,转发关系提供信息传播的边。三者叠加,你才能在一个图结构上同时做社区发现、影响力排序和传播路径回溯。适合做课程设计、毕设、社交网络论文复现,以及需要真实图数据做算法验证的从业者。下面按「数据长什么样 → 怎么加载 → 怎么建图 → 怎么避坑 → 怎么进阶」的顺序拆开讲。

2. 三张表的结构拆解与加载方案

2.1 用户信息表:字段含义与清洗要点

用户信息表通常以 CSV 或 JSON 格式存在,核心字段包括用户 ID、昵称、性别、粉丝数、关注数、微博数、认证类型、所在地等。拿到手第一件事不是直接读,而是先确认编码和分隔符。微博昵称里经常出现逗号、引号、换行符,如果 CSV 没有做转义,用默认的pd.read_csv会直接翻车。

import pandas as pd # 先探测编码,常见的是 utf-8 或 gbk with open('user_info.csv', 'rb') as f: raw = f.read(4) print(raw) # 看 BOM 头判断编码 # 读取时显式指定编码和引号处理 df_user = pd.read_csv( 'user_info.csv', encoding='utf-8-sig', # 处理带 BOM 的文件 quotechar='"', # 引号包裹的字段 escapechar='\\', # 转义字符 on_bad_lines='warn', # 坏行不直接崩,先警告 dtype={'user_id': str} # ID 必须用字符串,防止大数精度丢失 ) print(df_user.shape) print(df_user.isnull().sum()) # 看哪些字段缺失严重

逻辑说明:encoding='utf-8-sig'是为了处理 Windows 下 Excel 导出的 BOM 头,不加这个参数第一列列名会带一个不可见字符,后面按列名取值全部报 KeyError。dtype={'user_id': str}是血泪经验——微博用户 ID 是 10 位数字,用 int64 读没问题,但如果后续要和转发表做 join,两边类型不一致会静默产生空结果。on_bad_lines='warn'让你先看到有多少坏行,而不是直接抛异常中断。

参数方面,如果你的文件是 JSON Lines 格式(每行一个 JSON 对象),改用pd.read_json('user_info.jsonl', lines=True)。如果字段嵌套层级深,比如user.profile.gender,先json_normalize展平再存成 DataFrame。

2.2 好友关系表:有向边与去重策略

好友关系表记录的是关注关系,典型结构是两列:from_user_id和to_user_id,表示 from 关注了 to。这是一张有向图。常见问题是重复边和自环。

df_friend = pd.read_csv('friend_relation.csv', dtype={'from_user_id': str, 'to_user_id': str}) # 去掉自环(自己关注自己,通常是数据采集异常) df_friend = df_friend[df_friend['from_user_id'] != df_friend['to_user_id']] # 去重:同一对关注关系可能被采集多次 df_friend = df_friend.drop_duplicates(subset=['from_user_id', 'to_user_id']) # 检查是否有孤立节点(出现在好友表但不在用户表) user_ids = set(df_user['user_id']) friend_ids = set(df_friend['from_user_id']) | set(df_friend['to_user_id']) orphan = friend_ids - user_ids print(f'孤立节点数: {len(orphan)}')

逻辑说明:自环在有向图算法里会导致 PageRank 计算异常,必须先清。去重时用subset指定两列联合去重,不要用drop_duplicates()全列去重,因为可能还有其他列(如关注时间)不同但关系相同。孤立节点检查是为了后续建图时不报错——如果直接用 networkx 建图,孤立节点不会报错但会让你的节点属性查询返回 None,分析结果里混入空值很难排查。

2.3 转发关系表:传播链的边与时序

转发关系表比好友关系多一个关键维度:时间。典型字段是user_id、retweeted_user_id、weibo_id、retweet_time。这条边表示 user_id 转发了 retweeted_user_id 的微博。

df_retweet = pd.read_csv('retweet_relation.csv', dtype={'user_id': str, 'retweeted_user_id': str}) df_retweet['retweet_time'] = pd.to_datetime(df_retweet['retweet_time'], errors='coerce') # 去掉时间解析失败的行 df_retweet = df_retweet.dropna(subset=['retweet_time']) # 按时间排序,后续做传播路径回溯必须有序 df_retweet = df_retweet.sort_values('retweet_time').reset_index(drop=True) # 统计每个用户的转发次数和被转发次数 retweet_count = df_retweet.groupby('user_id').size().rename('retweet_out') be_retweeted_count = df_retweet.groupby('retweeted_user_id').size().rename('retweet_in')

逻辑说明:errors='coerce'把解析不了的时间变成 NaT,然后 drop 掉,避免后续时间排序时抛异常。排序这一步很多人忽略,但如果你要做传播路径还原(比如找出某条微博从首发到扩散的完整链路),时间乱序会导致路径断裂。groupby统计出的两个 Series 后续可以 merge 回用户表,作为影响力特征的输入。

注意:三张表的 user_id 字段命名可能不一致,有的用uid,有的用user_id,有的用id。加载后先统一列名再做关联,否则 merge 出来全是空。

3. 用 NetworkX 构建关注网络与传播网络

3.1 建图:从 DataFrame 到 Graph 对象

有了清洗后的三张表,下一步是建图。关注网络用有向图DiGraph,传播网络也用DiGraph,但边属性不同。

import networkx as nx # 关注网络 G_follow = nx.from_pandas_edgelist( df_friend, source='from_user_id', target='to_user_id', create_using=nx.DiGraph() ) # 把用户属性挂到节点上 user_attrs = df_user.set_index('user_id').to_dict('index') nx.set_node_attributes(G_follow, user_attrs) print(f'节点数: {G_follow.number_of_nodes()}') print(f'边数: {G_follow.number_of_edges()}') print(f'平均出度: {df_friend.groupby("from_user_id").size().mean():.2f}')

逻辑说明:from_pandas_edgelist比手动add_edge循环快一个数量级,十万级边基本秒建。set_node_attributes把用户信息挂上去之后,后续做社区发现时可以按属性着色或分组统计。平均出度反映的是用户主动关注行为的分布,如果这个值异常高(比如超过 100),说明数据里混入了营销号或者采集时把粉丝也当成了关注。

3.2 传播网络:边属性与时序切片

传播网络建图时要保留时间属性,否则没法做时序分析。

G_retweet = nx.from_pandas_edgelist( df_retweet, source='user_id', target='retweeted_user_id', edge_attr=['weibo_id', 'retweet_time'], create_using=nx.DiGraph() ) # 按时间窗口切片:只看某一天的传播 import datetime day_start = datetime.datetime(2024, 1, 1) day_end = day_start + datetime.timedelta(days=1) edges_in_day = [ (u, v) for u, v, d in G_retweet.edges(data=True) if day_start <= d['retweet_time'] < day_end ] G_day = G_retweet.edge_subgraph(edges_in_day).copy()

逻辑说明:edge_attr把微博 ID 和时间挂到边上,后续可以按微博 ID 筛选出单条微博的传播子图。edge_subgraph返回的是视图,加.copy()变成独立图,否则后续修改会影响原图。时间窗口切片是做传播速率分析的基础——你可以统计每小时新增转发量,画出传播曲线。

3.3 关联分析:把三张图叠在一起

单独看关注网络或传播网络都有局限。关注网络告诉你「谁可能看到」,传播网络告诉你「谁实际转了」。两者叠加才能算「传播转化率」。

# 找出既在关注网络中又在传播网络中的边 follow_edges = set(G_follow.edges()) retweet_edges = set(G_retweet.edges()) both = follow_edges & retweet_edges print(f'关注且转发的边数: {len(both)}') print(f'传播转化率: {len(both) / len(retweet_edges) * 100:.2f}%')

逻辑说明:这个转化率衡量的是「关注关系中有多少最终产生了转发行为」。如果转化率极低(比如低于 1%),说明大部分转发来自非关注用户,信息是通过推荐流或搜索扩散的,而不是社交关系链。这个结论直接影响你的传播模型选型——独立级联模型还是线性阈值模型,取决于传播是关系驱动还是内容驱动。

提示:如果数据量超过百万边,NetworkX 的内存和速度会吃紧。常见做法是先用scipy.sparse存邻接矩阵做数值计算,只在需要图算法时转成 NetworkX。或者直接用graph-tool或igraph,但安装门槛高一些。

4. 避坑与排查:数据关联时的五个翻车现场

4.1 现象:merge 之后行数暴涨

原因:好友关系表里同一对用户有多条记录(不同时间采集),或者用户表里有重复 user_id。解决:merge 前先对两张表分别去重,用户表按 user_id 去重,好友表按 from+to 去重。用df.drop_duplicates(subset=['user_id'])和df.drop_duplicates(subset=['from_user_id','to_user_id'])。

4.2 现象:时间字段全是 NaT

原因:时间格式不统一,有的用2024-01-01 12:00:00,有的用时间戳,有的用01/01/2024。解决:先抽样看几种格式,然后写一个解析函数用pd.to_datetime加format参数分批处理,或者统一转成 Unix 时间戳再转回来。

4.3 现象:PageRank 结果全是同一个值

原因:图里有大量孤立节点或者图不连通,PageRank 在悬挂节点上分配不均。解决:先取最大连通子图G.subgraph(max(nx.weakly_connected_components(G), key=len)),再跑 PageRank。另外检查是否有自环,自环会让权重回流。

4.4 现象:社区发现结果不稳定

原因:Louvain 算法有随机性,每次跑结果不一样。解决:设置随机种子random_state=42,或者跑多次取模块度最高的那次。如果图太大,先用k-core裁剪掉低度节点再跑。

4.5 现象:转发关系里出现不存在的用户

原因:转发表中的 user_id 在用户信息表中查不到,可能是采集时用户已注销,或者 ID 类型不一致(字符串 vs 整数)。解决:统一转成字符串再比对,对于确实缺失的用户,要么丢弃相关边,要么保留但标记为 unknown,不要直接删掉——删掉会丢失传播链的完整性。

5. 进阶玩法:从转发关系还原传播路径与影响力排序

5.1 传播路径回溯

拿到一条微博 ID,你可以从转发关系表中筛出所有相关边,按时间排序,构建一棵传播树。

def build_cascade(df_retweet, weibo_id): sub = df_retweet[df_retweet['weibo_id'] == weibo_id].copy() sub = sub.sort_values('retweet_time') G = nx.DiGraph() for _, row in sub.iterrows(): G.add_edge(row['retweeted_user_id'], row['user_id'], time=row['retweet_time']) return G cascade = build_cascade(df_retweet, 'some_weibo_id') print(f'传播树深度: {nx.dag_longest_path_length(cascade)}') print(f'参与用户数: {cascade.number_of_nodes()}')

逻辑说明:传播树是有向无环图(DAG),因为转发时间不可逆。dag_longest_path_length给出传播链的最大深度,反映信息经过了几跳。参与用户数就是这条微博的转发人数。你可以对多条微博批量跑这个函数,统计深度分布和广度分布,判断哪些内容更容易形成长链传播。

5.2 影响力排序:PageRank 与转发加权

在关注网络上跑 PageRank 得到的是「关注影响力」,在传播网络上跑 PageRank 得到的是「传播影响力」。两者结合可以做一个加权排序。

pr_follow = nx.pagerank(G_follow, alpha=0.85) pr_retweet = nx.pagerank(G_retweet, alpha=0.85) # 加权融合 combined = {} for uid in set(pr_follow) | set(pr_retweet): combined[uid] = 0.4 * pr_follow.get(uid, 0) + 0.6 * pr_retweet.get(uid, 0) top_users = sorted(combined.items(), key=lambda x: x[1], reverse=True)[:20] for uid, score in top_users: print(uid, f'{score:.6f}')

逻辑说明:alpha=0.85是 PageRank 的阻尼系数,默认值,表示用户有 85% 概率继续点击下一个节点。加权融合的系数 0.4 和 0.6 是我一般会用的经验值——传播行为比关注行为更能反映真实影响力,所以给传播权重更高。你可以根据业务场景调整,比如做广告投放就偏向传播权重,做社交推荐就偏向关注权重。

5.3 验证方法:用已知案例做回溯测试

跑完算法不要直接信结果。找一个你熟悉的微博账号或者热点事件,看算法排序是否和直觉一致。如果 PageRank 排出来的 Top 20 里全是营销号,说明数据里营销号占比过高,需要先做异常账号过滤。常见过滤规则是:关注数超过 5000 且粉丝数低于 100 的账号标记为异常,或者微博数超过 10 万但转发数极低的账号。

注意:传播路径还原依赖转发时间的准确性。如果数据采集时时间字段有缺失或者时区不统一,传播树会断裂。我一般会先检查时间字段的缺失率,超过 5% 就放弃做路径分析,只做静态图分析。

从那以后我每次拿到新的社交网络数据集,都强制先跑一遍「三查」:查 ID 类型一致性、查时间字段缺失率、查重复边比例。这三项不过关,后面所有分析都是沙上建塔。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询