python計算稀疏表示的TF-IDF
阿新 • • 發佈:2019-01-23
使用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(lambdax: [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]