【算法竞赛学习】金融风控之贷款违约预测-特征工程
Task3 特征工程
此部分為零基礎(chǔ)入門金融風(fēng)控的 Task3 特征工程部分,帶你來了解各種特征工程以及分析方法,歡迎大家后續(xù)多多交流。
賽題:零基礎(chǔ)入門數(shù)據(jù)挖掘 - 零基礎(chǔ)入門金融風(fēng)控之貸款違約
項(xiàng)目地址:https://github.com/datawhalechina/team-learning-data-mining/tree/master/FinancialRiskControl
比賽地址:https://tianchi.aliyun.com/competition/entrance/531830/introduction
3.1 學(xué)習(xí)目標(biāo)
- 學(xué)習(xí)特征預(yù)處理、缺失值、異常值處理、數(shù)據(jù)分桶等特征處理方法
- 學(xué)習(xí)特征交互、編碼、選擇的相應(yīng)方法
- 完成相應(yīng)學(xué)習(xí)打卡任務(wù),兩個(gè)選做的作業(yè)不做強(qiáng)制性要求,供學(xué)有余力同學(xué)自己探索
3.2 內(nèi)容介紹
- 數(shù)據(jù)預(yù)處理
- 缺失值的填充
- 時(shí)間格式處理
- 對(duì)象類型特征轉(zhuǎn)換到數(shù)值
- 異常值處理
- 基于3segama原則
- 基于箱型圖
- 數(shù)據(jù)分箱
- 固定寬度分箱
- 分位數(shù)分箱
- 離散數(shù)值型數(shù)據(jù)分箱
- 連續(xù)數(shù)值型數(shù)據(jù)分箱
- 卡方分箱(選做作業(yè))
- 特征交互
- 特征和特征之間組合
- 特征和特征之間衍生
- 其他特征衍生的嘗試(選做作業(yè))
- 特征編碼
- one-hot編碼
- label-encode編碼
- 特征選擇
- 1 Filter
- 2 Wrapper (RFE)
- 3 Embedded
3.3 代碼示例
3.3.1 導(dǎo)入包并讀取數(shù)據(jù)
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import datetime from tqdm import tqdm from sklearn.preprocessing import LabelEncoder from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 from sklearn.preprocessing import MinMaxScaler import xgboost as xgb import lightgbm as lgb from catboost import CatBoostRegressor import warnings from sklearn.model_selection import StratifiedKFold, KFold from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss warnings.filterwarnings('ignore') data_train =pd.read_csv('../train.csv') data_test_a = pd.read_csv('../testA.csv')3.3.2特征預(yù)處理
- 數(shù)據(jù)EDA部分我們已經(jīng)對(duì)數(shù)據(jù)的大概和某些特征分布有了了解,數(shù)據(jù)預(yù)處理部分一般我們要處理一些EDA階段分析出來的問題,這里介紹了數(shù)據(jù)缺失值的填充,時(shí)間格式特征的轉(zhuǎn)化處理,某些對(duì)象類別特征的處理。
首先我們查找出數(shù)據(jù)中的對(duì)象特征和數(shù)值特征
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns) category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns))) label = 'isDefault' numerical_fea.remove(label)在比賽中數(shù)據(jù)預(yù)處理是必不可少的一部分,對(duì)于缺失值的填充往往會(huì)影響比賽的結(jié)果,在比賽中不妨嘗試多種填充然后比較結(jié)果選擇結(jié)果最優(yōu)的一種;
比賽數(shù)據(jù)相比真實(shí)場(chǎng)景的數(shù)據(jù)相對(duì)要“干凈”一些,但是還是會(huì)有一定的“臟”數(shù)據(jù)存在,清洗一些異常值往往會(huì)獲得意想不到的效果。
缺失值填充
-
把所有缺失值替換為指定的值0
data_train = data_train.fillna(0)
-
向用缺失值上面的值替換缺失值
data_train = data_train.fillna(axis=0,method=‘ffill’)
-
縱向用缺失值下面的值替換缺失值,且設(shè)置最多只填充兩個(gè)連續(xù)的缺失值
data_train = data_train.fillna(axis=0,method=‘bfill’,limit=2)
- category_fea:對(duì)象型類別特征需要進(jìn)行預(yù)處理,其中[‘issueDate’]為時(shí)間格式特征。
時(shí)間格式處理
#轉(zhuǎn)化成時(shí)間格式 for data in [data_train, data_test_a]:data['issueDate'] = pd.to_datetime(data['issueDate'],format='%Y-%m-%d')startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')#構(gòu)造時(shí)間特征data['issueDateDT'] = data['issueDate'].apply(lambda x: x-startdate).dt.days data_train['employmentLength'].value_counts(dropna=False).sort_index() 1 year 52489 10+ years 262753 2 years 72358 3 years 64152 4 years 47985 5 years 50102 6 years 37254 7 years 35407 8 years 36192 9 years 30272 < 1 year 64237 NaN 46799 Name: employmentLength, dtype: int64對(duì)象類型特征轉(zhuǎn)換到數(shù)值
def employmentLength_to_int(s):if pd.isnull(s):return selse:return np.int8(s.split()[0]) for data in [data_train, data_test_a]:data['employmentLength'].replace(to_replace='10+ years', value='10 years', inplace=True)data['employmentLength'].replace('< 1 year', '0 years', inplace=True)data['employmentLength'] = data['employmentLength'].apply(employmentLength_to_int) data['employmentLength'].value_counts(dropna=False).sort_index() 0.0 15989 1.0 13182 2.0 18207 3.0 16011 4.0 11833 5.0 12543 6.0 9328 7.0 8823 8.0 8976 9.0 7594 10.0 65772 NaN 11742 Name: employmentLength, dtype: int64- 對(duì)earliesCreditLine進(jìn)行預(yù)處理
類別特征處理
# 部分類別特征 cate_features = ['grade', 'subGrade', 'employmentTitle', 'homeOwnership', 'verificationStatus', 'purpose', 'postCode', 'regionCode', \'applicationType', 'initialListStatus', 'title', 'policyCode'] for f in cate_features:print(f, '類型數(shù):', data[f].nunique()) grade 類型數(shù): 7 subGrade 類型數(shù): 35 employmentTitle 類型數(shù): 79282 homeOwnership 類型數(shù): 6 verificationStatus 類型數(shù): 3 purpose 類型數(shù): 14 postCode 類型數(shù): 889 regionCode 類型數(shù): 51 applicationType 類型數(shù): 2 initialListStatus 類型數(shù): 2 title 類型數(shù): 12058 policyCode 類型數(shù): 1像等級(jí)這種類別特征,是有優(yōu)先級(jí)的可以labelencode或者自映射
for data in [data_train, data_test_a]:data['grade'] = data['grade'].map({'A':1,'B':2,'C':3,'D':4,'E':5,'F':6,'G':7}) # 類型數(shù)在2之上,又不是高維稀疏的,且純分類特征 for data in [data_train, data_test_a]:data = pd.get_dummies(data, columns=['subGrade', 'homeOwnership', 'verificationStatus', 'purpose', 'regionCode'], drop_first=True)3.3.3 異常值處理
- 當(dāng)你發(fā)現(xiàn)異常值后,一定要先分清是什么原因?qū)е碌漠惓V?#xff0c;然后再考慮如何處理。首先,如果這一異常值并不代表一種規(guī)律性的,而是極其偶然的現(xiàn)象,或者說你并不想研究這種偶然的現(xiàn)象,這時(shí)可以將其刪除。其次,如果異常值存在且代表了一種真實(shí)存在的現(xiàn)象,那就不能隨便刪除。在現(xiàn)有的欺詐場(chǎng)景中很多時(shí)候欺詐數(shù)據(jù)本身相對(duì)于正常數(shù)據(jù)勒說就是異常的,我們要把這些異常點(diǎn)納入,重新擬合模型,研究其規(guī)律。能用監(jiān)督的用監(jiān)督模型,不能用的還可以考慮用異常檢測(cè)的算法來做。
- 注意test的數(shù)據(jù)不能刪。
檢測(cè)異常的方法一:均方差
在統(tǒng)計(jì)學(xué)中,如果一個(gè)數(shù)據(jù)分布近似正態(tài),那么大約 68% 的數(shù)據(jù)值會(huì)在均值的一個(gè)標(biāo)準(zhǔn)差范圍內(nèi),大約 95% 會(huì)在兩個(gè)標(biāo)準(zhǔn)差范圍內(nèi),大約 99.7% 會(huì)在三個(gè)標(biāo)準(zhǔn)差范圍內(nèi)。
def find_outliers_by_3segama(data,fea):data_std = np.std(data[fea])data_mean = np.mean(data[fea])outliers_cut_off = data_std * 3lower_rule = data_mean - outliers_cut_offupper_rule = data_mean + outliers_cut_offdata[fea+'_outliers'] = data[fea].apply(lambda x:str('異常值') if x > upper_rule or x < lower_rule else '正常值')return data- 得到特征的異常值后可以進(jìn)一步分析變量異常值和目標(biāo)變量的關(guān)系
- 例如可以看到異常值在兩個(gè)變量上的分布幾乎復(fù)合整體的分布,如果異常值都屬于為1的用戶數(shù)據(jù)里面代表什么呢?
檢測(cè)異常的方法二:箱型圖
- 總結(jié)一句話:四分位數(shù)會(huì)將數(shù)據(jù)分為三個(gè)點(diǎn)和四個(gè)區(qū)間,IQR = Q3 -Q1,下觸須=Q1 ? 1.5x IQR,上觸須=Q3 + 1.5x IQR;
3.3.4 數(shù)據(jù)分桶
-
特征分箱的目的:
- 從模型效果上來看,特征分箱主要是為了降低變量的復(fù)雜性,減少變量噪音對(duì)模型的影響,提高自變量和因變量的相關(guān)度。從而使模型更加穩(wěn)定。
-
數(shù)據(jù)分桶的對(duì)象:
- 將連續(xù)變量離散化
- 將多狀態(tài)的離散變量合并成少狀態(tài)
-
分箱的原因:
- 數(shù)據(jù)的特征內(nèi)的值跨度可能比較大,對(duì)有監(jiān)督和無監(jiān)督中如k-均值聚類它使用歐氏距離作為相似度函數(shù)來測(cè)量數(shù)據(jù)點(diǎn)之間的相似度。都會(huì)造成大吃小的影響,其中一種解決方法是對(duì)計(jì)數(shù)值進(jìn)行區(qū)間量化即數(shù)據(jù)分桶也叫做數(shù)據(jù)分箱,然后使用量化后的結(jié)果。
-
分箱的優(yōu)點(diǎn):
- 處理缺失值:當(dāng)數(shù)據(jù)源可能存在缺失值,此時(shí)可以把null單獨(dú)作為一個(gè)分箱。
- 處理異常值:當(dāng)數(shù)據(jù)中存在離群點(diǎn)時(shí),可以把其通過分箱離散化處理,從而提高變量的魯棒性(抗干擾能力)。例如,age若出現(xiàn)200這種異常值,可分入“age > 60”這個(gè)分箱里,排除影響。
- 業(yè)務(wù)解釋性:我們習(xí)慣于線性判斷變量的作用,當(dāng)x越來越大,y就越來越大。但實(shí)際x與y之間經(jīng)常存在著非線性關(guān)系,此時(shí)可經(jīng)過WOE變換。
-
特別要注意一下分箱的基本原則:
- (1)最小分箱占比不低于5%
- (2)箱內(nèi)不能全部是好客戶
- (3)連續(xù)箱單調(diào)
當(dāng)數(shù)值橫跨多個(gè)數(shù)量級(jí)時(shí),最好按照 10 的冪(或任何常數(shù)的冪)來進(jìn)行分組:09、1099、100999、10009999,等等。固定寬度分箱非常容易計(jì)算,但如果計(jì)數(shù)值中有比較大的缺口,就會(huì)產(chǎn)生很多沒有任何數(shù)據(jù)的空箱子。
# 通過除法映射到間隔均勻的分箱中,每個(gè)分箱的取值范圍都是loanAmnt/1000 data['loanAmnt_bin1'] = np.floor_divide(data['loanAmnt'], 1000) ## 通過對(duì)數(shù)函數(shù)映射到指數(shù)寬度分箱 data['loanAmnt_bin2'] = np.floor(np.log10(data['loanAmnt']))- 這一部分屬于進(jìn)階部分,學(xué)有余力的同學(xué)可以自行搜索嘗試。
3.3.5 特征交互
- 交互特征的構(gòu)造非常簡(jiǎn)單,使用起來卻代價(jià)不菲。如果線性模型中包含有交互特征對(duì),那它的訓(xùn)練時(shí)間和評(píng)分時(shí)間就會(huì)從 O(n) 增加到 O(n2),其中 n 是單一特征的數(shù)量。
這里給出一些特征交互的思路,但特征和特征間的交互衍生出新的特征還遠(yuǎn)遠(yuǎn)不止于此,拋磚引玉,希望大家多多探索。請(qǐng)學(xué)習(xí)者嘗試其他的特征交互方法。
3.3.6 特征編碼
labelEncode 直接放入樹模型中
#label-encode:subGrade,postCode,title # 高維類別特征需要進(jìn)行轉(zhuǎn)換 for col in tqdm(['employmentTitle', 'postCode', 'title','subGrade']):le = LabelEncoder()le.fit(list(data_train[col].astype(str).values) + list(data_test_a[col].astype(str).values))data_train[col] = le.transform(list(data_train[col].astype(str).values))data_test_a[col] = le.transform(list(data_test_a[col].astype(str).values)) print('Label Encoding 完成') 100%|██████████| 4/4 [00:08<00:00, 2.04s/it]Label Encoding 完成邏輯回歸等模型要單獨(dú)增加的特征工程
- 對(duì)特征做歸一化,去除相關(guān)性高的特征
- 歸一化目的是讓訓(xùn)練過程更好更快的收斂,避免特征大吃小的問題
- 去除相關(guān)性是增加模型的可解釋性,加快預(yù)測(cè)過程。
3.3.7 特征選擇
- 特征選擇技術(shù)可以精簡(jiǎn)掉無用的特征,以降低最終模型的復(fù)雜性,它的最終目的是得到一個(gè)簡(jiǎn)約模型,在不降低預(yù)測(cè)準(zhǔn)確率或?qū)︻A(yù)測(cè)準(zhǔn)確率影響不大的情況下提高計(jì)算速度。特征選擇不是為了減少訓(xùn)練時(shí)間(實(shí)際上,一些技術(shù)會(huì)增加總體訓(xùn)練時(shí)間),而是為了減少模型評(píng)分時(shí)間。
特征選擇的方法:
- 1 Filter
- 方差選擇法
- 相關(guān)系數(shù)法(pearson 相關(guān)系數(shù))
- 卡方檢驗(yàn)
- 互信息法
- 2 Wrapper (RFE)
- 遞歸特征消除法
- 3 Embedded
- 基于懲罰項(xiàng)的特征選擇法
- 基于樹模型的特征選擇
Filter
- 基于特征間的關(guān)系進(jìn)行篩選
方差選擇法
- 方差選擇法中,先要計(jì)算各個(gè)特征的方差,然后根據(jù)設(shè)定的閾值,選擇方差大于閾值的特征
相關(guān)系數(shù)法
- Pearson 相關(guān)系數(shù)
皮爾森相關(guān)系數(shù)是一種最簡(jiǎn)單的,可以幫助理解特征和響應(yīng)變量之間關(guān)系的方法,該方法衡量的是變量之間的線性相關(guān)性。
結(jié)果的取值區(qū)間為 [-1,1] , -1 表示完全的負(fù)相關(guān), +1表示完全的正相關(guān),0 表示沒有線性相關(guān)。
卡方檢驗(yàn)
- 經(jīng)典的卡方檢驗(yàn)是用于檢驗(yàn)自變量對(duì)因變量的相關(guān)性。 假設(shè)自變量有N種取值,因變量有M種取值,考慮自變量等于i且因變量等于j的樣本頻數(shù)的觀察值與期望的差距。 其統(tǒng)計(jì)量如下: χ2=∑(A?T)2T,其中A為實(shí)際值,T為理論值
- (注:卡方只能運(yùn)用在正定矩陣上,否則會(huì)報(bào)錯(cuò)Input X must be non-negative)
互信息法
- 經(jīng)典的互信息也是評(píng)價(jià)自變量對(duì)因變量的相關(guān)性的。 在feature_selection庫的SelectKBest類結(jié)合最大信息系數(shù)法可以用于選擇特征,相關(guān)代碼如下:
Wrapper (Recursive feature elimination,RFE)
- 遞歸特征消除法 遞歸消除特征法使用一個(gè)基模型來進(jìn)行多輪訓(xùn)練,每輪訓(xùn)練后,消除若干權(quán)值系數(shù)的特征,再基于新的特征集進(jìn)行下一輪訓(xùn)練。 在feature_selection庫的RFE類可以用于選擇特征,相關(guān)代碼如下(以邏輯回歸為例):
Embedded
- 基于懲罰項(xiàng)的特征選擇法 使用帶懲罰項(xiàng)的基模型,除了篩選出特征外,同時(shí)也進(jìn)行了降維。 在feature_selection庫的SelectFromModel類結(jié)合邏輯回歸模型可以用于選擇特征,相關(guān)代碼如下:
- 基于樹模型的特征選擇 樹模型中GBDT也可用來作為基模型進(jìn)行特征選擇。 在feature_selection庫的SelectFromModel類結(jié)合GBDT模型可以用于選擇特征,相關(guān)代碼如下:
本數(shù)據(jù)集中我們刪除非入模特征后,并對(duì)缺失值填充,然后用計(jì)算協(xié)方差的方式看一下特征間相關(guān)性,然后進(jìn)行模型訓(xùn)練
# 刪除不需要的數(shù)據(jù) for data in [data_train, data_test_a]:data.drop(['issueDate','id'], axis=1,inplace=True) "縱向用缺失值上面的值替換缺失值" data_train = data_train.fillna(axis=0,method='ffill') x_train = data_train.drop(['isDefault','id'], axis=1) #計(jì)算協(xié)方差 data_corr = x_train.corrwith(data_train.isDefault) #計(jì)算相關(guān)性 result = pd.DataFrame(columns=['features', 'corr']) result['features'] = data_corr.index result['corr'] = data_corr.values # 當(dāng)然也可以直接看圖 data_numeric = data_train[numerical_fea] correlation = data_numeric.corr()f , ax = plt.subplots(figsize = (7, 7)) plt.title('Correlation of Numeric Features with Price',y=1,size=16) sns.heatmap(correlation,square = True, vmax=0.8) <matplotlib.axes._subplots.AxesSubplot at 0x12d88ad10> features = [f for f in data_train.columns if f not in ['id','issueDate','isDefault'] and '_outliers' not in f] x_train = data_train[features] x_test = data_test_a[features] y_train = data_train['isDefault'] def cv_model(clf, train_x, train_y, test_x, clf_name):folds = 5seed = 2020kf = KFold(n_splits=folds, shuffle=True, random_state=seed)train = np.zeros(train_x.shape[0])test = np.zeros(test_x.shape[0])cv_scores = []for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):print('************************************ {} ************************************'.format(str(i+1)))trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]if clf_name == "lgb":train_matrix = clf.Dataset(trn_x, label=trn_y)valid_matrix = clf.Dataset(val_x, label=val_y)params = {'boosting_type': 'gbdt','objective': 'binary','metric': 'auc','min_child_weight': 5,'num_leaves': 2 ** 5,'lambda_l2': 10,'feature_fraction': 0.8,'bagging_fraction': 0.8,'bagging_freq': 4,'learning_rate': 0.1,'seed': 2020,'nthread': 28,'n_jobs':24,'silent': True,'verbose': -1,}model = clf.train(params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix], verbose_eval=200,early_stopping_rounds=200)val_pred = model.predict(val_x, num_iteration=model.best_iteration)test_pred = model.predict(test_x, num_iteration=model.best_iteration)# print(list(sorted(zip(features, model.feature_importance("gain")), key=lambda x: x[1], reverse=True))[:20])if clf_name == "xgb":train_matrix = clf.DMatrix(trn_x , label=trn_y)valid_matrix = clf.DMatrix(val_x , label=val_y)params = {'booster': 'gbtree','objective': 'binary:logistic','eval_metric': 'auc','gamma': 1,'min_child_weight': 1.5,'max_depth': 5,'lambda': 10,'subsample': 0.7,'colsample_bytree': 0.7,'colsample_bylevel': 0.7,'eta': 0.04,'tree_method': 'exact','seed': 2020,'nthread': 36,"silent": True,}watchlist = [(train_matrix, 'train'),(valid_matrix, 'eval')]model = clf.train(params, train_matrix, num_boost_round=50000, evals=watchlist, verbose_eval=200, early_stopping_rounds=200)val_pred = model.predict(valid_matrix, ntree_limit=model.best_ntree_limit)test_pred = model.predict(test_x , ntree_limit=model.best_ntree_limit)if clf_name == "cat":params = {'learning_rate': 0.05, 'depth': 5, 'l2_leaf_reg': 10, 'bootstrap_type': 'Bernoulli','od_type': 'Iter', 'od_wait': 50, 'random_seed': 11, 'allow_writing_files': False}model = clf(iterations=20000, **params)model.fit(trn_x, trn_y, eval_set=(val_x, val_y),cat_features=[], use_best_model=True, verbose=500)val_pred = model.predict(val_x)test_pred = model.predict(test_x)train[valid_index] = val_predtest = test_pred / kf.n_splitscv_scores.append(roc_auc_score(val_y, val_pred))print(cv_scores)print("%s_scotrainre_list:" % clf_name, cv_scores)print("%s_score_mean:" % clf_name, np.mean(cv_scores))print("%s_score_std:" % clf_name, np.std(cv_scores))return train, test def lgb_model(x_train, y_train, x_test):lgb_train, lgb_test = cv_model(lgb, x_train, y_train, x_test, "lgb")return lgb_train, lgb_testdef xgb_model(x_train, y_train, x_test):xgb_train, xgb_test = cv_model(xgb, x_train, y_train, x_test, "xgb")return xgb_train, xgb_testdef cat_model(x_train, y_train, x_test):cat_train, cat_test = cv_model(CatBoostRegressor, x_train, y_train, x_test, "cat") lgb_train, lgb_test = lgb_model(x_train, y_train, x_test) ************************************ 1 ************************************ Training until validation scores don't improve for 200 rounds [200] training's auc: 0.749225 valid_1's auc: 0.729679 [400] training's auc: 0.765075 valid_1's auc: 0.730496 [600] training's auc: 0.778745 valid_1's auc: 0.730435 Early stopping, best iteration is: [455] training's auc: 0.769202 valid_1's auc: 0.730686 [0.7306859913754798] ************************************ 2 ************************************ Training until validation scores don't improve for 200 rounds [200] training's auc: 0.749221 valid_1's auc: 0.731315 [400] training's auc: 0.765117 valid_1's auc: 0.731658 [600] training's auc: 0.778542 valid_1's auc: 0.731333 Early stopping, best iteration is: [407] training's auc: 0.765671 valid_1's auc: 0.73173 [0.7306859913754798, 0.7317304414673989] ************************************ 3 ************************************ Training until validation scores don't improve for 200 rounds [200] training's auc: 0.748436 valid_1's auc: 0.732775 [400] training's auc: 0.764216 valid_1's auc: 0.733173 Early stopping, best iteration is: [386] training's auc: 0.763261 valid_1's auc: 0.733261 [0.7306859913754798, 0.7317304414673989, 0.7332610441015461] ************************************ 4 ************************************ Training until validation scores don't improve for 200 rounds [200] training's auc: 0.749631 valid_1's auc: 0.728327 [400] training's auc: 0.765139 valid_1's auc: 0.728845 Early stopping, best iteration is: [286] training's auc: 0.756978 valid_1's auc: 0.728976 [0.7306859913754798, 0.7317304414673989, 0.7332610441015461, 0.7289759386807912] ************************************ 5 ************************************ Training until validation scores don't improve for 200 rounds [200] training's auc: 0.748414 valid_1's auc: 0.732727 [400] training's auc: 0.763727 valid_1's auc: 0.733531 [600] training's auc: 0.777489 valid_1's auc: 0.733566 Early stopping, best iteration is: [524] training's auc: 0.772372 valid_1's auc: 0.733772 [0.7306859913754798, 0.7317304414673989, 0.7332610441015461, 0.7289759386807912, 0.7337723979789789] lgb_scotrainre_list: [0.7306859913754798, 0.7317304414673989, 0.7332610441015461, 0.7289759386807912, 0.7337723979789789] lgb_score_mean: 0.7316851627208389 lgb_score_std: 0.0017424259863954693 testA_result = pd.read_csv('../testA_result.csv') roc_auc_score(testA_result['isDefault'].values, lgb_test) 0.72909177294878963.4 總結(jié)
特征工程是機(jī)器學(xué)習(xí),甚至是深度學(xué)習(xí)中最為重要的一部分,在實(shí)際應(yīng)用中往往也是所花費(fèi)時(shí)間最多的一步。各種算法書中對(duì)特征工程部分的講解往往少得可憐,因?yàn)樘卣鞴こ毯途唧w的數(shù)據(jù)結(jié)合的太緊密,很難系統(tǒng)地覆蓋所有場(chǎng)景。本章主要是通過一些常用的方法來做介紹,例如缺失值異常值的處理方法詳細(xì)對(duì)任何數(shù)據(jù)集來說都是適用的。但對(duì)于分箱等操作本章給出了具體的幾種思路,需要讀者自己探索。在特征工程中比賽和具體的應(yīng)用還是有所不同的,在實(shí)際的金融風(fēng)控評(píng)分卡制作過程中,由于強(qiáng)調(diào)特征的可解釋性,特征分箱尤其重要。
總結(jié)
以上是生活随笔為你收集整理的【算法竞赛学习】金融风控之贷款违约预测-特征工程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ChatGPT 化身硅谷资本家,学大厂
- 下一篇: 【算法竞赛学习】金融风控之贷款违约预测-