1. 程式人生 > 其它 >c++怎麼打印出句子中的各個單詞_知識詳解+Python實現|文字挖掘中的預處理方法...

c++怎麼打印出句子中的各個單詞_知識詳解+Python實現|文字挖掘中的預處理方法...

技術標籤:c++怎麼打印出句子中的各個單詞python正則表示式處理文字內容toarray方法因為某種原因阻止文字引擎初始化

在文字挖掘的預處理過程中,原始文字需要經過分詞、去除標點、去停用詞、向量化表示、TF-IDF處理等諸多流程,本文將專注TF-IDF矩陣的構建過程,向大家介紹Scikit-learn包中的兩個將原始文件轉換為TF-IDF矩陣的模組TfidftransformerTfidfvectorizer。在文章中您將瞭解到文字的詞袋模型表示、兩個TF-IDF矩陣構建模組的使用及其差異,最後在中文語境下進行完成一個簡單的文字預處理流程。

0 1 詞袋模型Bag of Words

詞袋模型是最基本的將句子轉化為向量表示的模型,它不考慮句子中單詞的順序,只考慮詞表(vocabulary)中單詞在這個句子中的出現次數。下面給出一個詞袋模型的例子:

1"thecatsawthemouse"2"themouseranawayfromthehouse"

對於這兩個句子,我們要用詞袋模型把它轉化為向量表示,這兩個句子形成的詞表為:

1['away', 'cat', 'from', 'house', 'mouse', 'ran', 'saw', 'the']

則其對應的詞袋模型向量為:

1 ['away', 'cat', 'from', 'house', 'mouse', 'ran', 'saw', 'the']2s1 = [ 0 1 0 0 1 0 1 2 ]3s2 = [ 1 0 1 1 1 1 0 2 ]

在scikit-learn中的CountVectorizer()函式實現了BOW模型,具體實現步驟包括:

首先我們對CountVectorizer進行初始化,均使用其預設引數(預設會將所有單詞轉為小寫、去除單字元單詞等)。在實際使用過程中也可以傳入stopword引數自定義停用詞列表,min_df引數限制最小詞頻,ngram_range 引數考慮片語等進行個性化設定。

之後CountVectorizer對輸入的所有文件生成詞表,並計算每一個文件中各個單詞出現的次數,即完成詞袋模型BOW的構建,輸出5行(5個文件)6列(16個唯一單詞,預設排除單字元單詞‘a’)的矩陣。

最後,可以通過類函式get_feature_names()訪問生成的詞表,以及輸出生成的詞頻矩陣。也可以傳入全新的文件進行文字向量的構建,但限於test、doc、string等單詞不在詞表中,生成的向量會產生誤差,實際情況若在大量文字中構建詞表,全新文件的向量構建會更精確。

1importpandasaspd 2fromsklearn.feature_extraction.textimportCountVectorizer 3docs=["Thehousehadatinylittlemouse", 4"thecatsawthemouse", 5"theMouseranawayfromthehouse", 6"thecatfinallyatethemouse", 7"theendofthemousestory" 8] 9#呼叫CountVectorizer生成文件-詞頻矩陣10cv=CountVectorizer()11word_count_vector=cv.fit_transform(docs)12#輸出矩陣維度13print(word_count_vector.shape)14#輸出提取的詞表15print(cv.get_feature_names())16#輸出各個文件的詞頻向量17print(word_count_vector.toarray())18#用已有的CountVectorizer計算全新的文件19print(cv.transform(['thetestdocstring']).toarray())

輸出結果如下:

1(5,16)2['ate','away','cat','end','finally','from','had','house','little','mouse','of','ran','saw','story','the','tiny']3[[0000001111000011] [0010000001001020] [0100010101010020] [1010100001000020] [0001000001100120]]4[[0000000000000010]]

0 2 TF-IDF

第一部分我們構建了詞袋模型BOW,能夠簡便的將文字轉換為向量,但其也存在一定的缺點,如沒有考慮單詞之間的順序,無法確定關鍵詞等。詞袋模型僅能夠根據高頻詞來確定關鍵詞,TF-IDF方法通過逆文字頻率對詞頻進行加權處理,在關鍵詞識別上有一定的進步。

TF(Term Frequency,詞頻)的公式為:

e6e110e1c13da30fd7229b0463fe01a4.png

IDF(inverse document frequency,逆文字頻率)的公式為(分母加1防止除零錯誤):

e783a1637243180032624a2ae3b9ae37.png

TF-IDF的公式為:

7ff10d7d6787012677dc518a1526cf9e.png

在scikit-learn中的Tfidftransformer()和TfidfVectorizer()函式實現了TF-IDF模型。Tfidftransformer()函式需要輸入上文生成的文件-詞頻矩陣(即詞袋模型的結果),具體實現步驟如下:

1#初始化TfidfTransformer 2tfidf_transformer=TfidfTransformer(smooth_idf=False,use_idf=True) 3#輸入詞袋模型矩陣word_count_vector計算IDF 4tfidf_transformer.fit(word_count_vector) 5#計算TF-IDF 6count_vector=cv.transform(docs) 7tf_idf_vector=tfidf_transformer.transform(count_vector) 8#計算第一個文件的TF-IDF值,並降序列印 9feature_names=cv.get_feature_names()10first_document_vector=tf_idf_vector[0]11df=pd.DataFrame(first_document_vector.T.todense(),index=feature_names,columns=["tfidf"])12df.sort_values(by=["tfidf"],ascending=False)[:8]

