【机器学习入门】(10) 特征工程:特征抽取,字典特征抽取、文本特征抽取,附完整python代码
各位同學好,今天和大家介紹一下python機器學習中的特征工程。在將數據放入模型之前,需要對數據的一些特征進行特征抽取,方法有:
(1) 字典特征抽取?DictVectorizer(),(2) 文本特征抽取(英文單詞、中文字詞)?CountVectorizer(),(3) tf-idf 文本抽取?TfidfVectorizer()
由于模型訓練函數.fit() 函數只能傳入數值類型的特征值,因此我們需要將特征值中的文本類型轉換成數值類型。
1. 字典特征抽取
導入方法:?from sklearn.feature_extraction import DictVectorizer
字典向量化方法:?vect.fit_transform()
字典特征提取方法在前面的章節已經講述過,見下文2.3小節:【機器學習入門】(5) 決策樹算法實戰:sklearn實現決策樹,實例應用(沉船幸存者預測)附python完整代碼及數據集
這里再簡單復習一下。
首先我們定義一個由字典組成的列表,使用 vect?接收字典向量化方法,注意:傳入字典向量化方法的變量必須是一個由字典組成的列表,特征提取完成之后,返回sparse矩陣,通過.toarray()函數將sparse矩陣轉化成普通列表,便于觀察。獲取的特征名對應sparse矩陣轉換后的列表的列名。
#(1)字典特征抽取
# 定義一個由字典組成的列表
fruits = [{'fruits':'蘋果','price':5},{'fruits':'橘子','price':3.9},{'fruits':'菠蘿','price':8.5}]
# 導入字典特征抽取方法
from sklearn.feature_extraction import DictVectorizer
# 接收字典向量化方法
vect = DictVectorizer()
# 將列表傳入特征抽取方法,返回sparse矩陣,sparse矩陣只會記錄傳入的數據中,非0位置的值
result = vect.fit_transform(fruits)
# 將sparse矩陣轉換成數組形式,便于觀察
result_arr = result.toarray()
# 獲取sparse矩陣的每一列的特征名
result_names = vect.get_feature_names()
觀察sparse變成的數組,第0列表示橘子,第1列表示蘋果,第2列表示菠蘿,result_arr的第0行表示我們定義的fruits列表的第0行。我們定義的列表的第0行是蘋果,因此只有在sparse數組中的第1列計數為1。而price列是三個字典共有的key,因此都有值。
將字符串類型轉換成sparse數值矩陣之后我們就能將其放入模型進行訓練。
2. 文本特征提取
文本特征抽取應用于很多方面,比如文檔分類、垃圾郵件分類、新聞分類。文本分類是通過詞是否存在、以及詞的概率(重要性)來表示。
2.1 方法一:文檔中詞出現的個數
通過記錄字符串中某些單詞出現的個數。
導入方法:?from sklearn.feature_extraction.text import CountVectorizer
文本抽取方法:?vect.fit_transform()
2.1.1 對英文操作
對單詞的文檔抽取方法之前已經介紹過,見下文第1.4小節:【機器學習入門】(2) 樸素貝葉斯算法:原理、實例應用(文檔分類預測)附python完整代碼及數據集_小狄同學的博客-CSDN博客
這里再簡單復習一下。
首先,我們定義一個由兩個字符串組成的列表,使用vect接收文本抽取方法,將字符串列表傳入特征提取函數,得到一個sparse矩陣。
## 對英文操作
# 定義一個字符串
string = ['life is short, i need python, life is short','life is too long, i do not need python']
# 導入文本抽取方法
from sklearn.feature_extraction.text import CountVectorizer
# 接收方法
vect = CountVectorizer()
# 記錄字符串中單詞出現的次數,返回sparse矩陣
result = vect.fit_transform(string)
# 將sparse矩陣轉換成數組形式,便于觀察
result_arr = result.toarray()
# 獲取sparse矩陣的每一列的特征名
result_names = vect.get_feature_names()
sparse矩陣轉換后的result_arr列表的每一行分別代表兩個字符串,列代表res_names中的特征值名稱。矩陣第一列為'do'出現的次數,第一行代表第一個字符串,第二行代表第二個字符串。'do'在第一個字符串中沒有出現,在第二個字符串中出現了1次。'is'在第一個字符串中出現了2次,在第二個字符串中出現了1次。
2.1.2 對中文操作
如果想統計中文中某些詞出現的次數,首先要對中文進行分詞,這時需要第三方庫?jieba分詞
通過 pip install jieba 安裝,通過?import jieba 導入該庫,再自定義三個中文文檔。
# 安裝jieba庫
pip install jieba
# 導入jieba庫
import jieba
# 自定義中文句子
word1 = '黨的十九屆六中全會是在重要歷史關頭召開的一次具有重大歷史意義的會議。'
word2 = '民主不是裝飾品,不是用來做擺設的,而是要用來解決人民需要解決的問題的。'
word3 = '堅持黨的領導,堅持人民至上,堅持理論創新,堅持獨立自主,堅持中國道路。'
在文檔特征抽取時,中文的標點符號對于文檔分類沒有意義,我們需要把標點符號刪除,我們創建一個刪除中文標點的函數。
# 刪除所有的中文標點符號
punct = set(u'''!·~?。,:“”‘’@#¥%……&*()《》、|''')
fileterpunt = lambda s:''.join(filter(lambda x: x not in punct,s))
然后,以word1操作為例,使用jieba庫的切分方法 jieba.cut() 對刪除標點后的文檔進行切分,返回Token對象,將其轉換成列表list(),便于觀察。分完詞以后在每個詞后面加一個空格,再使用 ' '.join() 方法將字詞重新組合起來,形成一個新的字符串,這樣文本提取函數才能識別。
# 對中文word1去除標點并進行切分,返回Token對象
con1 = jieba.cut(fileterpunt(word1))
# 轉換成列表,便于觀察
con1_list = list(con1)
# 分完詞以后,需要將每個詞后面加一個空格,再拼接成字符串
con1 = ' '.join(con1_list)
到此,我們就完成了對中文字詞的切分,可以用來進行文本特征提取。以上是對word1的操作,word2和3的操作同理如下。
# 同理對word2和word3操作
con2 = ' '.join(jieba.cut(fileterpunt(word2)))
con3 = ' '.join(jieba.cut(fileterpunt(word3)))
接下來的文本提取方法和處理英文類似,我們使用?CountVectorizer() 方法對中文進行文本提取,返回 sparse 矩陣,如下。
# 文本提取
vect_chinese = CountVectorizer()
# 傳入剪切后的中文,返回sparse矩陣
result = vect_chinese.fit_transform([con1,con2,con3])
# 轉換成列表
result_list = result.toarray()
# 顯示每一列的特征名
result_names = vect_chinese.get_feature_names()
在三個文檔中,'一次' 這個詞在第一個字符串中出現了1次,在第二和三個字符串中出現了0次。
2.2 方法二:tf-idf文本抽取
方法介紹: tf-idf 文本抽取是一種用于信息檢索與文本挖掘的常用加權技術。td-idf 是一種統計方法,用以評估一個字詞對于一個文件集或一個語料庫中的其中一份文件的重要程度。
字詞的重要性隨著它在文件中出現的次數成正比增加,但同時會隨著他在語言庫中出現的頻數成反比下降。
比如,‘創新’ 這個詞在一篇文章中出現很多次,在其他文章中出現的比較少,說明‘創新’這個詞對于文章分類很重要。而 ‘我們’‘你好’ 等詞在一篇文章中出現了很多次,但在別的文件中也出現了很多次,該詞的重要程度也不高。
計算方法: (一篇文章的關鍵詞次數/一篇文章總字數) / log(文章總篇數/出現過關鍵詞的文章數)
假設現在總共有1000篇文章,‘民主’這個詞在500篇文章中出現了,并且A文章中總共有800個詞,‘民主’出現了12次,那么 ‘民主’對文章A的tf-idf 的值為:(12/800)/log(1000/500)。值越大說明越重要。
導入方法:?from sklearn.feature_extraction.text import TfidfVectorizer
tf-idf 特征抽取方法:?tfidf.fit_transform()
首先自定義三個文檔,以中文文檔為例,先刪除無意義的中文標點符號,再進行字詞切分 jieba.cut(),再將每個字詞后面加上一個空格,把字詞拼接再一起 ' '.join(),重新組合成字符串。
# 自定義文檔
document1 = '深刻總結我們黨一百年來團結帶領人民從勝利走向勝利的偉大歷程,教育引導全黨深刻認識紅色政權來之不易、新中國來之不易、中國特色社會主義來之不易,增強我們繼續前進的勇氣和力量;'
document2 = '深刻總結我們黨一百年來從小到大、從弱到強的成長歷程,教育引導全黨深刻認識加強黨的政治建設的重要性,增強全黨團結統一的自覺性和堅定性;'
document3 = '深刻總結我們黨一百年來加強自身建設、推進自我革命的偉大實踐,教育引導全黨深刻認識全面從嚴治黨的重要性和必要性,確保我們黨始終成為中國特色社會主義事業的堅強領導核心。'
# 由于是中文,所有需要進行文檔分詞操作
import jieba
# 除去標點符號的函數
punct = set(u'''!·~?。,:“”‘’@#¥%……&*()《》、|''')
fileterpunt = lambda s:''.join(filter(lambda x: x not in punct,s))
# 文檔分割后每個關鍵詞后面加空格,然后拼接在一起,重新組成一個字符串
document1 = ' '.join(jieba.cut(fileterpunt(document1)))
document2 = ' '.join(jieba.cut(fileterpunt(document2)))
document3 = ' '.join(jieba.cut(fileterpunt(document3)))
處理完成之后的中文文檔如下:?
通過sklearn庫使用 tfidf 方法進行文檔特征提取,接收tf-idf方法?TfidfVectorizer()?,將文檔組成的列表輸入到特征抽取函數中,返回sparse數值矩陣。
from sklearn.feature_extraction.text import TfidfVectorizer
# 接收tf-idf方法
tfidf = TfidfVectorizer()
# 輸入文檔,提取特征值并轉換,返回sparse矩陣
result = tfidf.fit_transform([document1,document2,document3])
# 轉換成列表便于觀察
result_array = result.toarray()
# 顯示特征名
result_names = tfidf.get_feature_names()
結果可見,'事業'這個詞在第三個文檔中的itfidf值為0.21,即重要度為0.21,在第一和二個文檔中的if-idf值為0,沒出現。
在我之前寫的樸素貝葉斯文檔分類案例中使用的是文檔抽取方法,也可以使用tfidf方法,感興趣的可以試一下。?
python完整代碼:
# 特征抽取
# 將數據放入模型之前,需要對數據的一些特征進行特征抽取#(1)字典特征抽取
# .fit() 函數只能傳入數值類型的特征值,因此我們需要將特征值中的文本類型轉換成數值類型# 定義一個由字典組成的列表
fruits = [{'fruits':'蘋果','price':5},{'fruits':'橘子','price':3.9},{'fruits':'菠蘿','price':8.5}]
# 導入字典特征抽取方法
from sklearn.feature_extraction import DictVectorizer
# 接收字典向量化方法
vect = DictVectorizer()
# 將列表傳入特征抽取方法,返回sparse矩陣,sparse矩陣只會記錄傳入的數據中,非0位置的值
result = vect.fit_transform(fruits)
# 將sparse矩陣轉換成數組形式,便于觀察
result_arr = result.toarray()
# 獲取sparse矩陣的每一列的特征名
result_names = vect.get_feature_names()# 觀察sparse變成的數組,第一列表示橘子,第一行表示我們定義的列表的第一行
# 我們定義的列表的第一行是蘋果,因此只有在第二列計數為1,橘子列和菠蘿列計數為0
# price列是三個字典共有的key,因此都有值# 將字符串類型轉換成sparse數值矩陣之后我們就能將其放入模型進行訓練#(2)文本特征抽取
# 文本特征抽取應用于很多方面,比如文檔分類、垃圾郵件分類、新聞分類。
# 文本分類是通過詞是否存在、以及詞的概率(重要性)來表示。# ==1== 文檔中詞出現的個數
# 記錄字符串中某些單詞出現的個數## 對英文操作
# 定義一個字符串
string = ['life is short, i need python, life is short','life is too long, i do not need python']
# 導入文本抽取方法
from sklearn.feature_extraction.text import CountVectorizer
# 接收方法
vect = CountVectorizer()
# 記錄字符串中單詞出現的次數,返回sparse矩陣
result = vect.fit_transform(string)
# 將sparse矩陣轉換成數組形式,便于觀察
result_arr = result.toarray()
# 獲取sparse矩陣的每一列的特征名
result_names = vect.get_feature_names()# 矩陣第一列為do,第一行代表第一個字符串,第二行代表第二個字符串。
# 表示do在第一個字符串中沒有出現,在第二個字符串中出現了1次## 對中文操作
# 如果想統計中文中某些詞出現的次數,首先要對中文進行分詞,這是需要第三方庫jieba分詞,通過 pip install jieba 安裝
# 導入jieba庫
import jieba
# 自定義中文句子
word1 = '黨的十九屆六中全會是在重要歷史關頭召開的一次具有重大歷史意義的會議。'
word2 = '民主不是裝飾品,不是用來做擺設的,而是要用來解決人民需要解決的問題的。'
word3 = '堅持黨的領導,堅持人民至上,堅持理論創新,堅持獨立自主,堅持中國道路。'# 文本抽取時,標點符號對于預測沒有意義,可以把標點刪除
# 刪除所有的中文標點符號
punct = set(u'''!·~?。,:“”‘’@#¥%……&*()《》、|''')
fileterpunt = lambda s:''.join(filter(lambda x: x not in punct,s))# 對中文word1去除標點并進行切分,返回Token對象
con1 = jieba.cut(fileterpunt(word1))
# 轉換成列表,便于觀察
con1_list = list(con1)
# 分完詞以后,需要將每個詞后面加一個空格,再拼接成字符串,這樣文本提取才能識別出來
con1 = ' '.join(con1_list)# 同理對word2和word3操作
con2 = ' '.join(jieba.cut(fileterpunt(word2)))
con3 = ' '.join(jieba.cut(fileterpunt(word3)))# 文本提取
vect_chinese = CountVectorizer()
# 傳入剪切后的中文,返回sparse矩陣
result = vect_chinese.fit_transform([con1,con2,con3])
# 轉換成列表
result_list = result.toarray()
# 顯示每一列的特征名
result_names = vect_chinese.get_feature_names()# ==2== tf-idf文本抽取# 自定義文檔
document1 = '深刻總結我們黨一百年來團結帶領人民從勝利走向勝利的偉大歷程,教育引導全黨深刻認識紅色政權來之不易、新中國來之不易、中國特色社會主義來之不易,增強我們繼續前進的勇氣和力量;'
document2 = '深刻總結我們黨一百年來從小到大、從弱到強的成長歷程,教育引導全黨深刻認識加強黨的政治建設的重要性,增強全黨團結統一的自覺性和堅定性;'
document3 = '深刻總結我們黨一百年來加強自身建設、推進自我革命的偉大實踐,教育引導全黨深刻認識全面從嚴治黨的重要性和必要性,確保我們黨始終成為中國特色社會主義事業的堅強領導核心。'
# 由于是中文,所有需要進行文檔分詞操作
import jieba
# 除去標點符號
punct = set(u'''!·~?。,:“”‘’@#¥%……&*()《》、|''')
fileterpunt = lambda s:''.join(filter(lambda x: x not in punct,s))
# 文檔分割后每個關鍵詞后面加空格,然后拼接在一起,重新組成一個字符串
document1 = ' '.join(jieba.cut(fileterpunt(document1)))
document2 = ' '.join(jieba.cut(fileterpunt(document2)))
document3 = ' '.join(jieba.cut(fileterpunt(document3)))# 導入sklearn庫的tfidf方法
from sklearn.feature_extraction.text import TfidfVectorizer
# 接收tf-idf方法
tfidf = TfidfVectorizer()
# 輸入文檔,提取特征值并轉換,返回sparse矩陣
result = tfidf.fit_transform([document1,document2,document3])
# 轉換成列表便于觀察
result_array = result.toarray()
# 顯示特征名
result_names = tfidf.get_feature_names()
總結
以上是生活随笔為你收集整理的【机器学习入门】(10) 特征工程:特征抽取,字典特征抽取、文本特征抽取,附完整python代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【机器学习入门】(8) 线性回归算法:正
- 下一篇: 【机器学习入门】(12) 特征工程:特征