科学玩推特(3):基于主题模型的推文分析

真真是没想到,再次更新【科学玩推特】这个系列居然也是两个多月以后了。回美帝之后一度忙着找工,就没继续推文分析这项大工程。之前试图套 Topic Model (主题模型,下同)到推文上,但因为 Rwordseg 的中文分词太差劲所以就没弄成。好吧我总算是不再拖延了,也大概是学会了如何用搜索引擎吧= = 所有的源代码都可以在这里找到哦~

起源

重新开始想分析推文是因为推特3月26日十岁生日啦。发了 #LoveTwitter 推以后发现好多人都开始晒自己的第一条推。就算推特官方提供了一个小网页让用户能方便的找到自己的第一条推文,可是像我这样的话痨账户加锁的用户就没办法看到咯。无他,只能动用硬盘里的存档(13年10月缓存的版本)自己手动去找。找的时候在根目录下发现了一个叫 tweets.csv 的东西。点开来看(记事本此处死机十五分钟)发现这是一个已经清理过的结构非常好的数据存档,里面记载着我08年上推至下载存档时所有的推文以及相关的信息。当时就觉得啊都已经为我搞好了不分析一下好像有点说不过去哦,然后就开始问 Google 啦。

模型概述

Topic Model 这玩意儿去年上 Text Mining 课的时候老师非常非常粗略的讲过,但因为讲得太快了所以我只记得这个词但根本不知道它是怎么一回事。对数学推论感兴趣的可以来看这里的第二部分。(等我看懂了我会来更新这一部分)根据英文维基百科的总结,主题模型是一种能自动寻找大文档内隐藏的抽象主题的统计模型。而我这次用的 Latent Dirichlet Allocation (LDA) 是主题模型这个大模块下面的一种常用的实现方式(啊我果然不会说中文了)。简单来说就是:假设这个文档里出现了5次“牛肉”,而我感兴趣的主题是“美国”。LDA会试图算出美国这个主题里频繁出现牛肉二字的概率。在算的过程中LDA会假设每篇文章都是出自一些设定好的前提,而后它会不断重复学习过程并最后归纳总结出 K 个主题,以及相对应最有可能会出现的字眼。(我知道我解释的不是很好,但 Quora 上的这篇对 LDA 进行了非常细致的讨论,强烈建议一读)简而言之:你喂LDA一堆大文本数据,它会自己在墙角里很乐意的学习然后归纳出最可能的几个主题给你哒!不知为什么想到了 k-mean clustering,改天换个方法重新分析一下这数据好了。。。

原数据

由于推特官方提供的数据已经很精美了(……),所以直接扔到 R 里读就是了。看看数据长啥样好了。

# Read in the data!
tweets <- read.csv("tweets.csv", sep = ",", header = T, fill = T, stringsAsFactors=FALSE, 
                   encoding="UTF-8")

# Overview
summary(tweets)

tweet_summary_r

其实蛮无聊的。。。。好吧硬要说的话 source 大概会有趣吧(可以看我最常用哪个平台发推!)但这篇文关注的重心还是那74864条推。本来想直接开始分析的,但后来分词遇到了一点问题。。。详见下节。。。

中文分词:JiebaR

如果都是英文的话,那好说。R里我已经安了tm啥的可以直接开始来 document to term matrix 啥的。但坏就坏在是中文,tm没法分析这玩意儿。万能的谷歌大神让我看到了谈和大神的这篇文章,才知道原来有这么一个新的中文分词工具叫 JiebaR。以下摘自官方文档:

JiebaR

“结巴”中文分词的R语言版本,支持最大概率法(Maximum Probability),隐式马尔科夫模型(Hidden Markov Model),索引模型(QuerySegment),混合模型(MixSegment),共四种分词模式,同时有词性标注,关键词提取,文本Simhash相似度比较等功能。项目使用了RcppCppJieba进行开发。

后来试了一下,发现很好用,但是R里直接调用后出来的分词文件没办法保存在本地,只会在 console 里打出。就只能用类似

seg <= "./tweets_2.csv"

这样的办法曲线救国了。

把纯推文导出成 csv 倒是不难,难就难在分词出来的文件特别小。我一开始不知道,还在小的文件基础上跑了一遍主题模型,出来的结果好像也还是那么回事儿。打开小的分词文件,发现它特别短。再跟我的推文一对比,发现只读了大概头300条推的样子。怎么回事呢?打开原 tweets.csv 一看——果然!又是特殊字符 emoji!!(抱头痛哭)我如何过滤 emoji、数字和标点符号的艰辛过程此处略去不表(Python斜眼:你不过也就抄了个正则表达式嘛),反正最后在 Python 里做了文件预处理,读取了所有的推文并去除了特殊字符和数字,每一行都是中文或英文字符串。这大概也方便 JiebaR 分词吧?虽说这样读取的推文都是支离破碎没有美感了,但我也只当作是我先分了一次词。。。希望这不会对后面的结果有影响。。。

