数据的特征工程
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 數據的特征工程
1 什么是數據的特征工程
特征工程是將原始數據轉換為更好地代表預測模型的潛在問題的特征的過程,從而提高了對未知數據的模型準確性。
特征工程的意義:將直接影響模型的預測結果。
2 數據的來源與類型
2.1 數據的來源
企業日益積累的大量數據,各大機構的實驗數據等等。總之數據無處不在,大都是可用的。
2.2 數據的類型
按照機器學習的數據分類分成:
? ? ? ? ? ?標稱型:目標變量的結果只在有限目標集中取值,如真與假(標稱型目標變量主要用于分類)
? ? ? ? ? ?數值型:目標變量則可以從無限的數值集合中取值,如0.100,42.001等 (數值型目標變量主要用于回歸分析)
按照數據的本身分布特性:
? ? ? ? ? ?離散型:其數值只能用自然數或整數單位計算的則為離散變量.例如,班級人數、進球個數、是否是某個類別等等
? ? ? ? ? ?連續型:是指在指定區間內可以是任意一個數值,例如,票房數據、花瓣大小分布數據
總結:離散型是區間內不可分,連續型是區間內可分
3 數據特征的抽取
現實世界中多數特征都不是連續變量,比如分類、文字、圖像等,為了對非連續變量做特征表述,需要對這些特征做數學化表述,就是特征提取。
特征抽取針對非連續型數據,文本等進行特征值化,是為了計算機更好的去理解數據。
?sklearn.feature_extraction提供了特征提取的很多方法
3.1 分類(字典)特征變量抽取
類:sklearn.feature_extraction.DictVectorizer
語法:DictVectorizer(sparse=True,…) 將映射列表轉換為Numpy數組或scipy.sparse矩陣。sparse 是否轉換為scipy.sparse矩陣表示,默認開啟
| DictVectorizer.fit_transform(X,y) ? ? | 應用并轉化映射列表X,y為目標類型。X:字典或者包含字典的迭代器 返回值:返回sparse矩陣 |
| DictVectorizer.inverse_transform(X,[, dict_type]) | 將Numpy數組或scipy.sparse矩陣轉換為映射列表X:array數組或者sparse矩陣 返回值:轉換之前數據格式 |
| DictVectorizer.get_feature_names() | 返回類別名稱 |
| DictVectorizer.transform(X) | ? 按照原先的標準轉換 |
sparse矩陣:節約內存,方便讀取處理
使用流程:①實例化類DictVectorizer
②調用fit_transform方法輸入數據并轉換
| 舉例 | 結果 |
| from sklearn.feature_extraction import DictVectorizer dict = DictVectorizer() example = [{'city': '北京','temperature':30},{'city': '上海','temperature':35},{'city': '深圳','temperature':38}] data = dict.fit_transform(example) print(data) print(type(data)) | sparse矩陣:(0,1) 1.0 ?第一個行的第1個位置的值為1.0 |
| from sklearn.feature_extraction import DictVectorizer dict = DictVectorizer(sparse=False) example = [{'city': '北京','temperature':30},{'city': '上海','temperature':35},{'city': '深圳','temperature':38}] data = dict.fit_transform(example) print(data) print(type(data)) | 修改parse,轉換為ndarray矩陣 |
| from sklearn.feature_extraction import DictVectorizer dict = DictVectorizer() example = [{'city': '北京','temperature':30},{'city': '上海','temperature':35},{'city': '深圳','temperature':38}] data = dict.fit_transform(example).toarray() data1 = dict.inverse_transform(data) print(dict.get_feature_names()) print(data) print(type(data)) print(data1) |
3.2 one-hot編碼
如上圖所示的句為one-hot編碼,又稱為一位有效編碼,主要是采用N位狀態寄存器來對N個狀態進行編碼,每個狀態都由他獨立的寄存器位,并且在任意時候只有一位有效。one-hot編碼是分類變量作為二進制向量的表示。這首先要求將分類值映射到整數值。然后,每個整數值被表示為二進制向量,除了整數的索引之外,它都是零值,它被標記為1。
one-hot適用于處理離散型數據:在回歸,分類,聚類等機器學習算法中,特征之間距離的計算或相似度的計算是非常重要的,而我們常用的距離或相似度的計算都是在歐式空間的相似度計算。而我們使用one-hot編碼,將離散特征的取值擴展到了歐式空間,離散特征的某個取值就對應歐式空間的某個點。將離散型特征使用one-hot編碼,確實會讓特征之間的距離計算更加合理。比如,有一個離散型特征,代表工作類型,該離散型特征,共有三個取值,不使用one-hot編碼,其表示分別是x_1 = (1), x_2 = (2), x_3 = (3)。兩個工作之間的距離是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那么x_1和x_3工作之間就越不相似嗎。顯然這樣的表示,計算出來的特征的距離是不合理。那如果使用one-hot編碼,則得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那么兩個工作之間的距離就都是sqrt(2).即每兩個工作之間的距離是一樣的,顯得更合理。
one-hot有自己的意義,但是在機器學習中的意義就是為了把類別型的特征轉換成one-hot編碼格式利于進行分析
3.3 文本特征抽取
文本特征抽取就是對文本數據進行特征值化,應用于很多方面,比如說文檔分類、垃圾郵件分類和新聞分類。那么文本分類是通過詞是否存在、以及詞的概率(重要性)來表示。
類:sklearn.feature_extraction.text.CountVectorizer
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() | 返回值:單詞列表 |
流程:①實例化類CountVectorizer
②調用fit_transform方法輸入數據并轉換
注意返回格式,利用toarray()進行sparse矩陣轉換array數組或修改sparse屬性為false
| from sklearn.feature_extraction.text import CountVectorizervector = CountVectorizer()
content = ["use a class CountVectorizer good good study","in order to feature abstraction day day up"]
data = vector.fit_transform(content).toarray()
print(vector.get_feature_names())
print(data) 由結果可知,①統計文章中所有的詞,重復的值看做一次; ②對于每篇文章,在詞的列表中進行統計每個詞出現的次數 ③單個字母不統計 |
3.4 中文特征值化
中文的話要先進行分詞才能詳細的進行特征值化處理
中文特征值流程:
①準備句子,利用jieba.cut進行分詞
①實例化類CountVectorizer
②將分詞結果變成字符串當作fit_transform的輸入值
| from sklearn.feature_extraction.text import CountVectorizer
import jieba
vector = CountVectorizer()
#分詞
content1 = jieba.cut("好好學習天天向上")
content2 = jieba.cut("命運是掌握在自己手中的")
content3 = jieba.cut("我就是我,不一樣的煙花")
print(content1)
#轉換成列表,并拼接成字符串
c1 = ' '.join(list(content1))
c2 = ' '.join(list(content2))
c3 = ' '.join(list(content3))
data = vector.fit_transform([c1,c2,c3]).toarray()
print(vector.get_feature_names())
print(data) 單個字不統計 |
3.5 TF-IDF
TF(term frequency詞的頻率):統計每篇文章詞出現的次數
IDF(inverse document frequency逆文檔頻率):log(總文檔數量/該詞出現的文檔次數)
TF-IDF的主要思想是:如果某個詞或短語在一篇文章中出現的概率高, 并且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類。
TF-IDF作用:用以評估一字詞對于一個文件集或一個語料庫中的其中一份文件的重要程度。
類:sklearn.feature_extraction.text.TfidfVectorizer
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 TfidfVectorizer import jieba vector = TfidfVectorizer() #分詞 content1 = jieba.cut("好好學習天天向上") content2 = jieba.cut("命運是掌握在自己手中的") content3 = jieba.cut("我就是我,不一樣的煙花") print(content1) #轉換成列表,并拼接成字符串 c1 = ' '.join(list(content1)) c2 = ' '.join(list(content2)) c3 = ' '.join(list(content3)) data = vector.fit_transform([c1,c2,c3]).toarray() print(vector.get_feature_names()) print(data) |
?
4 數值型數據的特征預處理
通過特定的統計方法(數學方法)將數據轉換成算法要求的數據
類:sklearn. preprocessing
4.1 單個特征
4.1.1 歸一化
特點:通過對原始數據進行變換把數據映射到(默認為[0,1])之間。
歸一化首先在特征(維度)非常多的時候,可以防止某一維或某幾維對數據影響過大,也是為了把不同來源的數據統一到一個參考區間下,這樣比較起來才有意義,其次可以程序可以運行更快。 例如:一個人的身高和體重兩個特征,假如體重50kg,身高175cm,由于兩個單位不一樣,數值大小不一樣。如果比較兩個人的體型差距時,那么身高的影響結果會比較大,k-臨近算法會有這個距離公式。
注意:在特定場景下最大值最小值是變化的,另外,最大值與最小值非常容易受異常點影響,所以這種方法魯棒性較差,只適合傳統精確小數據場景。
類: ?sklearn.preprocessing.MinMaxScaler
語法:MinMaxScalar(feature_range=(0,1)…) 每個特征縮放到給定范圍(默認[0,1])
| MinMaxScalar.fit_transform(X) ? ? ? | X:numpy array格式的數據[n_samples,n_features] 返回值:轉換后的形狀相同的array |
流程:①實例化MinMaxScalar
②通過fit_transform轉換
4.1.2 標準化
特點:常用的方法是z-score標準化,通過對原始數據進行變換把數據變換到均值為0,標準差為1范圍內
它們可以通過現有的樣本進行估計,在已有的樣本足夠多的情況下比較穩定,適合嘈雜的數據場景
類:scikit-learn.preprocessing.StandardScaler
StandardScaler語法:StandardScaler(…) 處理之后每列來說所有數據都聚集在均值0附近標準差為1
常用方法:
| StandardScaler.fit_transform(X,y)?? | X:numpy array格式的數據[n_samples,n_features] 返回值:轉換后的形狀相同的array |
| StandardScaler.mean_ | 原始數據中每列特征的平均值 |
| StandardScaler.std_ | 原始數據每列特征的方差 |
流程:①實例化StandardScaler
②通過fit_transform轉換
歸一化與標準化對比:
歸一化:如果出現異常點,影響了最大值和最小值,那么結果顯然會發生改變;
標準化:如果出現異常點,由于具有一定數據量,少量的異常點對于平均值的影響并不大,從而方差改變較小。
?
4.1.3 缺失值
缺失值:由于各種原因,數據集包含缺少的值,通常編碼為空白,NaN或其他占位符。
缺失值的處理方法:①刪除:如果每列或者行數據缺失值達到一定的比例,建議放棄整行或者整列
②插補:可以通過缺失值每行或者每列的平均值、中位數來填充
有缺失值的數據集與scikit的分類器不兼容,它們假設數組中的所有值都是數字,并且都具有和保持含義。使用不完整數據集的基本策略是丟棄包含缺失值的整個行和/或列。然而,這是以丟失可能是有價值的數據(即使不完整)的代價。更好的策略是估算缺失值,即從已知部分的數據中推斷它們。
類:?sklearn.preprocessing.Imputer
語法:Imputer(missing_values='NaN', strategy='mean', axis=0) 完成缺失值插補
missing_values:integer or "NaN", optional (default="NaN")丟失值的占位符,對于編碼為np.nan的缺失值,使用字符串值“NaN”
strategy:string, optional (default="mean")插補策略,如果是“平均值”,則使用沿軸的平均值替換缺失值;如果為“中位數”,則使用沿軸的中位數替換缺失值;如果“most_frequent”,則使用沿軸最頻繁的值替換缺失
axis: integer, optional (default=0)插補的軸,如果axis = 0,則沿列排列,如果axis = 1,則沿行排列
| Imputer.fit_transform(X,y)?? | X:numpy array格式的數據[n_samples,n_features] 返回值:轉換后的形狀相同的array |
流程:①初始化Imputer,指定”缺失值”,指定填補策略,指定行或列。缺失值也可以是別的指定要替換的值
②調用fit_transform
| import numpy as np
from sklearn.preprocessing import Imputer
array = [[1, 2], [np.nan, 3], [4, 5]]
print(array)
imp = Imputer(missing_values="NaN",strategy="mean",axis=0)
data = imp.fit_transform(array)
print(data) numpy的數組中可以使用np.nan/np.NaN來代替缺失值,屬于float類型 ;如果是文件中的一些缺失值,可以替換成nan,通過np.array轉化成float型的數組即可 |
4.2 多個特征
4.2.1 降維
PCA(Principal component analysis),主成分分析。特點是保存數據集中對方差影響最大的那些特征,PCA極其容易受到數據中特征范圍影響,所以在運用PCA前一定要做特征標準化,這樣才能保證每維度特征的重要性等同。
本質:PCA是一種分析、簡化數據集的技術。
目的:是數據維數壓縮,盡可能降低原數據的維數(復雜度),損失少量信息。
作用:可以削減回歸分析或者聚類分析中特征的數量
類:sklearn.decomposition.PCA
語法:PCA(n_components=None) 將數據分解為較低維數空間。
相關參數
n_components: int, float, None or string:這個參數可以幫我們指定希望PCA降維后的特征維度數目。最常用的做法是直接指定降維到的維度數目,此時n_components是一個大于1的整數。我們也可以用默認值,即不輸入n_components,此時n_components=min(樣本數,特征數)
whiten: bool, optional (default False)判斷是否進行白化。所謂白化,就是對降維后的數據的每個特征進行歸一化。對于PCA降維本身來說一般不需要白化,如果你PCA降維后有后續的數據處理動作,可以考慮白化,默認值是False,即不進行白化
vd_solver:選擇一個合適的SVD算法來降維,一般來說,使用默認值就夠了。
常用方法
| PCA.fit_transform(X) ? ? ? | X:numpy array格式的數據[n_samples,n_features] 返回值:轉換后指定維度的array |
| import numpy as np from sklearn.decomposition import PCA nparray = np.array([[4,5,1,6],[7,1,5,2],[5,6,8,6]]) print(nparray) pca = PCA(n_components=3) data = pca.fit_transform(nparray) print(data) |
5 數據的特征選擇
特征選擇就是單純地從提取到的所有特征中選擇部分特征作為訓練集特征, 特征在選擇前和選擇后可以改變值、也不改變值,但是選擇后的特征維數肯 定比選擇前小,畢竟我們只選擇了其中的一部分特征。
特征選擇方法:Filter(過濾式):VarianceThreshold;Embedded(嵌入式):正則化、決策樹;Wrapper(包裹式)。
其中過濾式的特征選擇后,數據本身不變,而數據的維度減少。而嵌入式的特征選擇方法也會改變數據的值,維度也改變。Embedded方式是一種自動學習的特征選擇方法。
類:sklearn.feature_selection.VarianceThreshold
VarianceThreshold語法:VarianceThreshold(threshold = 0.0) 刪除所有低方差特征
常用方法:
| Variance.fit_transform(X,y) ? ? ? | X:numpy array格式的數據[n_samples,n_features] 返回值:訓練集差異低于threshold的特征將被刪除。 默認值是保留所有非零方差特征,即刪除所有樣本 中具有相同值的特征。 |
流程:①初始化VarianceThreshold,指定閥值方差
②調用fit_transform
| import numpy as np from sklearn.feature_selection import VarianceThreshold var = VarianceThreshold(1.0) nparray = np.array([[0,1,3,1],[2,1,0,1],[0,2,1,0]]) print(nparray) data = var.fit_transform(nparray) print(data) |
五 fit_transform(),fit(),transform()
特征工程的步驟:①實例化 (實例化的是一個轉換器類(Transformer))
②調用fit_transform(對于文檔建立分類詞頻矩陣,不能同時調用)
fit_transform():輸入數據直接轉換
fit():輸入數據但是不做事情,計算平均值方差等等
transform():進行數據的轉換
注意:fit_transform或fit后,如果還有數據需要轉換,直接調用transform就可以,不要再調用fit或者fit_transform了,因為再次調用fit標準就改了。
總結
- 上一篇: Spark2.x RPC解析
- 下一篇: 搜索引擎下拉食云速捷详细_下拉框优化才云