打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
TF

  参加完数模之后休息了几天,今天继续看TF-IDF算法。上篇中对TF-IDF算法已经做了详细的介绍,在此不再赘述。今天主要是通过python,结合sklearn库实现该算法,并通过k-means算法实现简单的文档聚类。

一 结巴分词                                                                                     

1.简述

  中文分词是中文文本处理的一个基础性工作,长久以来,在Python编程领域,一直缺少高准确率、高效率的分词组建,结巴分词正是为了满足这一需求而提出。

2.安装

(1)全自动安装

在安装了easy—stall的情况之下可以全自动安装:easy_install jieba

(2)半自动安装

  ·下载地址:https://pypi.python.org/pypi/jieba/

  ·在cmd下找到具体的目录python setup.py安装

3.功能

(1)全模式:将句子中所有的可以成词的词语都扫描出来,速度非常快,但是不能解决歧义问题;

  jieba.cut方法接收两个参数:第一个参数为需要分词的字符串,第二个cut_all参数用来控制是否采用全模式进行分词。

>>> #coding:utf-8>>> import jieba>>> seg_list = jieba.cut("我爱西邮西邮爱我",cut_all = True)>>> print "Full Mode:","/".join(seg_list)

  Full Mode: 我/爱/西/邮/西/邮/爱/我

(2)精确模式:将句子最精确分开,适合文本分析: 

>>> seg_list = jieba.cut("喜欢玩游戏,可以把编程当成玩游戏,还挺好玩的,哈哈哈哈")>>> print "Default Mode:", "/ ".join(seg_list)

   Default Mode: 喜欢/ 玩游戏/ ,/ 可以/ 把/ 编程/ 当成/ 玩游戏/ ,/ 还/ 挺好玩/ 的/ ,/ 哈哈哈哈

  除此之外,默认表示的也是精确模式: 

>>> seg_list = jieba.cut("喜欢玩游戏,可以把编程当成玩游戏,还挺好玩的,哈哈哈哈")>>> print ",".join(seg_list)

 (3)搜索引擎模式:在精确模式的基础上,对长词再次切分 ,提高召回率。

  jieba.cut_for_search方法只接收需要分词的字符串,这种方法分词分的比较细: 

>>> seg_list = jieba.cut_for_search("西邮就是西安邮电大学的简称")>>> print ",".join(seg_list)

结果:西邮,就是,西安,邮电,电大,大学,邮电大学,的,简称

  当然结巴分词还有很多功能,比如添加字典啊什么的,在此不再详细说明。

二  scikit-learn                                                         

  scikit-learn含有完善的文档和丰富的机器学习算法,已经实现了所有基本的机器学习算法,并且其本身就带有一些标准的数据集。比如用来分类的iris数据集、digits数据集;用来回归的boston house price 数据集。

  更多内容见http://dataunion.org/20071.html。

三 python实现TF-IDF算法                                                                                             

  之前用的是python3.4,但由于不可抗的原因,又投入了2.7的怀抱,在这里编写一段代码,简单的实现TF-IDF算法。大致的实现过程是读入一个测试文档,计算出文档中出现的词的tfidf值,并保存在另一个文档中。

# -*- coding: cp936 -*-import jiebaimport jieba.posseg as psegimport osimport sysfrom sklearn import feature_extractionfrom sklearn.feature_extraction.text import TfidfTransformerfrom sklearn.feature_extraction.text import CountVectorizerimport sysreload(sys)sys.setdefaultencoding( "utf-8" )sys.path.append("C:\Users\Administrator\Desktop\9.17")from numpy import *fr = open('exercise.txt')fr_list = fr.read()dataList = fr_list.split('\n')data = []for oneline in dataList:    data.append(" ".join(jieba.cut(oneline))) #将得到的词语转换为词频矩阵freWord = CountVectorizer()#统计每个词语的tf-idf权值transformer = TfidfTransformer()#计算出tf-idf(第一个fit_transform),并将其转换为tf-idf矩阵(第二个fit_transformer)tfidf = transformer.fit_transform(freWord.fit_transform(data))#获取词袋模型中的所有词语word = freWord.get_feature_names()#得到权重weight = tfidf.toarray()tfidfDict = {}for i in range(len(weight)):    for j in range(len(word)):        getWord = word[j]        getValue = weight[i][j]        if getValue != 0:            if tfidfDict.has_key(getWord):                tfidfDict[getword] += string.atof(getValue)            else:                tfidfDict.update({getWord:getValue})sorted_tfidf = sorted(tfidfDict.iteritems(),                      key = lambda d:d[1],reverse = True)fw = open('result.txt','w')for i in sorted_tfidf:    fw.write(i[0] + '\t' + str(i[1]) +'\n')

