TF-IDF算法(2)—python实现

  参加完数模之后休息了几天,今天继续看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 jieba
import jieba.posseg as pseg
import os
import sys
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
import sys
reload(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,ImageDraw
import os, codecs, random
from 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

#test
if __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算法的优化,实现更好的聚类。

时间: 2024-12-24 03:05:20

TF-IDF算法(2)—python实现的相关文章

tf–idf算法解释及其python代码实现(下)

tf–idf算法python代码实现 这是我写的一个tf-idf的核心部分的代码,没有完整实现,当然剩下的事情就非常简单了,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四句话,每句表示一个文档 copus=['我正在学习计算机','它正在吃饭','我的书还在你那儿','今天不上班'] 由于中文需要分词,jieba分词是python里面比较好用的分词工具,所以选用jieba分词,文末是jieba的链接.首先对文档进行分词: i

tf–idf算法解释及其python代码实现(上)

tf–idf算法解释 tf–idf, 是term frequency–inverse document frequency的缩写,它通常用来衡量一个词对在一个语料库中对它所在的文档有多重要,常用在信息检索和文本挖掘中. 一个很自然的想法是在一篇文档中词频越高的词对这篇文档越重要,但同时如果这个词又在非常多的文档中出现的话可能就是很普通的词,没有多少信息,对所在文档贡献不大,例如‘的’这种停用词.所以要综合一个词在所在文档出现次数以及有多少篇文档包含这个词,如果一个词在所在文档出现次数很多同时整个

55.TF/IDF算法

主要知识点: TF/IDF算法介绍 查看es计算_source的过程及各词条的分数 查看一个document是如何被匹配到的 一.算法介绍 relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度.Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法 1.Term frequency 搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,

25.TF&IDF算法以及向量空间模型算法

主要知识点: boolean model IF/IDF vector space model 一.boolean model 在es做各种搜索进行打分排序时,会先用boolean model 进行初步的筛选,boolean model类似and这种逻辑操作符,先过滤出包含指定term的doc.must/must not/should(过滤.包含.不包含 .可能包含)这几种情况,这一步不会对各个doc进行打分,只分过滤,为下一步的IF/IDF算法筛选数据. 二.TF/IDF 这一步就是es为boo

Elasticsearch学习之相关度评分TF&amp;IDF

relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度 Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法 Term frequency(TF):搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关 Inverse document frequency(IDF):搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的

分类算法——k最近邻算法(Python实现)(文末附工程源代码)

kNN算法原理 k最近邻(k-Nearest Neighbor)算法是比较简单的机器学习算法.它采用测量不同特征值之间的距离方法进行分类,思想很简单:如果一个样本在特征空间中的k个最近邻(最相似)的样本中大多数属于某一个类别,则该样本也属于这个类别. kNN算法的步骤 第一阶段:确定k值(指最近的邻居的个数),一般是一个奇数 第二阶段:确定距离度量公式.文本分类一般使用夹角余弦,得出待分类数据点和所有已知类别的样本点,从中选择距离最近的k个样本: 第三阶段:统计这k个样本点钟各个类别的数量 kN

文本分类学习(三) 特征权重(TF/IDF)和特征提取

上一篇中,主要说的就是词袋模型.回顾一下,在进行文本分类之前,我们需要把待分类文本先用词袋模型进行文本表示.首先是将训练集中的所有单词经过去停用词之后组合成一个词袋,或者叫做字典,实际上一个维度很大的向量.这样每个文本在分词之后,就可以根据我们之前得到的词袋,构造成一个向量,词袋中有多少个词,那这个向量就是多少维度的了.然后就把这些向量交给计算机去计算,而不再需要文本啦.而向量中的数字表示的是每个词所代表的权重.代表这个词对文本类型的影响程度. 在这个过程中我们需要解决两个问题:1.如何计算出适

《机器学习实战》之K-均值聚类算法的python实现

<机器学习实战>之K-均值聚类算法的python实现 最近的项目是关于"基于数据挖掘的电路故障分析",项目基本上都是师兄们在做,我只是在研究关于项目中用到的如下几种算法:二分均值聚类.最近邻分类.基于规则的分类器以及支持向量机.基于项目的保密性(其实也没有什么保密的,但是怕以后老板看到我写的这篇博文,所以,你懂的),这里就不介绍"基于数据挖掘的电路故障分析"的思路了. 废话不多说了,开始正题哈. 基本K-均值聚类算法 基本K均值算法的基本思路为:首先选择

《机器学习实战》之二分K-均值聚类算法的python实现

<机器学习实战>之二分K-均值聚类算法的python实现 上面博文介绍了K-均值聚类算法及其用python实现,上篇博文中的两张截图,我们可以看到,由于K-均值聚类算法中由于初始质心的选取,会造成聚类的局部最优,并不是全局最优,因此,会造成聚类的效果并不理想,为克服K-均值算法收敛于局部最小值的问题,就有了二分K-均值算法. 二分K-均值聚类算法 二分K均值算法是基本K均值算法的直接扩充,其基本思想是:为了得到K个簇,首先将所有点的集合分裂成两个簇,然后从这些簇中选取一个继续分裂,迭代直到产生

[Elasticsearch] 控制相关度 (四) - 忽略TF/IDF

本章翻译自Elasticsearch官方指南的Controlling Relevance一章. 忽略TF/IDF 有时我们不需要TF/IDF.我们想知道的只是一个特定的单词是否出现在了字段中.比如我们正在搜索度假酒店,希望它拥有的卖点越多越好: WiFi 花园(Garden) 泳池(Pool) 而关于度假酒店的文档类似下面这样: { "description": "A delightful four-bedroomed house with ... " } 可以使用