Tfidftvectorizer()函式的使用要簡單的多,程式碼也要短的多,可以一次性計算詞頻、IDF和TF-IDF值,具體實現步驟如下:

1#初始化TfidfVectorize,傳入原始文件集並計算TF-IDF 2fromsklearn.feature_extraction.textimportTfidfVectorizer 3tfidf_vectorizer=TfidfVectorizer() 4tfidf_vectorizer_vectors=tfidf_vectorizer.fit_transform(docs) 5#降序列印第一個文件的TF-IDF值 6first_vector_tfidfvectorizer=tfidf_vectorizer_vectors[0] 7df=pd.DataFrame(first_vector_tfidfvectorizer.T.todense(),index=tfidf_vectorizer.get_feature_names(),columns=["tfidf"]) 8df.sort_values(by=["tfidf"],ascending=False)[:8] 9#也可以分別呼叫fit和transform來實現TFIDF的方法10tfidf_vectorizer=TfidfVectorizer()11fitted_vectorizer=tfidf_vectorizer.fit(docs)12tfidf_vectorizer_vectors=fitted_vectorizer.transform(docs)

Tfidftransformer與Tfidftvectorizer最後的輸出結果均如下所示。可以看到只有部分單詞有TF-IDF得分,是因為第一個文件本身出現的單詞都具有TFIDF得分,但在集合中出現的其他詞也被列出來,得分為零。就我們的第一個文件而言,其TD-IDF得分具有明顯的意義,跨文件的單詞越普遍,其得分越低(如little、tiny),單詞越獨特,得分就越高(如the、mouse)。

1e9ef2f3d84fba5dbc42490d36e36c6e.png

03

Tfidftransformer VS. Tfidfvectorizer

兩個函式之間的主要區別如下:

(1)使用Tfidftransformer時,需要先使用CountVectorizer計算詞頻,然後再計算逆文件頻率(IDF)值,最後得到TD-IDF值。

(2)使用Tfidfvectorizer時,我們可以一次性完成三個步驟,其在後臺使用相同的資料集計算詞頻,IDF值和TF-IDF值。

如何挑選使用的函式:

(1)如果需要在接下來的任務中繼續使用詞頻向量時,請使用Tfidftransformer。

(2)如果僅需要在“訓練”資料集中的文件上計算TF-IDF時,請使用Tfidfvectorizer。

(3)如果您需要在“訓練”資料集之外的文件上計算TF-IDF時,請使用任意一個,兩者都可以。

04

中文處理流程

1#構建中文文件集 2docs=["如果需要在不同任務中使用詞頻(術語計數)向量時,請使用Tfidftransformer", 3"如果需要在“訓練”資料集中的文件上計算tf-idf分數時,請使用Tfidfvectorizer。", 4"如果您需要在“訓練”資料集之外的文件上計算tf-idf分數時,請使用任意一個,兩者都可以。"] 5#文字預處理流程 6#構建停用詞、中英文標點列表 7stop_word_list=['的','呀','這','那','就','的話','如果'] 8importstring 9punctuation_list=list(string.punctuation+'.,;《》?!“”‘’@#¥%…&×()——+【】{};;●,。&~、|\s::')10stop_word_list.extend(punctuation_list)11#分詞:中文jieba包英文nltk包12#TF-IDF中文輸入文件格式應與英文保持一致,用空格連線分詞結果,如["今天天氣很好","明天去打球"]13importjieba14docs_token=[]15fordocindocs:16docs_token.append("".join([wordforwordinjieba.lcut(doc)ifwordnotinstop_word_list]))1718#CountVectorizer19cv=CountVectorizer()20word_count_vector=cv.fit_transform(docs_token)21#TfidfTransformer22tfidf_transformer=TfidfTransformer().fit(word_count_vector)23#計算TF-IDF24count_vector=cv.transform(docs_token)25tf_idf_vector=tfidf_transformer.transform(count_vector)26#計算第一個文件的TF-IDF值,並降序列印27feature_names=cv.get_feature_names()28first_document_vector=tf_idf_vector[0]29df=pd.DataFrame(first_document_vector.T.todense(),index=feature_names,columns=["tfidf"])30df.sort_values(by=["tfidf"],ascending=False)3132#TfidfVectorizer33tfidf_vectorizer=TfidfVectorizer()34tfidf_vectorizer_vectors=tfidf_vectorizer.fit_transform(docs_token)35first_vector_tfidfvectorizer=tfidf_vectorizer_vectors[0]36df=pd.DataFrame(first_vector_tfidfvectorizer.T.todense(),index=tfidf_vectorizer.get_feature_names(),columns=["tfidf"])37df.sort_values(by=["tfidf"],ascending=False)

輸出結果如下(部分擷取):

e3e70173e0d8e65807861f9669c1918d.png

原文作者:Kavita Ganesan

原文標題:How to Use Tfidftransformer & Tfidfvectorizer?

原文來源:https://kavita-ganesan.com/tfidftransformer-tfidfvectorizer-usage-differences

原文程式碼:https://github.com/kavgan/nlp-in-practice/tree/master/tfidftransformer

注:本文經師兵範和朝樂門進行了補充、擴充套件、翻譯、排版和校對。