提取豆瓣电影短评关键词

昨天看到了一篇文章,利用这个 MonkeyLearn 提供的 API,创建情感分析模型。其数据源来自某网站的评论数据,恰好最近打算投豆瓣的实习,想到豆瓣电影的打分和短评也可以做类似的事情。不过目前还没有做到分类器,只是利用 TF-IDF 做了关键词提取。

昨天晚上找了一下豆瓣的 API,发现限制颇多,于是决定直接爬。今天下午完成了一个简单的模拟登录和抓取程序(没有用到什么代理和多线程),晚上搞定了用了一会尝试了用 sklearn 中的 TF-IDF 提取关键词,之后发现 jieba 分词直接带有关键词提取器,还有 TF-IDF 和 textrank 两种模式!(关于 textrank 也是在另一篇文章里知道的),不过最后发现最终的结果差别不大,甚至 TF-IDF 的一些词更加具有显著性。

爬取豆瓣电影短评

原本还想整理一下写一下这部分呢,结果今天下午分析页面的时候发现很简单。。。于是简单提一下几个点吧:

  • 豆瓣在未登录状态下,只能获取前200条短评,之后会返回403。这让我一度以为我被反爬了……
  • requests 真的很很很方便,Session 大法不用管什么 cookie,只用改 headers 就 ok 了。
  • 电影短评的页面结构很清晰,直接使用 BeautifulSoup 解析即可
  • 短评有没有评分的,于是单独按评分为 0 处理,作为异常数据
  • 下一页的标签也很容易找到
  • 豆瓣的也是直接 post 到 https://accounts.douban.com/login,只不过某些情况下,会被要求输入验证码
  • 验证码,用了很直接的。。。手工输入方法,不能更弱了
  • 数据保存,直接插入 mongodb 了,毕竟本科的时候看了两页书(´_`。)

第一遍写出来的代码,扔到 pylint 里检测,竟然不到5分。。。当然是自己写的太随意。看问题,多数是赋值等号左右空格,docstring 的问题。不过不打算完善了,有精力的话回头弄到 scrapy 里去,那样至少可以称为“爬虫”了吧。

关键词提取

爬取数据的时候,保存了三个字段:评论编号,打分,评论内容。爬完想起来,竟然忘了存评论时间。。。因为最近的《北京遇上西雅图2》只有 2w 左右的短评,就没有爬太多。

关于TF-IDF,第一次真正的使用,应该是在 edX 的 Spark 课程中,也是对文本做关键词提取。在 ruanyifeng 的一篇教程里又温习了一遍。关键在于 TF 和 IDF,引用文章里的三个公式:

标准化的 TF

标准化的 TF

IDF

 

 

 

TF-IDF

 

 

可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。

TF-IDF算法的优点是简单快速,结果比较符合实际情况。缺点是,单纯以”词频”衡量一个词的重要性,不够全面,有时重要的词可能出现次数并不多。而且,这种算法无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的。(一种解决方法是,对全文的第一段和每一段的第一句话,给予较大的权重。)

在 sklearn 中提供了文本特征提取工具,可以实现 TF-IDF 的计算。我把相同评价的短评连接在一起,作为一篇“文章”(不知道这样做是否合适),然后对所有评分计算 TF-IDF。这样可以获得不同评分的短评之间关键词的差别。关于分词,是用的 jieba 分词,不过直接对分词结果观察,发现并不是很理想,也许会再尝试其他的分词程序。

在我计算快要计算完,查看 jieba 分词的文档时,发现其提供了extract_tags 和 textrank 函数实现对文本的关键词提取。仔细看了一下,发现 extract_tags 是使用内置的 IDF 权重进行的。

结果呢?

首先是《北京遇上西雅图2》,豆瓣的评分只有6.3

sklearn 的评分为1的Top20结果:

jieba 的评分为1的TF-IDF 的Top20结果:

jieba 的评分为1的 textrank 的Top20结果:

总体来说,对于同样评分的关键词提取,差别不大,像 “烂片”,“尴尬” 都能被提取出来,也有一些没有太多含义的词,比如“电影”,意外的是发现都有 “好看” 这个词。。。应该是分词的问题。

接下来比较一下不同评分的关键词结果:

sklearn 的评分为5的Top20结果:

jieba 的评分为5的TF-IDF 的Top20结果:

jieba 的评分为5的 textrank 的Top20结果:

同样也是各有千秋,领我意外的是,jieba 的提取结果竟然发现了 84 这个词(电影中书的关键词之一),jieba 的两个结果都提到了“爷爷奶奶”,这也确实是电影里很重要第一部分。这次 sklearn 的提取结果并没有太多特色,毕竟像 “84”、“爷爷奶奶” 这些词,在相关的评论中可能出现次数不少,因为导致 IDF 不高而 TF 也不高。

还能做什么?

最初我可是想做一个分类器的啊,不过已经完成了文本特征提取的部分,分类器无外乎决策树、随机森林、SVM 等等(我熟悉的就这几个了,GBDT 不懂)。sklearn 的话应该也不难,加到 TODOLIST吧。

本着程序要需要重复造轮子的精神,或许我需要自己实现一遍 TF-IDF,来加深理解,以及计算过程。以及 textrank 并不是十分明白计算过程。

参考链接:

  1. http://scikit-learn.org/stable/modules/feature_extraction.html#common-vectorizer-usage
  2. http://www.ruanyifeng.com/blog/2013/03/tf-idf.html
  3. http://www.hankcs.com/nlp/textrank-algorithm-to-extract-the-keywords-java-implementation.html

提取豆瓣电影短评关键词》上有1条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注