- 數(shù)據(jù)挖掘的步驟
數(shù)據(jù)挖掘通常包括數(shù)據(jù)采集卒暂、數(shù)據(jù)分析环鲤、特征工程、訓(xùn)練模型俏蛮、模型評(píng)估等步驟。
-
sklearn工作流程
sklearn主要進(jìn)行虛線(xiàn)框內(nèi)的工作(sklearn也可進(jìn)行文本特征提取)
-
sklearn的主要方法fit上遥、fit_transform搏屑、transform
transform 方法主要用來(lái)對(duì)特征進(jìn)行轉(zhuǎn)換
- 從可利用信息的角度,轉(zhuǎn)換分為無(wú)信息轉(zhuǎn)換和有信息轉(zhuǎn)換:
無(wú)信息轉(zhuǎn)換:指不利用任何其他信息進(jìn)行轉(zhuǎn)換
如: 指數(shù)粉楚、對(duì)數(shù)函數(shù)轉(zhuǎn)換等
> - 有信息轉(zhuǎn)換從是否利用目標(biāo)值向量又分為無(wú)監(jiān)督轉(zhuǎn)換和有監(jiān)督轉(zhuǎn)換:
* 無(wú)監(jiān)督轉(zhuǎn)換: 只利用特征的統(tǒng)計(jì)信息的轉(zhuǎn)換,統(tǒng)計(jì)信息包括均值辣恋、標(biāo)準(zhǔn)差亮垫、邊界等等 如:標(biāo)準(zhǔn)化、PCA法降維等
* 有監(jiān)督轉(zhuǎn)換:即利用了特征信息又利用了目標(biāo)值信息的轉(zhuǎn)換伟骨。如:通過(guò)模型選特征饮潦、LDA法降維等 -
對(duì)常用轉(zhuǎn)換類(lèi)進(jìn)行總結(jié)可得如下表:
import sklearn.preprocessing as prep
import sklearn.feature_selection as fs
import sklearn.decomposition as dp
包 | 類(lèi) | 參數(shù)列表 | 類(lèi)別 | fit方法有用 | 說(shuō)明 |
---|---|---|---|---|---|
prep | StandardScaler | 特征 | 無(wú)監(jiān)督 | Y | 標(biāo)準(zhǔn)化 |
prep | MinMaxScaler | 特征 | 無(wú)監(jiān)督 | Y | 區(qū)間縮放 |
prep | Normalizer | 特征 | 無(wú)信息 | N | 歸一化 |
prep | Binarizer | 特征 | 無(wú)信息 | N | 定量特征二值化 |
prep | OneHotEncoder | 特征 | 無(wú)監(jiān)督 | Y | 定性特征編碼 |
prep | Imputer | 特征 | 無(wú)監(jiān)督 | Y | 缺失值計(jì)算 |
prep | PolynomialFeatures | 特征 | 無(wú)信息 | N | 多項(xiàng)式變換(fit方法僅僅生成了多項(xiàng)式表達(dá)式) |
prep | FunctionTransformer | 特征 | 無(wú)信息 | N | 自定義函數(shù)變換(自定義函數(shù)在transform方法中調(diào)用) |
fs | VarianceThreshold | 特征 | 無(wú)監(jiān)督 | Y | 方差選擇法 |
fs | SelectKBest | 特征/特征+目標(biāo)值 | 無(wú)監(jiān)督/有監(jiān)督 | Y | 自定義特征評(píng)分選擇 |
fs | SelectKBest+chi2 | 特征+目標(biāo)值 | 有監(jiān)督 | Y | 卡方檢驗(yàn)選擇法 |
fs | RFE | 特征+目標(biāo)值 | 有監(jiān)督 | Y | 遞歸特征消除法 |
fs | SelectFromModel | 特征+目標(biāo)值 | 有監(jiān)督 | Y | 自定義模型訓(xùn)練選擇法 |
dp | PCA | 特征 | 無(wú)監(jiān)督 | Y | PCA降維 |
sklearn.lda | LDA | 特征+目標(biāo)值 | 有監(jiān)督 | Y | LDA降維 |
- fit方法主要工作是獲取特征信息和目標(biāo)值信息
Normalizer的fit方法實(shí)現(xiàn)如下
def fit(self, X, y=None):
"""Do nothing and return the estimator unchanged
This method is just there to implement the usual API and hence
work in pipelines.
"""
X = check_array(X, accept_sparse='csr')
return self
- 流水線(xiàn)式:前一個(gè)工作的輸出是后一個(gè)工作的輸入
- 并行式:工作可同時(shí)進(jìn)行,使用同樣的輸入底靠,所有工作完成后將各自的輸出合并后輸出
sklearn提供pipeline來(lái)完成流水線(xiàn)式和并行式的工作
-
關(guān)鍵技術(shù)
* 并行處理和流水線(xiàn)處理:將處理多個(gè)特征處理工作害晦,甚至包括模型訓(xùn)練工作組合成一個(gè)工作(即將多個(gè)對(duì)象組合為一個(gè)對(duì)象) * 自動(dòng)化調(diào)參:減少人工調(diào)參的繁瑣 * 持久化:訓(xùn)練好的模型是儲(chǔ)存在內(nèi)存中的數(shù)據(jù),持久化能將這些數(shù)據(jù)保存在文件系統(tǒng)中暑中,之后使用無(wú)需進(jìn)行訓(xùn)練壹瘟,直接從文件系統(tǒng)中加載
并行處理
并行處理使得多個(gè)特征處理工作能夠同時(shí)進(jìn)行,根據(jù)對(duì)特征矩陣的讀取方式不同,可分為整體并行處理和部分并行處理鳄逾。
- 整體并行處理:即并行處理的每個(gè)工作輸入都是矩陣的整體稻轨。
pipeline包提供了FeatureUnion來(lái)實(shí)現(xiàn)整體并行處理
from numpy import log1p
from sklearn.preprocessing import FunctionTransformer
from sklearn.preprocessing import Binarizer
from sklearn.pipeline import FeatureUnion
#新建將整體特征矩陣進(jìn)行對(duì)數(shù)函數(shù)轉(zhuǎn)換的對(duì)象
step2_1 = ('ToLog', FunctionTransformer(log1p))
#新建將整體特征矩陣進(jìn)行二值化類(lèi)的對(duì)象
step2_2 = ('ToBinary', Binarizer())
#新建整體并行處理對(duì)象
#該對(duì)象也有fit和transform方法,fit和transform方法均是并行地調(diào)用需要并行處理的對(duì)象的fit和transform方法
#參數(shù)transformer_list為需要并行處理的對(duì)象列表雕凹,該列表為二元組列表殴俱,第一元為對(duì)象的名稱(chēng),第二元為對(duì)象
step2 = ('FeatureUnion', FeatureUnion(transformer_list=[step2_1, step2_2, step2_3]))
- 部分并行處理枚抵,即可定義每個(gè)工作需要輸入的特征矩陣
在pipeline.FeatureUnion的基礎(chǔ)上優(yōu)化
from sklearn.pipeline import FeatureUnion, _fit_one_transformer, _fit_transform_one, _transform_one
from sklearn.externals.joblib import Parallel, delayed
from scipy import sparse
import numpy as np
class FeatureUnionExt(FeatureUnion):
def __init__(self, transformer_list, idx_list, n_jobs=1, transformer_weights=None):
self.idx_list = idx_list
FeatureUnion.__init__(self, transformer_list=map(lambda trans:(trans[0], trans[1]), transformer_list), n_jobs=n_jobs, transformer_weights=transformer_weights)
def fit(self, X, y=None):
transformer_idx_list = map(lambda trans, idx:(trans[0], trans[1], idx), self.transformer_list, self.idx_list)
transformers = Parallel(n_jobs=self.n_jobs)(
delayed(_fit_one_transformer)(trans, X[:,idx], y)
for name, trans, idx in transformer_idx_list)
self._update_transformer_list(transformers)
return self
def fit_transform(self, X, y=None, **fit_params):
transformer_idx_list = map(lambda trans, idx:(trans[0], trans[1], idx), self.transformer_list, self.idx_list)
result = Parallel(n_jobs=self.n_jobs)(
delayed(_fit_transform_one)(trans, name, X[:,idx], y,
self.transformer_weights, **fit_params)
for name, trans, idx in transformer_idx_list)
Xs, transformers = zip(*result)
self._update_transformer_list(transformers)
if any(sparse.issparse(f) for f in Xs):
Xs = sparse.hstack(Xs).tocsr()
else:
Xs = np.hstack(Xs)
return Xs
def transform(self, X):
transformer_idx_list = map(lambda trans, idx:(trans[0], trans[1], idx), self.transformer_list, self.idx_list)
Xs = Parallel(n_jobs=self.n_jobs)(
delayed(_transform_one)(trans, name, X[:,idx], self.transformer_weights)
for name, trans, idx in transformer_idx_list)
if any(sparse.issparse(f) for f in Xs):
Xs = sparse.hstack(Xs).tocsr()
else:
Xs = np.hstack(Xs)
return Xs
在本文提出的場(chǎng)景中线欲,我們對(duì)特征矩陣的第1列(花的顏色)進(jìn)行定性特征編碼,對(duì)第2汽摹、3李丰、4列進(jìn)行對(duì)數(shù)函數(shù)轉(zhuǎn)換,對(duì)第5列進(jìn)行定量特征二值化處理逼泣。使用FeatureUnionExt類(lèi)進(jìn)行部分并行處理的代碼如下:
from numpy import log1p
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import FunctionTransformer
from sklearn.preprocessing import Binarizer
#新建將部分特征矩陣進(jìn)行定性特征編碼的對(duì)象
step2_1 = ('OneHotEncoder', OneHotEncoder(sparse=False))
#新建將部分特征矩陣進(jìn)行對(duì)數(shù)函數(shù)轉(zhuǎn)換的對(duì)象
step2_2 = ('ToLog', FunctionTransformer(log1p))
#新建將部分特征矩陣進(jìn)行二值化類(lèi)的對(duì)象
step2_3 = ('ToBinary', Binarizer())
#新建部分并行處理對(duì)象
#參數(shù)transformer_list為需要并行處理的對(duì)象列表趴泌,該列表為二元組列表,第一元為對(duì)象的名稱(chēng)拉庶,第二元為對(duì)象
#參數(shù)idx_list為相應(yīng)的需要讀取的特征矩陣的列
step2 = ('FeatureUnionExt', FeatureUnionExt(transformer_list=[step2_1, step2_2, step2_3], idx_list=[[0], [1, 2, 3], [4]]))
- 流水線(xiàn)處理
pipeline提供了Pipeline類(lèi)來(lái)實(shí)現(xiàn)流水線(xiàn)處理嗜憔。
流水線(xiàn)上除最后一個(gè)工作以外,其他都要執(zhí)行fit_transform方法氏仗,且上一個(gè)工作輸出作為下一個(gè)工作的輸入吉捶。最后一個(gè)工作必須實(shí)現(xiàn)fit方法,輸入為上一個(gè)工作的輸出皆尔;但是不限定一定有transform方法呐舔,因?yàn)榱魉€(xiàn)的最后一個(gè)工作可能是訓(xùn)練!
from numpy import log1p
from sklearn.preprocessing import Imputer
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import FunctionTransformer
from sklearn.preprocessing import Binarizer
from sklearn.preprocessing import MinMaxScaler
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
#新建計(jì)算缺失值的對(duì)象
step1 = ('Imputer', Imputer())
#新建將部分特征矩陣進(jìn)行定性特征編碼的對(duì)象
step2_1 = ('OneHotEncoder', OneHotEncoder(sparse=False))
#新建將部分特征矩陣進(jìn)行對(duì)數(shù)函數(shù)轉(zhuǎn)換的對(duì)象
step2_2 = ('ToLog', FunctionTransformer(log1p))
#新建將部分特征矩陣進(jìn)行二值化類(lèi)的對(duì)象
step2_3 = ('ToBinary', Binarizer())
#新建部分并行處理對(duì)象床佳,返回值為每個(gè)并行工作的輸出的合并
step2 = ('FeatureUnionExt', FeatureUnionExt(transformer_list=[step2_1, step2_2, step2_3], idx_list=[[0], [1, 2, 3], [4]]))
#新建無(wú)量綱化對(duì)象
step3 = ('MinMaxScaler', MinMaxScaler())
#新建卡方校驗(yàn)選擇特征的對(duì)象
step4 = ('SelectKBest', SelectKBest(chi2, k=3))
#新建PCA降維的對(duì)象
step5 = ('PCA', PCA(n_components=2))
#新建邏輯回歸的對(duì)象滋早,其為待訓(xùn)練的模型作為流水線(xiàn)的最后一步
step6 = ('LogisticRegression', LogisticRegression(penalty='l2'))
#新建流水線(xiàn)處理對(duì)象
#參數(shù)steps為需要流水線(xiàn)處理的對(duì)象列表,該列表為二元組列表砌们,第一元為對(duì)象的名稱(chēng)杆麸,第二元為對(duì)象
pipeline = Pipeline(steps=[step1, step2, step3, step4, step5, step6])
- 自動(dòng)化調(diào)參
grid_search包提供了自動(dòng)化調(diào)參的工具搁进,包括GridSearchCV類(lèi)。對(duì)組合好的對(duì)象進(jìn)行訓(xùn)練以及調(diào)參
from sklearn.grid_search import GridSearchCV
#新建網(wǎng)格搜索對(duì)象
#第一參數(shù)為待訓(xùn)練的模型
#param_grid為待調(diào)參數(shù)組成的網(wǎng)格昔头,字典格式饼问,鍵為參數(shù)名稱(chēng)(格式“對(duì)象名稱(chēng)__子對(duì)象名稱(chēng)__參數(shù)名稱(chēng)”),值為可取的參數(shù)值列表
grid_search = GridSearchCV(pipeline, param_grid={'FeatureUnionExt__ToBinary__threshold':[1.0, 2.0, 3.0, 4.0], 'LogisticRegression__C':[0.1, 0.2, 0.4, 0.8]})
#訓(xùn)練以及調(diào)參
grid_search.fit(iris.data, iris.target)
- 持久化
externals.joblib包提供了dump和load方法來(lái)持久化和加載內(nèi)存數(shù)據(jù):
#持久化數(shù)據(jù)
#第一個(gè)參數(shù)為內(nèi)存中的對(duì)象
#第二個(gè)參數(shù)為保存在文件系統(tǒng)中的名稱(chēng)
#第三個(gè)參數(shù)為壓縮級(jí)別揭斧,0為不壓縮莱革,3為合適的壓縮級(jí)別
dump(grid_search, 'grid_search.dmp', compress=3)
#從文件系統(tǒng)中加載數(shù)據(jù)到內(nèi)存中
grid_search = load('grid_search.dmp')