代码

恩上面说啦,都在基特哈布上。R代码几乎是照抄谈和大神的,文本预处理的代码虽然是我写的但关键的正则表达式也是出自 stackoverflow(我是故意把超链接都做得妥妥贴贴的这样你们就没法指责我抄袭或者来问我为什么代码不工作了)具体的我就不在这里细说了,就说几个折磨死我的难点。中文分词上面说了,接下来要说的是如何正确的显示中文字体。不得不说 Python 天然支持 utf8 中文真好呀!在编译器里和写出来的中文都能被正确的识别。R里就麻烦了,浏览器这个小婊砸也没合作。如果你想复制与我一样的结果,请务必做到以下这几点:

  1. 运行代码前先把R的 locale 设置成中文
  2. 运行完代码后到画图的部分一定要运行 change the encoding of JSON file 那一行代码,不然就要:
    1. 手动打开JSON复制->在 notepad++ 里创建一个新的空白文档,encoding 存成UTF8->粘贴JSON->保存 notepad++ 里的文档,扩展名务必存为.json->在 index.html 里替换JSON名为新的文档

唉,中文支持真是我心中的痛。哦对除此以外记得找个靠谱的服务器空间把vis文件夹上传上去,不然没法看结果。。。

结果

对不起我很不擅长写技术文,总感觉前面罗哩叭嗦说了一大堆其实都是废话直接扔结果出来就好了啦(。恩我的推文结果在这里~我相信你能打开的(暂时还没有撤下来的打算),那我就先解释一下网页里每个部分是啥意思:

左上角可以选择看哪个主题,选中的主题会变红,右边的柱状图也会相应的变色。左下角的图看起来有点像PCA里的 biplot,画出了头两个 principal component 呢。貌似主题越靠前包含的 tokens 越多(topic 1 includes  24.9% of tokens, topic 2 22.1%, etc.)。右上角的 relevance metric 可调节的范围是0~1,如谈和大神总结的那样:

某个词语主题的相关性,由λ参数来调节。如果λ接近1,那么在该主题下更频繁出现的词,跟主题更相关;如果λ越接近0,那么该主题下更特殊、更独有(exclusive)的词,跟主题更相关。所以读者可以通过调节λ的大小来改变词语跟主题的相关性,至于λ取多少,读者可以自己多尝试。

右下角那个大大的柱状图就是大家非常熟悉的词频统计啦,其实没啥特别的。LDAvis 包的作者还很贴心的在下面注明了突出度和相关度是怎么计算的,好棒w

我观察到的几个点(基于08-13年的七万余条推文):

  1. 我果然是RT狂魔啊!!!RT了七千多次,妥妥的超了第二名两倍!推特出了官方RT的功能真的是非常贴心的w
  2. 基本上玩的好的都是北美党了,天朝玩得好的推友好像都是饭否或者高中同学啥的。。。
  3. 就算我已经在喂给LDA的分词文档里去除了停止词,最后出来的结果还是有很多没有什么实际含义的词汇(真的,感觉,居然等),大大干扰了我归纳总结每个主题的含义
  4. 五个大主题可能的含义:
    1. 互黑(当年我、插座、A姐、粘粘等经常互相黑对方是大大)+少量北美圈日常生活推
    2. 大量转推+北美圈单身痛苦求脱团探讨(MADAO和老公鸡抱怨找不到妹子,张师傅为爱所困等)
    3. 女生的小心思日常推(一度和同校孙小姐超好呢,没事就约吃饭。还有【女生】【喜欢】【姐姐】等字眼。当然A姐第一名我是看不太懂了)——第三个话题和第五个太黏着了,估计相关度过强,很可能是重复的话题
    4. 伪·科技推(因为看到了叉烧柠檬小凉等人,印象里他们都蛮 geek 的。。。还有男生字眼!)+少量生活推
    5. 我可以确认这是2011年秋专属的一块儿主题,因为当时我和驴风哥哥感情很好,刚到美国上学各种不习惯,还去了狗村面基推友等,都发生在11年快结尾时短短的几个月里

所以你看我非要乱总结的话也还是能总结出一套一套的嘛。估计加上近几年的数据又会跑出不一样的结果。但因为我太懒,跑一次又很累,所以就先分析到13年为止啦。抛砖引玉,接下来我想继续深入学习LDA是如何工作的,争取不用抄别人的代码自己上(喂

不是很会结尾,但终于知道怎么在R里跑词云了!原来只要知道词+对应频率就好了啊,亏我还之前一直以为非要用tm造 corpus 呢(我是不是很笨)。图中每个词出现的频率都至少有200次呢。好些提到的推友都已经不上推或因为这样那样的原因擦肩而过了,但我还是想说:感谢你们曾经听我碎碎念过。

040216wc_200

这篇文我保不准会再更新,但你要不要看就是你的自由啦~果然推特要这样才好玩(误

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s