1喂分、前言
自動(dòng)機(jī)器學(xué)習(xí)(AutoML) 旨在通過(guò)讓一些通用步驟 (如數(shù)據(jù)預(yù)處理姓迅、模型選擇和調(diào)整超參數(shù)) 自動(dòng)化瓣俯,來(lái)簡(jiǎn)化機(jī)器學(xué)習(xí)中生成模型的過(guò)程夹抗。AutoML是指盡量不通過(guò)人來(lái)設(shè)定超參數(shù)
绳慎,而是使用某種學(xué)習(xí)機(jī)制,來(lái)調(diào)節(jié)這些超參數(shù)漠烧。這些學(xué)習(xí)機(jī)制包括傳統(tǒng)的貝葉斯優(yōu)化杏愤,多臂老虎機(jī)(multi-armed bandit),進(jìn)化算法已脓,還有比較新的強(qiáng)化學(xué)習(xí)珊楼。當(dāng)我們提起AutoML時(shí),我們更多地是說(shuō)自動(dòng)化數(shù)據(jù)準(zhǔn)備(即數(shù)據(jù)的預(yù)處理度液,數(shù)據(jù)的生成和選擇)和模型訓(xùn)練(模型選擇和超參數(shù)調(diào)優(yōu))厕宗。這個(gè)過(guò)程的每一步都有非常多的選項(xiàng)(options),根據(jù)我們遇到的問(wèn)題堕担,需要設(shè)定各種不同的選項(xiàng)已慢。
Auto-Sklearn 是一個(gè)基于 Python 的開(kāi)源工具包,用于執(zhí)行 AutoML霹购,它采用著名的 Scikit-Learn 機(jī)器學(xué)習(xí)包進(jìn)行數(shù)據(jù)處理和機(jī)器學(xué)習(xí)算法佑惠。
在正式介紹Auto-Sklearn前我們先要聲明幾個(gè)問(wèn)題:
1、Auto-Sklearn不能再Windows上使用
厕鹃,不要試圖掙扎了
2兢仰、不能使用非數(shù)值型數(shù)據(jù),也就是還需要特征工程進(jìn)行處理才行
3剂碴、不支持深度學(xué)習(xí)把将,后面我們會(huì)介紹Auto-PyTorch
4、運(yùn)行時(shí)間比較長(zhǎng)忆矛,時(shí)間設(shè)置短的話訓(xùn)練不充分
2察蹲、介紹
Auto-Sklearn 是改進(jìn)了一般的 AutoML 方法,自動(dòng)機(jī)器學(xué)習(xí)框架采用貝葉斯超參數(shù)優(yōu)化方法催训,有效地發(fā)現(xiàn)給定數(shù)據(jù)集的性能最佳的模型管道洽议。
這里另外添加了兩個(gè)組件:
- 一個(gè)用于初始化貝葉斯優(yōu)化器的元學(xué)習(xí)(meta-learning)方法
- 優(yōu)化過(guò)程中的自動(dòng)集成(automated ensemble)方法
這種元學(xué)習(xí)方法是貝葉斯優(yōu)化的補(bǔ)充,用于優(yōu)化 ML 框架漫拭。對(duì)于像整個(gè) ML 框架一樣大的超參數(shù)空間亚兄,貝葉斯優(yōu)化的啟動(dòng)速度很慢。通過(guò)基于元學(xué)習(xí)選擇若干個(gè)配置來(lái)用于種子貝葉斯優(yōu)化采驻。這種通過(guò)元學(xué)習(xí)的方法可以稱為熱啟動(dòng)優(yōu)化方法审胚。再配合多個(gè)模型的自動(dòng)集成方法匈勋,使得整個(gè)機(jī)器學(xué)習(xí)流程高度自動(dòng)化,將大大節(jié)省用戶的時(shí)間膳叨。從這個(gè)流程來(lái)看洽洁,讓機(jī)器學(xué)習(xí)使用者可以有更多的時(shí)間來(lái)選擇數(shù)據(jù)以及思考要處理的問(wèn)題本身。
2.1 貝葉斯優(yōu)化
貝葉斯優(yōu)化的原理是利用現(xiàn)有的樣本在優(yōu)化目標(biāo)函數(shù)中的表現(xiàn)菲嘴,構(gòu)建一個(gè)后驗(yàn)?zāi)P投鲎浴T摵篁?yàn)?zāi)P蜕系拿恳粋€(gè)點(diǎn)都是一個(gè)高斯分布,即有均值和方差龄坪。若該點(diǎn)是已有樣本點(diǎn)昭雌,則均值就是該點(diǎn)的優(yōu)化目標(biāo)函數(shù)取值,方差為0悉默。而其他未知樣本點(diǎn)的均值和方差是后驗(yàn)概率擬合的城豁,不一定接近真實(shí)值。那么就用一個(gè)采集函數(shù)抄课,不斷試探這些未知樣本點(diǎn)對(duì)應(yīng)的優(yōu)化目標(biāo)函數(shù)值唱星,不斷更新后驗(yàn)概率的模型。由于采集函數(shù)可以兼顧Explore/Exploit跟磨,所以會(huì)更多地選擇表現(xiàn)好的點(diǎn)和潛力大的點(diǎn)间聊。因此,在資源預(yù)算耗盡時(shí)抵拘,往往能夠得到不錯(cuò)的優(yōu)化結(jié)果哎榴。即找到局部最優(yōu)的優(yōu)化目標(biāo)函數(shù)中的參數(shù)。
auto-sklearn用的是smac(https://github.com/automl/SMAC3)算法
僵蛛,是貝葉斯優(yōu)化算法的一種尚蝌。算法在剛初始化時(shí),的確類似隨機(jī)搜索充尉,但是隨著搜索的進(jìn)行飘言,算法知道的信息越來(lái)越多,就能預(yù)知下一次搜索哪個(gè)點(diǎn)模型的表現(xiàn)會(huì)最好驼侠。
圖中淺藍(lán)色的表示95%置信區(qū)間的上下界姿鸿,越寬表示對(duì)某個(gè)點(diǎn)預(yù)測(cè)的標(biāo)準(zhǔn)差越大,表示對(duì)這個(gè)點(diǎn)越不確定倒源。隨著搜索過(guò)的點(diǎn)越來(lái)越多苛预,歷史點(diǎn)(紅叉)附近的標(biāo)準(zhǔn)差就會(huì)降低,表示對(duì)附近的點(diǎn)越確定笋熬。就這樣會(huì)擬合出一個(gè)參數(shù)空間映射到模型表現(xiàn)的函數(shù)热某,從這個(gè)空間中找一個(gè)點(diǎn),作為下次的搜索點(diǎn)。
2.2 從時(shí)間維度看
上圖是在一個(gè)簡(jiǎn)單的 1D 問(wèn)題上應(yīng)用貝葉斯優(yōu)化的實(shí)驗(yàn)圖昔馋,這些圖顯示了在經(jīng)過(guò)四次迭代后芜繁,高斯過(guò)程對(duì)目標(biāo)函數(shù)的近似。我們以 t=3 為例分別介紹一下圖中各個(gè)部分的作用绒极。
上圖 2 個(gè) evaluations 黑點(diǎn)和一個(gè)紅色 evaluations,是三次評(píng)估后顯示替代模型的初始值估計(jì)蔬捷,會(huì)影響下一個(gè)點(diǎn)的選擇垄提,穿過(guò)這三個(gè)點(diǎn)的曲線可以畫(huà)出非常多條。黑色虛線曲線是實(shí)際真正的目標(biāo)函數(shù) (通常未知)周拐。黑色實(shí)線曲線是代理模型的目標(biāo)函數(shù)的均值铡俐。紫色區(qū)域是代理模型的目標(biāo)函數(shù)的方差。綠色陰影部分指的是acquisition function的值妥粟,選取最大值的點(diǎn)作為下一個(gè)采樣點(diǎn)审丘。只有三個(gè)點(diǎn),擬合的效果稍差勾给,黑點(diǎn)越多滩报,黑色實(shí)線和黑色虛線之間的區(qū)域就越小,誤差越小播急,代理模型越接近真實(shí)模型的目標(biāo)函數(shù)脓钾。
3、實(shí)戰(zhàn)
3.1 分類
這里我們使用Titanic數(shù)據(jù)集來(lái)演示桩警,因?yàn)檫@個(gè)數(shù)據(jù)集大家比較熟悉可训,所以看起來(lái)會(huì)更加簡(jiǎn)單點(diǎn)
3.1.1數(shù)據(jù)導(dǎo)入
說(shuō)明
:可以自動(dòng)識(shí)別NAN值,這個(gè)是Auto-Sklearn比較人性化的一點(diǎn)捶枢;大部分sklearn原生模型都不能自動(dòng)處理Nan值握截。
import pandas as pd
data = pd.read_csv("/datasource/DL數(shù)據(jù)集demo/titanic.csv")
# 這里對(duì)性別用One-Hot編碼,其實(shí)流程跟單個(gè)算法一樣
one_hot=OneHotEncoder()
data_temp = pd.DataFrame(one_hot.fit_transform(data[['Sex']]).toarray(),columns=one_hot.get_feature_names(['Sex']),dtype='int32')
data_onehot=pd.concat((data,data_temp),axis=1) #也可以用merge,join
data_onehot.head()
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare Cabin | Embarked | Sex_female | Sex_male | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S | 0 | 1 |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C | 1 | 0 |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S | 1 | 0 |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S | 1 | 0 |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S | 0 | 1 |
3.1.2 數(shù)據(jù)定義
X ,y = (data_onehot[["Pclass","Age","Fare", "Sex_female","Sex_male"]],data_onehot["Survived"])
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y)
3.1.3 模型定義
AutoSklearn 類提供了大量的配置選項(xiàng)作為參數(shù)烂叔。
大部分參數(shù)可以默認(rèn)谨胞,這里只介紹兩個(gè)參數(shù)
time_left_for_this_task:任務(wù)的最長(zhǎng)時(shí)間,以秒為單位长已;默認(rèn)是一個(gè)小時(shí)畜眨,所以自己用來(lái)演示的話可以設(shè)置5-10分鐘;
per_run_time_limit :分配給每個(gè)模型評(píng)估的時(shí)間术瓮,以秒為單位康聂,需要依照time_left_for_this_task來(lái)進(jìn)行制定,如果大于或者等于time_left_for_this_task胞四,模型一般會(huì)提示并自動(dòng)賦值恬汁。
memory_limit=None:如果內(nèi)存報(bào)錯(cuò)的話,建議這樣設(shè)置辜伟;
n_jobs=-1:這個(gè)也會(huì)報(bào)錯(cuò)氓侧,具體錯(cuò)誤忘記記下來(lái)了脊另,建議設(shè)置成-1
另外還有其他參數(shù),如ensemble_size约巷、initial_configurations_via_metalearning偎痛,可用于微調(diào)分類器
如果有需要可以自行配置其他參數(shù)
但是既然我們要學(xué)習(xí)自動(dòng)機(jī)器學(xué)習(xí),不建議考慮太多參數(shù)独郎。
automl = autosklearn.classification.AutoSklearnClassifier(
time_left_for_this_task=3*60,
per_run_time_limit=2*60,
n_jobs=-1,
memory_limit=None
)
3.1.4 訓(xùn)練預(yù)測(cè)
預(yù)測(cè)時(shí)間要比一般的sklearn模型要長(zhǎng)踩麦,一般的模型,比如GBDT氓癌,設(shè)置1000棵樹(shù)谓谦,基本也在秒級(jí)完成,但是這個(gè)需要根據(jù)設(shè)置的時(shí)間來(lái)運(yùn)行贪婉。
優(yōu)點(diǎn)就是不需要自己進(jìn)行網(wǎng)格調(diào)參反粥,所以整體看下來(lái),autosklearn是比較節(jié)省時(shí)間的疲迂。
automl.fit(X_train, y_train)
print(automl.score(X_train, y_train))
# 0.9251497005988024
y_AUTO= automl.predict(X_test)
雖然autosklearn有score查看準(zhǔn)確率才顿,但是最好跟其他的算法統(tǒng)一,用sklearn的數(shù)據(jù)進(jìn)行評(píng)估
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import roc_auc_score
from sklearn.metrics import precision_score
from sklearn.metrics import f1_score
from sklearn.metrics import recall_score
acc = accuracy_score(y_test,y_AUTO)#"accuracy"(準(zhǔn)確率)
auc = roc_auc_score(y_test, y_AUTO)#從預(yù)測(cè)分?jǐn)?shù)中尤蒿,計(jì)算ROC曲線的面積(ROC AUC)
precision = precision_score(y_test,y_AUTO)#精確率
recall = recall_score(y_test,y_AUTO)#計(jì)算召回率
f1 = f1_score(y_test,y_AUTO)#計(jì)算F1評(píng)分娜膘,也被稱為balanced F-score或者F-measure
print(acc,auc,precision,recall,f1)
#0.7937219730941704 0.7673930921052632 0.8888888888888888 0.5894736842105263 0.7088607594936708
3.1.5 模型查看
sprint_statistics()函數(shù)總結(jié)了上述搜索和選擇的最佳模型的性能
print(automl.sprint_statistics())
auto-sklearn results:
Dataset name: b7f831d5-8013-11ed-9911-c3531a603d75
Metric: accuracy
Best validation score: 0.846154
Number of target algorithm runs: 92
Number of successful target algorithm runs: 91
Number of crashed target algorithm runs: 0
Number of target algorithms that exceeded the time limit: 1
Number of target algorithms that exceeded the memory limit: 0
leaderboard()函數(shù)查看所有模型打印排行榜
print(automl.leaderboard())
model_id | rank | ensemble_weight | type | cost | duration |
---|---|---|---|---|---|
39 | 1 | 0.04 | random_forest | 0.153846 | 1.876512 |
26 | 2 | 0.06 | random_forest | 0.162896 | 1.979716 |
76 | 3 | 0.04 | random_forest | 0.162896 | 2.221861 |
2 | 4 | 0.04 | random_forest | 0.167421 | 2.143343 |
92 | 5 | 0.02 | random_forest | 0.171946 | 1.950003 |
7 | 7 | 0.04 | mlp | 0.180995 | 8.816894 |
68 | 6 | 0.02 | random_forest | 0.180995 | 1.625041 |
67 | 8 | 0.06 | adaboost | 0.185520 | 0.962228 |
13 | 10 | 0.02 | random_forest | 0.190045 | 2.401354 |
21 | 9 | 0.04 | libsvm_svc | 0.190045 | 1.238663 |
4 | 11 | 0.06 | extra_trees | 0.194570 | 2.202599 |
18 | 12 | 0.02 | gradient_boosting | 0.194570 | 1.983646 |
30 | 13 | 0.02 | random_forest | 0.194570 | 1.753223 |
22 | 14 | 0.02 | gradient_boosting | 0.199095 | 1.955653 |
19 | 18 | 0.02 | extra_trees | 0.203620 | 2.184760 |
36 | 17 | 0.04 | extra_trees | 0.203620 | 1.547301 |
72 | 16 | 0.02 | qda | 0.203620 | 1.264002 |
74 | 15 | 0.18 | k_nearest_neighbors | 0.203620 | 0.933298 |
40 | 19 | 0.02 | lda | 0.208145 | 1.531620 |
14 | 21 | 0.12 | adaboost | 0.212670 | 2.197585 |
79 | 20 | 0.02 | random_forest | 0.212670 | 1.693966 |
20 | 22 | 0.02 | gradient_boosting | 0.221719 | 1.806265 |
49 | 23 | 0.02 | random_forest | 0.230769 | 1.673310 |
15 | 25 | 0.02 | qda | 0.235294 | 1.421954 |
23 | 24 | 0.02 | random_forest | 0.235294 | 2.352457 |
show_models()函數(shù)可以查看所有模型的信息
print(automl.show_models())
{4: {'model_id': 4,
'rank': 1,
'cost': 0.1945701357466063,
'ensemble_weight': 0.08,
'data_preprocessor': <autosklearn.pipeline.components.data_preprocessing.DataPreprocessorChoice at 0x7fe8f5e35550>,
'balancing': Balancing(random_state=1),
'feature_preprocessor': <autosklearn.pipeline.components.feature_preprocessing.FeaturePreprocessorChoice at 0x7fe8f5747070>,
'classifier': <autosklearn.pipeline.components.classification.ClassifierChoice at 0x7fe8f5747580>,
'sklearn_classifier': ExtraTreesClassifier(max_features=5, min_samples_leaf=3, min_samples_split=11,
n_estimators=512, n_jobs=1, random_state=1,
warm_start=True)},
7: {'model_id': 7,
'rank': 2,
'cost': 0.1809954751131222,
'ensemble_weight': 0.06,
'data_preprocessor': <autosklearn.pipeline.components.data_preprocessing.DataPreprocessorChoice at 0x7fe766d14b80>,
'balancing': Balancing(random_state=1, strategy='weighting'),
'feature_preprocessor': <autosklearn.pipeline.components.feature_preprocessing.FeaturePreprocessorChoice at 0x7fe88710f970>,
'classifier': <autosklearn.pipeline.components.classification.ClassifierChoice at 0x7fe88710f460>,
'sklearn_classifier': MLPClassifier(alpha=4.2841884333778574e-06, beta_1=0.999, beta_2=0.9,
hidden_layer_sizes=(263, 263, 263),
learning_rate_init=0.0011804284312897009, max_iter=256,
n_iter_no_change=32, random_state=1, validation_fraction=0.0,
verbose=0, warm_start=True)},
其他參數(shù):
官網(wǎng):APIs — AutoSklearn 0.15.0 documentation
源碼:https://github.com/automl/auto-sklearn
3.2 回歸
我們使用常見(jiàn)的波士頓房?jī)r(jià)預(yù)測(cè)
import pandas as pd
data = pd.read_csv("/datasource/DL數(shù)據(jù)集demo/boston_house_prices.csv")
X = data[['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX',
'PTRATIO', 'B', 'LSTAT']]
y = data['MEDV']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
流程與分類一致,所以就不廢話了
automl = autosklearn.regression.AutoSklearnRegressor(
time_left_for_this_task=180,
per_run_time_limit=30,
memory_limit=None,
n_jobs=-1,
)
automl.fit(X_train, y_train, dataset_name='boston')
# evaluate the best model
y_pred = automl.predict(X_test)
# 結(jié)果評(píng)估
print('均方誤差: %.2f' % mean_squared_error(y_test,y_pred))
print('確定系數(shù)(R^2): %.2f' % r2_score(y_test,y_pred))
均方誤差: 15.37
確定系數(shù)(R^2): 0.82