转载

jieba与nltk结合处理评论(一)

0.前言

  1. 操作系统:Windows 64

  2. 开发工具:pycharm

  3. 研究原因:组内有个研究生,想研究当当图书用户评论的情感分析,需要计算TF_IDF值,但是代码写不出来,这个时候组长的价值就要体现出来了。虽然人肉帮助她实现了代码,但是总感觉应该有现成方案现,于是就开始研究nltk,可惜这个目前对于中文的分词还不太行,因此就考虑到使用结巴分词来先对中文进行分词,然后使用nltk进行处理。遗憾是没有网络上目前目前还没有发现优秀的blog来讲明过程,那我就自己来吧~咩哈哈~

  4. 全部代码以及使用材料下载

    下载地址

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)

代码解析:

  1. 第4行主要是编码问题,本机使用的是windows环境,默认编码是GBK,而python里面都是用的unicode来处理字符,因此要先从GBK解码成unicode。

  2. 第5行就是结巴的分词函数, jieba.cut 这个函数返回的是一个生成器(Generator)对象,迭代一次之后里面的内容就消失了。

  3. 第6行主要是把分词过后产生的生成器拼成一个新的字符串,并且通过/来进行分割词,这里使用/来分割词语仅仅是为了展示分词效果,真正要和nltk联合使用的使用要改成 ans=' '.join(jieba_cut) ,即用空格连接,因为英文默认是通过空格来分词的,因此nltk也是通过空格来读取分词。

  4. 第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. 第1行 corpus_root 是用来指明语料库的地址,可用相对路径或者绝对路径,我这里用的是相对路径。

  2. 第5行 PlaintextCorpusReader(corpus_root, ['comment4.txt', 'comment5.txt']) ,其第一个参数是语料库的路径,第二个参数指的是该路径下要加在文件的文件名,既可以为 ['comment4.txt', 'comment5.txt'] 的list格式,也可以使用通配符加载,如 .*.txt

  3. 第9行 allText.words() ,用于返回所加载文档的所有词汇

  4. 第11~15行 TextCollection ,用于返回一个文档集合,其中 len(mytexts._texts) 表示里面包含的文档个数, len(mytexts) 表示里面包含的词汇个数。

  5. 第17行通过 set(sinica_text) 来去除文档中重复的词汇,从而形成词汇表。

  6. 第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

原文  https://segmentfault.com/a/1190000004434983
正文到此结束
Loading...