1. 说明
前篇《实战微博互动预测之一_问题分析》中,已经对微博的整体反馈情况,以及单个用户的反馈做了初步的分析。本篇将从微博的信息内容中提取更多特征。
文本分析是数据分析中的常用技术,使用范围很广,比如:信息搜索,内容推荐,文章分类,内容提取等等。其核心是分析连续的文本,抽取关键数据,再进行下一步分析。
2. 文本分析
1) TF-IDF算法
TF-IDF是一种统计方法,TF指词频,IDF是逆向文件频率。TF好理解,就是词在文章中出现的频率,出现频率高的词更可能是文章的关键词。但有些词如:“是”,“的”,“了”(即停用词)在任何文章出现频率都高,于是使用IDF。IDF通过总文件数目除以包含该词语之文件的数目,再将商取对数得到,它弱化了常用词的权重。TF-IDF倾向于过滤掉常见的词语,保留重要的词语。
2) 中文分词
中文分析一般以词为单位,与英文不同的是中文的词与词之间没有空格划分,所以处理时,首先要分词。简单的方法是把所有词放在一个词典中,通过正向匹配,逆向匹配,双向匹配等方式分词,这种方式经常会产生歧义;也可以利用统计的方法如HMM,SVM通过训练学习分词。实际操作中最常使用的方法是直接调库。常用库有jieba分词,SnowNLP等,后面详述。
3) 文本分析功能
常见的文本分析一般有:分词,计算TF、IDF,词性标注,提取关键词,提取摘要,情感分析,文本相似度等等。
4) 文本分析工具
有很多在线工具提供API实际自然语言的处理,效果比离线的好一些,但在处理大量数据时,速度太慢了。下面来看看常用的离线工具。
i. NLTK
Natural Language Toolkit,自然语言处理工具包,它是NLP领域中,最常使用的一个Python库。功能非常全,但对中文处理相对弱一些。
ii. SnowNLP
SnowNLP是一个中文工具,它实现了大部分文本分析的常用功能,并且可以自己训练数据。但是试了一下它自带的分析器,如:情感分析,关键词提取功能,代入微博文本,效果都不太好,后面只使用了它的分词功能。使用方法如下:
from snownlp import SnowNLP
s = SnowNLP("跟框架学代码设计,跟应用学功能设计")
print(s.words) # 分词
print(s.sentiments) # 消极or积极,结果在0-1之间
print(s.tags) # 词性标注
print(s.keywords(3)) # 关键词
print(s.summary(3)) # 摘要
print(s.tf) # tf
print(s.idf) # idf
我的机器速度一般,计算1000条微博20s,处理所有数据约5小时左右。
iii. 结巴分词
结巴分词的效果也不错,支持自定义词典,词性标注等等,具体使用方法如下:
#encoding=utf-8
import jieba
print(jieba.cut("跟框架学代码设计,跟应用学功能设计", cut_all=True))
iv. 其它
这里只使用了分词功能,所以用哪个工具都差不多。除上述工具,还有PyLTP,THULAC,Pynlpir,CoreNLP等中文文本处理工具,详见:
http://blog.csdn.net/sinat_26917383/article/details/77067515
3. 文本的简单分析
微博的训练数据有100多万条,分析一遍花很多时间,所以第一步,先对文本做简单的字符串处理,包括:判断是否含有@,是否含有链接,提取标题,提取表情。这里主要用到的技术是:对DataFrame数据列的函数处理apply,以及正则表达式。
1) 正则表达式
具体使用re库,假设标题是用”##”,”【 】”,”《》”括起来的字符串。提取标题的方法如下:
import re
patt=re.compile(r'[#【《](.*?)[#】》]',re.S)
topics=patt.findall(content) # 提取标题
plain=re.sub(patt,'', content) # 从正文中去掉标题
2) Apply处理列数据
假设content列存储的是文本信息,提取标题到topic列中:
def getTopic(content):
…
data['topic']=data.content.apply(getTopic)
注意尽量不要用for循环处理DataFrame,那样做速度非常慢。
4. 文本提供的信息量
1) 统计分析
没人关注的用户发的文约占9%(发的所有微博都得不到反馈),这部分数据单独处理。
其它数据统计如下:带标题占39%,带链接占55%,带表情占12%,带@占20%。
2) 计算相关系数
dataframe.corr()
计算得出的结论和人的经验类似:带表情的更容易得到反馈,自己写的更容易得到反馈(不带标题,不带链接),带链接的容易被转发,带@得到的反馈较少,正文长度与转发相关……
3) 分析
从上面的分析看来,用户个人的相关数据比信息内容重要得多,但回想前篇我们对单一用户的数据分析,他发的700多条微信中,167条转发0次,而其中有一篇被转发了8000多次。对于用户个体来说,还是需要根据信息内容来进一步判断。这个原理就如同决策树,在第一层“用户信息”的信息增益更大,但在第一层之后,其它信息就变得重要了。
5. 文本的复杂分析
分词和文章分类,都是庞大的体系,有很多方法构造和优化。但在微博预测问题中,只是想借此得到更多的数据特征。所以这里不去构造分类器,而是寻找现成最简单有效的方法,这里使用了SnowNLP和《同义词词林》。
首先使用SnowNLP对标题和正文分词和词性标注,然后筛选出句子中的名词,代入同义词词林,找到相应的分类。
同义词词林是一本词典,最初目标是提供较多的同义词语,对创作和翻译工作有所帮助。它把中文词组分为大类,中类,小类。这里对信息中的名词归类,最终将信息归类。分词后共抽取名词性关键字2605965个,去重后18515个,用词林分成95个类别。
使用时还需要解决一词多义,以及句中含有不同类别名词的问题,具体的方法是优先选择:社会,经济,文教等抽象分类。
6. 一些想法
一开始做的时候,数据很多,可提取的特征也多,有点无从下手。解决的方法是:先切出一部分,使用现有的工具测试。
当数据多的时候,每个操作,尤其是面向所有数据的操作,都会花很多时间,最好是先处理少量记录,并且记下各个步骤的运行时间。
我觉得无论是写算法还是文本分析,能确定的都用确定的,不能确定的再用统计方法处理。比如某个用户数据中均值确定,方差很少,那就直接用均值。