Chinaunix首页 | 论坛 | 博客
  • 博客访问: 54183
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 152
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-06 21:55
文章分类

全部博文(14)

文章存档

2015年(2)

2014年(12)

我的朋友

分类: Python/Ruby

2014-02-16 08:03:30

问题:语料库里有若干类中文文档,现在想提取每类文档中能代表该类特点的词。本文的语料库是用户上传的视频名称。
解决办法:先对文档分词,然后计算词的TF*IDF, 结果值大的词可作为该类文档的备选主题词。下面详细说这两个步骤:
a. 分词:现在主要有两种分词方法: 1)最长匹配 2)语义相关(如HMM)。如果文档不规范,比如口语化和网络化(本文就如此),语义相关的方法就派不上用场。而对于方法1)来说,最关键的要属词库了。如果不考虑进行新词识别,网上最全的词库应该是搜狗细胞词库了,可以从上面爬取需要的词加进自己的分词词库。这步我使用IKAnalyzer来做的
b. TF*IDF计算:计算本身没有问题,要考虑的是用几阶的模型去做。单用一阶(unigram)可能得到的词太泛(比如印度),把一阶到到n阶(nth-gram)放到一起算,可能得到的词太窄(比如印度|性感|肚皮舞),并且会重复(n阶词包含一阶词)。如何融合还没想好,这步我简单地使用了一阶模型
可用NLTK的ConditionalFreqDist函数简化计算,这个函数会给出某个维度取不同值下的频率统计结果(并且倒序排好)。还要注意的是计算中要把中文字符转为unicode, 如果用python, 在打开文件时用codecs.open, 指明encode='utf-8'就好了。
下边是实现第二步(TF*IDF计算)的python代码:

点击(此处)折叠或打开

  1. #coding=utf-8
  2. #import re
  3. from nltk import *
  4. from nltk.util import ngrams
  5. from nltk.corpus import PlaintextCorpusReader
  6. from math import log
  7. from os import listdir
  8. import codecs
  9. corpus_dir='d:/python_workspace/corpus2/'
  10. #consider n-grams, 构造一个dict, fileid:<tokens>
  11. #此处语料库的格式是文件夹,里边每个文件为一个分类。
  12. #文件已分好了词,词之间用空格隔开,如:
  13. #马云 催泪 励志 演讲 为什么 你还是 穷人
  14. #谢霆锋 励志 演讲 看完 跟 打了 鸡血 似的
  15. corpus={}
  16. for f in listdir(corpus_dir):
  17.     print f
  18.     fi=codecs.open(corpus_dir+f, 'r', encoding='utf-8')
  19.     grams=[]
  20.     for line in fi:
  21.         sigram=line.strip().split()
  22.         l=len(sigram)
  23.         for cnt in range(l):
  24.             grams.append(sigram[cnt])
  25.             #可加入高阶模型
  26.             #if cnt < l-1:
  27.                 #grams.append('%s|%s' % (sigram[cnt], sigram[cnt+1]))
  28.             #if cnt < l-2:
  29.                 #grams.append('%s|%s|%s' % (sigram[cnt], sigram[cnt+1], sigram[cnt+2]))
  30.     corpus[f]=grams
  31.     fi.close()
  32. print 'step1 OK'

  33. cfd_dir='D:\\python_workspace\\corpus_res2\\unigram\\'
  34. cfd=ConditionalFreqDist(
  35.     (topic, word)
  36.     for topic in corpus.keys()
  37.     for word in corpus[topic])

  38. df={}
  39. print 'step2 OK'
  40. #类
  41. topics=cfd.conditions()
  42. sum_topics=len(topics)
  43. #store idf of every word
  44. #df
  45. for topic in topics:
  46.     for k in cfd[topic].keys():
  47.         if k not in df:
  48.             df[k]=0
  49.         df[k]+=1
  50. #tf-idf
  51. topic_tf_idf={}
  52. for topic in topics:
  53.     if topic not in topic_tf_idf:
  54.             topic_tf_idf[topic]={}
  55.     sum_tf=len(corpus[topic])
  56.     for k, v in cfd[topic].items():
  57.         topic_tf_idf[topic][k]=float(v)/sum_tf*log(float(sum_topics)/df[k])
  58. #输出到文件夹中,每个文件一个类,里边是依tf-idf倒序排列的主题词,如:
  59. #演讲 0.375399
    #励志 0.337192
    #马云 0.242213

  60. for topic, tf_idf in topic_tf_idf.items():
  61.     fw=open(cfd_dir+topic, 'w')
  62.     for k, v in sorted(tf_idf.items(), key=lambda x:x[1], reverse = True):
  63.         fw.write('%s\t%f\n' % (k.encode('utf-8'), v))
  64.     fw.close()


阅读(6138) | 评论(0) | 转发(0) |
0

上一篇:新年博客目标

下一篇:Linux netstat命令详解

给主人留下些什么吧!~~