Hike News
Hike News

機器學習-特徵工程-文本特徵抽取

文本特徵抽取

  • 文本數據進行特徵值化
    • 單詞出現的次數作為特徵對文本進行特徵值化
  • 使用sklearn.feature_extraction.text.CountVectorizer
  • 應用場景:文本分類、情感分析

CountVectorizer(stop_words=[])

  • 統計每個樣本特徵詞出現的個數
  • 返回詞頻矩陣
  • 可統計中文(但以空格作為分詞的依據),但不支持單個中文字
    • 需自己將詞跟詞之間以空格分開
    • 進行自動分詞處理(jieba)
  • stop_words:停用詞
    • 對文本分類沒有好處的單詞列表
    • stop_words = [is,am,are,to]
    • 可google停用詞表

fit_transform(X)

X: 文本或者包含文本字符串的可迭代對象
返回值: 返回sparse矩陣

  • 使用效果:
  1. 統計所有文本中所有的詞,重複的只看作一次(單個字母不統計 [沒有分類依據])
  2. 對每篇文章,在此的列表裡進行統計每個詞的出現次數並返回矩陣

get_feature_names()

返回值: 為一列表存放文章所出現的單詞

1
2
3
4
5
['an', 'apple', 'away', 'bird', 
'bridge', 'bush', 'come', 'cross',
'day', 'doctor', 'hand', 'in', 'is',
'it', 'keeps', 'that', 'the', 'to',
'two', 'we', 'when', 'worth']

inverse_transform(X)

X: array陣列或者sparse矩陣
返回值: 轉換之前數據格式

流程

  1. 實例化類CountVectorizer
  2. 調用fit_transform方法輸入數據並轉換
  • 注意返回格式,利用toarray()進行sparse矩陣轉換array陣列

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from sklearn.feature_extraction.text import CountVectorizer

textData = [
"an apple a day keeps the doctor away",
"a bird in the hand is worth two the bush",
"cross that bridge when we come to it"
]

#對文本進行特徵值化
def countvec():

# 實例化
cv = CountVectorizer()

# 調用fit_transform
cv_data = cv.fit_transform(textData)

print(cv_data)

if __name__ == '__main__':
countvec()

返回sparse矩陣

1
2
3
4
5
6
7
8
  (0, 2)	1
(0, 9) 1
(0, 16) 1
(0, 14) 1
(0, 8) 1
...
...
...

得到一般矩陣

  • 須調用sparse矩陣的toarray()方法 —-> cv_data.toarray()
    1
    2
    3
    [[1 1 1 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 0]
    [0 0 0 1 0 1 0 0 0 0 1 1 1 0 0 0 2 0 1 0 0 1]
    [0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 1 0 1 0 1 1 0]]

中文分詞處理(jieba)

須對中文文本進行特徵抽取的前處理

下載

1
pip3 install jieba

使用

1
2
import jieba
new_text = jieba.cut("我熱愛機器學習")

tips

返回值:詞語產生器(generator)

  1. 用list()方法得到分詞的結果
    new_text = list(new_text)
  2. 再用join()方法拼出整句
    new_text = " ".join(new_text)

tf-idf分析

在進行文章分類時,不管是那種類型的文章常常會出現一些比較中性的詞語,例如:所以 就是 我們 明天…等
當這些中性詞語頻繁出現在幾篇文章時,我們不能說文章的性質是一樣的
因此要解決此問題會需要用到tf-idf分析(term frequency–inverse document frequency)

TF-IDF的主要思想:如果某個詞或短語在一篇文章中出現的概率較高,並且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類

作用

用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度
其所做的事情如下

  1. 統計每個詞出現的次數(詞頻[tf], term frequency)
  2. 逆文檔頻率[inverse document frequency]
  • 是一個詞語普遍重要性的度量
  • 其值越小代表此單詞越接近中性
  • 計算詞重要性程度:tf x idf (其值越高表示 單詞代表此文章分類的意義越大)

文本特徵抽取-Tfidf

  • 應用場景:自然語言處理、情感分析等
  • 使用sklearn.feature_extraction.text.TfidfVectorizer

TfidfVectorizer(stop_words=None,…)

  • 返回詞的重要性權重矩陣

fit_transform(X)

  • X: 文本或者包含文本字符串的可迭代物件
  • 返回值: 返回sparse矩陣

inverse_transform(X)

  • X: array數組或者sparse矩陣
  • 返回值: 轉換之前的數據格式

get_feature_names()

  • 返回值:單詞列表

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer

Text_Data = ["ㄧ個人的快樂, 不是因為他擁有的多,而是因為他計較得少。",
"人的心地是一畦田,土地沒有播下好種子,也長不出好的果實。",
"人生的煩惱,是不分貧富貴賤的,透過煩惱轉成智慧,這個煩惱才有意義。",
"真正的快樂是施捨後的那份清靜、安慰與喜悅。"]
NewTextData = []

def jieba_cut():
for text in Text_Data:
split_result = list(jieba.cut(text))
sentence = " ".join(split_result)
NewTextData.append(sentence)

def tfidfvec():

# 實例化
tfidf = TfidfVectorizer()

# 調用fit_transform
trans_data = tfidf.fit_transform(NewTextData)

print(trans_data)


if __name__ == '__main__':
jieba_cut()
tfidfvec()

返回sparse矩陣

1
2
3
4
5
6
7
8
9
10
  (0, 9)	0.2685092134645423
(0, 2) 0.34056989045654285
(0, 5) 0.6811397809130857
(0, 11) 0.34056989045654285
(0, 21) 0.34056989045654285
(0, 22) 0.34056989045654285
(1, 8) 0.3535533905932738
(1, 18) 0.3535533905932738
...
...

得到一般矩陣

  • trans_data.toarray()
1
2
3
4
5
6
7
8
9
10
11
[[0.         0.         0.34056989 0.         0.         0.68113978
0. 0. 0. 0.26850921 0. 0.34056989
0. 0. 0. 0. 0. 0.
0. 0. 0. 0.34056989 0.34056989 0.
0. 0. 0. 0. 0. ]
[0.35355339 0. 0. 0. 0. 0.
...
...

0. 0.42176478 0. 0. 0. 0.
0. 0. 0. 0. 0.42176478]]