python计算稀疏表示的TF-IDF

使用sklean的计算方法,这种结果是稠密矩阵,如果数据集太大,计算结果将会占满内存,或者直接报MemeryError的错误。

tfidf详细计算参考:https://blog.csdn.net/Eastmount/article/details/50323063

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  
  
if __name__ == "__main__":  
    corpus=["我 来到 北京 清华大学",#第一类文本切词后的结果,词之间以空格隔开  
        "他 来到 了 网易 杭研 大厦",#第二类文本的切词结果  
        "小明 硕士 毕业 与 中国 科学院",#第三类文本的切词结果  
        "我 爱 北京 天安门"]#第四类文本的切词结果  
    vectorizer=CountVectorizer()#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频  
    transformer=TfidfTransformer()#该类会统计每个词语的tf-idf权值  
    tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))#第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵  
    word=vectorizer.get_feature_names()#获取词袋模型中的所有词语  
    weight=tfidf.toarray()#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重  
    for i in range(len(weight)):#打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重  
        print u"-------这里输出第",i,u"类文本的词语tf-idf权重------"  
        for j in range(len(word)):  
            print word[j],weight[i][j]  


当数据集过大的时候,我们可以使用稀疏存储的方式来计算TF-IDF。最后返回结果是一个list,里面的元素是字典,同时这样表示之后的余弦相似度计算也更简单。

corpus 就是分词好的数据,每行是一个数组;
直接传入函数calc_tfidf(corpus)计算得到tfidf;
每一行里面是一个map,key是词,value是tfidf;
cos_sim函数传入两行数据,map格式,计算两个文本的相似度;

get_top(tfidf,top)保留每个文本里面的top词,可以直接传入小数,表示保留百分比;

# coding=utf-8
# @author: bryan
corpus = data['标题'].apply(lambda x: [i for i in jb.cut(x)])
import math

def list2dic(l):
    tmp = {}
    for i in l:
        if i in tmp:
            tmp[i] += 1
        else:
            tmp[i] = 1
    return tmp

def calc_tfidf(corpus):
    tf, tmp = [], []
    for line in corpus:
        tf.append(list2dic(line))
    for i in tf:
        tmp.extend(i.keys())
    idf = list2dic(tmp)
    N = len(tf)
    for i in idf:
        idf[i] = math.log(N / (idf[i] + 1))
    for i in range(len(tf)):
        for word in tf[i]:
            tf[i][word] = tf[i][word] * idf[word]
    return tf

def cos_sim(x1, x2):
    if (not x1) | (not x2):
        return 0
    if (len(x1) == 0) | (len(x2) == 0):
        return 0
    fenzi, fenmu1, fenmu2 = 0, 0, 0
    for i in x1.keys():
        if i in x2:
            fenzi += x1[i] * x2[i]
        fenmu1 += x1[i] * x1[i]
    for i in x2.values():
        fenmu2 += i * i
    fenmu = math.sqrt(fenmu1) * math.sqrt(fenmu2)
    return fenzi / fenmu

def get_top(tfidf, top):
    # 根据tf-idf保留top的词
    return [dict(sorted(i.items(), key=lambda x: x[1], reverse=True)[:int(len(i) * top)]) for i in tfidf]  

猜你喜欢

转载自blog.csdn.net/Bryan__/article/details/79794514
今日推荐