DBLP( Digital Bibliography and Library Project )是一个计算机类英文文献的集成数据库系统。DBLP所收录的论文质量较高, 文献更新速度很快, 很好地反应了国际学术研究的前沿方向。DBLP数据可以为人们提供大量有用的知识, 通过对DBLP数据的分析, 可以找到权威作者。对权威作家的分析, 可以挖掘出计算机研究的新领域。
作者合著关系属于社会网络范畴, 目的是研究合著论文的作者间的关系。通过对这种关系的研究,可以使人们了解科学协作的结构, 即协作以何种方式组织的; 了解研究者在科学研究中所处的位置; 还可以应用到多种会议上, 使人们了解在某一特定会议上发表论文的作者间的关系。
通过对DBLP数据的处理,找到DBLP上作者间协作的关系,输出合作次数较多的作者合著关联规则。具体按以下三个方面展开:
1.DBLP数据预处理
从DBLP网站:http://dblp.uni-trier.de/xml/得到DBLP XML记录。研究分析XML文件的内容和特点,选择适合的解析方法得到作者数据集。
同时,可根据实验要求与数据特点对数据集进行适当的筛选,以达到进一步压缩数据的目的。
2.实现格式转化
将解析得到的数据集(一般为csv格式文件)通过weka或者其他编辑器加入头部定义,转化为weka专用的文件格式arff。
3.挖掘关联规则
将arff文件导入到weka中,选用关联规则并设定好各参数的值挖掘频繁项并按作者合著关系的次数由大到小输出关联规则。
1.关联规则
关联规则概念首先由R. AgrawaI 等于1993 年提出。所谓关联规则,是指客体之间的相互关系。关联规则形如:A1∩A2∩Ai->B1∩B2∩⋯∩Bj,(4%,70%)意味着目标数据中客体B1, B2, ⋯, Bj 倾向于同客体A1,A2,···,Ai
一起出现,其中4%为关联规则的支持度,70%为关联规则的信任度。
2.Apriori算法
Apriori 算法采用的是迭代方法,需要多遍扫描事务数据库, 为了提高频繁项目集的产生效率,可利用一个重要的性质来减少项目搜索空间。Apriori 性质就是规定一个频繁项目集的所有非空子集必需也是频繁项目集。根据这一性质,进行第 遍扫描之前,可先产生候选集C , C 可以分两步来产生,设前一步(第 k-1)步已生成(k-1)-频繁集Lk-1,则首先可以通过对Lk -1中的成员进行联接来产生候选,Lk-1 中的两个成员必需满足在两个成员项目中有k-2个项目是相同的这个条件方可联接,即:C = Lk-1ΘLk-1 = { AΘB|A, BcLk-1, |A∩B|=k-2 }
接着,再从C 中删除所有包含不是频繁的( k-1)-子集的成员项目集即可。
3.矩阵交集算法
关联规则挖掘的难点主要在挖掘频繁项目集,由于其面对的是海量数据,其理论上的搜索空间是2i,该算法存在“项集生成瓶颈”问题,目前,Apriori关联规则优化算法也是针对这个问题提出的.
由于关联规则算法存在上述问题,因此,我们在实验过程中参考一篇学术论文采用了新的关联规则挖掘算法—矩阵交集算法.算法步骤如下:
(1) 产生数据库D':遍历数据库D,筛选出所有大于min_sup的项目,并产生数据库D'(在本实验中表现为在原数据集中将出现次数小于min_up的作者删掉),同时列出在数据库D'中候选项的集合记做ak (2<k<m),所有的频繁1-项集都包含在ak中.
(2) 转换数据形式生成矩阵:由ak(D'中候选项的集合)产生k个列,按TID(人物标识)包含的项目由多到少的规律排列,由行计数器sr 统计每个交易行中项目集合数,由列计数器cr 为列中相同的项目计数,为每个ak 集合中的项
目赋值(0,1),有则赋1,无为0.扫描数据库为每个ak 计数,生成新数据库包含T(t1 ~tn ),并按照交易项数ak 的计数从大到小排列.
(3) 产生交集:由sr 和cr 产生最大项目集和次项目集n个,求其交集t1∩t3,t1∩t4,⋯,t1∩tn 找出最大频繁项集.其可信度由sr 最大项集中的项同时满足cr 较大值来验证.算法应用过程举例如下:
① 取min_up=50%=2,
数据库D
|
TID |
Items |
|
100 |
a,c,d,f,n |
|
200 |
b,c,d,e,f,i,k |
|
300 |
d,e,f,g,m |
|
400 |
b,f,p,s |
|
500 |
c,d,f,s |
|
600 |
a,b,c,e,h,o |
数据库D’
|
TID |
Items |
|
100 |
a,c,d,f |
|
200 |
b,c,d,e,f |
|
300 |
d,e,f,g,m |
|
400 |
b,f,p,s |
|
500 |
c,d,f,s |
|
600 |
a,b,c,e,h,o |
② 生成矩阵
|
TID |
a |
b |
c |
d |
e |
f |
sr |
|
100 |
1 |
|
1 |
1 |
|
1 |
|
|
200 |
|
1 |
1 |
1 |
1 |
1 |
|
|
300 |
|
|
|
1 |
1 |
1 |
|
|
400 |
|
1 |
|
|
|
1 |
|
|
500 |
|
|
1 |
1 |
|
1 |
|
|
600 |
1 |
1 |
1 |
|
1 |
|
|
|
cr |
|
|
|
|
|
|
|
③计数筛选
|
TID |
a |
b |
c |
d |
e |
f |
Sr |
|
200 |
1 |
|
1 |
1 |
|
1 |
5 |
|
100 |
|
1 |
1 |
1 |
1 |
1 |
4 |
|
600 |
|
|
|
1 |
1 |
1 |
4 |
|
300 |
|
1 |
|
|
|
1 |
3 |
|
500 |
|
|
1 |
1 |
|
1 |
3 |
|
400 |
1 |
1 |
1 |
|
1 |
|
2 |
|
cr |
2 |
3 |
4 |
4 |
3 |
5 |
|
产生项集的最大集合和次集合T1、T2 、T3,求其互相的交集:
T1∩T2={b,c,d,e,f}∩{a,c,d,f} ={c,d,f},
T1∩T3={b,c,d,e,f}∩{a,b,c,e} ={b,c,e},
根据cr值和关联规则的性质删除{b,c,e}从而产生最大频繁项集{f,c,d}.
实现:
4.1 过程详解
1. 从DBLP官网(http://dblp.uni-trier.de/xml/)下载得到原始数据文件dblp.xml。使用vi打开:
2. 分析xml文件的标签,得知作者名在<author>和</author>之间,我们现在只提取article的作者名,主要C/C++代码如下:
1 int dblp2csv() 2 { 3 ofstream outfile("dblp.csv") ; 4 ifstream infile("dblp.xml") ; 5 6 string line ; 7 8 for(; getline(infile,line) ;) 9 { 10 if(line.substr(0,8) == "<article") 11 { 12 for(int count = 0 ; getline(infile,line);) 13 { 14 if(line.substr(0,10) == "</article>") 15 { 16 outfile << '\n' ; 17 break ; 18 } 19 if(line.substr(0,8) == "<author>") 20 { 21 if(count != 0) 22 outfile << ',' ; 23 for(string::size_type pos = 8 ; pos != line.size() ; ++pos ) 24 { 25 if(line[pos] == '<') 26 { 27 if(line.substr(pos,9) == "</author>") 28 { 29 count += 1 ; 30 break ; 31 } 32 } 33 else 34 outfile << line[pos] ; 35 } 36 } 37 } 38 } 39 } 40 41 outfile.close(); 42 infile.close(); 43 return 0 ; 44 }
3. 提取作者名的文件dblp.csv:
4. 试图将dblp.csv文件导入到weka时,发现格式不对。
分析:少了第一行属性值,以及每一行属性对应的值如果缺失则需要用缺失值(在arff格式中用‘?’表示)表示,所以在csv文件中每一行没有达到最大属性值个数的需要用逗号隔开,以表示这是缺失值,并非不存在属性值。
因此将dblp.csv文件稍作修改,主要C/C++代码如下:
1 int dblp_mod() 2 { 3 ofstream outfile("dblp_new.csv") ; 4 ifstream infile("dblp.csv") ; 5 6 int max_au = 0 ; 7 string line ; 8 9 for(;getline(infile , line);) 10 { 11 if(line == "") 12 continue ; 13 int count = 1 ; 14 for(string::size_type i = 0 ; i != line.size() ; ++i) 15 { 16 if(line[i] == ',') 17 count += 1 ; 18 } 19 if(max_au < count) 20 max_au = count ; 21 } 22 int i = 0 ; 23 for( ; i != max_au ; ++i) 24 { 25 outfile << "auth" << i << ',' ; 26 } 27 outfile << "auth" << i << '\n' ; 28 29 infile.clear(); 30 infile.seekg(0); 31 for( ; getline(infile , line) ; ) 32 { 33 if(line == "") 34 continue ; 35 for(string::size_type n = 0 ; n != (line.size()-1) ; ++n) 36 { 37 outfile << line[n] ; 38 } 39 int count = 0 ; 40 for(string::size_type j = 0 ; j != line.size() ; ++j) 41 { 42 if(line[j] == ',') 43 count += 1 ; 44 } 45 for(int duf = 0 ; duf != (max_au - count - 1) ; ++duf) 46 { 47 outfile << ',' ; 48 } 49 outfile << '\n' ; 50 } 51 infile.close(); 52 outfile.close(); 53 return 0 ; 54 }