做社会网络分析,最让人头疼的往往不是算法本身,而是数据怎么从问卷、Excel、爬虫结果变成一个UCINET能读懂的网络矩阵。这个系列前面几篇讲了UCINET的基本界面和网络分析的大致流程,这篇专门聊聊数据准备与导入。我见过太多人卡在这一步:矩阵整理好了,导入却报错;导进去了,节点标签全乱;矩阵不对称,后面所有中心度指标都变得不可信。数据是SNA的地基,地基歪了,后面算得再花哨也是白搭。
这篇文章从数据格式选型、矩阵整理规范、Excel导入实操、DL格式手写,到二模数据和属性数据的导入处理,把数据进UCINET的完整链路走一遍。适合正在用问卷、访谈、爬虫、二手数据做网络分析的学生和研究者参考,也适合第一次接触UCINET的初学者照着操作。
1. 为什么数据准备这一步经常栽跟头
1.1 UCINET的定位:它是分析工具,不是录入工具
很多新手第一次用UCINET,下意识会在里面直接敲数据,然后发现界面简陋得不像现代软件。这不是UCINET不行,而是它的设计思路很明确:只管分析,不管录入。它真正的主场是中心度计算、凝聚子群检测、结构洞分析、QAP相关、多维量表这些统计方法。
你可以把UCINET理解成一个“计算器”,它不负责帮你把原始数字抄到纸上,只负责在数字喂进去之后做运算。喂进去的数字从哪来?通常是Excel、文本文件、Pajek格式或者其他外部数据源。UCINET预设了多种导入通道:Excel矩阵、DL文本文件、Pajek文件,还有内置的矩阵编辑器(Data > Matrices > Matrix Editor)可以临时手工录入。
我的建议是:除非你的网络极小(比如七八个节点),否则不要用内置编辑器手工录入。理由很简单,手工录入无法做批量检查和可视化预览,行数一多就容易漏掉关系,而且你很难回头排查哪一格填错了。相比之下,在Excel里把矩阵准备好,检查清楚,再一次性导入UCINET,效率和可靠性都高得多。
1.2 四条导入路径的选型对比
UCINET的导入选项看着多,实际用下来,核心路径就四条。
| 导入路径 | 适合场景 | 优点 | 缺点 |
|---|---|---|---|
| Excel矩阵导入 | 手工整理的邻接矩阵、属性表 | 直观、可核对、适合中小规模网络 | 大矩阵时Excel本身容易卡 |
| DL格式文本导入 | 边列表、大网络、程序生成的数据 | 格式简单、易自动化生成、可批量处理 | 手写容易出错,需要小心格式声明 |
| Pajek格式导入 | 已有Pajek格式数据或从其他工具迁移 | 兼容性好、生态成熟 | 节点编号规则与UCINET不完全一样,需确认 |
| 内置矩阵编辑器 | 小型网络临时录入、快速试算 | 无需切换软件、操作直接 | 不适合大网络,检查困难 |
选型逻辑也很简单:如果网络规模在100个节点以下,Excel矩阵导入最直观,你可以在Excel里同时看到行列标签,方便逐格检查;如果是几百上千节点的大网络,或者数据是从数据库、爬虫脚本里导出的,那么DL格式的边列表(edgelist)更合适,因为边列表本身就适合程序批量生成,文件体量也更小。
1.3 统一的预处理原则:先清后导
不管你走哪条导入路径,预处理的原则是相通的:先清理,后导入。很多导入报错,根源不是UCINET读不懂文件格式,而是源数据里带了脏东西。
常见的“脏数据”包括:多余的空行空列、标签列里混入不可见字符、数字与文本混在同一列、矩阵中留有空格导致读取错位、中文标点和英文标点混用。这些在Excel里肉眼很难发现,但UCINET读取时非常敏感,稍微多一个空格或者一个不可见字符,就可能让它把矩阵解析失败。
所以,我一般会在数据进UCINET之前,先在Excel里做一轮“数据体检”:检查行列数是否一致、标签列是否有重复、单元格是否有非数字内容、矩阵是否有全零行(孤立节点)。这一步看起来琐碎,却能把后续导入和排查的时间省掉大半。
2. 数据准备第一关:矩阵怎么整理才不会被软件“嫌弃”
2.1 分清你要做的是哪类网络数据
UCINET里常说的数据,主要是三类:1-mode关系矩阵(单模网络)、2-mode发生矩阵(二模网络)、属性数据(节点属性表)。三者用途不一样,在UCINET里的存放方式和导入逻辑也不一样。
单模网络数据是最常见的。它描述的是“一批节点之间的两两关系”,典型例子是朋友关系、合作关系、邮件往来、引用关系。矩阵的行和列都是同一批节点,第i行第j列的值表示从节点i到节点j有没有关系、有多强。单模网络又分成有向和无向两种:有向关系(比如“A关注B”不等于“B关注A”)需要按照实际方向填写,矩阵未必对称;无向关系(比如“A和B认识”)通常填成对称矩阵,A行B列和B行A列都填1。
二模网络数据描述的是“一类节点与另一类节点之间的归属或参与关系”,典型例子是员工参与哪些项目、学生选修哪些课程、作者发表在哪些期刊。行和列是两类不同的节点,矩阵往往是矩形的而不是方阵,导入方式也和单模网络不一样。
属性数据不是网络关系本身,而是节点的外部特征,比如性别、部门、点击量、年龄。这类数据在做“按属性分组比较网络指标”或者“根据属性给节点着色”时会用到。
我在实操中见过最普遍的问题,不是不知道数据类别,而是把三类数据混在一起:有人把属性表当成矩阵导进去,有人把二模数据当单模矩阵硬填成方阵。根子上还是要先想清楚:“我手里这批数据,行是什么、列是什么、交叉格代表什么”。
2.2 Excel里的一表流规范:行是发出方,列是接收方
如果你选择Excel矩阵导入,那么表格的整理规范可以直接决定导入成败。
先说一个最基础的约定:矩阵的行代表关系的发出方(ego),列代表关系的接收方(alter)。这个约定在UCINET里没有强制显示,但后面解读中心度等指标时都依赖它。比如行和分别是张三、李四、王五,行列交叉处的格子填1表示张三主动联系了李四一次,那么这个矩阵就是有向的,因为“张三联系李四”和“李四联系张三”未必同时发生。
实操上,我推荐的Excel布局是这样的:
- 第一行(或第一列)放节点名称,作为行列标签;
- 剩下的单元格全部是数值,不需要加单位,不需要加符号;
- 对角线位置,如果没有自环关系,一律填0;
- 不要用合并单元格,不要留空行空列,不要在表格里写注释。
这里有一个细节:行列标签要严格按照相同的顺序排列。也就是说,第一列从上到下的节点顺序,必须和第一行从左到右的节点顺序完全一致。如果顺序错位,UCINET不会报错,但后面算出来的密度、中心度全都会张冠李戴,这种错误是最隐蔽也最危险的。
2.3 有向、无向、二值、多值:怎么判断,怎么录入
数据到底该按有向填还是无向填,按0/1填还是按实际数值填,这是两对容易混淆的概念。
第一对概念是“有向”和“无向”。判断标准只有一个:关系本身有没有方向性。比如“甲给乙发邮件”就是有向关系;“甲乙在同一个项目组”就是无向关系。如果是有向关系,行列交叉处要区分方向;如果是无向关系,通常上下三角互为镜像,A对B和B对A都填同一个值。当然也可以在导入后通过UCINET的Symmetrize功能把有向矩阵对称化,但我建议在Excel里就处理清楚,别把希望寄托在后期转换上。
第二对概念是“二值”和“多值”。如果只关心“有关系还是没关系”,那就填0/1;如果关心关系的强度、频次,比如“合作了3次”“联系了半个月”,那就填实际数值。多值矩阵在导入后,UCINET默认会按数值处理,但某些分析模块会要求先二值化(Data > Matrix > Dichotomize),这个后续再讲。
我在多个项目里总结出的实操原则是:在Excel里尽量保留原始数值,不要急着二值化。0/1二值化会丢失大量信息,而且阈值怎么定本来就是一门学问。宁可先把多值数据导进去,后面在UCINET里再做二值化处理,这样弹性更大。不过要注意一点:多值矩阵导入后,UCINET部分算法会把数值当成权重,如果你本意只是“有无关系”而误录成了带刻度的数值,结果解读上要格外小心。
2.4 节点编号与标签分离的思路
节点怎么命名,是个经常被低估的问题。我见过不少人直接用中文姓名或者很长的单位名称作为矩阵的行列头,导入之后看着方便,但后续处理容易出幺蛾子。
最稳妥的做法是“编号为主、标签为辅”:在Excel里用一个短ID(比如n1、n2、n3,或者直接用数字1到N)作为行列标签导入UCINET,另外单独做一个属性表,把短ID和完整名称对应起来。这样既避免了中文编码问题,也避免了长标签在分析输出时撑爆显示。
如果你确实需要中文标签,最好先确认你用的UCINET版本对中文的支持情况。在我的经验里,旧版本对中文的支持并不稳定,会出现标签乱码或者节点名截断的情况。新版虽然改善了一些,但为了省事,我还是倾向于用拼音/英文/数字编号,等分析做完了,出图或输出表格时再通过属性表映射回中文名称。这个习惯帮我避过不少坑。
3. 实测导入流程:Excel矩阵导入和DL格式手写
3.1 从问卷或关系表到矩阵的加工过程
很多人的原始数据不是现成的矩阵,而是一张“两两关系表”,比如一列是“谁”,一列是“跟谁”,可能还有第三列“关系的次数”。这种数据其实比矩阵更接近原始状态,需要先转成方阵再导入UCINET。
转换步骤说起来很简单:先枚举出所有节点,给每个节点编号,然后建立一个N×N的方阵,逐条把关系填进去。实际操作中,如果节点量一大,手工填就不可行了,我一般用Excel的数据透视表来做。
做法是:把“谁”放在行区域,“跟谁”放在列区域,“次数”放在值区域,透视表自动就能生成一个计数矩阵。生成之后,再把透视表的行列复制成数值粘贴到新工作表里,补上对角线0,检查一遍行列顺序,就可以导入了。用透视表还有一个好处:它会自动把缺失的格子填成空值,这时你可以用“查找替换”把空值统一替换成0。
为了避免原始关系表里出现“自己填自己”的情况,在转矩阵之前先做一次去重和自环检查:同一对节点如果有重复记录,按实际语义决定是合并频次还是去重;自环一般直接删除,除非你的研究问题明确要分析自我关系。
3.2 菜单操作:Data > Import > Excel Matrix 的完整走一遍
把Excel矩阵准备好之后,正式导入UCINET的操作流程并不复杂,但有几个对话框选项值得注意。
打开UCINET,依次点击 Data > Import > Excel Matrix,弹窗里先选择Excel文件路径,接着选择Sheet和Range。Range这里容易出错:你的矩阵如果从A1开始,节点标签占据了第一行和第一列,那么Range要包括标签区域,不能只选数字区。选定后,UCINET会问两个关键问题:第一行是否为列标签(First row is column labels),第一列是否为行标签(First column is row labels)。这两个问题一定要根据实际情况回答,答错了节点标签就会被当成数据读入,矩阵维度立刻错乱。
设置完成后导入,UCINET会生成一个数据集。这时不要急着做分析,先看一眼:点击Data > Describe,或者直接调入NetDraw(NetDraw > File > Open > Ucinet dataset),把网络画出来看看。如果节点数、连线方向、孤立点数量和你源数据对得上,再继续后续分析。这一步视觉检查非常关键,很多矩阵错位问题在NetDraw里一眼就能看出来。
3.3 DL格式手写:什么时候需要,怎么写不出错
DL格式是UCINET支持的文本格式,它的好处是可以用任何文本编辑器生成,也可以由脚本批量输出。当你手上数据量很大,或者数据是从数据库导出时,DL格式往往比Excel更省事。
DL格式的核心结构分三块:头部声明、标签声明、数据体。
一个最常用的“全矩阵”DL文件长这样:
dl n=4 format=fullmatrix labels: n1,n2,n3,n4 data: 0 1 1 0 1 0 0 1 1 0 0 0 0 1 0 0头部里n=4声明节点数,format=fullmatrix声明这是完整矩阵。然后labels:列出节点名称,顺序必须和后面矩阵的行列顺序一致。data:之后写数据,数字之间用空格或逗号分隔。
如果你手里的数据是边列表,可以写成:
dl n=4 format=edgelist1 labels: n1,n2,n3,n4 data: n1 n2 1 n1 n3 1 n2 n4 1边列表的每一行代表一条关系:“发出方、接收方、关系值”。格式声明还可以是edgelist(不带值)或者nodelist。新手最容易犯的错是头部声明的n=和实际节点数不一致,或者labels数量对不上,导致UCINET读取时矩阵维度混乱。
在实际项目中,我遇到过用python导出几千条边生成DL文件的情况。只要保证头部声明和每行边的格式稳定,批量生成完全没问题。但有一条必须叮嘱:DL文件保存时最好使用UTF-8编码,并且确认文本编辑器的换行符是LF,如果文件里夹杂了其他不可见控制符,导入时会出现莫名其妙的解析失败。
3.4 导入后第一时间要做的三件事
数据成功导入UCINET不代表大功告成,我每次导入后固定做三件事,可以叫“导入三查”。
第一查节点数。用Data > Explore或者直接在NetDraw里查看节点总数,确认没有意外的重复节点或者缺失节点。
第二查孤点。一个节点如果不在任何一条关系里,它在很多分析中会被忽略,但会影响密度计算。用NetDraw的Ego networks或者描述统计看一下孤立点情况,再决定是保留还是剔除。
第三查矩阵对称性。如果数据本应是无向关系,导入后却发现矩阵不对称,那说明源数据里必有录入遗漏。可以用UCINET里的Data > Matrix > Symmetrize功能临时处理,但我更建议回到Excel里把漏掉的关系补上,因为对称化操作虽然快,却是在“抹平”原始数据的不对称性,掩盖了真实的数据录入问题。
4. 二模数据与属性数据:两个容易被忽视的导入场景
4.1 二模矩阵长什么样,什么时候会用到
二模数据在社会网络分析里其实非常常见,但UCINET的默认导入界面更偏向单模矩阵,所以很多人第一次接触二模数据时不知道往哪里放。
二模数据的典型特征是“行和列不是同类事物”。比如“员工—项目参与矩阵”:行是员工,列是项目,交叉格填1表示该员工参与了该项目。再比如“作者—期刊发表矩阵”:行是作者,列是期刊。这个矩阵是矩形的,行数不需要等于列数。
这类数据在研究“两个群体之间的交互”“隶属网络如何转化为共现网络”时特别有用。比如你想知道两个员工是否因为参与了同一个项目而产生联系,就需要先把二模矩阵转成员工之间的共现矩阵,再做单模网络分析。
4.2 二模数据导入的完整步骤
二模数据的导入其实和单模矩阵导入路径是一样的:Data > Import > Excel Matrix,选择正确的Range后正常读入。关键区别在于导入之后,你要做一步“二模声明”。
在UCINET中,二模数据导入后通过Data > 2-Mode > 2-Mode to 1-Mode功能做转换。这个功能的核心逻辑是:基于二模矩阵的列(或行)计算“共享模式”矩阵。比如员工—项目矩阵,转换后得到“员工之间的共现矩阵”,矩阵的值表示两个员工共同参与了多少个项目。
实操中有一个易错点:二模数据导入前,在Excel里就要把两类节点的名称区分清楚。比如员工名和项目名如果都叫“张三”“李四”,转换时就可能混乱。我的习惯是给列节点名加前缀,比如员工名直接用“E1”“E2”,项目名用“P1”“P2”,这样转换后生成的矩阵节点名还能看出原始归属,后续出报告也更方便。
4.3 属性数据导入:让网络分析带上“背景信息”
属性数据是节点的外部标签,比如参与者分组、性别、区域、规模等。它不参与网络矩阵的运算,但能辅助分析——比如对比不同分组的网络密度、聚类系数,或者在NetDraw里按属性给节点着色。
属性表在Excel里的格式也很简单:第一列是节点ID(必须和网络矩阵的节点ID一一对应),后面每一列是一个属性变量。导入时通过Data > Import > Excel Matrix,选中整个属性表格识别为数据即可。导入后如果你发现节点ID和网络矩阵节点ID的顺序不一致,可以用Data > Matrices > Merge或者Data > Sort来重新对齐。
有一个必须强调的点:属性表的节点ID可以在顺序上打乱,但ID值必须和网络矩阵的节点ID完全对应。如果网络矩阵用的是n1到n20,属性表里也必须是同一套ID,顺序可以不同,UCINET会按照ID匹配合并,但前提是ID本身没有重复、没有缺失。
5. 高频报错与避坑清单实录
5.1 我实际碰到过的几个典型问题
数据导入报错,永远是新手期最消耗耐心的事。这里把我在多个项目里实际碰到过的典型问题整理成表格,每一类我都单独处理过,排查思路可以直接用。
| 报错或异常现象 | 常见原因 | 排查方法 |
|---|---|---|
| Import后矩阵维度不对 | Range选择错误,或者行列标签被误判为数据 | 重新检查Range,重答行列标签问题 |
| 节点标签全变乱码 | 中文编码问题 | 改用数字/英文ID,属性表映射中文 |
| 密度异常偏高或偏低 | 漏填关系、多填了自环 | 在NetDraw里画图检查孤立点和自环 |
| 有向矩阵算出无向指标 | 导入时没区分矩阵对称性 | 确认矩阵是否应对称,必要时用Symmetrize |
| DL文件解析失败 | 头部声明与数据不符 | 检查n=数量、labels数量和实际数据数量 |
| Excel文件路径含中文时打不开 | 部分版本对中文路径支持不佳 | 把Excel文件路径改成纯英文,文件名不要带中文 |
| 导入后矩阵中有大量空值 | 透视表或Excel空格未替换成0 | 查找替换空单元格为0,再导入 |
| 节点数量大时导入超时或卡住 | 矩阵太大 | 改用DL边列表导入 |
5.2 我的独家避坑习惯
有几个教训是我被反复折磨之后总结出来的,现在每次做数据准备都会遵守。
第一个习惯是“矩阵复制时只粘贴数值”。Excel透视表或者计算列生成的值,直接复制粘贴到新表格时,很可能带走公式和原表格格式。我一般用“选择性粘贴 > 值”,保证导入UCINET的是一个纯静态数值表,避免公式上下文意外干扰。
第二个习惯是“文件路径与文件名全程英文”。UCINET对中文路径的兼容性在不同版本上表现不稳定,与其跟报错纠缠,不如从一开始就把数据文件放在C:\sna_data\这样的英文目录下。这个习惯看起来很小,但能省掉很多莫名的“File not found”。
第三个习惯是“导入前先保存UCINET数据集”。从Excel导入成功后,立刻把它保存为UCINET的.##h格式文件。后续所有分析都从.##h文件开始,而不是每次重新导入Excel。原因很简单:如果你一次性导入了多个文件,或者Excel源文件后来被改动,重新导入可能会让数据不一致。保存为UCINET自带格式后,数据就“冻结”了,后续分析基于同一份快照,结果可复现性才有保障。
5.3 数据备份和版本管理的朴素建议
SNA项目的数据链路通常很长:原始问卷、清洗后的关系表、整理好的矩阵、导入后的UCINET数据集、NetDraw图、分析结果表。任何一个环节的数据被不经意的操作覆盖,往回追都会很痛苦。
我现在的做法是给每个环节单独建文件夹,命名带上日期和版本号。比如matrix_v1_20240115、matrix_v2_20240118。矩阵文件在Excel里改过一版就另存为新文件,不在原文件上直接覆盖。这个习惯帮我避免过至少三次“改错了不知道哪里错”的窘境。
另外,关键矩阵文件可以顺手在NetDraw里导出一张可视化图保存下来。这张图不仅能直观展示网络形态,还能在后续分析出错时作为“当时网络长这样”的参照证据。我经常在分析一个网络之前和之后各画一张图,前后对比就能快速发现数据导入是否可靠。
6. 最后再分享一点实操体会
做了几个完整的SNA项目之后,我最深的体会是:数据准备在整个流程里的时间占比,远比新手想象得高。很多人以为社会网络分析的瓶颈在算法选择或软件操作上,其实真正大量消耗精力的是把“关系”这个概念从现实世界干净地转成矩阵。关系谁是发出方、谁是接收方、关系强弱怎么量化、缺失关系怎么处理,每一个环节都会影响最终结论。
我个人习惯的做法是:在动手导入之前,先在纸上或Excel里画出“我要分析的关系的定义”。不需要很复杂,一句话就行,比如“如果A在过去一年内给B发过至少一封内部邮件,则记为1”。把定义写清楚,后面所有数据整理和矩阵填写都有了判断依据,遇到模糊数据时就不会摇摆。
这个系列后面会继续聊分析模块的具体操作。数据这块如果还有别的疑问,按我上面说的排查思路基本都能解决。做SNA不追求一步到位,数据准备扎实了,后面每一步都会顺很多。