1. 程式人生 > >python計算稀疏表示的TF-IDF

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]