至此,对算法已经有了一个简单的实现,接下来需要做的是将其应用到文档聚类中加以运用。 

四 实现简单的文本聚类                                                                

  要聚类,聚什么是重点!结合上述分析,我们可以将一篇文章中的关键词和对应的tf-idf值一一对应起来,显然想到的是dict,那么聚类是聚的当然不止一篇文章,那么我们就可以分别将每篇文章的关键词和对应的tf-idf值对应起来,最后整合起来进行聚类,当然还是得用到dict。

  结合上述tf-idf的实现,可以将得到的结果分别存在同一个目录下的.txt中,导入目录读取并整合,直接上代码: 

# -*- coding: cp936 -*-#-*- coding:utf-8 -*-from PIL import Image,ImageDrawimport os, codecs, randomfrom math import sqrt#将得到的结果按照字典存放rows_norms = {}def readfile(dirname):    rows = {}    for f in os.listdir(dirname):#目录        fr = codecs.open(dirname + f,'r',encoding = 'utf-8')        tw_dict = {}        norm = 0        for line in fr:            items = line.split('\t')            token = items[0].strip()            if len(token)<2:                continue            w = float(items[1].strip())            norm = w**2            tw_dict[token] = w        rows[str(f[:-4])] = tw_dict        rows_norms[str(f[:-4])] = sqrt(float(norm))    #print len(rows)    return rows

   至此,相当于得到了数据,接下来就是k-means算法的实现了,之前的文章中都有详细说明,在此不再赘述,所不同的是在此采用了余弦距离计算相似度:

#得到余弦距离,其中v1就是row,v2是聚类中心点def cosine(v1,norm_v1,v2,norm_v2):    if norm_v1 == 0 or norm_v2 == 0:        return 1.0    dividend = 0    for k,v in v1.items():        for k in v2:            dividend += v*v2[k]    return 1.0-dividend/(norm_v1*norm_v2)

主程序段如下:

#算法的实现def kcluster(rows,distance=cosine,k=3):    ranges=rows_range(rows)    #初始化聚类中心    clusters=[]    for i in range(k):        clusters.append(random_vec(ranges))    clusteres_norm=[]    for i in range(k):        clusteres_norm.append(norm(clusters[i]))    lastmatches=None    #开始迭代    for t in range(300):        print '第%d次迭代' % t        bestmatches=[[] for i in range(k)]        for j in rows.keys():            row=rows[j]            row_norm=rows_norms[j]            bestmatch=0            min_dis=10000000            for i in range(k):                d=distance(row, row_norm, clusters[i],clusteres_norm[i])                if d<min_dis:                    bestmatch=i                    min_dis=d            bestmatches[bestmatch].append(j)        if bestmatches==lastmatches:             break        lastmatches=bestmatches        for i in range(k):            clusters[i]=center(bestmatches[i], rows)    print bestmatches    return bestmatches#testif __name__ == '__main__':    corpus_dir='D:/python2.7/exercise/clusting/data/'    rows=readfile(corpus_dir)    print 'create vectorspace'    n=3    clust=kcluster(rows,k=n)

  简单测试,结果还是挺理想的,但还是可以结合之前对k-means算法的优化,实现更好的聚类。

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
seo 关键词词库建立和维护
中文文本聚类(切词以及Kmeans聚类)
文本关键词提取算法
Jieba中文分词 (二) ——词性标注与关键词提取
基于 Spark 的文本情感分析
python 中文文本分类
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服