化柏林分享 http://blog.sciencenet.cn/u/huabolin

博文

用VBA实现文献计量分析研究中的数据预处理技术

已有 4517 次阅读 2008-10-24 12:16 |个人分类:文献计量| 算法, 计量分析, 实现技术, 预处理技术

数据预处理技术
 (中国科学技术信息研究所    北京 100038)
(发表于《现代图书情报技术》2007年第3期)
【摘要】 首先对网页数据的特点进行简单分析,针对网页数据的特点设计统计分析的预处理流程,对每一步处理过程都用几种不同的算法进行实验,以期得到最优的解决方案。实验证明,通过减少IO操作、提高处理粒度、适当使用词表等方法可以提高程序运行速度与准确率。
【关键词】  计量分析 实现技术 预处理技术 算法 excel VBA
【分类号】 TP311,G35
Implementation of preprocess technology in bibliometric and analytic research via VBA
Hua Bolin
 (Institute of Scientific and Technical Information of China, Beijing 100038, china)
Abstract  Process of statistic is designed in accordance with character of web data after analyzing them. Each stage is experimented with some different algorithms in order to achieve optimal solution. According to experiment, efficiency and effectiveness can be improved by decreasing IO operation, increasing process granularity and using lexicon.
Keywordsbibliometric, implement technology, preprocess technology, arithmetic, excel, VBA
1 引言
从网页上复制来的题录数据,由于不符合关系范式(连1NF都不符合),直接导入数据库处理起来也很不方便。当前的统计分析,要么直接用统计软件的工具(如SPSS、SAS等)进行统计;要么就直接做成管理信息系统并封装起来,把统计做成与导入、查询相并行的模块,对用户的开放性不够。这类论文(如文献[1][2][3])的论述主要是关注数据库结构、数据访问接口或检索实现等,而对统计实现以及计量分析技术的探讨很不充分,对关注文献计量的非技术人员的启迪也较少。
目前的应用型文献统计分析缺乏把二者结合起来,在相应的统计软件里进行简单的编程实现多式多样的统计,把简单的工具用活用好来解决现实的复杂问题。因此几万条之内的小数据量统计分析的量佳方案是通过VBA在excel里进行,因为它不需要很强的计算机编程能力,只要掌握好for循环、条件判断和常用字符串处理函数就够了。
2 数据来源格式分析
中国期刊全文数据库(清华同方)与中文科技期刊全文数据库(重庆维普)都提供每页显示50条详细记录,如图1所示。数据库商的检索结果是单列的形式,把它复制到excel表格里时,字段名与记录值分布在同一列里,这是因为在显示检索结果的网页里,字段名与记录值在同一个<TD></TD>标签对里。分析时除标题外,其它字段皆从"]"的后一个字符开始取就是记录的值。
网页复制过来的数据预处理主要包括以下几个步骤:通过转换把它变成二维表格的形式;滤掉通知类非正式文献;根据标记符拆分作者、关键词、分类号等字段;析取多项目字段,从机构字段中提取作者单位、城市名、邮编等,从期刊字段中析取期刊名、年、卷期号、起止页码等信息。
1 重庆维普期刊全文数据库检索结果全记录显示示例图
3 行列转换与过滤
从图1复制过来的数据,首先要把它转换成二维表格的形式,就是把单列数据按不同字段转换成多行多列的形式,其关键是识别一条记录的始末,具体处理方法如下所述。
算法一。遍历所有有效行,如果行数被iFieldCount整除,把源表的单元格值赋给目标表相应行的末列;如果不是整除行,就把源表的单元格值赋给目标表相应行的余数列。此算法对于缺乏程序设计思想的人比较容易理解,类似于最直接的手工操作方式,一个值一个值地赋,一条数据结束后回车换行。
1:
For i = 1 To iRowCount
2:
    sTemp = Trim(Worksheets(sSrce).Cells(i, 1))
 
    '如果整除就换行,不整除就放在当前行相应的列里
3:
    If i Mod iFieldCount = 0 Then
