我用爬虫挂了一天半,从知乎的哔哩哔哩专栏中得到了200+个精华问题的所有回答,我们能够在这里得到什么呢?
word2vec简介
Word2vec 是 Google 在 2013 年年中开源的一款将词表征为实数值向量的高效工具, 其利用深度学习的思想,可以通过训练,把对文本内容的处理简化为 K 维向量空间中的向量运算,而向量空间上的相似度可以用来表示文本语义上的相似度。Word2vec输出的词向量可以被用来做很多 NLP 相关的工作,比如聚类、找同义词、词性分析等等。如果换个思路, 把词当做特征,那么Word2vec就可以把特征映射到 K 维向量空间,可以为文本数据寻求更加深层次的特征表示 。
这里的算法原理已经和机器学习挂钩了,我们不做深度剖析(算法的简介),只要使用其python包.然后介绍一下这里需要使用的方法.
在使用
word2vec
之前请先装好codecs
模块,这个模块可以免去读取文件时很多编码的麻烦,专门针对自然语言处理的编码转换,只要指定一个编码方式打开文件就ok了.word2vec
的导入以及使用:
|
|
word2vec
里面的方法
|
|
jieba分词
先利用jieba将爬下来的文本进行分词,将自定义的词典和自定义的
stopwords
加进来123456789101112131415161718192021222324#部分自定义词典bilibibinoconicoacfun爱奇艺土豆优酷哔哩哔哩ACGb站B站节奏大师A站炮姐御坂美琴2233娘bishi9bishi小学生徐逸陈睿鬼畜二次元...123456789101112131415161718192021#部分stopwords其实已经大家很多觉得喜欢现在真的看到这种可能感觉一下不能来说非常一点之后之前...
分完词后大约还有20M的文本
统计词频
我们先对文本中出现最多的进行一次统计,看看回答中出现的的最多的是哪些?我们这里总共有
5943182
个词.12345678910111213141516171819202122232425262728293031下标 名称 出现次数97414 视频 2337154703 弹幕 231504519 B站 2288011108 b站 18979107100 问题 1108053473 广告 954122541 二次元 851681406 用户 851133925 动画 849020256 中国 811490403 网站 771476830 游戏 717033915 动漫 674825484 会员 638581685 电影 591283461 直播 585519501 东西 583298289 评论 562331548 出来 520526480 作品 5018111438 鬼畜 488366494 日本 467332541 别人 434784898 知乎 433441814 回答 415519316 世界 414410933 bilibili 408988315 粉丝 390565153 文化 386652613 希望 3822可以看到视频,弹幕,B站出现的次数稳居前三,同时我们自定义词典中二次元,鬼畜这些词也都在.这些数据还是比较符合我们的预期的,同时也证明了分出来的词没问题.
12345678910111213141516171819202122232425262728293031323334353637#coding: utf-8import reimport timeimport numpy as npimport pandasimport jiebaimport osfrom wordcloud import WordCloudimport matplotlib.pyplot as pltfrom pylab import *import codecsmpl.rcParams['font.sans-serif'] = ['SimHei']mpl.rcParams['axes.unicode_minus'] = False#遍历文件中的数据with codecs.open(u"data_analysis/cut_text.txt",'r','utf-8') as f:context=f.read()segment = context.split()#去停用词words_df=pandas.DataFrame({'segment':segment})words_df.head()stopwords = []with codecs.open('data_analysis/stopwords.txt','r','utf-8') as f:context = f.read()stopwords = context.split()words_df=words_df[~words_df.segment.isin(stopwords)]#统计词频words_stat=words_df.groupby(by=['segment'])['segment'].agg({"number":np.size})words_stat=words_stat.reset_index().sort_values(by="number",ascending=False)print 'index','segment','number'for index,Series in words_stat.head(30).iterrows():print index,Series['segment'].decode('utf-8'),Series['number']words_stat[:30].plot(x='segment', y='number', kind='bar')plt.show()
利用word2vec进行数据挖掘
我们将对b站站长
bishi
在window这个参数上,分别设置上下文跨度为5,10和15。找到与bishi
最接近的20个关键词.12345678910111213141516model1 = word2vec.Word2Vec(sentences, size=200,window=5,min_count=10,workers=3)model2 = word2vec.Word2Vec(sentences, size=200,window=10,min_count=10)model3 = word2vec.Word2Vec(sentences, size=200,window=15,min_count=10)y_t_1 = model1.most_similar(u'bishi',topn=20)y_t_2 = model2.most_similar(u'bishi',topn=20)y_t_3 = model3.most_similar(u'bishi',topn=20)#输出结果for item in y_t_1:print item[0],item[1]printfor item in y_t_2:print item[0],item[1]printfor item in y_t_3:print item[0],item[1]print下图是当跨度分别为5,10,15情况下的结果.我们可以看到结果是比较符合我们的预期的,特首(另一个外号),徐逸(bishi真名),睿国(bilibili董事长),逸国,陈睿,9bishi这些词都出现了,冠名说的是b站冠名上海篮球队,体现了word2vec在聚类、找近义词方面强大的功能.在这里没有看出不同跨度下哪组结果更好,实际应用中可能要根据需要进行调节.
我们对
b站
与bishi
,bilibili
,acfun
的余弦相似度进行分析.对这个结果我是不满意的,因为bilibili与b站应该是同一个词,可是相似度却只有40%.123456print model1.similarity(u'b站',u'bishi')#0.437511023039print model1.similarity(u'b站',u'bilibili')#0.405590707607print model1.similarity(u'b站',u'acfun')#0.394401775964然后我试了一下
bilibili
与哔哩哔哩
,B站
,弹幕
的余弦相似度,发现只有第一个令我满意.可能是语料不够充分的原因.123456print model1.similarity(u'bilibili',u'哔哩哔哩')#0.90745918569print model1.similarity(u'bilibili',u'B站')#0.381251411934print model1.similarity(u'bilibili',u'弹幕')#0.15385446278接下来做个比较有意思的实验:
弹幕
+刷屏
-字幕
=?,结果如下,还是比较科学的,都是经常出现在弹幕中的词.12345678910和谐 0.669674515724撕逼 0.629316687584热闹 0.627753138542游客 0.595176875591莫名其妙 0.585232615471弹幕礼仪 0.583511531353喷子 0.583252549171习惯 0.570423543453屏蔽 0.568080067635动不动 0.565914690495接下来做实验,找出集合中不同类的词:输出bishi,没问题,嗯..(要是有问题我就要怀疑数据集了)
123list = [u'b站', u'bishi', u'哔哩哔哩', u'B站',u'bilibili']print model1.doesnt_match(list)#bishiword2vec的基本用法就介绍到这里了,大家也可以弄点数据来玩玩,算法细节有精力的也可以深究.