生活随笔
收集整理的這篇文章主要介紹了
迁移学习和冷启动
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? 本文是《智能風控原理、算法和工程實踐》第3章學習筆記。算法推導部分較難,就沒有列出來,因為我也看不懂。
冷啟動
? 冷啟動是指在沒有或只有很少量數據的情況下,從0到1建立業務模型的過程。在風控業務中,早期缺乏數據積累,遷移學習和異常檢測技術都可以用來處理部分冷啟動問題。
應用場景
新開了某個業務,只有少量樣本,需要用其他場景的數據來建模。此時其他場景為源域,新業務場景為目標域。 業務被迫停止3個月后重啟,大部分訓練樣本比較老舊。大部分舊樣本為源域,新的少量訓練樣本為目標域。 在某個國家開展類似國內的業務。國內業務積累的數據為源域,新國家場景為目標域。
? 概括起來,源域樣本和目標域樣本分布有區別,目標域樣本量又不夠。
概念介紹
? 遷移學習是一種通過調用不同場景中的數據來建立模型的方法。通過遷移學習可以將知識從源域遷移到目標域。 ? 一個簡單的例子,假如現在有大量英短銀漸層和少量英短高地的圖片,期望訓練一個能夠識別當前的貓是不是英短高地的學習器。這時可以用英短銀漸層圖片來訓練一個卷積神經網絡,并將這個網絡的中間結點取出來作為目標模型的前半部分,然后在少量英短高地的樣本上再繼續訓練學習后面的幾層網絡。 ? 卷積神經網絡前幾層學習的是輪廓和局部形狀等貓的共性特征,通過前面網絡的學習模型就掌握了貓的共性,再通過后續網絡對英短高地學習。
常見遷移學習算法
TrAdaBoost。 ? 賦予源域中的樣本某種權重,使其分布靠近目標域。 聯合分布適配方法(JDA)。 ? 尋找一個低維子空間,使源域和目標域的數據樣本在映射到該子空間后服從相同或相近的分布。 遷移極限學習機(DTELM)。 ? 利用低秩矩陣重構數據點,實現域之間的魯棒自適應。 ? 第一種算法因為不在特征空間上做任何扭曲變化,可以很好地保留模型的解釋性,所以應該更為廣泛。第二、第三種算法在解釋性上有一定不足,但不需要在目標場景有真實的樣本標簽,對于初期的業務支持度更好。
TrAdaBoost模型
? 將不同分布的訓練集放在一起訓練,這種方法也叫作基于實例的遷移學習方法。 ? TraAdaBoost是有AdaBoost演變而來。在一個包含源域訓練數據和目標域樣本的訓練集中,TrAdaBoost會對訓練樣本進行權重調整。
對目標域樣本,如果被誤分類,根據目標域樣本的分類錯誤率進行調整,增加其權重,使得下次訓練時更關注錯分的目標域樣本。 對源域樣本,如果被誤分類,則會認為它們是與目標數據不同分布的,會降低其權重。
跨場景遷移模型
? 在新場景下開展小額現金貸產品,積累了1200條有標簽的樣本,嘗試對原有大額產品的存量客戶進行遷移。有4個在舊業務上表現較好的特征,保證原有場景和目標場景都有這個特征且含義一致。
import pandas
as pd
from sklearn
. metrics
import roc_auc_score
, roc_curve
, auc
from sklearn
. model_selection
import train_test_split
from sklearn
import metrics
from sklearn
. linear_model
import LogisticRegression
from sklearn
. svm
import LinearSVC
import numpy
as np
import random
import math
from sklearn
. calibration
import CalibratedClassifierCVdata
= pd
. read_excel
( './data/tra_sample.xlsx' )
data
. head
( )
? type的三種標簽分別代表著目標域、源域和時間外樣本集。根據標簽劃分樣本集。
feature_lst
= [ 'zx_score' , 'msg_cnt' , 'phone_num_cnt' , 'register_days' ] train
= data
[ data
. type == 'target' ] . reset_index
( ) . copy
( )
diff
= data
[ data
. type == 'origin' ] . reset_index
( ) . copy
( )
val
= data
[ data
. type == 'offtime' ] . reset_index
( ) . copy
( )
train
= train
. loc
[ : 1200 ] trans_S
= train
[ feature_lst
] . copy
( )
label_S
= train
[ 'bad_ind' ] . copy
( ) trans_A
= diff
[ feature_lst
] . copy
( )
label_A
= diff
[ 'bad_ind' ] . copy
( ) val_x
= val
[ feature_lst
] . copy
( )
val_y
= val
[ 'bad_ind' ] . copy
( ) test
= val_x
. copy
( )
? 對目標域的少量樣本進行擬合,結果如下:
? 訓練集和時間外樣本集KS相差超過10%,遠高于行業要求的5%。且ROC曲線不穩定,意味著模型的泛化能力較差。 ? 將源域數據和目標域數據整合到一起擬合,注意一下整合時用到的函數,結果如下:
trans_data
= np
. concatenate
( ( trans_A
, trans_S
) , axis
= 0 )
trans_label
= np
. concatenate
( ( label_A
, label_S
) , axis
= 0 )
? 下面使用TrAdaBoost算法,將源域數據中與目標域分布差別較大的數據設置一個很小的值,來弱化兩個數據集的分布差異。 算法比較復雜,代碼無法看懂,等用到的時候再回來研究。
import numpy
as np
from sklearn
import tree
def calculate_P ( weights
, label
) : total
= np
. sum ( weights
) return np
. asarray
( weights
/ total
, order
= 'C' )
def train_classify ( trans_data
, trans_label
, test_data
, P
) : clf
= LogisticRegression
( C
= 0.3 , class_weight
= 'balanced' , solver
= 'liblinear' ) clf
. fit
( trans_data
, trans_label
, sample_weight
= P
[ : , 0 ] ) return clf
. predict_proba
( test_data
) [ : , 1 ] , clf
def calculate_error_rate ( label_R
, label_H
, weight
) : total
= np
. sum ( weight
) return np
. sum ( weight
[ : , 0 ] / total
* np
. abs ( label_R
- label_H
) )
def put_label ( score_H
, thred
) : new_label_H
= [ ] for i
in score_H
: if i
<= thred
: new_label_H
. append
( 0 ) else : new_label_H
. append
( 1 ) return new_label_H
N
= 500 trans_data
= np
. concatenate
( ( trans_A
, trans_S
) , axis
= 0 )
trans_label
= np
. concatenate
( ( label_A
, label_S
) , axis
= 0 ) row_A
= trans_A
. shape
[ 0 ]
row_S
= trans_S
. shape
[ 0 ]
row_T
= test
. shape
[ 0 ] test_data
= np
. concatenate
( ( trans_data
, test
) , axis
= 0 )
weights_A
= np
. ones
( [ row_A
, 1 ] ) / row_A
weights_S
= np
. ones
( [ row_S
, 1 ] ) / row_S
* 2
weights
= np
. concatenate
( ( weights_A
, weights_S
) , axis
= 0 ) bata
= 1 / ( 1 + np
. sqrt
( 2 * np
. log
( row_A
/ N
) ) )
bata_T
= np
. zeros
( [ 1 , N
] )
result_label
= np
. ones
( [ row_A
+ row_S
+ row_T
, N
] ) predict
= np
. zeros
( [ row_T
] ) trans_data
= np
. asarray
( trans_data
, order
= 'C' )
trans_label
= np
. asarray
( trans_label
, order
= 'C' )
test_data
= np
. asarray
( test_data
, order
= 'C' ) best_ks
= - 1
best_round
= - 1
best_model
= - 1 for i
in range ( N
) : P
= calculate_P
( weights
, trans_label
) result_label
[ : , i
] , model
= train_classify
( trans_data
, trans_label
, test_data
, P
) score_H
= result_label
[ row_A
: row_A
+ row_S
, i
] pctg
= np
. sum ( data
. bad_ind
) / len ( data
. bad_ind
) thred
= pd
. DataFrame
( score_H
) . quantile
( 1 - pctg
) [ 0 ] label_H
= put_label
( score_H
, thred
) error_rate
= calculate_error_rate
( label_S
, label_H
, weights
[ row_A
: row_A
+ row_S
, : ] ) if error_rate
> 0.5 : error_rate
= 0.5 if error_rate
== 0 : N
= i
break bata_T
[ 0 , i
] = error_rate
/ ( 1 - error_rate
) for j
in range ( row_S
) : weights
[ row_A
+ j
] = weights
[ row_A
+ j
] * np
. power
( bata_T
[ 0 , i
] , ( - np
. abs ( result_label
[ row_A
+ j
, i
] - label_S
[ j
] ) ) ) for j
in range ( row_A
) : weights
[ j
] = weights
[ j
] * np
. power
( bata
, np
. abs ( result_label
[ j
, i
] - label_A
[ j
] ) ) y_pred
= result_label
[ ( row_A
+ row_S
) : , i
] fpr_lr_train
, tpr_lr_train
, _
= roc_curve
( val_y
, y_pred
) train_ks
= abs ( fpr_lr_train
- tpr_lr_train
) . max ( ) print ( 'test_ks : ' , train_ks
, '當前第' , i
+ 1 , '輪' ) if train_ks
> best_ks
: best_ks
= train_ksbest_round
= ibest_model
= model
? 訓練結束后,用最優的邏輯回歸模型對樣本進行測試,結果如下:
? 該方案只使用訓練過程中表現最好的學習器進行決策,因此保留了單個邏輯回歸模型的解釋性,對于模型上線部署沒有影響。但是這也增大了過擬合的風險,在實際使用中需要權衡迭代次數。
【作者】:Labryant 【原創公眾號】:風控獵人 【簡介】:某創業公司策略分析師,積極上進,努力提升。乾坤未定,你我都是黑馬。 【轉載說明】:轉載請說明出處,謝謝合作!~
總結
以上是生活随笔 為你收集整理的迁移学习和冷启动 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。