4:
        Worksheets(sDest).Cells(k, iFieldCount) = sTemp
5:
        k = k + 1
6:
    Else
7:
        Worksheets(sDest).Cells(k, i Mod iFieldCount) = sTemp
8:
    End If
9:
Next
算法二。每遇到一条记录进行一次操作,一次把该记录的所有字段赋过去。算法比较容易理解,特别是对具有关系数据思想的人。两重for循环合起来(iRowCount除以iFieldCount再乘以iFieldCount)的赋值语句执行次数与算法一相当,速度要快一些,因为不用执行条件判断。程序代码如下:
1:
For i = 1 To iRowCount step iFieldCount
2:
k = k + 1
3:
         For j=1 to iFieldCount
4:
sTemp = Trim(Worksheets(sSrce).Cells(i-j, 1))
5:
       Worksheets(sDest).Cells(k, j) = sTemp
6:
Next
7:
Next
算法三。此算法把条件写到控制目标表行列的变量里去,用i与iFieldCount的商控制行,用它们的余数控制列。程序代码简单,可读性差。
1:
For i = 1 To iRecCount
2:
         sTemp = Trim(Worksheets(sSrce).Cells(i, 1))
3:
Worksheets(sDest).Cells(i / iFieldCount + 1, (i - 1) Mod iFieldCount + 1) = sTemp
4:
Next
经过行列转换后滤掉所有通知类文献,包括征稿简则、会讯通知、年度索引等。此类文献的特征是没有作者或作者单位,作者为“无”,作者单位为“不详”。数据处理完的结果如图2所示。
2 行列转换后的数据格式示例图
4 拆分
格式转换后有两类字段不符合一范式,一类是多值同字段,如作者、机构、关键词、分类号等,一篇文章有多个作者、多个关键词、多个分类号等,但这些词的属性是同质的。另一类是多值异字段,如清华同方的单位或重庆维普的机构都含有三项内容,分别为作者所在单位、地名、邮编等信息,这些字段是异构的,数据类型、长度与取值范围都有所不同,重庆维普的刊名也含有很多信息,包括期刊名称、年、卷、期、起止页码等,需要进行拆分。
在维普中文科技期刊数据库里,多于一个作者的都会加上标记[i],并在其后加上空格;对于机构,在多机构的前面加[i],不同的机构间以空格分开;关键词、分类号用空格自然切分。如果是清华同方的数据库,则每位作者后都会有分号,而关键词之间用双分号相隔。具体处理方法如下:
算法一。如果待分析串里含有标记符,就析取标记符前面的值,同时把指针移到分隔符后面的位置,也就是截取待分析串。如果待分析串里已没有分隔符,则把最后一个值赋过去。
1:
For i = 1 To iRecCount
2:
    sTemp = Worksheets(sSrce).Cells(i, iCol)
3:
    For j = 1 To 20
4:
iFind= InStr(1, sTemp, sFlag)
5:
如果含标记符就析取
6:
If iFind> 0 Then
7:
           Worksheets(sDest).Cells(i, j) = Mid(sTemp, 1, iFind - 1)
8:
           sTemp = Mid(sTemp, iFind+ iFlagLen)
9:
        Else
10:
           Worksheets(sDest).Cells(i, j) = sTemp
11:
           Exit For
12:
        End If
13:
    Next
14:
Next
算法二。从字串首字符到末尾,如果是分隔符,则把前面的值赋过去,并把存放分隔符前面值的变量清空;如果不是分隔符,则把该字符压入队列,相对于队列的“零存整取”操作。同算法一比较,内循环的执行次数显然增多,但中间计算比较简单。
1:
For i = 1 To iRecCount
2:
sTemp = Worksheets(sSrce).Cells(i, iCol)
3:
    For j = 1 To len(sTemp)
4:
    If mid(sTemp, j, 1) =sFlag Then
5:
           Worksheets(sDest).Cells(i, j) =sSplit
6:
                   sSplit=””
7:
     Else
