0.前言
操作系统:Windows 64
开发工具:pycharm
全部代码以及使用材料下载
下载地址
1.使用jieba对中文进行分词
1.1 测试文本
本次实验的评论comment2中的内容为:
使用了一周多才来评价 优化过后开机10秒左右 运行不卡顿 屏幕清晰无漏光 巧克力键盘触感非常不错 音质也很好 外观漂亮 质量轻巧 尤其值得称赞的是其散热系统 我玩LOL三四个小时完全没有发烫 暂时没有发现什么缺点 如果有光驱就更好了 值得入手 值得入手 值得入手~ 不枉费我浪费了12期免息券加首单减免*的优惠最后换了这台适合办公的 之前是买的惠普的暗夜精灵 玩游戏超棒的
1.2 分词代码
with open('./comment2.txt') as f:
tmp_line = f.read()
tmp_line_decode = tmp_line.decode('GBK')
jieba_cut = jieba.cut(tmp_line_decode)
ans = '/'.join(jieba_cut)
ans = ans.encode('utf-8')
with open('./comment5_forward_slash.txt', 'w') as f2:
f2.write(ans)
代码解析:
第4行主要是编码问题,本机使用的是windows环境,默认编码是GBK,而python里面都是用的unicode来处理字符,因此要先从GBK解码成unicode。
第5行就是结巴的分词函数,
jieba.cut
这个函数返回的是一个生成器(Generator)对象,迭代一次之后里面的内容就消失了。第6行主要是把分词过后产生的生成器拼成一个新的字符串,并且通过/来进行分割词,这里使用/来分割词语仅仅是为了展示分词效果,真正要和nltk联合使用的使用要改成
ans=' '.join(jieba_cut)
,即用空格连接,因为英文默认是通过空格来分词的,因此nltk也是通过空格来读取分词。第8行就是将拼接好的unicode字符串拼接成utf-8,方便python以外的程序识别
1.3 分词结果
通过这段代码分割之后,生成的comment5的内容:
使用/了/一周/多才/来/评价/ /优化/过后/开机/10/秒左右/ /运行/不卡顿/ /屏幕/清晰/无/漏光/ /巧克力/键盘/触感/非常/不错/ /音质/也/很/好/ /外观/漂亮/ /质量/轻巧/ /尤其/值得称赞/的/是/其/散热/系统/ /我/玩/LOL/三四个/小时/完全/没有/发烫/ /暂时/没有/发现/什么/缺点/ /如果/有/光驱/就/更好/了/ /值得/入手/ /值得/入手/ /值得/入手/~/ /不/枉费/我/浪费/了/12/期/免息/券加/首单/减免/*/的/优惠/最后/换/了/这台/适合/办公/的/ /之前/是/买/的/惠普/的/暗夜精灵/ /玩游戏/超棒/的
前后对比:
使用了一周多才来评价 优化过后开机10秒左右 运行不卡顿 屏幕清晰无漏光 巧克力键盘触感非常不错 音质也很好 外观漂亮 质量轻巧 尤其值得称赞的是其散热系统 我玩LOL三四个小时完全没有发烫 暂时没有发现什么缺点 如果有光驱就更好了 值得入手 值得入手 值得入手~ 不枉费我浪费了12期免息券加首单减免*的优惠最后换了这台适合办公的 之前是买的惠普的暗夜精灵 玩游戏超棒的
使用/了/一周/多才/来/评价/ /优化/过后/开机/10/秒左右/ /运行/不卡顿/ /屏幕/清晰/无/漏光/ /巧克力/键盘/触感/非常/不错/ /音质/也/很/好/ /外观/漂亮/ /质量/轻巧/ /尤其/值得称赞/的/是/其/散热/系统/ /我/玩/LOL/三四个/小时/完全/没有/发烫/ /暂时/没有/发现/什么/缺点/ /如果/有/光驱/就/更好/了/ /值得/入手/ /值得/入手/ /值得/入手/~/ /不/枉费/我/浪费/了/12/期/免息/券加/首单/减免/*/的/优惠/最后/换/了/这台/适合/办公/的/ /之前/是/买/的/惠普/的/暗夜精灵/ /玩游戏/超棒/的
我们可以看出,此评论已经被成功分词。
2.nltk计算评论的TF_IDF值
2.1 测试文本
测试文本分为comment4和comment5,其内容如下:
comment4:
从 下单 到手 只用 了 3 个 多 小时 , 真快 啊 , 赞 一下 京东 的 配送 速度 , 机子 收到 是 原封 的 , 深圳 产 , 没有 阴阳 屏 和 跑马灯 , 还 不错 , 三星 的 U , 但 不 纠结 , 也 没有 感觉 有 多 费电 , 激活 后 买 了 ac + , 可以 随意 裸机 体验 了 , 整体 来说 很 满意
comment5:
使用 了 一周 多才 来 评价 优化 过后 开机 10 秒左右 运行 不卡顿 屏幕 清晰 无 漏光 巧克力 键盘 触感 非常 不错 音质 也 很 好 外观 漂亮 质量 轻巧 尤其 值得称赞 的 是 其 散热 系统 我 玩 LOL 三四个 小时 完全 没有 发烫 暂时 没有 发现 什么 缺点 如果 有 光驱 就 更好 了 值得 入手 值得 入手 值得 入手 ~ 不 枉费 我 浪费 了 12 期 免息 券加 首单 减免 * 的 优惠 最后 换 了 这台 适合 办公 的 之前 是 买 的 惠普 的 暗夜精灵 玩游戏 超棒 的
注意:以上内容均经过结巴分词处理,且以空格为间隔进行分词。
2.3 导入及计算IF_IDF代码
corpus_root = './'
allText = ''
allText = PlaintextCorpusReader(corpus_root, ['comment4.txt', 'comment5.txt'])
print type(allText)
sinica_text = nltk.Text(allText.words())
mytexts = TextCollection(allText)
print len(mytexts._texts)
print len(mytexts)
the_set = set(sinica_text)
print len(the_set)
for tmp in the_set:
print tmp, "tf", mytexts.tf(tmp, allText.raw(['comment4.txt'])), "idf", mytexts.idf(tmp), mytexts.tf_idf(tmp, allText.raw(['comment4.txt']))
代码解析
第1行
corpus_root
是用来指明语料库的地址,可用相对路径或者绝对路径,我这里用的是相对路径。第5行
PlaintextCorpusReader(corpus_root, ['comment4.txt', 'comment5.txt'])
,其第一个参数是语料库的路径,第二个参数指的是该路径下要加在文件的文件名,既可以为['comment4.txt', 'comment5.txt']
的list格式,也可以使用通配符加载,如.*.txt
第9行
allText.words()
,用于返回所加载文档的所有词汇第11~15行
TextCollection
,用于返回一个文档集合,其中len(mytexts._texts)
表示里面包含的文档个数,len(mytexts)
表示里面包含的词汇个数。第17行通过
set(sinica_text)
来去除文档中重复的词汇,从而形成词汇表。第18~20行,通过
tf
,idf
,tf_idf
函数来计算每个词汇在语料库以及对应文章中的值。其中allText.raw(['comment4.txt'])
用于返回对应文章的所有内容,用于计算tf和tf_idf值。
2.4 测试结果(部分)
不卡顿 tf 0.0 idf 0.69314718056 0.0
真快 tf 0.00584795321637 idf 0.69314718056 0.00405349228398
ac tf 0.00584795321637 idf 0.69314718056 0.00405349228398
了 tf 0.0175438596491 idf 0.0 0.0
很 tf 0.00584795321637 idf 0.0 0.0
注:python当中的log函数的底是以自然对数为基础而nltk调用的就是基础的log函数,因此计算结果可能会和一般的公式计算结果有区别