作文本分類等問題的時,須要從大量語料中提取特徵,並將這些文本特徵變換爲數值特徵。經常使用的有詞袋模型和TF-IDF 模型html
詞袋模型是最原始的一類特徵集,忽略掉了文本的語法和語序,用一組無序的單詞序列來表達一段文字或者一個文檔。能夠這樣理解,把整個文檔集的全部出現的詞都丟進袋子裏面,而後無序的排出來(去掉重複的)。對每個文檔,按照詞語出現的次數來表示文檔。python
句子1:我/有/一個/蘋果數組
句子2:我/明天/去/一個/地方this
把全部詞丟進一個袋子:我,有,一個,蘋果,明天,去,地方。spa
如今咱們創建一個無序列表:我,有,一個,蘋果,明天,去,地方並根據每一個句子中詞語出現的次數來表示每一個句子。3d
這樣的一種特徵表示,咱們就稱之爲詞袋模型的特徵。code
這種模型主要是用詞彙的統計特徵來做爲特徵集。TF-IDF 由兩部分組成:TF(Term frequency,詞頻),IDF(Inverse document frequency,逆文檔頻率)兩部分組成。IDF反映的是一個詞能將當前文本與其它文本區分開的能力orm
TF:xml
其中分子 nij表示詞 ii在文檔 j 中出現的頻次。分母則是全部詞頻次的總和,也就是全部詞的個數。htm
舉個例子:
句子1:上帝/是/一個/女孩
句子2:桌子/上/有/一個/蘋果
每一個句子中詞語的 TF :
IDF:
其中 |D|表明文檔的總數,分母部分 |Di|則是表明文檔集中含有 i 詞的文檔數。原始公式是分母沒有 +1 的,這裏 +1 是採用了拉普拉斯平滑,避免了有部分新的詞沒有在語料庫中出現而致使分母爲零的狀況出現。
最後,把 TF 和 IDF 兩個值相乘就能夠獲得 TF-IDF 的值。即:
把每一個句子中每一個詞的 TF-IDF 值 添加到向量表示出來就是每一個句子的 TF-IDF 特徵。
在 Python 當中,咱們能夠經過 scikit-learn 來分別實現詞袋模型以及 TF-IDF 模型。而且,使用 scikit-learn 庫將會很是簡單。這裏要用到 CountVectorizer()
類以及 TfidfVectorizer()
類。
看一下兩個類的參數:
#詞袋 sklearn.featur_extraction.text.CountVectorizer(min_df=1, ngram_range=(1,1))
min_df
:忽略掉詞頻嚴格低於定閾值的詞ngram_range
:將 text 分紅 n1,n1+1,……,n2個不一樣的詞組。好比好比'Python is useful'中ngram_range(1,3)以後可獲得 'Python' , 'is' , 'useful' , 'Python is' , 'is useful' , 'Python is useful'。若是是ngram_range (1,1) 則只能獲得單個單詞'Python' , 'is' , 'useful'。#Tf-idf sklearn.feature_extraction.text.TfidfVectorizer(min_df=1,norm='l2',smooth_idf=True,use_idf=True,ngram_range=(1,1))
min_df
: 忽略掉詞頻嚴格低於定閾值的詞。norm
:標準化詞條向量所用的規範。smooth_idf
:添加一個平滑 idf 權重,即 idf 的分母是否使用平滑,防止0權重的出現。use_idf
: 啓用 idf 逆文檔頻率從新加權。ngram_range
:同詞袋模型python代碼實現:
詞袋:
from sklearn.feature_extraction.text import CountVectorizer vectorizer = CountVectorizer(min_df=1, ngram_range=(1, 1)) #創建文本庫 corpus = ['This is the first document.', 'This is the second second document.', 'And the third one.', 'Is this the first document?'] #訓練數據 corpus 得到詞袋特徵 a = vectorizer.fit_transform(corpus) #查看詞的排列形式 vectorizer.get_feature_names() a.toarray()
tf-idf
from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer( min_df=1, norm='l2', smooth_idf=True, use_idf=True, ngram_range=(1, 1)) #用 TF-IDF 類去訓練上面同一個 corpus b = vectorizer.fit_transform(corpus)
須要注意的是 b
這個特徵矩陣是以稀疏矩陣的形式存在的,使用 Compressed Row Storage 格式存儲,也就是這個特徵矩陣的信息是被壓縮了。
爲何要這麼作呢?由於在實際運用是文本數據量是很是大的,若是完整的存儲會消耗大量的內存,所以會將其壓縮存儲。可是仍然能夠像 numpy 數組同樣取特徵矩陣中的數據。