8:
          sSplit=sSplit & mid(sTemp, j, 1)
9:
     End If
10:
   Next
11:
Next
仅仅通过标题来确定一条记录并不可行,标题不能作为主码,因为标题会有重复,为每篇文章加一个ID是个好的选择。本实验中并未作主码处理,需要其它信息时再去图3所示的表里找,因为图3显示内容与图2显示内容是行对应的。拆分完的结果如图3所示。 
图3 关键词拆分结果示例图
5 提取
关键词与作者的拆分属于同构拆分,还有一些列的拆分属于异构拆分。就是一个单元格里存在着多个字段内容。如机构、期刊等信息不符合第一范式(1NF),这些字段可以再分。拆分过的机构包含作者单位、城市、邮编等信息,如“南京大学信息管理系,南京210093”,特点是单位与城市名间以逗号分隔,城市名与邮编紧密相连。作者单位的提取从字符串开头取,取到逗号分隔符;城市名的提取比较困难一些,有的城市名是两个字符,而有的城市名是三个字符,所以不能用从逗号的下一个字符开始取定数个字符,可以采用从逗号的下一个字符开始取,取到数字为止,或者先去掉右6位,再从逗号开始取,因为邮编都是6位,无一例外。可是由于有些编辑部要求不严或数据库加工商粗糙等原因致使机构的信息非常复杂,机构主要有以下几种情况:
类别
特征描述
举例
问题责任者
项目齐全、内容完整、格式规范
单位与城市名间加逗号,城市与邮编中间加空格的形式
武汉大学信息资源研究中心,武汉430072
正常
项目齐全、内容完整、格式不规范
单位与城市名中间缺少逗号,或者地名与邮编中间缺少空格
南京理工大学经济管理学院南京210094
编辑部或数据加工商
项目齐全、内容完整、格式规范、地名表述不规范
城市名后带有标记城市名前加省名,直接用省名代替城市名
河北工业大学图书馆,天津市300130 
江汉石油学院,湖北荆州434102
聊城大学图书馆,山东252059
编辑部或数据加工商
一人多单位情况
单位之间用双斜杠加以区分
河北大学管理学院,保定071002//中科院研究生院,北京100039
正常
项目不齐全、内容完整
缺少邮编
缺少城市和邮编
美国密苏里大学,美国
江苏理工大学图书馆
编辑部
项目不齐全、内容不完整
单位名称不完整,或城市名不完整,或邮编不是6
数据加工商
作者单位所在的城市大都是地级市以上的城市,落座在县级市的也有,如曲阜师范大学就落座在山东的曲阜。因为有了邮编,所以不需要在城市名前加省名。如果含有邮编, 先把邮编取出来,因为邮编肯定是数字,正常情况下应该是六位,而且在末尾。如果含有标记符,根据标记符提取,把逗号左边的内容提取出来作为机构,逗号后面的内容为城市名;如果不含标记符,可以用城市列表来从右边进行匹配,这种办法准确率高,但会影响速度,前提是有权威的中国城市名库。也可以用机构名后缀进行截取,需要人工分析机构名后缀特征,然后构造数组来进行匹配。简单处理算法如下:
 
邮编处理
1:
If Asc(Right(sTemp, 1)) > 47 And Asc(Right(sTemp, 1)) < 58 Then
2:
    sPostcode = Right(sTemp, 6)
3:
    sTemp = Mid(sTemp, 1, Len(sTemp) - 6)
4:
End If
 
串中含标记符,如分号、逗号等
5:
If InStr(1, sTemp, sFlag) > 1 Then
6:
    sAffiliation = Left(sTemp, InStr(1, sTemp, sFlag) - 1)
7:
    sCity = Mid(sTemp, Len(sAffiliation) + 2)
8:
Else
 
    单位与地名之间无标记符,可以利用定义好的数组进行处理,如系、学院、所等
9:
    For m = 1 To Ubound(sIdentify)
10:
      If InStr(1, sTemp, sIdentify(m)) > 0 Then
