Hike News
Hike News

機器學習-特徵工程-特徵抽取(feature extraction)

機器學習

機器學習是從數據(data)中自動分析獲得模型(model),並利用規律對未知的數據進行預測(predict)

one-hot 編碼

  • 不讓不同的特徵(皮膚顏色:黃、黑、白, 性別:男、女)之間有優先級之分
  • 把不同類別的特徵轉換為以下形式,利於進行分析
Sample\皮膚顏色
1 0 1 0
2 1 0 0
3 0 0 1

特徵抽取(feature extraction)

特徵抽取是對文本等數據進行特徵值化

  • 特徵值化是為了計算機更好的去理解數據

sklearn特徵抽取API

  • 使用sklearn.feature_extraction

字典特徵抽取

字典數據進行特徵值化

  • 把字典中一些類別的數據,分別轉換成特徵
  • 使用sklearn.feature_extraction.DictVectorizer

DictVectorizer(sparse=True,…)

  • sparse矩陣(節約內存,方便讀取處理)
  • sparse=False時則返回一般矩陣(ndarray type)
fit_transform(X)

使用此方法就能將一個字典數據化

  • X: 字典或者包含字典的迭代器
  • 返回值: 返回sparse矩陣
inverse_transform(X)
  • X: array陣列或者sparse矩陣
  • 返回值: 轉換之前的數據格式(將陣列轉回原本的字典,形式會改變)
1
2
3
4
[{'city=Taipei': 1.0, 'temperature': 35.0}, 
{'city=Tainan': 1.0, 'temperature': 32.0},
{'city=Nantou': 1.0, 'temperature': 30.0},
{'city=Chiayi': 1.0, 'temperature': 31.0}]
get_feature_names()
  • 返回類別的名稱
1
2
3
4
5
['city=Chiayi', 
'city=Nantou',
'city=Tainan',
'city=Taipei',
'temperature']
transform(X)
  • 按照原先的標準轉換

流程

  1. 實例化類DictVectorizer
  2. 調用fit_transform方法輸入數據並轉換
  • 注意返回格式為sparse矩陣

Example

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

dictData = [
{"city":"Taipei","temperature":35},
{"city":"Tainan","temperature":32},
{"city":"Nantou","temperature":30},
{"city":"Chiayi","temperature":31},
]

#字典數據抽取
def dictvec():

# 實例化
dict = DictVectorizer()

# 調用fit_transform
trans_data = dict.fit_transform(dictData)

print(trans_data)

if __name__ == '__main__':
dictvec()
sparse = True(預設)

結果返回sparse矩陣

1
2
3
4
5
6
7
8
(0, 3)	1.0
(0, 4) 35.0
(1, 2) 1.0
(1, 4) 32.0
(2, 1) 1.0
(2, 4) 30.0
(3, 0) 1.0
(3, 4) 31.0

  • sparse矩陣較節約內存,方便進行處理
  • 前面的元組為第幾行,第幾列的值
sparse = False

DictVectorizer(sparse=False),返回ndarray(一般矩陣)

1
2
3
4
[[ 0.  0.  0.  1. 35.]
[ 0. 0. 1. 0. 32.]
[ 0. 1. 0. 0. 30.]
[ 1. 0. 0. 0. 31.]]


文本特徵抽取

  • 文本數據進行特徵值化
  • 使用sklearn.feature_extraction.text.CountVectorizer
  • 應用場景:文本分類、情感分析

CountVectorizer()

  • 返回詞頻矩陣
  • 可統計中文(但以空格作為分詞的依據),需進行分詞處理(jieba)
fit_transform(X)

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

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

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

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']

流程

  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
jieba.cut("我熱愛機器學習")

tips

返回值:詞語產生器

  • 用list()方法得到分詞的結果
  • 再用join()方法拼出整句

tf-idf分析

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

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

作用

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

  1. 統計每個詞出現的次數(詞頻[tf], term frequency)
  2. 逆文檔頻率[inverse document frequency] –> log(總文檔數量/該詞出現的文檔數)
  • 其值越小代表此單詞越接近中性
  • 計算詞重要性程度:tf * 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]]