03_数据的特征抽取,sklearn特征抽取API,字典特征抽取DictVectorizer,文本特征抽取CountVectorizer,TF-IDF(TfidfVectorizer),详细案例
數據的特征抽取
A:特征抽取實例演示
通過演示得出結論:
- 特征抽取針對非連續型數據
- 特征抽取對文本等進行特征值化
注:特征值化是為了計算機更好的去理解數據。
B:sklearn特征抽取API
sklearn.feature_extraction模塊,可以用于從包含文本和圖片的數據集中提取特征,以便支持機器學習算法使用。
注意:Feature extraction與Feature Selection是完全不同的:前者將專有數據(文本或圖片)轉換成機器學習中可用的數值型特征;后者則是用在這些特征上的機器學習技術。
C:字典特征抽取
作用:對字典數據進行特征值化
類:sklearn.feature_extraction.DictVectorizer
以下來自:https://www.cnblogs.com/hufulinblog/p/10591339.html
將特征與值的映射字典組成的列表轉換成向量。
DictVectorizer通過使用scikit-learn的estimators,將特征名稱與特征值組成的映射字典構成的列表轉換成Numpy數組或者Scipy.sparse矩陣。
當特征的值是字符串時,這個轉換器將進行一個二進制One-hot編碼。One-hot編碼是將特征所有可能的字符串值構造成布爾型值。
例如:特征f有一個值ham,一個值spam,轉換后會變成兩個特征f=ham和f=spam.
注意:轉換器只會將字符串形式的特征轉換成One-hot編碼,數值型的不會轉換。
一個字典中樣本沒有的特征在結果矩陣中的值是0.
構造參數:
class sklearn.feature_extraction.DictVectorizer(dtype=<class‘numpy.float64’>, separator=’=’, sparse=True, sort=True)
dtype:callable, 可選參數, 默認為float。特征值的類型,傳遞給Numpy.array或者Scipy.sparse矩陣構造器作為dtype參數。
separator:string,可選參數,默認為"="。當構造One-hot編碼的特征值時要使用的分割字符串。分割傳入字典數據的鍵與值的字符串,生成的字符串會作為特征矩陣的列名。
sparse: boolearn, 可選參數,默認為True。transform是否要使用scipy產生一個sparse矩陣。DictVectorizer的內部實現是將數據直接轉換成sparse矩陣,如果sparse為False, 再把sparse矩陣轉換成numpy.ndarray型數組。
sort:boolearn,可選參數,默認為True。在擬合時是否要多feature_names和vocabulary_進行排序。
屬性:
vocabulary_: 特征名稱和特征索引的映射字典。
feature_names_: 一個包含所有特征名稱的,長度為特征名稱個數的列表。
方法:
fit(X,y=None): 計算出轉換結果中feature name與列索引之間的對照字典vocabulary_,同時會計算出特征名稱列表 feature_names_。這里的參數y沒有任何作用。(X:字典或者包含字典的迭代器,返回值:返回sparse矩陣)
fit_transform(X,y=None): 包含fit函數的功能,并且會將X轉換成矩陣。
get_feature_names(): 返回feature_names_ (返回類別名稱)
get_params(deep=True): 返回當前DictVectorizer對象的構造參數。
inverse_transform(X[,dict_type]): 將矩陣還原成特征字典列表。還原出來的字典跟原數據并不是完全一樣。傳入的X必須是這個DictVectorizer經過transform或者fit_transform產生的X。(X:array數組或者sparse矩陣,返回值:轉換之前數據格式)
restrict(support, indicies=False): 根據傳入的support參數,對特征矩陣進行篩選。
**set_params(params): 設置DictVectorizer的參數
transform(X): 將X轉換為numpy.ndarray或者Scipy.sparse (按照原先的標準轉換)
流程:
1、實例化類DictVectorizer。
2、調用fit_transform方法輸入數據并轉換。
案例1:
from sklearn.feature_extraction import DictVectorizerdef dictvec():"""字典數據抽取:return:"""#實例化dict = DictVectorizer(sparse=False)#調用fit_transformdata = dict.fit_transform([{'city': '北京','temperature': 100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature': 30}])print("--------------get_feature_names-----------------------------------------------")print(dict.get_feature_names())print("--------------data,含有該feature_names的為1,否則為0,最終的目標值是實際的值-----")print(data)print("--------------inverse_transform:通過特征抽取的結果還原原來的數據---------------")print(dict.inverse_transform(data))return Noneif __name__ == "__main__":dictvec()輸出結果:
--------------get_feature_names----------------------------------------------- ['city=上海', 'city=北京', 'city=深圳', 'temperature'] --------------data,含有該feature_names的為1,否則為0,最終的目標值是實際的值----- [[ 0. 1. 0. 100.] 0. 1. 0:表示有'city=北京'這個特征,'temperature'的值為100.[ 1. 0. 0. 60.][ 0. 0. 1. 30.]] --------------inverse_transform:通過特征抽取的結果還原原來的數據--------------- [{'city=北京': 1.0, 'temperature': 100.0}, {'city=上海': 1.0, 'temperature': 60.0}, {'city=深圳': 1.0, 'temperature': 30.0}]案例2:
from sklearn.feature_extraction import DictVectorizer# 設置sparse=False獲得numpy ndarray形式的結果 v = DictVectorizer(sparse=False) D = [{"foo": 1, "bar": 2}, {"foo": 3, "baz": 1}]# 對字典列表D進行轉換,轉換成特征矩陣 X = v.fit_transform(D) # 特征矩陣的行代表數據,列代表特征,0表示該數據沒有該特征 print(X) # 獲取特征列名 print(v.get_feature_names())# inverse_transform可以將特征矩陣還原成原始數據 print(v.inverse_transform(X) == D)# 直接進行轉換,不先進行擬合的話,無法識別新的特征 print(v.transform([{"foo": 4, "unseen_feature": 3}]))輸出結果:
[[2. 0. 1.][0. 1. 3.]] ['bar', 'baz', 'foo'] True [[0. 0. 4.]]配合特征選擇:
from sklearn.feature_extraction import DictVectorizer from sklearn.feature_selection import SelectKBest,chi2# 設置sparse=False獲得numpy ndarray形式的結果 v = DictVectorizer(sparse=False) D = [{"foo": 1, "bar": 2}, {"foo": 3, "baz": 1}]# 對字典列表D進行轉換,轉換成特征矩陣 X = v.fit_transform(D) # 特征矩陣的行代表數據,列代表特征,0表示該數據沒有該特征 print(X) # 獲取特征列名 print(v.get_feature_names())# 得到一個篩選器,使用卡方統計篩選出最好的2個特征 support = SelectKBest(chi2, k=2).fit(X, [0, 1])# 進行篩選,篩選的結果會自動覆蓋原有的特征矩陣 print(v.restrict(support.get_support())) print(v.get_feature_names())輸出結果為:
[[2. 0. 1.][0. 1. 3.]] ['bar', 'baz', 'foo'] DictVectorizer(dtype=<class 'numpy.float64'>, separator='=', sort=True,sparse=False) ['bar', 'foo']D:文本特征抽取
作用:對文本數據進行特征值化
類:sklearn.feature_extraction.text.CountVectorizer
CountVectorizer()函數只考慮每個單詞出現的頻率;然后構成一個特征矩陣,每一行表示一個訓練文本的詞頻統計結果。其思想是,先根據所有訓練文本,不考慮其出現順序,只將訓練文本中每個出現過的詞匯單獨視為一列特征,構成一個詞匯表(vocabulary list),該方法又稱為詞袋法(Bag of Words)。
CountVectorizer語法:
CountVectorizer(max_df=1.0,min_df=1,…)
-
返回詞頻矩陣
-
CountVectorizer.fit_transform(X,y)
X:文本或者包含文本字符串的可迭代對象
返回值:返回sparse矩陣 -
CountVectorizer.inverse_transform(X)
X: array數組或者sparse矩陣
**返回值:**轉換之前數據格式 -
CountVectorizer.get_feature_names()
**返回值:**單詞列表
流程:
1、實例化類CountVectorizer
2、調用fit_transform方法輸入數據并轉換
注意返回格式,利用toarray()進行sparse矩陣轉換array數組
案例:
from sklearn.feature_extraction.text import CountVectorizertexts = ["orange banana apple grape","banana apple apple","grape", "orange apple"] cv = CountVectorizer() cv_fit = cv.fit_transform(texts)print("------------cv.get_feature_names()-----------------") print(cv.get_feature_names()) """ 結果為: ['apple', 'banana', 'grape', 'orange'] """print("-----------------cv.vocabulary_--------------------") print(cv.vocabulary_) """ 結果是: {'orange': 3, 'banana': 1, 'apple': 0, 'grape': 2} 這里是根據首字母順序,將texts變量中所有單詞進行排序,按照單詞首字母排序的順序: apple 序號:0 banana 序號:1 grape 序號:2 orange 序號:3 """print("-----------------cv_fit----------------------------") print(cv_fit) """ 結果是:(0, 3) 1(0, 1) 1(0, 0) 1(0, 2) 1(1, 1) 1(1, 0) 2(2, 2) 1(3, 3) 1(3, 0) 1其中括號里面的第一列表示的是字符串的序號,以下針對第一列進行說明 0:表示字符串"orange banana apple grape" 1:表示字符串"banana apple apple" 2:表示字符串"grape" 3:表示字符串"orange apple"組合起來:(0, 3) 1 表示第一個字符串"orange banana apple grape"中出現orange的次數是1(0, 1) 1 表示第一個字符串"orange banana apple grape"中出現banana的次數是1依次類推(1, 0) 2 表示第一個字符串"banana apple apple"中出現apple的次數是2... """print("--------------cv_fit.toarray()---------------------") print(cv_fit.toarray()) """ 結果為: [[1 1 1 1][2 1 0 0][0 0 1 0][1 0 0 1]]可以理解為: {'orange': 3, 'banana': 1, 'apple': 0, 'grape': 2}'apple' 'banana' 'grape' 'orange' "orange banana apple grape" [[1 1 1 1] "banana apple apple" [ 2 1 0 0] "grape" [ 0 0 1 0] "orange apple" [ 1 0 0 1]]即行表示字符串,列表示單詞 """再如案例:
from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizerX_test = ['I am a student','You can’t even make this stuff up'] # stop_words=None表示不去掉停用詞,若改為stop_words='english'則去掉停用詞 count_vec=CountVectorizer(stop_words=None) #訓練count_vec中的屬性,并返回數組 arr = count_vec.fit_transform(X_test).toarray()print('vocabulary list:\n', count_vec.get_feature_names()) """ 輸出的結果為: ['am', 'can', 'even', 'make', 'student', 'stuff', 'this', 'up', 'you'] """print('result array:\n',arr) """ 輸出結果為:[[1 0 0 0 1 0 0 0 0] #這里表示am和student都出現了1次,其它的出現了0次[0 1 1 1 0 1 1 1 1]] #這里表示am和student沒出現,其它的單詞都出現了一次上面的數組的列對應:['am', 'can', 'even', 'make', 'student', 'stuff', 'this', 'up', 'you']上面的數組有兩行,表示有2段字符串 """print('vocabulary_:\n', count_vec.vocabulary_) """ 結果是:{'am': 0, 'student': 4, 'you': 8, 'can': 1, 'even': 2, 'make': 3, 'this': 6, 'stuff': 5, 'up': 7}0 4 8 1 等這些數值表示在單詞在count_vec.get_feature_names()的順序 """########################################################## ########## CountVectorizer同樣適用于中文 ################## ##########################################################X_test = ['中國 你 是 城市 都是 小區', '中國 你 小區 旅行 飲食 學校'] ## 默認將所有單個漢字視為停用詞; count_vec=CountVectorizer(token_pattern=r"(?u)\b\w\w+\b") arr = count_vec.fit_transform(X_test).toarray()print('vocabulary list:\n', count_vec.get_feature_names()) """ 輸出結果為: vocabulary list:['中國', '城市', '學校', '小區', '旅行', '都是', '飲食'] """print('result array:\n', arr) """ 輸出結果為: result array:[[1 1 0 1 0 1 0][1 0 1 1 1 0 1]] """print('vocabulary_:\n', count_vec.vocabulary_) """ 輸出結果為: vocabulary_:{'中國': 0, '城市': 1, '都是': 5, '小區': 3, '旅行': 4, '飲食': 6, '學校': 2} """再如:
# 文檔進行特征值化 # 導入包 from sklearn.feature_extraction.text import CountVectorizerdef countvec():"""對文本進行特征值化:return:"""cv = CountVectorizer()data = cv.fit_transform(["人生 苦短,我 喜歡 python","人生漫長,不用 python"])print(cv.get_feature_names())print(data.toarray())return Noneif __name__ == "__main__":countvec()輸出結果為:
['python', '不用', '人生', '人生漫長', '喜歡', '苦短'] [[1 0 1 0 1 1][1 1 0 1 0 0]]注意:不支持單個中文字
另外如果文本是一段連續的話,這時候就需要對中文進行分詞才能詳細的進行特征值化
中文分詞,使用:jieba分詞
下載:
使用方法:
import jieba jieba.cut("我是一個好程序員")注意:
返回值:詞語生成器案例:
from sklearn.feature_extraction.text import CountVectorizer import jieba def cutword():con1 = jieba.cut("今天很殘酷,明天更殘酷,后天很美好,但絕大部分是死在明天晚上,所以每個人不要放棄今天")con2 = jieba.cut("我們看到的從很遠星系來的光是在幾百萬年之前發出的,這樣當我們看到宇宙時,我們是在看它的過去。")con3 = jieba.cut("如果只用一種方式了解某樣事物,你就才會真正了解它。")# 轉換成列表content1 = list(con1)content2 = list(con2)content3 = list(con3)# 把列表轉換成字符串c1 = ' '.join(content1)c2 = ' '.join(content2)c3 = ' '.join(content3)return c1,c2,c3def hanzivec():"""中文特征值化:return:"""c1,c2,c3 = cutword()print("----------------------c1,c2,c3--------------------------------")print(c1,c2,c3)cv = CountVectorizer()data = cv.fit_transform([c1,c2,c3])print("----------------------get_feature_names:----------------------")print(cv.get_feature_names())print("----------------------data.toarray:---------------------------")print(data.toarray())return Noneif __name__ == "__main__":hanzivec()輸出結果:
----------------------c1,c2,c3-------------------------------- 今天 很 殘酷 , 明天 更 殘酷 , 后天 很 美好 , 但 絕大部分 是 死 在 明天 晚上 , 所以 每個 人 不要 放棄 今天 我們 看到 的 從 很 遠 星系 來 的 光是在 幾百萬年 之前 發出 的 , 這樣 當 我們 看到 宇宙 時 , 我們 是 在 看 它 的 過去 。 如果 只用 一種 方式 了解 某樣 事物 , 你 就 才 會 真正 了解 它 。 ----------------------get_feature_names:---------------------- ['一種', '不要', '之前', '了解', '事物', '今天', '光是在', '幾百萬年', '發出', '只用', '后天', '如果', '宇宙', '我們', '所以', '放棄', '方式', '明天', '星系', '晚上', '某樣', '殘酷', '每個', '看到', '真正', '絕大部分', '美好', '過去', '這樣'] ----------------------data.toarray:--------------------------- [[0 1 0 0 0 2 0 0 0 0 1 0 0 0 1 1 0 2 0 1 0 2 1 0 0 1 1 0 0][0 0 1 0 0 0 1 1 1 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 1 1][1 0 0 2 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0]]TF-IDF
**TF-IDF的主要思想是:**如果某個詞或短語在一篇文章中出現的概率高,并且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類。
TF-IDF作用:用以評估一個字詞對于一個文件集或一個語料庫中的其中一份文件的重要程度。
類:sklearn.feature_extraction.text.TfidfVectorizer
語法:
TfidfVectorizer(stop_words=None,…)
- 返回詞的權重矩陣
TfidfVectorizer.fit_transform(X,y)
- **X:**文本或者包含文本字符串的可迭代對象
- **返回值:**返回sparse矩陣
TfidfVectorizer.inverse_transform(X)
X: array數組或者sparse矩陣
返回值: 轉換之前數據格式
TfidfVectorizer.get_feature_names()
**返回值:**單詞列表
案例:
from sklearn.feature_extraction.text import TfidfVectorizerX_test = ['中國 你 是 城市 都是 小區', '中國 你 小區 旅行 飲食 學校']# 默認將所有單個漢字視為停用詞: tfidf_vec=TfidfVectorizer(token_pattern=r"(?u)\b\w\w+\b") arr = tfidf_vec.fit_transform(X_test).toarray()print('vocabulary list:\n',tfidf_vec.get_feature_names()) """ 輸出結果: 下面相當于是特征值 vocabulary list:['中國', '城市', '學校', '小區', '旅行', '都是', '飲食'] """print('result array:\n',arr) """ 下面的列代表是:['中國', '城市', '學校', '小區', '旅行', '都是', '飲食'] 下面矩陣中有兩行,即詞的權重矩陣。 result array:[[0.40993715 0.57615236 0. 0.40993715 0. 0.57615236 0. ][0.35520009 0. 0.49922133 0.35520009 0.49922133 0. 0.49922133]] """機器學習原理這本書的介紹:
詞頻-逆向文件頻率(TF-IDF)是一種在文本挖掘中廣泛使用的特征向量化方法,它可以體現一個文檔中詞語在語料庫中的重要程度。
詞語由t表示,文檔由d表示,語料庫由D表示。詞頻TF(t,d)是詞語t在文檔d中出現的次數。文件頻率DF(t,D)是包含詞語的文檔的個數。如果我們只使用詞頻來衡量重要性,很容易過度強調在文檔中經常出現而并沒有包含太多與文檔有關的信息的詞語,比如“a”,“the”以及“of”。如果一個詞語經常出現在語料庫中,它意味著它并沒有攜帶特定的文檔的特殊信息。逆向文檔頻率數值化衡量詞語提供多少信息:
其中,|D|是語料庫中的文檔總數。由于采用了對數,如果一個詞出現在所有的文件,其IDF值變為0。
TFIDF(t,d,D)=TF(t,d) *
總結
以上是生活随笔為你收集整理的03_数据的特征抽取,sklearn特征抽取API,字典特征抽取DictVectorizer,文本特征抽取CountVectorizer,TF-IDF(TfidfVectorizer),详细案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 02_混淆矩阵、准确率(Accuracy
- 下一篇: 04_机器学习概述,什么是机器学习,应用