11:
         sAffiliation = Left(sTemp, InStr(1, sTemp, sIdentify(m)) + Len(sIdentify(m)) - 1)
12:
         sCity = Mid(sTemp, Len(sAffiliation) + 1)
13:
         Exit For
14:
      End If
15:
    Next
16:
End If
邮编处理完以后判断机构与城市间是否存在标记符,如果存在标记符,分别提取就可以;如果不存在标记符,可以用后缀截取法进行分割,因为机构名有规律可寻,大都以学院、系、所、中心、室、公司、馆等结尾,可以用特征枚举的方式构造数组,如程序中的sIdentify。但这种处理方式是没法保证结果的准确性,最好的方式还是获取官方数据,包括机构和城市列表。在具体处理中还可以利用其它信息(如作者和邮编)对不规范的机构数据进行自动修正,例如,利用规范的同一作者同一邮编的机构来修正不规范的机构(排除改名因素)。
期刊可以分为刊名、年、期、卷、起止页码等信息,如“情报学报-2005.24(3).-363-370”。刊名后以短横线接年,年后以句点接卷,卷号用圆括号把期号括起来,卷期后加句点是起止页码,起始页码和终止页码前都有短横线。而像清华同方的数据就不需要这项分隔了。
1:
For i = 1 To iRecCount
2:
    sTemp = Worksheets(sSrce).Cells(i, iCol)
3:
    Worksheets(sDest).Cells(i, 1) = Mid(sTemp, 1, InStr(1, sTemp, "-") - 1)
4:
    Worksheets(sDest).Cells(i, 2) = Mid(sTemp, InStr(1, sTemp, "-") + 1, 4)
5:
Next
6 总结
经过上述处理,就可以进行统计了。文献计量统计分析的流程包括数据获取、数据预处理、统计计算与应用四大模块。数据预处理也是关键一环,数据预处理的精确程度直接决定着统计计算的质量,从而决定着统计分析的结果。数据过滤与筛选,主要是把符合某种条件或不符合某种条件的数据滤掉。过滤是根据条件滤掉记录,拆分是根据字符串内的标记符分成同构的字段,而提取则是根据字符串内的标记符分成不同的字段。
       数据的预处理流程比较简单,技术实现也比较简单,无非就是行列转换、数据过滤、拆分与提取等几个步骤,所有的步骤只用了for循环、条件判断与常用字符串处理函数。实验中,对关键的处理都采取了几种不同的算法,并从执行速度、程序复杂度等方面对算法进行了比较,总结如下:涉及反复操作一定要读到内存,减少IO读写;循环内的处理过程越简单越好,能放在循环外的尽量往外放;数据处理的粒度尽可能地大,在不影响准确度的情况下,数据处理粒度越大,效率就会越高。
       地名与机构等信息的内容提取有相当的难度,准确率也难以保证,但通过复杂情况的归类以及支撑资源的不断更新,然后回溯分析,可以渐渐地提高准确率,尤其是一级单位与二级单位的划分开始涉及自然语言处理的浅层次问题。在实验中用重庆维普的数据时发现作者统计结果可信度也非常低,简单记录和详细记录的作者信息差别非常大,似乎从不同的数据表里取出来一样,这个问题不是算法本身的问题,没有好的算法能解决数据遗漏的问题。在涉及自然语言处理的问题上,资源的支撑显得相当重要,回溯分析也会提高准确度。
 
参考文献
1 陈涛武警学院学术论文统计系统开发及功能实现武警学院学报2005(3):94-96
2 张守胜.基于Web的科技论文统计信息系统的应用研究.安徽理工大学学报(自然科学版) 2004(01)59-63
3 袁通路.基于ASP的学术论文信息检索统计系统.微机发展,2004(02)57-60
 
 


http://blog.sciencenet.cn/blog-91591-43850.html

上一篇:图书情报学核心期刊论文关键词计量分析研究(下)
下一篇:文献计量分析研究的分类与处理流程

0

发表评论 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2021-1-24 09:02

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部