TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。
同样,理论我这里不再赘述,因为和阮一峰大神早在2013年就将TF-IDF用一种非常通俗的方式讲解出来
材料
1.语料库(已分好词)
2.停用词表(哈工大停用词表)
3.python3.5
语料库的准备
这里使用的语料库是《人民日报》2015年1月16日至1月18日的发表的新闻。并且在进行TFIDF处理之前已经进行了人工分词(当然也可以使用jieba分词,但效果不好)
三天的新闻篇章数量如下:
语料库中共103篇新闻。每篇新闻存入在txt文件中,编码为UTF-8无BOM
这里放一篇文章示例下:
我在自己的项目路径下新建一个corpus的文件夹,用于存放已经分好词待计算的语料。corpus文件夹的架构如下:
2015年1月16日至1月18日共三天,每天可获取的新闻分了四版,因此针对每一天下的每一版我又分别建了编号为1、2、3、4的文件夹,用于存放每一版的新闻。
其实也没必要这么麻烦,可以直接把所有的新闻都放到一个文件夹下,只是我个人的文件管理习惯。当然放到数据库里面更好。
关于停用词表
较好用的停用词表有哈工大停用词表、百度停用词表、川大停用词表,网上一查一大堆。我这里选择的是哈工大停用词表。
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# -*- coding: utf-8 -*- # @Date : 2017-04-11 09:31:55 # @Author : Alan Lau (rlalan@outlook.com) # @Language : Python3.5 import os import codecs import math import operator def fun(filepath): # 遍历文件夹中的所有文件,返回文件list arr = [] for root, dirs, files in os.walk(filepath): for fn in files: arr.append(root + "\\" + fn) return arr def wry(txt, path): # 写入txt文件 f = codecs. open (path, 'a' , 'utf8' ) f.write(txt) f.close() return path def read(path): # 读取txt文件,并返回list f = open (path, encoding = "utf8" ) data = [] for line in f.readlines(): data.append(line) return data def toword(txtlis): # 将一片文章按照‘/'切割成词表,返回list wordlist = [] alltxt = '' for i in txtlis: alltxt = alltxt + str (i) ridenter = alltxt.replace( '\n' , '') wordlist = ridenter.split( '/' ) return wordlist def getstopword(path): # 获取停用词表 swlis = [] for i in read(path): outsw = str (i).replace( '\n' , '') swlis.append(outsw) return swlis def getridofsw(lis, swlist): # 去除文章中的停用词 afterswlis = [] for i in lis: if str (i) in swlist: continue else : afterswlis.append( str (i)) return afterswlis def freqword(wordlis): # 统计词频,并返回字典 freword = {} for i in wordlis: if str (i) in freword: count = freword[ str (i)] freword[ str (i)] = count + 1 else : freword[ str (i)] = 1 return freword def corpus(filelist, swlist): # 建立语料库 alllist = [] for i in filelist: afterswlis = getridofsw(toword(read( str (i))), swlist) alllist.append(afterswlis) return alllist def wordinfilecount(word, corpuslist): # 查出包含该词的文档数 count = 0 # 计数器 for i in corpuslist: for j in i: if word in set (j): # 只要文档出现该词,这计数器加1,所以这里用集合 count = count + 1 else : continue return count def tf_idf(wordlis, filelist, corpuslist): # 计算TF-IDF,并返回字典 outdic = {} tf = 0 idf = 0 dic = freqword(wordlis) outlis = [] for i in set (wordlis): tf = dic[ str (i)] / len (wordlis) # 计算TF:某个词在文章中出现的次数/文章总词数 # 计算IDF:log(语料库的文档总数/(包含该词的文档数+1)) idf = math.log( len (filelist) / (wordinfilecount( str (i), corpuslist) + 1 )) tfidf = tf * idf # 计算TF-IDF outdic[ str (i)] = tfidf orderdic = sorted (outdic.items(), key = operator.itemgetter( 1 ), reverse = True ) # 给字典排序 return orderdic def befwry(lis): # 写入预处理,将list转为string outall = '' for i in lis: ech = str (i).replace( "('" , ' ').replace("' ,", '\t' ).replace( ')' , '') outall = outall + '\t' + ech + '\n' return outall def main(): swpath = r 'D:\Alan\myBlog\20170411《人民日报》TFIDF\code\哈工大停用词表.txt' #停用词表路径 swlist = getstopword(swpath) # 获取停用词表列表 filepath = r 'D:\Alan\myBlog\20170411《人民日报》TFIDF\corpus' filelist = fun(filepath) # 获取文件列表 wrypath = r 'D:\Alan\myBlog\20170411《人民日报》TFIDF\result\TFIDF.txt' corpuslist = corpus(filelist, swlist) # 建立语料库 outall = '' for i in filelist: afterswlis = getridofsw(toword(read( str (i))), swlist) # 获取每一篇已经去除停用的词表 tfidfdic = tf_idf(afterswlis, filelist, corpuslist) # 计算TF-IDF titleary = str (i).split( '\\' ) title = str (titleary[ - 1 ]).replace( 'utf8.txt' , '') echout = title + '\n' + befwry(tfidfdic) print (title + ' is ok!' ) outall = outall + echout print (wry(outall, wrypath) + ' is ok!' ) if __name__ = = '__main__' : main() |
运行效果:
最终结果
这里放两篇新闻的TFIDF
可以看到,第一篇新闻的关键词可以认为为:核工业、发展、安全
第二篇新闻:习近平总书记、廉政、党风
关于\u3000\u3000这个问题实在不知道怎么替换掉,各种方法使用过了,不知哪位大神看到恳请指点下。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/AlanConstantineLau/article/details/70046692