【机器学习】信用卡欺诈检测|用启发式搜索优化XGBoost超参数
本文將展示如何使用模擬退火[1]啟發式搜索[2]機器學習算法中超參數的最佳組合。這些方法比盲隨機生成參數得到的模型效果好。另外,模型效果最好是分別微調每個超參數,因為它們之間通常存在交互。
模擬退火簡介
模擬退火是一種用于逼近給定函數的全局最優值的概率技術。具體來說,對于優化問題,在大型搜索空間中近似全局優化是一種元啟發式。它通常用于搜索空間是離散的。對于在固定時間內找到近似全局最優比找到精確局部最優更重要的問題,模擬退火可能比精確算法(如梯度下降或分支定界)更可取。
該算法的名稱來自冶金中的退火,這是一種涉及加熱和控制材料冷卻以增加其晶體尺寸并減少其缺陷的技術。兩者都是取決于其熱力學自由能的材料屬性。加熱和冷卻材料會影響溫度和熱力學自由能或吉布斯能。模擬退火可用于精確算法失敗的非常困難的計算優化問題;盡管它通常會獲得全局最小值的近似解,但它對于許多實際問題來說已經足夠了。
在模擬退火算法中實施的這種緩慢冷卻的概念被解釋為在探索解決方案空間時接受更差解決方案的概率緩慢下降。接受更差的解決方案允許更廣泛地搜索全局最優解決方案。
通常,模擬退火算法的工作方式如下。溫度從初始正值逐漸降低到零。在每個時間步,算法隨機選擇一個接近當前解的解,測量它的質量,并根據選擇更好或更差解的溫度相關概率移動到它,在搜索過程中分別保持在 1(或正值) ) 并趨向于零。
選用XGBoost算法來應用該方法,是一個很好的例子,因為它有許多超參數。窮舉網格搜索在計算上可能是行不通的。
關于XGBoost的理論細節的討論,請參閱這個Slideshare presentation[3]?,標題為"Kaggle Winning Solution XGBoost algorithm—Let us learn from its author",作者是陳天奇。
數據集描述
本文數據集取自Kaggle數據集,其中包含信用卡交易數據和欺詐標簽。它最初是Dal Pozzolo, Andrea等人在Computational Intelligence, 2015 IEEE Symposium Series on. IEEE, 2015 Calibrating Probability with Undersampling for Unbalanced Classification[4]?發表的名為用不平衡分類的欠采樣概率校準的文章內所使用的數據集。數據集中有Time變量(第一次交易的時間),Amount變量,Class變量(1=欺詐,0=非欺詐),以及其余的(V1-V28)是對原始變量進行主成分分析得到的因子變量。若有朋友需要本數據集,可直接聯系原文作者云朵君(wx: Mr_cloud_data)免費獲取!
對于XGBoost來說,訓練及預測該數據集,并不是一個非常困難的情況。本文的主要目的是來說明啟發式搜索從相當大的潛在組合集中找到合適的超參數集的方法。
從下文數據探索中發現,這是一個典型的欺詐檢測數據集,且是一個高度不平衡的數據集。因此在XGBoost參數中設置觀測值的權重時需要將該因素考慮進去。
本數據集相對較大,因此可以將其劃分為訓練集、驗證集及測試集合,將在一個驗證數據集上校準超參數,并在一個新的測試數據集上評估模型預測性能。
import?numpy?as?np? import?pandas?as?pd import?matplotlib.pyplot?as?plt %matplotlib?inline import?random random.seed(1234)plt.style.use('ggplot') dat?=?pd.read_csv('creditcard.csv') dat.head()df['Class'].value_counts()/len(df)0 0.998273 1 0.001727 Name: Class, dtype: float64數據探索
缺失值分析
total?=?dat.isnull().sum().sort_values(ascending?=?False) percent?=?(dat.isnull().sum()/dat.isnull().count()*100).sort_values(ascending?=?False) pd.concat([total,?percent],?axis=1,?keys=['Total',?'Percent']).transpose()數據集分布
數據不平衡
利用plotly可視化信用卡欺詐類別,得到類別Class數據不平衡。
import?plotly.graph_objs?as?go from?plotly.offline?import?iplot temp?=?dat["Class"].value_counts() df?=?pd.DataFrame({'Class':?temp.index,'values':?temp.values})trace?=?go.Bar(x?=?df['Class'],y?=?df['values'],name="信用卡欺詐類別-數據不平衡?\n(非欺詐?=?0,?欺詐?=?1)",marker=dict(color="Blue"),text=df['values']) temp_data?=?[trace] layout?=?dict(title?=?'信用卡欺詐類別-數據不平衡?(非欺詐?=?0,?欺詐?=?1)',xaxis?=?dict(title?=?'Class',?showticklabels=True),?yaxis?=?dict(title?=?'交易數量'),hovermode?=?'closest',width=1000,?height=600) fig?=?dict(data=temp_data,?layout=layout) iplot(fig,?filename='class')類別Class隨時間Time的分布
amt99?=?1018 #?99%的交易 dat99?=?dat.iloc[?list(dat['Amount']<=amt99)?] #?1%的交易 dat01?=?dat.iloc[?list(dat['Amount']>amt99)?] class_0?=?dat99.loc[dat['Class']?==?0]["Time"] class_1?=?dat99.loc[dat['Class']?==?1]["Time"]上圖可以得到如下結果
欺詐交易和非欺詐交易的數據分布是不同的。
非欺詐交易分布和所有交易的總和分布使相同的,因為詐騙的案例很少,影響不了總體交易分布。
該數據集有兩天的數據,所以它顯示了正常交易的兩個高峰。
但無法從兩天的數據中識別出任何顯著的欺詐交易模式。
類別Class隨數量Amount的分布
上圖可以得到如下結果
欺詐交易和非欺詐交易的數據分布是不同的。
非欺詐交易分布和所有交易的總和分布使相同的,因為詐騙的案例很少,影響不了總體交易分布。
在99%的情況下,看到大多數交易都低于200美元,在1%的情況下,看到一個右尾鐘形曲線,平均在3000美元左右。
在這1%的數據中,看到了欺詐交易的激增。
交易價值欺詐分析
max_amount=int(round(max(dat.Amount)?*1.04,-3)) bins=list(range(0,1601,100)) bins.append(max_amount) dat['Amt']=pd.cut(dat.Amount,bins) all_trans?=?dat.pivot_table(index="Amt",columns="Class",values="V1",aggfunc=len)? all_trans['All']?=?all_trans[0]?+all_trans[1] all_trans?=?all_trans.drop(?0,?axis=1) all_trans.columns=['欺詐','總體'] all_trans['欺詐?%']?=?all_trans['欺詐']??/?len(?dat[dat.Class==1])*100 all_trans['總體?%']?=?all_trans['總體']??/?len(?dat.Class)*100上圖可以得到如下結果
79.5%的交易低于100美元,但這類欺詐占68%。
在200美元到1600美元之間的交易占9.57%,欺詐占16.86%
熱圖看變量間相關性
sns.heatmap(dat.corr(),?cmap="YlGnBu")從結果看沒有發現變量之間有任何顯著的相關性,因此這是PCA降維后的數據,所以給定變量之間沒有關系。除了時間和數量與其他字段有某種關系。
指定變量與兩個Class的數據點箱圖分布
通過多子圖,循環繪制每個變量與類之間的箱圖,sns.boxplot()可以直接繪制該圖形。
color?=?sns.color_palette("Set3",?6) plt.figure(figsize=(20,20)) i=1for?col?in?dat.columns:plt.subplot(8,4,i)ax=sns.boxplot(x=dat['Class'],y=dat[col],??palette=color)for?p?in?ax.patches:ax.annotate(format(p.get_height(),?'.2f'),?(p.get_x()?+?p.get_width()?/?2.,p.get_height()),?ha?=?'center',?va?=?'center',?fontsize=8,xytext?=?(0,?10),?textcoords?=?'離群點')i+=1 plt.tight_layout()▲ 部分截圖上圖可以得到如下結果
幾乎所有字段都有離群值。
對于所有變量,這兩個類的數據中值幾乎是相同的。
對于一些變量,如v1, v4, v5, v12, v14,v16, v17, v18, IQR范圍有顯著不同。
散點圖觀察兩個Calss的數量與其他變量之間的關系
這主要用sns.regplot()函數
plt.figure(figsize=(20,80)) i=1 for?col?in?dat.columns:plt.subplot(16,2,i)sns.regplot(y=dat[dat.Class==0].Amount,x=dat[dat.Class==0][col],?color="g")ax?=?sns.regplot(y=dat[dat.Class==1].Amount,x=dat[dat.Class==1][col],?color="r")ax.tick_params(labelsize=15)ax.set_xlabel(col,fontsize=15)i+=1 plt.tight_layout()▲ 部分截圖統計檢驗探索數據特征
盡管大多數變量的含義是未知的(V1-V28匯總交易數據的因子),但我們知道V1-V28是通過標準化(均值為0,標準差為1)處理過后的數據。當然時間和數量變量同樣也是經過標準化處理后的。
經數據探索,特別是采用韋爾奇t檢驗檢驗,結果顯示幾乎所有的特征都與Class變量顯著相關。這些變量的均值在Class 0?中幾乎為零,而在Class 1?中顯然是非零的。
另外時間和數量變量也很重要。似乎還沒有任何理由需要進行變量選擇。
另外發現一些變量分布不均(如Amount),在XGBoost對這種偏離常態的偏差并不敏感,但如果需要應用一些其他方法(如邏輯回歸),這里需用一些特征轉換的技巧,如分箱等。
from?scipy?import?stats from?sklearn?import?preprocessingdat['Time']?=?preprocessing.scale(dat['Time']) dat['Amount']?=?preprocessing.scale(dat['Amount']) pt?=?pd.pivot_table(dat,?values=dat.columns,?columns?=?'Class',?aggfunc='mean')print('\n韋爾奇t檢驗和形狀統計的p值:\n') for?i?in?range(30):col_name?=?dat.columns[i]t,?p_val?=?stats.ttest_ind(dat.loc[?dat['Class']==0,?col_name],?dat.loc[?dat['Class']==1,?col_name],equal_var=False)??skewness?=?dat.loc[:,col_name].skew()kurtosis?=?stats.kurtosis(dat.loc[:,col_name])print('Variable:?{:7s}'.format(col_name),end='')????print('p-value:?{:6.3f}??skewness:?{:6.3f}??kurtosis:?{:6.3f}'.format(p_val,?skewness,?kurtosis))for?i?in?range(30):axes[i].hist(dat[dat.columns[i]],?bins=50,facecolor='b',alpha=0.5)韋爾奇t檢驗和形狀統計的p值: Variable:?Time?p-value:?0.000?skewness:?-0.036??kurtosis:?-1.294 Variable:?V1???p-value:?0.000?skewness:?-3.281??kurtosis:?32.486 Variable:?V2???p-value:?0.000?skewness:?-4.625??kurtosis:?95.771 Variable:?V3???p-value:?0.000?skewness:?-2.240??kurtosis:?26.619 ... Variable:?Amount?p-value:??0.004??skewness:?16.978??kurtosis:?845.078▲ 部分截圖劃分數據集
這里將數據集劃分為40%的訓練、30%的驗證和30%的測試。注意使用了numpy中的random.shuffle()函數。還使相應的矩陣train,?valid和test分別包含只有標簽為trainY,?validity?和testY的預測器。
Class?=?dat['Class'].valuesallIndices?=?np.arange(len(Class)) np.random.shuffle(allIndices)?#?打亂觀察的索引numTrain?=?int(round(0.40*len(Class))) numValid?=?int(round(0.30*len(Class))) numTest?=?len(Class)-numTrain-numValidinTrain?=?allIndices[:numTrain] inValid?=?allIndices[numTrain:(numTrain+numValid)] inTest?=??allIndices[(numTrain+numValid):]train?=?dat.iloc[inTrain,:30] valid=?dat.iloc[inValid,:30] test?=??dat.iloc[inTest,:30]trainY?=?Class[inTrain] validY?=?Class[inValid] testY?=?Class[inTest]設置搜索參數
Booster準備:固定參數
首先,我們使用xgb.DMatrix()函數以XGBoost所需的格式創建矩陣,為每個數據集傳遞預測器數據和標簽。然后我們設置一些固定的參數。
其中增強迭代的次數(num_rounds)設置為20。通常情況下,該參數會使用更大的數字以使用更多的迭代次數,但在該實驗中,為了節約時間,將其設置為20。
用silent=1(無信息)初始化參數字典。因為數據是高度不平衡的,因此設置參數min_child_weight為默認值1。該參數用于進一步分區的子節點中觀察值的最小加權數。目標是二元分類,默認評價指標是曲線下面積(AUC),可以定制一個評估函數以實現更高級的模型評價。
另外設置內部隨機數種子為一個常量,這樣可以獲得可重復的結果(但這并不能保證,因為XGBoost是在線程中運行的。
將使用啟發式搜索中的參數來擴展參數字典。
import?xgboost?as?xgb #?將數據轉換為xgboost所需的矩陣 dtrain?=?xgb.DMatrix(train,?label=trainY) dvalid?=?xgb.DMatrix(valid,?label=validY) dtest?=?xgb.DMatrix(test,?label=testY)#?固定一些參數 #?boosting迭代數 num_rounds=20? param?=?{'silent':1,'min_child_weight':1,'objective':'binary:logistic','eval_metric':'auc','seed'?:?1234}Booster準備:可變參數
在接下來的內容中,參考了下面幾個文章的建議:
The official XGBoost documentation[5]?和?Notes on Parameter Tuning[6]
The article "Complete Guide to Parameter Tuning in XGBoost" from Analytics Vidhya[7]
Another Slideshare presentation with title "Open Source Tools & Data Science Competitions"[8]
以下為啟發式搜索選擇幾個重要參數:
max_depth
樹的最大深度,范圍在[1,∞]中,默認值為6。這是高度依賴數據的。[2]中選用3-10作為典型值。[3]中建議從6開始。而我們選擇探索更大的max_depth值,并從5-25,設置步長為5,共5步。subsample
參數范圍 (0,1] ,默認值為1。這是在樹中使用的訓練實例的比例,使用較小的值可以防止過擬合。[2]中建議的值為0.5-1。[3]中建議這個值保持為1。我們決定以0.1為步長,測試0.5-1.0中的值。colsample_bytree
參數范圍 (0,1] ,默認值為1。這是用于構建樹的列(特征)的子樣本比率。[2]中建議的值為0.5-1。[3]中建議是0.3-0.5。我們將嘗試與參數subsample相似的值。eta?(or?learning_rate)
參數范圍[0,1]中,默認值為0.3。特征權重的縮小率和較大的學習率值(但不是太高)可以用來防止過擬合。[2]中建議使用0.01-0.2中的值。我們可以在[0.01,0.4]中選擇一些值。gamma
范圍 [0, ∞], 默認值為0。這是樹分裂所需的最小損失函數減少值。[3]中建議這個保持使用默認值0。我們可以在0.05的步長中測試0-2的值。scale_pos_weight
默認值1,控制正樣本和負樣本權重的平衡。[1]中建議是使用正負樣本的比率是595,也就是說,給陽性的一個較大的權重。[2]中同樣表示在高階級不平衡的情況下,改參數值需要設置很大。我們可以既嘗試一些較小值也嘗試一些較大值。
上面所有參數的所有可能組合的總數可高達43200,我們只測試其中的一小部分,約100個,即與啟發式搜索迭代的次數相同。
我們還初始化一個DataFrame并將其結果保存以供以后檢查。
from?collections?import?OrderedDictratio_neg_to_pos?=?sum(trainY==0)/sum(trainY==1) print('負與正實例的比率:?{:6.1f}'.format(ratio_neg_to_pos))#?需要調節的參數 tune_dic?=?OrderedDict()tune_dic['max_depth']=?[5,10,15,20,25]?#?樹的最大深度 tune_dic['subsample']=[0.5,0.6,0.7,0.8,0.9,1.0]?#?在樹中使用的訓練實例的比例 tune_dic['colsample_bytree']=?[0.5,0.6,0.7,0.8,0.9,1.0]?#?列(特征)的子樣本比率 tune_dic['eta']=?[0.01,0.05,0.10,0.20,0.30,0.40]??#?學習率 tune_dic['gamma']=?[0.00,0.05,0.10,0.15,0.20]??#?分裂所需的最小損失函數減少值 tune_dic['scale_pos_weight']=[30,40,50,300,400,500,600,700]?#?正面/負面實例的相對權重lengths?=?[len(lst)?for?lst?in?tune_dic.values()] combs=1 for?i?in?range(len(lengths)):combs?*=?lengths[i] print('所有組合總數:?{:16d}'.format(combs))?? maxiter=100 columns=[*tune_dic.keys()]+['F-Score','Best?F-Score'] results?=?pd.DataFrame(index=range(maxiter),?columns=columns)?#?dataframe保存訓練結果負與正實例的比率: 580.2 所有組合總數: 43200自定義函數
構建訓練和評價模型的函數
接下來定義兩個函數:
函數?perf_measures()?接受必須參數preds和labels,及可選參數print_conf_matrix,并返回F-Score(精確度和召回率的調和平均值),將用于啟發式搜索。
函數?do_train()?接受如下參數:
當前選擇的變量參數的字典 (cur_choice),
要傳遞給XGBoost訓練主程序的完整參數字典 (param),
一個XGBoost格式的訓練數據集 (train),
一個字符串標識符 (train_s),
樣本標簽 (trainY),
驗證數據集的相應參數 (valid, valid_s, validY),
以及是否打印混淆矩陣的選項 (print_conf_matrix).
然后訓練模型,并將驗證數據集上預測得到的F-Score與模型一起返回。對主訓練程序xgb.train()的調用有以下參數:
完整參數字典 (param),
一個XGBoost格式的訓練數據集 (train),
boosting迭代次數 (num_boost),
產生參數隨機相鄰組合
接下來定義一個函數next_choice(),如果當前參數沒有通過cur_params傳遞時,它可以生成變量參數的隨機組合,或者生成通過cur_params傳遞的參數的相鄰組合。
在第二種情況下,首先隨機選擇一個要更改的參數。然后:
如果該參數是當前最小的值,則選擇下一個(更大)的值。
如果該參數是當前最大的值,則選擇前一個(較小)的值。
否則,隨機選擇左(小)或右(大)值。
這使得在執行啟發式搜索的函數中避免了重復。
def?next_choice(cur_params=None):"""返回變量參數的隨機組合(如果cur_params=None)或cur_params的隨機相鄰組合"""if?cur_params:#?選擇要更改的參數#?參數名稱和當前值choose_param_name,?cur_value?=?random.choice(list(cur_choice.items()))?#?參數名稱all_values?=??list(tune_dic[choose_param_name])?#?所選參數的所有值cur_index?=?all_values.index(cur_value)?#?選定參數的當前索引if?cur_index==0:?#?如果它是范圍中的第一個,則選擇第二個next_index=1elif?cur_index==len(all_values)-1:?#?如果它是范圍中的最后一個,則選擇前一個next_index=len(all_values)-2else:?#?否則隨機選擇左或右值direction=np.random.choice([-1,1])next_index=cur_index?+?directionnext_params?=?dict((k,v)?for?k,v?in?cur_params.items())next_params[choose_param_name]?=?all_values[next_index]?#?更改所選參數的值print('參數的選擇移動到:?{:10s}:?from?{:6.2f}?to?{:6.2f}'.format(choose_param_name,?cur_value,?all_values[next_index]?))else:?#?生成參數的隨機組合next_params=dict()for?i?in?range(len(tune_dic)):key?=?[*tune_dic.keys()][i]?values?=?[*tune_dic.values()][i]next_params[key]?=?np.random.choice(values)return(next_params)模擬退火算法的應用
在模擬退火算法的每一次迭代中,選擇一個超參數組合。利用這些參數對XGBoost算法進行訓練,得到驗證集上的F-score 。
如果這個 F-score比前一次迭代的 F-score更好(更大),即是“局部”改進,則該組合被接受,并設置為當前組合,通過調用next_choice()函數為下一次迭代選擇相鄰的組合。
否則,如果這個F-score 比上一個迭代的更差(更小),并且梯度下降為?,則接受該組合作為具有??概率的當前組合,其中??是一個常數,?是當前的"溫度"。該方法開始時是高溫,一開始"壞的"解決方案很容易被接受,此時是希望探索廣闊的搜索空間。但隨著溫度下降,不好的解決方案被接受的可能性降低,此時搜索變得更加集中。
溫度從一個固定的值T0開始,每n次迭代就減少一個因子 alpha < 1。這里T0 = 0.40, n=5, alpha = 0.85。常數beta=1.3。
這個"冷卻計劃"的參數選擇可以很容易地在Excel中完成。在這個例子中,我們選擇F-Score惡化的平均接受概率為?0.150,0.075,0.038,0.019,0.009,即初始值是0.150,公比1/2。我們將這些平均概率設置為50%左右在第1,第2,…,第5次的20次迭代,并使用Excel求解器尋找合適的參數。
▲ 部分截圖這里可以使用簡單的哈希方案可以避免重復。
一個警示:如果迭代的次數不足夠,即小于組合的總數,此時可能出現太多的重復和延遲。這里實現的生成組合的簡單方法并沒有解決這種情況。
import?time t0?=?time.clock() T=0.40 best_params?=?dict()?#?初始化字典用以保存最佳參數 best_f_score?=?-1.???#?初始化最佳F-score prev_f_score?=?-1.???#?初始化先前的F-score prev_choice?=?None???#?初始化先前選擇的參數 weights?=?list(map(lambda?x:?10**x,?[0,1,2,3,4]))?#?哈希函數的權值 hash_values=set()for?iter?in?range(maxiter):print('\nIteration?=?{:5d}??T?=?{:12.6f}'.format(iter,T))#?找到以前沒有訪問過的參數的下一個選擇while?True:#?第一個選擇或選擇prev_choice的鄰居cur_choice=next_choice(prev_choice)??????????#?按參數的字母順序排列的選擇索引??indices=[tune_dic[name].index(cur_choice[name])?for?name?in?sorted([*tune_dic.keys()])]??????#?檢查選擇是否已經被訪問hash_val?=?sum([i*j?for?(i,?j)?in?zip(weights,?indices)])if?hash_val?in?hash_values:print('\n再次訪問組合?--?再次搜索') #????????tmp=abs(results.loc[:,[*cur_choice.keys()]]?-?list(cur_choice.values())) #????????tmp=tmp.sum(axis=1) #????????if?any(tmp==0):?##?selection?has?already?been?visited #????????????print('\n再次訪問組合?--?再次搜索')else:hash_values.add(hash_val)break?#?跳出while循環#?訓練模型并在驗證數據集上獲得F-scoref_score,model=do_train(cur_choice,?param,?dtrain,'train',trainY,dvalid,'valid',validY)??#?存儲參數results.loc[iter,[*cur_choice.keys()]]=list(cur_choice.values())???print('F-Score:?{:6.2f}??先前值:?{:6.2f}?目前最佳值:?{:6.2f}'.format(f_score,?prev_f_score,?best_f_score))if?f_score?>?prev_f_score:print('局部改進')???#?接受這個組合作為新的起點prev_f_score?=?f_scoreprev_choice?=?cur_choice?????#?如果F-score全局較好,則更新最佳參數if?f_score?>?best_f_score:?????????best_f_score?=?f_scoreprint('全局改進?-?最佳F-score已更新')for?(key,value)?in?prev_choice.items():best_params[key]=valueelse:?##?F-score比先前值小????????##?接受這個組合作為新的概率起點?exp(-(1.6?x?f-score?下降)/溫度)?rnd?=?random.random()diff?=?f_score-prev_f_scorethres=np.exp(1.3*diff/T)if?rnd?<=?thres:print('更糟糕的結果。F-Score 變化:?{:8.4f}??閾值:?{:6.4f}??隨機數:?{:6.4f}?->?已接受'.format(diff,?thres,?rnd))prev_f_score?=?f_scoreprev_choice?=?cur_choiceelse:#?不更新以前的F-score和以前選擇的參數print('更糟糕的結果。F-Score 變化:?{:8.4f}??閾值:?{:6.4f}??隨機數:?{:6.4f}?->?已拒絕'.format(diff,?thres,?rnd))#?存儲結果results.loc[iter,'F-Score']=f_scoreresults.loc[iter,'最佳F-Score']=best_f_scoreif?iter?%?5?==?0:?T=0.85*T??#?每5次迭代降低溫度并繼續???????? print('\n{:6.1f}?分鐘處理時間\n'.format((time.clock()?-?t0)/60))???? print('找到最佳變量參數:\n') print(best_params)Iteration = 0 T = 0.400000 參數: eta : 0.05 colsample_bytree : 0.9 scale_pos_weight : 300 gamma : 0.2 max_depth : 20 subsample : 0.5 F-Score: 0.80 先前值: -1.00 目前最佳值: -1.00 局部改進 全局改進 - 最佳F-score已更新 ...19.2 分鐘處理時間 找到最佳變量參數: {'eta': 0.4, 'colsample_bytree': 1.0, 'scale_pos_weight': 50, 'gamma': 0.1, 'max_depth': 15, 'subsample': 0.5}對測試數據集的評估
對測試數據集的評估結果為F-Score=0.86該結果還可以,因為需要考慮到Class的高度不平衡性。
最好的超參數是在預期良好的范圍內。后期可以繼續優化:
縮小超參數的范圍。
或許可以添加其他這里沒有使用的參數(例如,正則化參數)。
獲取可以在變量重要性信息的基礎上進行變量選擇。
重要的是,與集成類似,可以將不同的模型組合起來。
測試數據集上的F-score:0.86
特征重要性
參考資料
[1]?
模擬退火:?https://en.wikipedia.org/wiki/Simulated_annealing
[2]?啟發式搜索:?https://github.com/KSpiliop/Fraud_Detection
[3]?Slideshare presentation:?https://www.slideshare.net/ShangxuanZhang/kaggle-winning-solution-xgboost-algorithm-let-us-learn-from-its-author
[4]?不平衡分類的欠采樣概率校準:?http://www.oliviercaelen.be/doc/SSCI_calib_final.pdf
[5]?Official XGBoost Guide:?http://xgboost.readthedocs.io/en/latest/parameter.html
[6]?Notes on Parameter Tuning:?http://xgboost.readthedocs.io/en/latest/how_to/param_tuning.html
[7]?Analytics Vidhya:?https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/
[8]?Second Slideshare presentation:?https://www.slideshare.net/odsc/owen-zhangopen-sourcetoolsanddscompetitions1
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載黃海廣老師《機器學習課程》視頻課黃海廣老師《機器學習課程》711頁完整版課件本站qq群955171419,加入微信群請掃碼:
總結
以上是生活随笔為你收集整理的【机器学习】信用卡欺诈检测|用启发式搜索优化XGBoost超参数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Python】这10个Python性能
- 下一篇: Android平台如何实现屏幕数据采集并