问题:语料库里有若干类中文文档,现在想提取每类文档中能代表该类特点的词。本文的语料库是用户上传的视频名称。
解决办法:先对文档分词,然后计算词的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代码:
-
#coding=utf-8
-
#import re
-
from nltk import *
-
from nltk.util import ngrams
-
from nltk.corpus import PlaintextCorpusReader
-
from math import log
-
from os import listdir
-
import codecs
-
corpus_dir='d:/python_workspace/corpus2/'
-
#consider n-grams, 构造一个dict, fileid:<tokens>
-
#此处语料库的格式是文件夹,里边每个文件为一个分类。
-
#文件已分好了词,词之间用空格隔开,如:
-
#马云 催泪 励志 演讲 为什么 你还是 穷人
-
#谢霆锋 励志 演讲 看完 跟 打了 鸡血 似的
-
corpus={}
-
for f in listdir(corpus_dir):
-
print f
-
fi=codecs.open(corpus_dir+f, 'r', encoding='utf-8')
-
grams=[]
-
for line in fi:
-
sigram=line.strip().split()
-
l=len(sigram)
-
for cnt in range(l):
-
grams.append(sigram[cnt])
-
#可加入高阶模型
-
#if cnt < l-1:
-
#grams.append('%s|%s' % (sigram[cnt], sigram[cnt+1]))
-
#if cnt < l-2:
-
#grams.append('%s|%s|%s' % (sigram[cnt], sigram[cnt+1], sigram[cnt+2]))
-
corpus[f]=grams
-
fi.close()
-
print 'step1 OK'
-
-
cfd_dir='D:\\python_workspace\\corpus_res2\\unigram\\'
-
cfd=ConditionalFreqDist(
-
(topic, word)
-
for topic in corpus.keys()
-
for word in corpus[topic])
-
-
df={}
-
print 'step2 OK'
-
#类
-
topics=cfd.conditions()
-
sum_topics=len(topics)
-
#store idf of every word
-
#df
-
for topic in topics:
-
for k in cfd[topic].keys():
-
if k not in df:
-
df[k]=0
-
df[k]+=1
-
#tf-idf
-
topic_tf_idf={}
-
for topic in topics:
-
if topic not in topic_tf_idf:
-
topic_tf_idf[topic]={}
-
sum_tf=len(corpus[topic])
-
for k, v in cfd[topic].items():
-
topic_tf_idf[topic][k]=float(v)/sum_tf*log(float(sum_topics)/df[k])
-
#输出到文件夹中,每个文件一个类,里边是依tf-idf倒序排列的主题词,如:
-
#演讲 0.375399
#励志 0.337192
#马云 0.242213
-
for topic, tf_idf in topic_tf_idf.items():
-
fw=open(cfd_dir+topic, 'w')
-
for k, v in sorted(tf_idf.items(), key=lambda x:x[1], reverse = True):
-
fw.write('%s\t%f\n' % (k.encode('utf-8'), v))
-
fw.close()
阅读(6138) | 评论(0) | 转发(0) |