【自然語言處理】【scikit-learn】文字特徵提取
詞袋錶示
文字分析是機器學習演算法的主要應用領域。 然而,原始資料,一串符號序列不能直接送到演算法本身,因為大多數演算法期望具有固定大小的數字特徵向量而不是具有可變長度的原始文字文件。
為了解決這個問題,scikit-learn提供了從文字內容中提取數字特徵的最常用方法的實用程式,即:
- 標記字串,為每個可能的標記給定整數id,例如通過使用空格和標點符號作為標記分隔符。
- 計算每個文件中標記的出現次數。
- 對在大多數樣本/檔案中出現的標記標準化並通過減少重要性的加權處理。
在該方案中,特徵和樣本定義如下:
• 每個標記發生頻率(標準化或不標準化)被視為特徵。
• 給定文件的所有標記頻率的向量被認為是多變數樣本
因此,文件語料庫可以由矩陣表示,出現在語料庫中的每個文件作為一行,每個標記作為一列(例如,單詞)。
我們將向量化稱為將文字文件集合轉換為數字特徵向量的一般過程。 這種特定的策略(標記化,計數和標準化)被稱為詞袋或“Bag of n-gram”表示。 文件由單詞出現描述,同時完全忽略文件中單詞的相對位置資訊。
稀疏性
由於大多數文件通常使用語料庫中所使用字的非常小的子集,因此得到的矩陣將具有許多零(通常超過99%)特徵值。 例如,10,000個短文字文件(例如電子郵件)的集合將使用總數為100,000個唯一單詞的詞彙表,而每個文件將單獨使用100到1000個唯一單詞。
為了能夠將這樣的矩陣儲存在儲存器中以及加速代數運算矩陣/向量,通常實現將使用稀疏的表示,例如scipy.sparse包中可用的實現。
常見的Vectorizer用法
CountVectorizer在單個類中實現標記化和出現次數計數:
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
>>> corpus = [
... 'This is the first document.',
... 'This is the second second document.',
... 'And the third one.',
... 'Is this the first document?',
... ]
>>> X = vectorizer.fit_transform(corpus)
>>> X
<4x9 sparse matrix of type '<... 'numpy.int64'>'
with 19 stored elements in Compressed Sparse ... format>
預設配置通過提取至少2個字母的單詞來標記字串。
因此,在將來對變換方法的呼叫中,將完全忽略在訓練語料庫中未看到的單詞:
>>> vectorizer.transform(['Something completely new.']).toarray()
...
array([[0, 0, 0, 0, 0, 0, 0, 0, 0]]...)
在擬合期間由分析器找到的每個項被賦予對應於結果矩陣中的列的唯一整數索引。
>>> vectorizer.get_feature_names() == (
... ['and', 'document', 'first', 'is', 'one',
... 'second', 'the', 'third', 'this'])
True
>>> X.toarray()
array([[0, 1, 1, 1, 0, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 2, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 1, 1, 0],
[0, 1, 1, 1, 0, 0, 1, 0, 1]]...)
Tf-idf術語加權
在大型文字語料庫中,一些單詞將非常常見(例如,英語中的“the”,“a”,“is”)因此攜帶關於文件的實際內容的非常少的有意義的資訊。 如果我們將直接計數資料直接地提供給分類器,那麼非常頻繁的術語會影響更稀有但更有趣的術語的頻率。
為了將計數特徵重新加權為適合分類器使用的浮點值,使用tf-idf變換是很常見的。
Tf表示術語頻率,而tf-idf表示術語頻率乘以逆文件頻率:
tf-idf(t,d)= tf(t,d)×idf(t)
每行被標準化為具有單位歐幾里德範數:
vnorm=v|v|2=vv12+v22+⋯+vn2
由於tf-idf經常用於文字特徵,因此還有另一個名為TfidfVectorizer的類,它將CountVectorizer和TfidfTransformer的所有選項組合在一個模型中:
讓我們舉一個例子來說明以下幾點。 第一個詞在100%的時間內出現,因此不是很有趣。
另外兩個功能僅在不到50%的時間內,因此可能更能代表文件的內容:
>>> counts = [[3, 0, 1],
... [2, 0, 0],
... [3, 0, 0],
... [4, 0, 0],
... [3, 2, 0],
... [3, 0, 2]]
...
>>> tfidf = transformer.fit_transform(counts)
>>> tfidf
<6x3 sparse matrix of type '<... 'numpy.float64'>'
with 9 stored elements in Compressed Sparse ... format>
>>> tfidf.toarray()
array([[ 0.81940995, 0. , 0.57320793],
[ 1. , 0. , 0. ],
[ 1. , 0. , 0. ],
[ 1. , 0. , 0. ],
[ 0.47330339, 0.88089948, 0. ],
[ 0.58149261, 0. , 0.81355169]])
random使用(附)
random.seed(a=None)
初始化隨機數生成器的內部狀態。
當前時間或作業系統特定隨機源(如果可用)中沒有或沒有引數種子(有關可用性的詳細資訊,請參閱os.urandom()函式)。
如果a不是None或int或long,則使用hash(a)代替。 請注意,啟用PYTHONHASHSEED時,某些型別的雜湊值是不確定的。