过滤豆瓣租房小组中介贴之 python 实现 TF-IDF 算法(二)

前段时间写过一篇 过滤豆瓣租房小组中介贴之 python 实现余弦相似度(一), 这里面使用 jieba 将文档分词,然后计算对分词的结果向量化计算相似度。比如 我的房子在方庄地铁附近的芳城园一区 会被分词为 方庄 芳城园 一区 地铁 房子 附近,我们发现少了 我 的 在 这些词,在自然语言处理的过程中,称这些词为停用词,简单的说就是这些词对于分词结果没有多少帮助,所以需要直接过滤掉。因为我们直接调用 jieba.analyse 方法,所以停用词被直接过滤了,如果只是调用 jieba.cut,会将返回包含停用词的结果。

再回到刚才的例子, 方庄 芳城园 一区 地铁 房子 附近 这个结果中到底哪个词需要重点关注,就是所谓的关键词。这个时候我们就引出了今天的主角,TF-IDF 算法, 具体原理可以参见这篇通俗易懂的文章,http://www.ruanyifeng.com/blog/2013/03/tf-idf.html 。至于为什么一步步的得出这种算法,也可以参考数学之美第 11 章。

那么如何用 python 实现这种算法呢,看过原理的发现其实这个算法不难,我们发现 jieba 已经自带这个算法了, 基于 TF-IDF 算法的关键词抽取,代码示例: https://github.com/fxsjy/jieba/blob/master/test/extract_tags.py, 试一下

1
2
3
content = u'我的房子在方庄地铁附近的芳城园一区'
for i in jieba.analyse.extract_tags(content, topK=20, withWeight=True):
print i

结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
(u'\u65b9\u5e84', 2.0485399565833333)
(u'\u82b3\u57ce\u56ed', 1.9924612504833332)
(u'\u4e00\u533a', 1.7444484079166667)
(u'\u5730\u94c1', 1.3667056797650001)
(u'\u623f\u5b50', 1.0526507623933334)
(u'\u9644\u8fd1', 0.8615568819066667)
方庄
芳城园
一区
地铁
房子
附近

对于租房子来说,地点确实最关键,所以 方庄 芳城园 一区三个词权重最高,然后是地铁,所以达到了想要的效果,当然只拿一个例子说明肯定是不够的。另外对于一些特殊的行业,有各自不同的术语,所以自定义语料很重要,比如租房的话,可以爬取所有租房帖子,然后分词,制作自己的语料库,最后得出的结果会更好。

自定义语料简单代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
all_dict = {}
for line in lines:
temp_dict = {}
total += 1
cut_line = jieba.cut(line, cut_all=False)
for word in cut_line:
temp_dict[word] = 1
for key in temp_dict:
num = all_dict.get(key, 0)
all_dict[key] = num + 1
for key in all_dict:
w = key.encode('utf-8')
p = '%.10f' % (math.log10(total/(all_dict[key] + 1)))

代码引用自:https://github.com/fxsjy/jieba/issues/393

最后,TF-IDF 算法 应用非常广泛,比如你用搜索引擎搜索的时候,如何确定你一句话的搜索关键词是什么,它功不可没。