特徵工程到底是什麼?
大概知道一些,但是不是很清楚領域內的知識是怎麼幫助特徵工程的呢?如果有例子就更好了。
轉自我的博文:使用sklearn做單機特徵工程目錄
1 特徵工程是什麼?
2 數據預處理2.1 無量綱化
2.1.1 標準化 2.1.2 區間縮放法 2.1.3 標準化與歸一化的區別 2.2 對定量特徵二值化 2.3 對定性特徵啞編碼 2.4 缺失值計算 2.5 數據變換3 特徵選擇 3.1 Filter3.1.1 方差選擇法
3.1.2 相關係數法 3.1.3 卡方檢驗 3.1.4 互信息法 3.2 Wrapper 3.2.1 遞歸特徵消除法 3.3 Embedded 3.3.1 基於懲罰項的特徵選擇法 3.3.2 基於樹模型的特徵選擇法4 降維4.1 主成分分析法(PCA)
4.2 線性判別分析法(LDA)5 總結6 參考資料1 特徵工程是什麼?有這麼一句話在業界廣泛流傳:數據和特徵決定了機器學習的上限,而模型和演算法只是逼近這個上限而已。那特徵工程到底是什麼呢?顧名思義,其本質是一項工程活動,目的是最大限度地從原始數據中提取特徵以供演算法和模型使用。通過總結和歸納,人們認為特徵工程包括以下方面:
特徵處理是特徵工程的核心部分,sklearn提供了較為完整的特徵處理方法,包括數據預處理,特徵選擇,降維等。首次接觸到sklearn,通常會被其豐富且方便的演算法模型庫吸引,但是這裡介紹的特徵處理庫也十分強大!
本文中使用sklearn中的IRIS(鳶尾花)數據集來對特徵處理功能進行說明。IRIS數據集由Fisher在1936年整理,包含4個特徵(Sepal.Length(花萼長度)、Sepal.Width(花萼寬度)、Petal.Length(花瓣長度)、Petal.Width(花瓣寬度)),特徵值都為正浮點數,單位為厘米。目標值為鳶尾花的分類(Iris Setosa(山鳶尾)、Iris Versicolour(雜色鳶尾),Iris Virginica(維吉尼亞鳶尾))。導入IRIS數據集的代碼如下:
from sklearn.datasets import load_iris
#導入IRIS數據集
iris = load_iris()
#特徵矩陣
iris.data
#目標向量
iris.target
通過特徵提取,我們能得到未經處理的特徵,這時的特徵可能有以下問題:
- 不屬於同一量綱:即特徵的規格不一樣,不能夠放在一起比較。無量綱化可以解決這一問題。
- 信息冗餘:對於某些定量特徵,其包含的有效信息為區間劃分,例如學習成績,假若只關心「及格」或不「及格」,那麼需要將定量的考分,轉換成「1」和「0」表示及格和未及格。二值化可以解決這一問題。
- 定性特徵不能直接使用:某些機器學習演算法和模型只能接受定量特徵的輸入,那麼需要將定性特徵轉換為定量特徵。最簡單的方式是為每一種定性值指定一個定量值,但是這種方式過於靈活,增加了調參的工作。通常使用啞編碼的方式將定性特徵轉換為定量特徵:假設有N種定性值,則將這一個特徵擴展為N種特徵,當原始特徵值為第i種定性值時,第i個擴展特徵賦值為1,其他擴展特徵賦值為0。啞編碼的方式相比直接指定的方式,不用增加調參的工作,對於線性模型來說,使用啞編碼後的特徵可達到非線性的效果。
- 存在缺失值:缺失值需要補充。
- 信息利用率低:不同的機器學習演算法和模型對數據中信息的利用是不同的,之前提到在線性模型中,使用對定性特徵啞編碼可以達到非線性的效果。類似地,對定量變數多項式化,或者進行其他的轉換,都能達到非線性的效果。
我們使用sklearn中的preproccessing庫來進行數據預處理,可以覆蓋以上問題的解決方案。
2.1 無量綱化無量綱化使不同規格的數據轉換到同一規格。常見的無量綱化方法有標準化和區間縮放法。標準化的前提是特徵值服從正態分布,標準化後,其轉換成標準正態分布。區間縮放法利用了邊界值信息,將特徵的取值區間縮放到某個特點的範圍,例如[0, 1]等。
2.1.1 標準化標準化需要計算特徵的均值和標準差,公式表達為:
使用preproccessing庫的StandardScaler類對數據進行標準化的代碼如下:
from sklearn.preprocessing import StandardScaler
#標準化,返回值為標準化後的數據
StandardScaler().fit_transform(iris.data)
2.1.2 區間縮放法
區間縮放法的思路有多種,常見的一種為利用兩個最值進行縮放,公式表達為:
使用preproccessing庫的MinMaxScaler類對數據進行區間縮放的代碼如下:
from sklearn.preprocessing import MinMaxScaler
#區間縮放,返回值為縮放到[0, 1]區間的數據
MinMaxScaler().fit_transform(iris.data)
2.1.3 標準化與歸一化的區別
簡單來說,標準化是依照特徵矩陣的列處理數據,其通過求z-score的方法,將樣本的特徵值轉換到同一量綱下。歸一化是依照特徵矩陣的行處理數據,其目的在於樣本向量在點乘運算或其他核函數計算相似性時,擁有統一的標準,也就是說都轉化為「單位向量」。規則為l2的歸一化公式如下:
使用preproccessing庫的Normalizer類對數據進行歸一化的代碼如下:
from sklearn.preprocessing import Normalizer
#歸一化,返回值為歸一化後的數據
Normalizer().fit_transform(iris.data)
2.2 對定量特徵二值化
定量特徵二值化的核心在於設定一個閾值,大於閾值的賦值為1,小於等於閾值的賦值為0,公式表達如下:
使用preproccessing庫的Binarizer類對數據進行二值化的代碼如下:
from sklearn.preprocessing import Binarizer
#二值化,閾值設置為3,返回值為二值化後的數據
Binarizer(threshold=3).fit_transform(iris.data)
2.3 對定性特徵啞編碼
由於IRIS數據集的特徵皆為定量特徵,故使用其目標值進行啞編碼(實際上是不需要的)。使用preproccessing庫的OneHotEncoder類對數據進行啞編碼的代碼如下:
from sklearn.preprocessing import OneHotEncoder
#啞編碼,對IRIS數據集的目標值,返回值為啞編碼後的數據
OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))
2.4 缺失值計算
由於IRIS數據集沒有缺失值,故對數據集新增一個樣本,4個特徵均賦值為NaN,表示數據缺失。使用preproccessing庫的Imputer類對數據進行缺失值計算的代碼如下:
from numpy import vstack, array, nan
from sklearn.preprocessing import Imputer
#缺失值計算,返回值為計算缺失值後的數據
#參數missing_value為缺失值的表示形式,默認為NaN
#參數strategy為缺失值填充方式,默認為mean(均值)
Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data)))
2.5 數據變換
常見的數據變換有基於多項式的、基於指數函數的、基於對數函數的。4個特徵,度為2的多項式轉換公式如下:
使用preproccessing庫的PolynomialFeatures類對數據進行多項式轉換的代碼如下:
from sklearn.preprocessing import PolynomialFeatures
#多項式轉換
#參數degree為度,默認值為2
PolynomialFeatures().fit_transform(iris.data)
基於單變元函數的數據變換可以使用一個統一的方式完成,使用preproccessing庫的FunctionTransformer對數據進行對數函數轉換的代碼如下:
from numpy import log1p
from sklearn.preprocessing import FunctionTransformer
#自定義轉換函數為對數函數的數據變換
#第一個參數是單變元函數
FunctionTransformer(log1p).fit_transform(iris.data)
3 特徵選擇
當數據預處理完成後,我們需要選擇有意義的特徵輸入機器學習的演算法和模型進行訓練。通常來說,從兩個方面考慮來選擇特徵:
- 特徵是否發散:如果一個特徵不發散,例如方差接近於0,也就是說樣本在這個特徵上基本上沒有差異,這個特徵對於樣本的區分並沒有什麼用。
- 特徵與目標的相關性:這點比較顯見,與目標相關性高的特徵,應當優選選擇。除方差法外,本文介紹的其他方法均從相關性考慮。
根據特徵選擇的形式又可以將特徵選擇方法分為3種:
- Filter:過濾法,按照發散性或者相關性對各個特徵進行評分,設定閾值或者待選擇閾值的個數,選擇特徵。
- Wrapper:包裝法,根據目標函數(通常是預測效果評分),每次選擇若干特徵,或者排除若干特徵。
- Embedded:集成法,先使用某些機器學習的演算法和模型進行訓練,得到各個特徵的權值係數,根據係數從大到小選擇特徵。類似於Filter方法,但是是通過訓練來確定特徵的優劣。
我們使用sklearn中的feature_selection庫來進行特徵選擇。
3.1 Filter3.1.1 方差選擇法使用方差選擇法,先要計算各個特徵的方差,然後根據閾值,選擇方差大於閾值的特徵。使用feature_selection庫的VarianceThreshold類來選擇特徵的代碼如下:
from sklearn.feature_selection import VarianceThreshold
#方差選擇法,返回值為特徵選擇後的數據
#參數threshold為方差的閾值
VarianceThreshold(threshold=3).fit_transform(iris.data)
3.1.2 相關係數法
使用相關係數法,先要計算各個特徵對目標值的相關係數以及相關係數的P值。用feature_selection庫的SelectKBest類結合相關係數來選擇特徵的代碼如下:
from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr
#選擇K個最好的特徵,返回選擇特徵後的數據
#第一個參數為計算評估特徵是否好的函數,該函數輸入特徵矩陣和目標向量,輸出二元組(評分,P值)的數組,數組第i項為第i個特徵的評分和P值。在此定義為計算相關係數
#參數k為選擇的特徵個數
SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
3.1.3 卡方檢驗
經典的卡方檢驗是檢驗定性自變數對定性因變數的相關性。假設自變數有N種取值,因變數有M種取值,考慮自變數等於i且因變數等於j的樣本頻數的觀察值與期望的差距,構建統計量:
不難發現,這個統計量的含義簡而言之就是自變數對因變數的相關性。用feature_selection庫的SelectKBest類結合卡方檢驗來選擇特徵的代碼如下:
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
#選擇K個最好的特徵,返回選擇特徵後的數據
SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)
3.1.4 互信息法
經典的互信息也是評價定性自變數對定性因變數的相關性的,互信息計算公式如下:
為了處理定量數據,最大信息係數法被提出,使用feature_selection庫的SelectKBest類結合最大信息係數法來選擇特徵的代碼如下:
from sklearn.feature_selection import SelectKBest
from minepy import MINE
#由於MINE的設計不是函數式的,定義mic方法將其為函數式的,返回一個二元組,二元組的第2項設置成固定的P值0.5
def mic(x, y):
m = MINE()
m.compute_score(x, y)
return (m.mic(), 0.5)
#選擇K個最好的特徵,返回特徵選擇後的數據
SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
3.2 Wrapper
3.2.1 遞歸特徵消除法遞歸消除特徵法使用一個基模型來進行多輪訓練,每輪訓練後,消除若干權值係數的特徵,再基於新的特徵集進行下一輪訓練。使用feature_selection庫的RFE類來選擇特徵的代碼如下:
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
#遞歸特徵消除法,返回特徵選擇後的數據
#參數estimator為基模型
#參數n_features_to_select為選擇的特徵個數
RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)
3.3 Embedded
3.3.1 基於懲罰項的特徵選擇法
使用帶懲罰項的基模型,除了篩選出特徵外,同時也進行了降維。使用feature_selection庫的SelectFromModel類結合帶L1懲罰項的邏輯回歸模型,來選擇特徵的代碼如下:
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
#帶L1懲罰項的邏輯回歸作為基模型的特徵選擇
SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(iris.data, iris.target)
實際上,L1懲罰項降維的原理在於保留多個對目標值具有同等相關性的特徵中的一個,所以沒選到的特徵不代表不重要。故,可結合L2懲罰項來優化。具體操作為:若一個特徵在L1中的權值為1,選擇在L2中權值差別不大且在L1中權值為0的特徵構成同類集合,將這一集合中的特徵平分L1中的權值,故需要構建一個新的邏輯回歸模型:
from sklearn.linear_model import LogisticRegression
class LR(LogisticRegression):
def __init__(self, threshold=0.01, dual=False, tol=1e-4, C=1.0,
fit_intercept=True, intercept_scaling=1, class_weight=None,
random_state=None, solver="liblinear", max_iter=100,
multi_class="ovr", verbose=0, warm_start=False, n_jobs=1):
#權值相近的閾值
self.threshold = threshold
LogisticRegression.__init__(self, penalty="l1", dual=dual, tol=tol, C=C,
fit_intercept=fit_intercept, intercept_scaling=intercept_scaling, class_weight=class_weight,
random_state=random_state, solver=solver, max_iter=max_iter,
multi_class=multi_class, verbose=verbose, warm_start=warm_start, n_jobs=n_jobs)
#使用同樣的參數創建L2邏輯回歸
self.l2 = LogisticRegression(penalty="l2", dual=dual, tol=tol, C=C, fit_intercept=fit_intercept, intercept_scaling=intercept_scaling, class_weight = class_weight, random_state=random_state, solver=solver, max_iter=max_iter, multi_class=multi_class, verbose=verbose, warm_start=warm_start, n_jobs=n_jobs)
def fit(self, X, y, sample_weight=None):
#訓練L1邏輯回歸
super(LR, self).fit(X, y, sample_weight=sample_weight)
self.coef_old_ = self.coef_.copy()
#訓練L2邏輯回歸
self.l2.fit(X, y, sample_weight=sample_weight)
cntOfRow, cntOfCol = self.coef_.shape
#權值係數矩陣的行數對應目標值的種類數目
for i in range(cntOfRow):
for j in range(cntOfCol):
coef = self.coef_[i][j]
#L1邏輯回歸的權值係數不為0
if coef != 0:
idx = [j]
#對應在L2邏輯回歸中的權值係數
coef1 = self.l2.coef_[i][j]
for k in range(cntOfCol):
coef2 = self.l2.coef_[i][k]
#在L2邏輯回歸中,權值係數之差小於設定的閾值,且在L1中對應的權值為0
if abs(coef1-coef2) &< self.threshold and j != k and self.coef_[i][k] == 0:
idx.append(k)
#計算這一類特徵的權值係數均值
mean = coef / len(idx)
self.coef_[i][idx] = mean
return self
使用feature_selection庫的SelectFromModel類結合帶L1以及L2懲罰項的邏輯回歸模型,來選擇特徵的代碼如下:
from sklearn.feature_selection import SelectFromModel
#帶L1和L2懲罰項的邏輯回歸作為基模型的特徵選擇
#參數threshold為權值係數之差的閾值
SelectFromModel(LR(threshold=0.5, C=0.1)).fit_transform(iris.data, iris.target)
3.3.2 基於樹模型的特徵選擇法
樹模型中GBDT也可用來作為基模型進行特徵選擇,使用feature_selection庫的SelectFromModel類結合GBDT模型,來選擇特徵的代碼如下:
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier
#GBDT作為基模型的特徵選擇
SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
4 降維
當特徵選擇完成後,可以直接訓練模型了,但是可能由於特徵矩陣過大,導致計算量大,訓練時間長的問題,因此降低特徵矩陣維度也是必不可少的。常見的降維方法除了以上提到的基於L1懲罰項的模型以外,另外還有主成分分析法(PCA)和線性判別分析(LDA),線性判別分析本身也是一個分類模型。PCA和LDA有很多的相似點,其本質是要將原始的樣本映射到維度更低的樣本空間中,但是PCA和LDA的映射目標不一樣:PCA是為了讓映射後的樣本具有最大的發散性;而LDA是為了讓映射後的樣本有最好的分類性能。所以說PCA是一種無監督的降維方法,而LDA是一種有監督的降維方法。
4.1 主成分分析法(PCA)使用decomposition庫的PCA類選擇特徵的代碼如下:
from sklearn.decomposition import PCA
#主成分分析法,返回降維後的數據
#參數n_components為主成分數目
PCA(n_components=2).fit_transform(iris.data)
4.2 線性判別分析法(LDA)
使用lda庫的LDA類選擇特徵的代碼如下:
from sklearn.lda import LDA
#線性判別分析法,返回降維後的數據
#參數n_components為降維後的維數
LDA(n_components=2).fit_transform(iris.data, iris.target)
5 總結
再讓我們回歸一下本文開始的特徵工程的思維導圖,我們可以使用sklearn完成幾乎所有特徵處理的工作,而且不管是數據預處理,還是特徵選擇,抑或降維,它們都是通過某個類的方法fit_transform完成的,fit_transform要不只帶一個參數:特徵矩陣,要不帶兩個參數:特徵矩陣加目標向量。這些難道都是巧合嗎?還是故意設計成這樣?方法fit_transform中有fit這一單詞,它和訓練模型的fit方法有關聯嗎?接下來,我將在《使用sklearn優雅地進行數據挖掘》中闡述其中的奧妙!
6 參考資料- FAQ: What is dummy coding?
- IRIS(鳶尾花)數據集
- 卡方檢驗
- 乾貨:結合Scikit-learn介紹幾種常用的特徵選擇方法
- 機器學習中,有哪些特徵選擇的工程方法?
- 機器學習中的數學(4)-線性判別分析(LDA), 主成分分析(PCA)
特徵工程是一個非常重要的課題,是機器學習中不可缺少的一部分,但是它幾乎很少出現於機器學習書本裡面的某一章。在機器學習方面的成功很大程度上在於如果使用特徵工程。
(I)特徵工程可以解決什麼樣的問題?
在機器學習中,經常是用一個預測模型(線性回歸,邏輯回歸,SVD等)和一堆原始數據來得到一些預測的結果,人們需要做的是從這堆原始數據中去提煉較優的結果,然後做到最優的預測。這個就包括兩個方面,第一就是如何選擇和使用各種模型,第二就是怎麼樣去使用這些原始的數據才能達到最優的效果。那麼怎麼樣才能夠獲得最優的結果呢?貼上一句經典的話就是:
Actually the sucess of all Machine Learning algorithms depends on how you present the data.
------ Mohammad Pezeshki直接翻譯過來便是:事實上所有機器學習演算法上面的成功都在於你怎麼樣去展示這些數據。由此可見特徵工程在實際的機器學習中的重要性,從數據裡面提取出來的特徵好壞與否就會直接影響模型的效果。從某些層面上來說,所使用的特徵越好,得到的效果就會越好。所需要的特徵就是可以藉此來描述已知數據的內在關係。總結一下就是:
Better feature means flexibility. Better feature means simpler models. Better feature means better results.
有的時候,可以使用一些不是最優的模型來訓練數據,如果特徵選擇得好的話,依然可以得到一個不錯的結果。很多機器學習的模型都能夠從數據中選擇出不錯的結構,從而進行良好的預測。一個優秀的特徵具有極強的靈活性,可以使用不那麼複雜的,運算速度快,容易理解和維護的模型來得到不錯的結果。
(II)什麼才是特徵工程?
Feature Engineering is the process of transforming raw data into features that better represent the underlying problem to the predictive models, resulting in improved model accuracy on unseen data.
------ Jason BrownleeFeature Engineering is manually designing what the input x"s should be.
------ Tomasz Malisiewicz從這個概念可以看出,特徵工程其實是一個如何展示和表現數據的問題,在實際工作中需要把數據以一種「良好」的方式展示出來,使得能夠使用各種各樣的機器學習模型來得到更好的效果。如何從原始數據中去除不佳的數據,展示合適的數據就成為了特徵工程的關鍵問題。
(III)特徵有用性的預估
每次構造了一個特徵,都需要從各個方面去證明該特徵的有效性。一個特徵是否重要主要在於該特徵與要預測的東西是否是高度相關的,如果是高度相關,那麼該特徵就是十分重要的。比如常用的工具就是統計學裡面的相關係數。
(IV)特徵的構造過程
在實際工作中首先肯定要確定具體的問題,然後就是數據的選擇和準備過程,再就是模型的準備和計算工作,最後才是展示數據的預測結果。構造特徵的一般步驟:
[1]任務的確定:根據具體的業務確定需要解決的問題;[2]數據的選擇:整合數據,收集數據;
[3]預處理數據:設計數據展現的格式,清洗數據,選擇合適的樣本使得機器學習模型能夠使用它。比方說一些年齡特徵是空值或者負數或者大於200等,或者說某個頁面的播放數據大於曝光數據,這些就是數據的不合理,需要在使用之前把這一批數據排除掉。
[4]特徵的構造:轉化數據,使之成為有效的特徵。常用的方法是標準化,歸一化,特徵的離散化等。
(4.1)標準化(Standardization):比方說有一些數字的單位是千克,有一些數字的單位是克,這個時候需要統一單位。如果沒有標準化,兩個變數混在一起搞,那麼肯定就會不合適。(4.2)歸一化(Normalization):歸一化是因為在特徵會在不同的尺度下有不同的表現形式,歸一化會使得各個特徵能夠同時以恰當的方式表現。比方說某個專輯的點擊播放率一般不會超過0.2,但是專輯的播放次數可能會達到幾千次,所以說為了能夠在模型裡面得到更合適結果,需要先把一些特徵在尺度上進行歸一化,然後進行模型訓練。(4.3)特徵的離散化(Discretization):離散化是指把特徵進行必要的離散處理,比方說年齡特徵是一個連續的特徵,但是把年齡層分成5-18歲(中小學生),19-23歲(大學生),24-29歲(工作前幾年),30-40歲(成家立業),40-60歲(中年人)從某些層面來說比連續的年齡數據(比如說某人年齡是20歲1月3日之類的)更容易理解不同年齡層人的特性。典型的離散化步驟:對特徵做排序-&> 選擇合適的分割點-&> 作出區間的分割 -&> 作出區間分割-&> 查看是否能夠達到停止條件。[5]模型的使用:創造模型,選擇合適的模型,用合適的模型來進行預測,用各種統計指標來判斷該特徵是否合適;
[6]上線的效果:通過在線測試來看效果。
數據的轉換(Transforming Data)就是把數據從原始的數據狀態轉換成適合模型計算的狀態,從某些層面上來說,「數據轉換「和」特徵構造「的過程幾乎是一致的。
(V)特徵工程的迭代過程
特徵工程的迭代步驟:[1]選擇特徵:需要進行頭腦風暴(brainstorm)。通過具體的問題分析,查看大量的數據,從數據中查看出可以提取出數據的關鍵;[2]設計特徵:這個需要具體問題具體分析,可以自動進行特徵提取工作,也可以進行手工進行特徵的構造工作,甚至混合兩種方法;[3]選擇特徵:使用不同的特徵構造方法,來從多個層面來判斷這個特徵的選擇是否合適;[4]計算模型:通過模型計算得到模型在該特徵上所提升的準確率。[5]上線測試:通過在線測試的效果來判斷特徵是否有效。關於特徵工程是什麼這個問題,我強烈推薦讀一篇文章:Discover Feature Engineering, How to Engineer Features and How to Get Good at It. 特徵工程大概包括兩個部分:特徵提取和特徵選擇。關於特徵選擇可以參見這個問題:機器學習中,有哪些特徵選擇的工程方法? - 知乎用戶的回答。一般來說,領域內的知識主要是應用在特徵提取。舉個例子的話,比如說基於內容的購物推薦,性別就是一個很重要的領域知識,男性和女性關注的物品差別就比較大,推薦也應該體現出這種差別,那麼這個特徵就是這個問題一個重要特徵,應該重點從已知數據提取,甚至專門為它再構建一個機器學習問題。
水裡沒有魚的情況下,再好的漁具也沒用,特徵工程就是找有魚的那片水域。
看到大家主要在談數據的預處理和特徵選擇,很少講到特徵提取。
提取特徵在不同領域差別較大,我儘可能抽象出一些通用的方法,總結了一點經驗,希望和大家交流~
如何提取特徵? - 知乎專欄
一.四類特徵
我將特徵分為四類:基本特徵,複雜特徵,統計特徵和自然特徵。
這裡的特徵設計主要針對非結構化數據,比如一個人的購物歷史,運營商通話記錄,位置的歷史記錄。當缺少領域知識無從下手的時候,可以從這四個方面來設計特徵。
首先是基本特徵,而後統計和複雜特徵層層遞進。其中針對圖像語音等抽提特徵有專用的知識方法,就不班門弄斧了。
掌握了這套特徵設計的思路,在複雜數據上幾乎可以設計出無窮無盡的特徵。而怎麼在最短的時間內,把數據中最有價值的特徵提煉出來,就要考驗數據挖掘工程師的功底。
二. 提取特徵思路
基本思路是2/8法則,要花20%的時間,做50%的特徵取得80%的效果。流程如下:
- 做經驗上最重要的
- 做容易做的
- 做可以批量產生的
- 觀察bad_case/good_feature,總結經驗回到1
我主要是分析人的行為數據,很大程度上要依賴生活經驗和領域知識。
將123步完成之後,通過數據去回歸特徵的效果,查看重要的特徵效果是否符合預期,不符合的話為什麼?怎麼修改?哪些意料之外的特徵很有效?對哪些人有效?為什麼?
在不斷的追問和查看數據的過程中,慢慢的積累領域知識和常識,形成自己的經驗,形成對目標客群的深入認識。
三.雜談
-經驗與偏見:
數據挖掘強調領域知識和常識經驗。但是不要用經驗生成一些很刻板的特徵。比如要找犯罪分子,經驗告訴你最近一個月刀具的人很可能是目標,製作特徵的時候,不妨把最近1/3/6/12個月購買過道具/化學藥品/火車票。。。。這一類相關的特徵都做出來,往往有新發現。要根據時間要求和對數據的熟悉程度,把握經驗思路和刻畫數據兩者的平衡。
-自動生成大量的特徵:
當你的數據量足夠大,可以嘗試著設計規則,自動生成大量的特徵。比如文本的one hot編碼,高頻電話通話次數。這種方式生成的特徵往往會非常稀疏,對數據量的要求較高。數據不夠經驗來湊,對於大量稀疏的特徵,又可以根據經驗對特徵分組合併來減少特徵維度,提升模型效果。
-空值,0值,特殊值(不存在的比例):
對建模不熟悉的工程師經常會把異常的特徵值都設置為0,或者把空值和0值混淆。一般來講特徵等於0是有特殊含義的,比如否或者數量上的0。對特徵值拿不準的時候,最好不要拿0來填充。可以用一個特殊值比如-999來標示一些奇怪的特徵取值(比如0/0),建模時候再做處理。實現特徵提取的時候盡量不要留空值,這樣一旦發現有特徵是空值,就說明代碼中有bug或者數據有異常,可以很方便的發現和處理邊邊角角的case。
-複雜數據,根據相似性降維:
還有一種生成特徵的思路很有意思。樣本並沒有明確的類別信息,但可以通過聚類將樣本劃歸成幾個類別,形成特徵。這個思路在神經科學中就是spike sort,先將很多信號根據波形劃分成幾類(即信號來自於幾個不同的細胞),而後再對每一個細胞產生的信號進行計算處理。
人或者軌跡同理,可以先通過降維聚類將相似的軌跡劃分類別,再將類別作為特徵進行處理。這樣就將很複雜的數據整理成了有意義的特徵。
正好為了手頭的項目在看特徵工程的東西,僅從機器學習的角度說說我的個人理解。
對於機器學習來說,數據是演算法的輸入;要保證演算法有好的表現,就要保證輸入數據的質量。有時我們會遇到這樣的情況:數據維數太高,甚至比數據點的個數還要多,這種情況下會對輸入數據的質量造成以下影響:(1)維數冗餘,有的數據只是雜訊,完全可以去掉;(2)計算困難,維數的增加導致計算時間空間複雜度的增加;(3)容易過擬合,維數越高模型複雜度就可能越高。
這種情況下我們就需要特徵工程來把數據「瘦身」成維數較少,維數質量高的數據集,去掉冗餘信息。通常來說常用的特徵工程方法有特徵提取和特徵選擇兩種。特徵提取主要通過PCA,CCA,ICA等方法從原來各維中總結出潛在的影響因子(latent features),就我的了解而言更注重數據變換,不太涉及領域內知識的運用(我的實踐經驗不多,如果其實是有的,還望指正);而特徵選擇中可能涉及的領域知識(domain language)會更多一些。
特徵選擇是指直接從原有維數中選出有用的維來,一個常見的例子就是NLP中停用詞(stop words)的使用。如果用一批文檔的總詞表(vocabulary)中的每一個單詞作為一個維,去掉停用詞就是去掉冗餘維的一個體現。又比如之前做過fMRI腦成像的圖像分類,領域內知識已知在某個實驗里有效維的數據點會呈現一個特定的分布,我們就可以把完全不呈現這一分布的維剔掉。當然特徵選擇也有不使用領域內知識的方法,比如使用L1 regularization自動進行特徵選擇等。科學總把簡單的問題轉化的很複雜,在彰顯其嚴謹的同時,也把大部分的學習者擋在了門外,jacky跟大家談談如何深入淺出的學習特徵工程?
《特徵工程三部曲》之一數據處理
要理解特徵工程,首先就要理解好數據(Data)和特徵(Feature)的概念
(一)邏輯梳理
- 特徵工程(Feature Engineering)
- 其本質上是一項工程活動,它目的是最大限度地從原始數據中提取特徵以供演算法和模型使用。
特徵工程在數據挖掘中有舉足輕重的位置
數據領域一致認為:數據和特徵決定了機器學習的上限,而模型和演算法只能逼近這個上限而已。
- 特徵工程重要性:
- 特徵越好,靈活性越強;
- 特徵越好,模型越簡單;
- 特徵越好,性能越出色;
好特徵即使使用一般的模型,也能得到很好的效果!好特徵的靈活性在於它允許你可以選擇不複雜的模型,同時,運行速度也更快,也更容易理解和維護。
好的特徵,即使參數不是最優解,模型性能也能表現很好,因此,不需要太多時間去尋找最優參數,大大的降低了模型的複雜度,使模型趨向簡單。模型的性能包括模型的效果,執行的效率及模型的可解釋性。特徵工程的最終目的就是提升模型的性能。
數據科學家通過總結和歸納,把特徵工程劃分為以下三個部分:
- 特徵工程包括:
- 數據處理
- 特徵選擇
- 維度壓縮
(二)數據處理
數據處理的常用技巧
- 量綱不一
- 虛擬變數
- 缺失值填充
1.數據處理——量綱不一
- 量綱:就是單位,特徵的單位不一致,特徵就不能放在一起比較。
- 解決量綱不一致的方法:標準化
- 0-1標準化
- Z標準化
- Normalizer歸一化
(1)0-1標準化
是對原始數據進行線性變換,將特徵值映射成區間為[0,1]的標準值中:
(2)Z標準化
基於特徵值的均值(mean)和標準差(standard deviation)進行數據的標準化。它的計算公式為:
標準化後的變數值圍繞0上下波動,大於0說明高於平均水平,小於0說明低於平均水平。
(3)Normalizer歸一化
將每個樣本縮放到單位範數(每個樣本的範數為1),計算公式如下:
(4)如何使用sklearn實現標準化
sklearn簡介
- sklearn
- 全名Scikit-Learn,是基於Python的機器學習模塊,基於BSD開源許可證,官網上可以找到相關sklearn的資源,模塊下載,文檔,歷程等等;
- sklearn的數據結構基於numpy和pandas;
- sklearn的數據計算基於scipy;
- sklearn的數據可視化基於matplotlib;
- sklearn是在現有的數據分析,數據計算,數據可視化最好的包的基礎上,搭建起來的最好python 機器學習的框架;
- sklearn的六大基本功能
- 分類
- 回歸
- 聚類
- 數據降維
- 模型選擇
- 模型預處理
- sklearn處理機器學習問題的三個步驟:
- 數據準備與預處理
- 模型選擇與訓練
- 模型驗證與參數調優
用sklearn實現標準化
#導入數據到data變數中
import pandas
data = pandas.read_csv("路徑.csv")
#(一)Min-Max 標準化
from sklearn.preprocessing import MinMaxScaler
#初始化一個scaler對象
scaler = MinMaxScaler()
#調用scaler的fit_transform方法,把我們要處理的列作為參數傳進去
data["標準化後的A列數據"] = scaler.fit_transform(data["A列數據"])
data["標準化後的B列數據"] = scaler.fit_transform(data["B列數據"])
#(二)Z-Score標準化 (可在scale中直接實現)
from sklearn.preprocessing import scale
data["標準化後的A列數據"] = scale(data["A列數據"])
data["標準化後的B列數據"] = scale(data["B列數據"])
# (三) Normalizer歸一化
from sklearn.preprocessing import Normalizer
scaler = Normalizer()
#歸一化可以同時處理多個列,所以[0]第一個進行賦值
data["歸一化後的A列數據"] = scaler.fit_transform(data["A列數據"])[0]
data["歸一化後的B列數據"] = scaler.fit_transform(data["B列數據"])[0]
2.數據處理——虛擬變數
- 虛擬變數:也叫啞變數和離散特徵編碼,可用來表示分類變數、非數據因素可能產生的影響。
- 虛擬變數的兩種數據類型:
- 離散特徵的取值之間有大小的意義:例如:尺寸(L、XL、XXL)
- 離散特徵的取值之間沒有大小的意義:例如:顏色(Red、Blue、Green)
- 離散特徵值有大小意義的虛擬變數處理
- 離散特徵的取值之間有大小意義的處理函數,我們只需要把大小值以字典的方式,作為第一個參數傳入即可;
- (1) dict 映射的字典
- pandas.Series.map(dict)
- 離散特徵值沒有大小意義的虛擬變數處理
- 離散特徵的取值之間沒有大小意義的處理方法,我們可以使用get_dummies方法處理,它有6個常用的參數
- (1) data 要處理的DataFrame
- (2) prefix 列名的前綴,在多個列有相同的離散項時候使用
- (3) prefix_sep 前綴和離散值的分隔符,默認為下劃線,默認即可
- (4) dummy_na 是否把NA值,作為一個離散值進行處理,默認不處理
- (5) columns 要處理的列名,如果不指定該列,那麼默認處理所有列
- (6) drop_first 是否從備選項中刪第一個,建模的時候為避免共線性使用
- pandas.getdummies(data,prefix=None,prefix_sep=』『,dummy_na=False,columns=None,drop_first=False)
虛擬變數—實戰案例
以互聯網金融行業為例:
import pandas
#有些朋友也可能是encoding="utf8"或其他
data=pandas.read_csv(
"file:///Users/apple/Desktop/jacky_1.csv",encoding="GBK"
)
print(data)
其實,虛擬變數的實質就是要把離散型的數據轉化為連續型的數據,因為第1列年齡已經是連續值,所以我們就不需要處理了。
我們看看如何處理學歷和性別?因為不同學歷之間是有高低之分的,因此我們要使用Map方法來處理這種類型的離散型數據;
- 第1步: 首先我們要處理不同學歷之間的大小值
- 我們使用drop_duplicates方法,來看看數據列都有哪些學歷
#查看學歷去重之後的情況
data["學歷"].drop_duplicates()
- 第2步:理解數據值背後的意義,作出我們自己的解析,對每個學歷進行評分
#構建學歷字典
educationLevelDict={"博士":4,"碩士":3,"大學":2,"大專":1}
#調用Map方法進行虛擬變數的轉換
data["Education Level Map"]=data["Education Level"].map(educationLevelDict)
- 第3步 對於性別這種沒有大小比較的離散變數,我們使用get_dummies方法,來進行調用處理即可;
dummies=pandas.get_dummies(
data,
columns=["性別"],
prefix=["性別"],
prefix_sep="_",
dummy_na=False,
drop_first=False)
完整代碼展示
import pandas
data=pandas.read_csv(
"file:///Users/apple/Desktop/jacky_1.csv",encoding="GBK"
)
data["學歷"].drop_duplicates()
educationLevelDict={"博士":4,"碩士":3,"大學":2,"大專":1}
data["學歷 Map"]=data["學歷"].map(educationLevelDict)
dummies=pandas.get_dummies(
data,columns=["性別"],
prefix=["性別"],
prefix_sep="_",
dummy_na=False,
drop_first=False
)
print(dummies)
3.數據處理——缺失值填充
- 缺失值產生原因
- 有些信息暫時無法獲取;
- 有些信息被遺漏或者錯誤的處理了
- 缺失值處理方法
- 數據補齊
- 刪除缺失行
- 不處理
實操-使用統計指標填充缺失值
import pandas
data=pandas.read_csv("路徑.csv")
from sclera.preprocessing import Imputer
#"mean","median","most_frequent"
imputer=Imputer(strategy="mean")
imputer.fit_transform(data[["需填充列的列名"]])
《特徵工程三部曲》之二 數據選擇
(一)什麼特徵選擇
- 特徵選擇 ( Feature Selection )也稱特徵子集選擇( Feature Subset Selection , FSS ) ,或屬性選擇( Attribute Selection ) ,是指從全部特徵中選取一個特徵子集,使構造出來的模型更好。
(二)為什麼要做特徵選擇
- 在機器學習的實際應用中,特徵數量往往較多,其中可能存在不相關的特徵,特徵之間也可能存在相互依賴,容易導致如下的後果:
- 特徵個數越多,分析特徵、訓練模型所需的時間就越長。
- 特徵個數越多,容易引起「維度災難」,模型也會越複雜,其推廣能力會下降。
- 特徵選擇能剔除不相關(irrelevant)或亢余(redundant )的特徵,從而達到減少特徵個數,提高模型精確度,減少運行時間的目的。另一方面,選取出真正相關的特徵簡化了模型,使研究人員易於理解數據產生的過程。
(三)特徵選擇基本原則
數據預處理完成之後,我們需要選擇有意義的特徵,輸入機器學習的演算法和模型進行訓練,通常來說,從兩個方面考慮來選擇特徵
- 如何選擇特徵
- 是否發散
- 是否相關
如果一個特徵不發散,例如方差接近於0,也就是說樣本在這個特徵上基本沒有差異,那我們就可以判斷,這個特徵對於樣本的區別並沒有什麼用
第二個是特徵與目標的相關性,與目標相關性高的特徵應該優先選擇
(四)特徵選擇常用的四種方法
我們以互聯網金融實際情景舉例:
- 說白了,特徵選擇,就是看累計銷售和用戶忠誠度評分能不能成為金融產品的特徵,我們會有一系統的評估標準,當然這些評估標準也都有人為主觀判斷在的。
1.方差選擇法(過濾法)
- 使用方差選擇法,先要計算各個特徵的方差,然後根據閾值,選擇方差大於閾值的特徵。使用feature_selection庫的VarianceThreshold類來選擇特徵的代碼如下:
#首先把數據導入到data變數中
import pandas
data=pandas.read_csv("路徑.csv")
#使用VarianceThreshold類進行方差過濾
from sklearn.feature_selection import VarianceThreshold
#要生成這個類的對象,就需要一個參數,就是最小方差的閾值,我們先設置為1,
#然後調用它的transform方法進行特徵值的過濾
variancethreshold=VarianceThreshold(threshold=1)
variancethreshold.fit_transform(
data[["累計銷售(億)","用戶忠誠度評分"]]
)
#使用get_support方法,可以得到選擇特徵列的序號,
#然後根據這個序號在原始數據中把對應的列名選擇出來即可
varianceThreshold.get_support()
threshold=1兩個特徵都被顯示出來了
為什麼閾值設定為1,累計銷售與用戶忠誠度這兩個特徵都被選擇了出來?
首先我們看下累計銷售與用戶忠誠度各自的方差是什麼?
#看下這兩個特徵的方差是什麼?data[["累計銷售(億)","用戶忠誠度評分"]].std()
2.相關係數法
- 先計算各個特徵對目標值的相關係數,選擇更加相關的特徵。
以互聯網金融行業為例
#首先導入數據到data變數中
import pandas
data=pandas.read_csv("路徑.csv")
#然後,SelectKBest類,通過回歸的方法,以及要選擇多少個特徵值,
#新建一個 SelectKBest對象,
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_regression
selectKBest = SelectKBest(
f_regression,k=2
)
#接著,把自變數選擇出來,然後調用fit_transform方法,
#把自變數和因變數傳入,即可選出相關度最高的兩個變數。
feature =data[["月份","季度","廣告推廣費","註冊並投資人數"]]
bestFeature =selectKBest.fit_transform(
feature,
data["銷售金額"]
)
#我們想要知道這兩個自變數的名字,使用get_support方法即可得到相應的列名
feature.columns[selectKBest.get_support()]
最終,python幫助我們選擇的特徵是:
3.遞歸特徵消除法
- 使用一個基模型來進行多輪訓練,經過多輪訓練後,保留指定的特徵數。
還是延用上面那個案例
#首先導入數據到data變數中
import pandas
data=pandas.read_csv("路徑.csv")
#接著,我們使用RFE類,在estimator中,
#把我們的基模型設置為線性回歸模型LinearRegression,
#然後在把我們要選擇的特徵數設置為2,
#接著就可以使用這個rfe對象,把自變數和因變數傳入fit_transform方法,
#即可得到我們需要的特徵值
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
feature =data[["月份","季度","廣告推廣費","註冊並投資人數"]]
rfe =RFE(
estimator=LinearRegression(),
n_features_to_select=2
)
sFeature = rfe.fit_transform(
feature,
data["銷售金額"]
)
#同理,我們要想知道這兩個自變數的名字,
#使用get_support方法,即可得到對應的列名
rfe.get_support()
4.模型選擇法
- 它是一種我們把建好的模型對象傳入選擇器,然後它會根據這個已經建好的模型,自動幫我嗎選擇最好的特徵值。
還是延用上面那個案例
import pandas
data = pandas.read_csv(
"file:///Users/apple/Desktop/jacky_2.csv",
encoding="GBK")
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LinearRegression
feature =data[["月份","季度","廣告推廣費","註冊並投資人數"]]
lrModel = LinearRegression()
selectFromModel = SelectFromModel(lrModel)
selectFromModel.fit_transform(
feature,
data["銷售金額"]
)
selectFromModel.get_support()
- 這裡jacky就強調一點,模型選擇法並不需要指定我們需要多少個特徵,selectFromModel的方法會自動幫我們選擇最優的特徵數
(五)總結
- 科學總把簡單的問題轉化的很複雜
- 有時間的小夥伴可以思考一下,特徵選擇的第一個方法對應的就是發散性,後面三個方法對應的就是回歸。我們細細琢磨,後三個方法其實是一回事,但是得到的結果卻略有不同,參透這其中的道理,也就參透數據挖掘和機器學習的奧秘了。
《特徵工程三部曲》之三 維度壓縮
當特徵選擇完成之後,就可以直接訓練模型了,但是可能由於特徵矩陣過大導致計算量大,訓練時間長的問題;因此,降低特徵矩陣維度,也是必不可少的,主成分分析就是最常用的降維方法,在減少數據集的維度的同時,保持對方差貢獻最大的特徵,在sklearn中,我們使用PCA類進行主成分分析。
- 主成分分析(Principal Components Analysis)
- PCA API
- 有一個參數用於設置主成分的個數:pca_3=PCA(n_components=3),設置好參數後,就可以生成PCA的對象了
- 接著我們可以調用fit_transform方法對高維數據進行壓縮:data_pca_3=pca3.fit_transform(data)
我們人類只能看到三維數據,那麼怎樣把四維數據壓縮到三維數據呢?
#導入iris特徵數據到data變數中
import pandas
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from mpl_toolkits.mplot3d import Axes3D
iris =datasets.load_iris()
data = iris.data
#分類變數到target變數中
target = iris.target
#使用主成分分析,將四維數據壓縮為三維
pca_3 = PCA(n_components=3)
data_pca_3 = pca_3.fit_transform(data)
#繪圖
colors={0:"r",1:"b",2:"k"}
markers={0:"x",1:"D",2:"o"}
#彈出圖形
#%matplotlib qt
#三維數據
fig = plt.figure(1,figsize=(8,6))
ax = Axes3D(fig,elev=-150,azim=110)
data_pca_gb = pandas.DataFrame(
data_pca_3
).groupby(target)
for g in data_pca_gb.groups:
ax.scatter(
data_pca_gb.get_group(g)[0],
data_pca_gb.get_group(g)[1],
data_pca_gb.get_group(g)[2],
c=colors[g],
marker=markers[g],
cmap=plt.cm.Paired
)
plt.show()
生成的效果圖如下:
End ... ...
演算法再牛逼,其上限也是由特徵工程決定的。
假如你會用機器學習演算法,那麼特徵工程幫你選擇最佳的學習材料,Data Engineer幫你整理好你需要的格式
看過一句話:一個團隊,可以沒有演算法組,不能沒有特徵工程組
原始集:概率分布為A訓練集:概率分布為B測試集:概率分布為C特徵工程:處理A,得到更接近C的B機器學習:擬合B,用以預測C
大部分都是說常規機器學習的,要不我來說下深度學習的特徵工程。
所謂特徵工程,其實就是根據業務設計出合適的特徵變數,做多了就知道這個東西比模型重要多了。數據質量高(指的是和業務有強關聯)、特徵工程好,隨便整個演算法效果也杠杠的,反之,調參什麼的就很痛苦了,而且不一定有效。
那麼,深度學習是怎麼做特徵工程呢?
其實,深度學習和一般機器學習最大的差別就是深度學習有進行「特徵工程」的部分,所有的特徵工程是它自己學的,而普通機器學習的特徵組合是要你自己去人肉發現並組合的。
吳恩達的課有說一個經典的房價模型,假設我們就有下面幾個特徵:
- 房屋大小
- 卧室數量
- 郵編
- 富裕程度
你直接丟進模型效果肯定一般,要是哥,哥就這麼做「特徵工程」,我可以用 「房屋大小」 * 「卧室數量」得到一個新特徵,就叫他「家庭成員數」,這個有道理吧?然後「郵編」 * 「富裕程度」又是一個新特徵,我們叫它"學校質量",不同的郵編代表不同的地區,不同地區的教育水平肯定不一樣,有錢與否決定了教育起點,這個特徵肯定也是極好的。相信用這些新組成的特徵和以前的特徵效果肯定比只用基礎特徵好的多。
那麼問題來了,人能發現多少特徵組合呢?如果「特徵工程」讓模型自己去嘗試,結果會好嘛?
答案是肯定的!
這就是為啥AlphaGo碾壓人類而Alpha Zero碾壓AlphaGo的原因——它站在一個我們沒法想像的高度拿到了自己認為最屌的特徵,這樣得到新的特徵後再進行其他步驟,自然事半功倍。
其實這這就是傳說中的表示學習。
我們用CNN來「用人話」說明一下深度學習的「特徵工程」是在幹啥。
CNN有很多卷積層,比如我們現在要用CNN訓練一個人臉識別模型,我們輸入的特徵都是像素點和RGB三個通道,神經網路會怎麼處理這些特徵呢。
在CNN前幾層,表示的基本粒度由像素升級為較抽象的邊(edges), 由於邊有眾多不同角度,如水平、垂直等,所以會分解(disentangle)為多個 (邊) 特徵(實際中遠大於三) 。而這層表示的基本粒度邊(edges)是由多個明暗相間的像素經過組合變換得到。通過這些層的學習,你可以想像簡單的像素特徵生成了「邊緣」,就類似你畫素描摹了個輪廓出來。
在中間幾層依次類推,兩條邊交叉後組成了角corner, 多條邊交叉後組成了contour, 而多個corners/ contours 又組成了人臉的眾多部分,如鼻子、耳朵等等。這些組合成的鼻子耳朵也是模型自己學習到的特徵。模型覺得我學到鼻子眼睛啥的就可以更好的幫我區分不同的人了,我們人類不也是如此咩。
最後,每一層的基本表示粒度都是由前一層多個元素組合而成。圖片在每一層中都有新的表示,而第三個隱藏層的表示經過簡單的線性分類器就能較好地預測圖片的類別。
你看,前面那麼多部分都是在做「特徵工程」,做好特徵工程吼,一個簡單的線性分類器就可以很好的預測了。
不多BB了,應該是說明白了……
我所理解的特徵工程,應該是貫穿整個模型訓練、預測以及後期應用的長期參考的工程,滲透在機器學習的整個過程。比如NBA星探需要從CBA少年隊選球員作為預備球員,現在NBA預備球員中缺少中鋒,星探在找球員的時候可能就會注重球員的身高、籃下持球進攻能力,如果想找組織後衛,可能就更在乎球員的場上視野、運球、助攻等組織能力。最後他們組織的球隊可能就是比較強的,因為方方面面都會考慮到。最後他們訓練好這個選人的標準,球探們可能就會去歐洲,菲律賓等聯賽里,按照這個標準去找人。這就是我理解的特徵工程到最後在進行不同的task的時候,特徵工程就是一種經驗,滲透在選模型、選參數、選特徵表示等
轉自自己的公眾號和博客。
對於機器學習應用而言,由於是用計算機強大的窮舉能力去求解可能的解,除了演算法設計與調優外,數據的獲取、理解、選擇才更是很多問題解決的核心。對此,業界的人起了個「特徵工程」的稱呼來指代這個從數據轉換為機器學習輸入項的過程。
工程的關鍵是在給定實際局限的情況下給出滿意的結果,之所以稱為「特徵工程」,或許也是因為從數據屬性中抽取特徵的過程更接近於一種界定於科學與實戰之間的產物吧。它沒有嚴格的數學理論證明為什麼這樣或那樣選擇或構造特徵一定是好的,答案或許取決於「靈光乍現」,考慮實際應用各種限制,同時又不可能給予足夠多的時間去窮盡所有的靈感,於是基於不同演算法的前提假設,經驗上歸結出一些方法步驟出來,在這個意義上,稱其為特徵工程,其實更接近是一種經驗藝術。
從機器學習的可學習理論出發,數據表達刻畫的概念集是否針對問題足夠完備,是否足夠準確能提供對應演算法的計算精度,是否足夠豐富以保證學習模型能在偏差和方差間很好的平衡等等,都是特徵工程需要重點考慮的問題。在這個意義上將,特徵工程其實是一個複雜的系統工程。
在具體實踐工作中,或可從以下五方面考慮:
特徵於之前的數據特徵不明顯,通過一些數學的方法變換特徵的值域空間,使得關注的特徵值更顯著。
- 特徵構造。廣義上講,特徵生成包括結合業務語義關聯新的數據特徵、或用演算法構造新的訓練數據特徵等,狹義上也可包括綜合兩個或多個特徵的交互作用而產生新的特徵。
- 特徵壓縮。對於某些機器學習分類器而言,並不是越多的特徵會產生更好的分類結果,去除一些非顯著特徵、噪音、異常點或更多特徵細節對演算法的影響。
- 特徵縮放。包括把不同屬性的特徵,如分類特徵、數值特徵等變換為統一的格式,同時標準化還可以避免不同特徵之間量綱不同的差異。
- 特徵選取。相比其他方法,特徵選取相對更成體系一些,目前已有Filter、Wrapper和Embeded三類方法,並且容易形成演算法自動的執行。
特徵工程可以認為是將大數據與人工智慧連接在一起的橋樑,同時也是保證機器學習演算法模型是否與業務目標問題匹配的關鍵制約因素。本文只是管中窺豹,試圖從宏觀角度做幾筆簡單的勾勒,今後有機會爭取從更微觀的問題出發寫得更具體些。
。。。。。 就是, 大多數情況下, 其實什麼降噪什麼分類的, 隨便選一個不太垃圾的就行, 基本上指標上來全靠特徵,說穿了就是人肉做一次分類, 讓機器學著舒服點。
個別公司的員工又來評論下面秀了,完全不知道他們公司是不是ppt驅動的, 真心給跪, 一點乾貨都沒有, 我也不和沒有乾貨的人撕逼的,同學, 回去寫ppt吧, 歡迎舉報
當然, 我在技術垃圾、產品也垃圾的百度, 您可以認為大公司不這麼做。小tip,一般情況,一個機器學習任務給定label y,如何收集數據設計特徵提高擬合程度,正向思維是p(y|x),例如做房價預估,可能會想到地價,地價高,房價也高;遇到瓶頸時不妨逆向思考,找出p(x|y),上面例子,房價高,那麼是不是地價也高
SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)這段代碼老報錯,是為什麼? error: float() argument must be a string or a number, not "map"
都在瞎掰,特徵工程說白了,就是根據很多其他表中的某些欄位,進行運算,衍生出新的變數,比如:有一張登錄表,記錄每次登錄的相關信息。然後衍生出一個變數,最近30天的登錄次數
一切唯有多參加比賽,多在現實問題歷練!
最簡單的例子就是,如果給你10000列的數據,你先把他變100列,再進行其他運算
推薦閱讀:
※Netflix 是如何判斷《紙牌屋》這樣的劇是符合其觀眾口味並且能夠拉動付費用戶增長的?
※誰能解釋下這個架構?
※推薦系統有哪些比較好的論文?