日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【数据分析与挖掘实战】金融风控之贷款违约预测详解1(有代码和数据集)

發布時間:2023/12/16 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【数据分析与挖掘实战】金融风控之贷款违约预测详解1(有代码和数据集) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

金融風控

  • 一.題目理解
    • 1.1.題目概況
    • 1.2數據概況
    • 1.3預測指標
  • 二.數據來源
  • 三.查看數據
  • 四.分類指標計算示例
    • 4.1混淆矩陣
    • 4.2準確度
    • 4.3precision(精確度),recall(召回率),f1-score
    • 4.4P-R曲線
    • 4.5ROC曲線
    • 4.6AUC曲線
    • 4.7KS值
  • 五.數據分析
    • 5.1基本信息
    • 5.2查看數據集中特征缺失值,唯一值等
    • 5.3查看特征的數值類型有哪些,對象類型有哪些
      • 5.3.1數值連續型變量分析
      • 5.3.2非數值類別型變量分析
      • 5.3.3總結:
    • 5.4變量分布可視化
      • 5.4.1單一變量分布可視化
      • 5.4.2根絕y值不同可視化x某個特征的分布
      • 5.4.3時間格式數據處理及查看
      • 5.4.4掌握透視圖可以讓我們更好的了解數據
      • 5.4.5用pandas_profiling生成數據報告
      • 5.4.6總結
  • 六.特征工程
    • 6.1導入包并讀取數據
    • 6.2數據預處理
    • 6.2缺失值填充
    • 6.3時間格式處理
    • 6.4類別特征處理
      • 6.5異常值處理
      • 6.6數據分桶
      • 6.7特征編碼
      • 6.8特征選擇

一.題目理解

1.1.題目概況

該數據來自某信貸平臺的貸款記錄,總數據量超過120w,包含47列變量信息,其中15列為匿名變量。為了保證比賽的公平性,將會從中抽取80萬條作為訓練集,20萬條作為測試集A,20萬條作為測試集B,同時會對employmentTitle、purpose、postCode和title等信息進行脫敏。

1.2數據概況

一般而言,對于數據在比賽界面都有對應的數據概況介紹(匿名特征除外),說明列的性質特征。了解列的性質會有助于我們對于數據的理解和后續分析。 Tip:匿名特征,就是未告知數據列所屬的性質的特征列。

train.csv

id 為貸款清單分配的唯一信用證標識

loanAmnt 貸款金額

term 貸款期限(year)

interestRate 貸款利率

installment 分期付款金額

grade 貸款等級

subGrade 貸款等級之子級

employmentTitle 就業職稱

employmentLength 就業年限(年)

homeOwnership 借款人在登記時提供的房屋所有權狀況

annualIncome 年收入

verificationStatus 驗證狀態

issueDate 貸款發放的月份

purpose 借款人在貸款申請時的貸款用途類別

postCode 借款人在貸款申請中提供的郵政編碼的前3位數字

regionCode 地區編碼

dti 債務收入比

delinquency_2years 借款人過去2年信用檔案中逾期30天以上的違約事件數

ficoRangeLow 借款人在貸款發放時的fico所屬的下限范圍

ficoRangeHigh 借款人在貸款發放時的fico所屬的上限范圍

openAcc 借款人信用檔案中未結信用額度的數量

pubRec 貶損公共記錄的數量

pubRecBankruptcies 公開記錄清除的數量

revolBal 信貸周轉余額合計

revolUtil 循環額度利用率,或借款人使用的相對于所有可用循環信貸的信貸金額

totalAcc 借款人信用檔案中當前的信用額度總數

initialListStatus 貸款的初始列表狀態

applicationType 表明貸款是個人申請還是與兩個共同借款人的聯合申請

earliesCreditLine 借款人最早報告的信用額度開立的月份

title 借款人提供的貸款名稱

policyCode 公開可用的策略代碼=1新產品不公開可用的策略代碼=2

n系列匿名特征 匿名特征n0-n14,為一些貸款人行為計數特征的處理

1.3預測指標

競賽采用AUC作為評價指標。AUC(Area Under Curve)被定義為 ROC曲線 下與坐標軸圍成的面積。

分類算法常見的評估指標如下:
1、混淆矩陣(Confuse Matrix)

(1)若一個實例是正類,并且被預測為正類,即為真正類TP(True Positive )
(2)若一個實例是正類,但是被預測為負類,即為假負類FN(False Negative )
(3)若一個實例是負類,但是被預測為正類,即為假正類FP(False Positive )
(4)若一個實例是負類,并且被預測為負類,即為真負類TN(True Negative )
2、準確率(Accuracy) 準確率是常用的一個評價指標,但是不適合樣本不均衡的情況。



8、AUC(Area Under Curve) AUC(Area Under Curve)被定義為 ROC曲線 下與坐標軸圍成的面積,顯然這個面積的數值不會大于1。又由于ROC曲線一般都處于y=x這條直線的上方,所以AUC的取值范圍在0.5和1之間。AUC越接近1.0,檢測方法真實性越高;等于0.5時,則真實性最低,無應用價值。

對于金融風控預測類常見的評估指標如下:
1、KS(Kolmogorov-Smirnov) KS統計量由兩位蘇聯數學家A.N. Kolmogorov和N.V. Smirnov提出。在風控中,KS常用于評估模型區分度。區分度越大,說明模型的風險排序能力(ranking ability)越強。 K-S曲線與ROC曲線類似,不同在于

ROC曲線將真正例率和假正例率作為橫縱軸
K-S曲線將真正例率和假正例率都作為縱軸,橫軸則由選定的閾值來充當。 公式如下:

二.數據來源

測試集

訓練集

三.查看數據

train = pd.read_csv('train.csv') testA = pd.read_csv('testA.csv') print('Train data shape:',train.shape) print('TestA data shape:',testA.shape) train.head()

Train data shape: (800000, 47)
TestA data shape: (200000, 46)

四.分類指標計算示例

4.1混淆矩陣

## 混淆矩陣 import numpy as np from sklearn.metrics import confusion_matrix y_pred = [0, 1, 0, 1] y_true = [0, 1, 1, 0] print('混淆矩陣:\n',confusion_matrix(y_true, y_pred))

4.2準確度

## accuracy from sklearn.metrics import accuracy_score y_pred = [0, 1, 0, 1] y_true = [0, 1, 1, 0] print('ACC:',accuracy_score(y_true, y_pred))

ACC: 0.5

4.3precision(精確度),recall(召回率),f1-score

## Precision,Recall,F1-score from sklearn import metrics y_pred = [0, 1, 0, 1] y_true = [0, 1, 1, 0] print('Precision',metrics.precision_score(y_true, y_pred)) print('Recall',metrics.recall_score(y_true, y_pred)) print('F1-score:',metrics.f1_score(y_true, y_pred))

Precision 0.5

Recall 0.5

F1-score: 0.5

4.4P-R曲線

## P-R曲線 import matplotlib.pyplot as plt from sklearn.metrics import precision_recall_curve y_pred = [0, 1, 1, 0, 1, 1, 0, 1, 1, 1] y_true = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1] precision, recall, thresholds = precision_recall_curve(y_true, y_pred) plt.plot(precision, recall)

4.5ROC曲線

## ROC曲線 from sklearn.metrics import roc_curve y_pred = [0, 1, 1, 0, 1, 1, 0, 1, 1, 1] y_true = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1] FPR,TPR,thresholds=roc_curve(y_true, y_pred) plt.title('ROC') plt.plot(FPR, TPR,'b') plt.plot([0,1],[0,1],'r--') plt.ylabel('TPR') plt.xlabel('FPR')

4.6AUC曲線

## AUC import numpy as np from sklearn.metrics import roc_auc_score y_true = np.array([0, 0, 1, 1]) y_scores = np.array([0.1, 0.4, 0.35, 0.8]) print('AUC socre:',roc_auc_score(y_true, y_scores))

AUC socre: 0.75

4.7KS值

## KS值 在實際操作時往往使用ROC曲線配合求出KS值 from sklearn.metrics import roc_curve y_pred = [0, 1, 1, 0, 1, 1, 0, 1, 1, 1] y_true = [0, 1, 1, 0, 1, 0, 1, 1, 1, 1] FPR,TPR,thresholds=roc_curve(y_true, y_pred) KS=abs(FPR-TPR).max() print('KS值:',KS)

KS值: 0.5238095238095237

五.數據分析

5.1基本信息

data_train.info()


總體粗略的查看數據集各個特征的一些基本統計量

data_train.describe()

data_train.head(3).append(data_train.tail(3))

5.2查看數據集中特征缺失值,唯一值等

查看缺失值

print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')

There are 22 columns in train dataset with missing values.

上面得到訓練集有22列特征有缺失值,進一步查看缺失特征中缺失率大于50%的特征

have_null_fea_dict = (data_train.isnull().sum()/len(data_train)).to_dict() fea_null_moreThanHalf = {} for key,value in have_null_fea_dict.items():if value > 0.5:fea_null_moreThanHalf[key] = value

具體的查看缺失特征及缺失率

# nan可視化 missing = data_train.isnull().sum()/len(data_train) missing = missing[missing > 0] missing.sort_values(inplace=True) missing.plot.bar()

  • 縱向了解哪些列存在 “nan”, 并可以把nan的個數打印,主要的目的在于查看某一列nan存在的個數是否真的很大,如果nan存在的過多,說明這一列對label的影響幾乎不起作用了,可以考慮刪掉。如果缺失值很小一般可以選擇填充。
  • 另外可以橫向比較,如果在數據集中,某些樣本數據的大部分列都是缺失的且樣本足夠的情況下可以考慮刪除。

Tips: 比賽大殺器lgb模型可以自動處理缺失值,Task4模型會具體學習模型了解模型哦!

查看訓練集測試集中特征屬性只有一值的特征

one_value_fea = [col for col in data_train.columns if data_train[col].nunique() <= 1] one_value_fea_test = [col for col in data_test_a.columns if data_test_a[col].nunique() <= 1]

[‘policyCode’]

print(f'There are {len(one_value_fea)} columns in train dataset with one unique value.') print(f'There are {len(one_value_fea_test)} columns in test dataset with one unique value.')

There are 1 columns in train dataset with one unique value.

There are 1 columns in test dataset with one unique value.

總結:

47列數據中有22列都缺少數據,這在現實世界中很正常。‘policyCode’具有一個唯一值(或全部缺失)。有很多連續變量和一些分類變量。

5.3查看特征的數值類型有哪些,對象類型有哪些

  • 特征一般都是由類別型特征和數值型特征組成,而數值型特征又分為連續型和離散型
  • 類別型特征有時具有非數值關系,有時也具有數值關系。比如‘grade’中的等級A,B,C等,是否只是單純的分類,還是A優于其他要結合業務判斷。
  • 數值型特征本是可以直接入模的,但往往風控人員要對其做分箱,轉化為WOE編碼進而做標準評分卡等操作。從模型效果上來看,特征分箱主要是為了降低變量的復雜性,減少變量噪音對模型的影響,提高自變量和因變量的相關度。從而使模型更加穩定。
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)))


data_train.grade

#過濾數值型類別特征 def get_numerical_serial_fea(data,feas):numerical_serial_fea = []numerical_noserial_fea = []for fea in feas:temp = data[fea].nunique()if temp <= 10:numerical_noserial_fea.append(fea)continuenumerical_serial_fea.append(fea)return numerical_serial_fea,numerical_noserial_fea numerical_serial_fea,numerical_noserial_fea = get_numerical_serial_fea(data_train,numerical_fea)

data_train['term'].value_counts()#離散型變量 data_train['homeOwnership'].value_counts()#離散型變量 data_train['verificationStatus'].value_counts()#離散型變量 data_train['initialListStatus'].value_counts()#離散型變量 data_train['applicationType'].value_counts()#離散型變量 data_train['policyCode'].value_counts()#離散型變量,無用,全部一個值 data_train['n11'].value_counts()#離散型變量,相差懸殊,用不用再分析 data_train['n12'].value_counts()#離散型變量,相差懸殊,用不用再分析

5.3.1數值連續型變量分析

#每個數字特征得分布可視化 # 這里畫圖估計需要10-15分鐘 f = pd.melt(data_train, value_vars=numerical_serial_fea) g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False) g = g.map(sns.distplot, "value")


圖片數量有點多,暫時放置幾張

  • 查看某一個數值型變量的分布,查看變量是否符合正態分布,如果不符合正太分布的變量可以log化后再觀察下是否符合正態分布。
  • 如果想統一處理一批數據變標準化 必須把這些之前已經正態化的數據提出
  • 正態化的原因:一些情況下正態非正態可以讓模型更快的收斂,一些模型要求數據正態(eg. GMM、KNN),保證數據不要過偏態即可,過于偏態可能會影響模型預測結果。
#Ploting Transaction Amount Values Distribution plt.figure(figsize=(16,12)) plt.suptitle('Transaction Values Distribution', fontsize=22) plt.subplot(221) sub_plot_1 = sns.distplot(data_train['loanAmnt']) sub_plot_1.set_title("loanAmnt Distribuition", fontsize=18) sub_plot_1.set_xlabel("") sub_plot_1.set_ylabel("Probability", fontsize=15)plt.subplot(222) sub_plot_2 = sns.distplot(np.log(data_train['loanAmnt'])) sub_plot_2.set_title("loanAmnt (Log) Distribuition", fontsize=18) sub_plot_2.set_xlabel("") sub_plot_2.set_ylabel("Probability", fontsize=15)

5.3.2非數值類別型變量分析

data_train['grade'].value_counts()

data_train['subGrade'].value_counts()

data_train['employmentLength'].value_counts()

data_train['issueDate'].value_counts()

5.3.3總結:

上面我們用value_counts()等函數看了特征屬性的分布,但是圖表是概括原始信息最便捷的方式。
數無形時少直覺。
同一份數據集,在不同的尺度刻畫上顯示出來的圖形反映的規律是不一樣的。python將數據轉化成圖表,但結論是否正確需要由你保證。

5.4變量分布可視化

5.4.1單一變量分布可視化

plt.figure(figsize=(8, 8)) sns.barplot(data_train["employmentLength"].value_counts(dropna=False)[:20],data_train["employmentLength"].value_counts(dropna=False).keys()[:20]) plt.show()

5.4.2根絕y值不同可視化x某個特征的分布

首先查看類別型變量在不同y值上的分布

train_loan_fr = data_train.loc[data_train['isDefault'] == 1] train_loan_nofr = data_train.loc[data_train['isDefault'] == 0]fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 8)) train_loan_fr.groupby('grade')['grade'].count().plot(kind='barh', ax=ax1, title='Count of grade fraud') train_loan_nofr.groupby('grade')['grade'].count().plot(kind='barh', ax=ax2, title='Count of grade non-fraud') train_loan_fr.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=ax3, title='Count of employmentLength fraud') train_loan_nofr.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=ax4, title='Count of employmentLength non-fraud') plt.show()

其次查看連續型變量在不同y值上的分布

fig, ((ax1, ax2)) = plt.subplots(1, 2, figsize=(15, 6)) data_train.loc[data_train['isDefault'] == 1] \['loanAmnt'].apply(np.log) \.plot(kind='hist',bins=100,title='Log Loan Amt - Fraud',color='r',xlim=(-3, 10),ax= ax1) data_train.loc[data_train['isDefault'] == 0] \['loanAmnt'].apply(np.log) \.plot(kind='hist',bins=100,title='Log Loan Amt - Not Fraud',color='b',xlim=(-3, 10),ax=ax2)

total = len(data_train) total_amt = data_train.groupby(['isDefault'])['loanAmnt'].sum().sum() plt.figure(figsize=(12,5)) plt.subplot(121)##1代表行,2代表列,所以一共有2個圖,1代表此時繪制第一個圖。 plot_tr = sns.countplot(x='isDefault',data=data_train)#data_train‘isDefault’這個特征每種類別的數量** plot_tr.set_title("Fraud Loan Distribution \n 0: good user | 1: bad user", fontsize=14) plot_tr.set_xlabel("Is fraud by count", fontsize=16) plot_tr.set_ylabel('Count', fontsize=16) for p in plot_tr.patches:height = p.get_height()plot_tr.text(p.get_x()+p.get_width()/2.,height + 3,'{:1.2f}%'.format(height/total*100),ha="center", fontsize=15) percent_amt = (data_train.groupby(['isDefault'])['loanAmnt'].sum()) percent_amt = percent_amt.reset_index() plt.subplot(122) plot_tr_2 = sns.barplot(x='isDefault', y='loanAmnt', dodge=True, data=percent_amt) plot_tr_2.set_title("Total Amount in loanAmnt \n 0: good user | 1: bad user", fontsize=14) plot_tr_2.set_xlabel("Is fraud by percent", fontsize=16) plot_tr_2.set_ylabel('Total Loan Amount Scalar', fontsize=16) for p in plot_tr_2.patches:height = p.get_height()plot_tr_2.text(p.get_x()+p.get_width()/2.,height + 3,'{:1.2f}%'.format(height/total_amt * 100),ha="center", fontsize=15)

5.4.3時間格式數據處理及查看

#轉化成時間格式 issueDateDT特征表示數據日期離數據集中日期最早的日期(2007-06-01)的天數 data_train['issueDate'] = pd.to_datetime(data_train['issueDate'],format='%Y-%m-%d') startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d') data_train['issueDateDT'] = data_train['issueDate'].apply(lambda x: x-startdate).dt.days#轉化成時間格式 data_test_a['issueDate'] = pd.to_datetime(data_train['issueDate'],format='%Y-%m-%d') startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d') data_test_a['issueDateDT'] = data_test_a['issueDate'].apply(lambda x: x-startdate).dt.daysplt.hist(data_train['issueDateDT'], label='train'); plt.hist(data_test_a['issueDateDT'], label='test'); plt.legend(); plt.title('Distribution of issueDateDT dates'); #train 和 test issueDateDT 日期有重疊 所以使用基于時間的分割進行驗證是不明智的

5.4.4掌握透視圖可以讓我們更好的了解數據

#透視圖 索引可以有多個,“columns(列)”是可選的,聚合函數aggfunc最后是被應用到了變量“values”中你所列舉的項目上。 pivot = pd.pivot_table(data_train, index=['grade'], columns=['issueDateDT'], values=['loanAmnt'], aggfunc=np.sum)

5.4.5用pandas_profiling生成數據報告

import pandas_profilingpfr = pandas_profiling.ProfileReport(data_train) pfr.to_file("./example.html")

5.4.6總結

數據探索性分析是我們初步了解數據,熟悉數據為特征工程做準備的階段,甚至很多時候EDA階段提取出來的特征可以直接當作規則來用。可見EDA的重要性,這個階段的主要工作還是借助于各個簡單的統計量來對數據整體的了解,分析各個類型變量相互之間的關系,以及用合適的圖形可視化出來直觀觀察。希望本節內容能給初學者帶來幫助,更期待各位學習者對其中的不足提出建議。

六.特征工程

6.1導入包并讀取數據

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')

6.2數據預處理

數據EDA部分我們已經對數據的大概和某些特征分布有了了解,數據預處理部分一般我們要處理一些EDA階段分析出來的問題,這里介紹了數據缺失值的填充,時間格式特征的轉化處理,某些對象類別特征的處理。

首先我們查找出數據中的對象特征和數值特征

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)

6.2缺失值填充

把所有缺失值替換為指定的值0

data_train = data_train.fillna(0)

向用缺失值上面的值替換缺失值

data_train = data_train.fillna(axis=0,method=‘ffill’)

縱向用缺失值下面的值替換缺失值,且設置最多只填充兩個連續的缺失值

data_train = data_train.fillna(axis=0,method=‘bfill’,limit=2)

#查看缺失值情況 data_train.isnull().sum()

#按照平均數填充數值型特征 data_train[numerical_fea] = data_train[numerical_fea].fillna(data_train[numerical_fea].median()) data_test_a[numerical_fea] = data_test_a[numerical_fea].fillna(data_train[numerical_fea].median()) #按照眾數填充類別型特征 data_train[category_fea] = data_train[category_fea].fillna(data_train[category_fea].mode()) data_test_a[category_fea] = data_test_a[category_fea].fillna(data_train[category_fea].mode()) data_train.isnull().sum()

6.3時間格式處理

#轉化成時間格式 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')#構造時間特征data['issueDateDT'] = data['issueDate'].apply(lambda x: x-startdate).dt.days data_train['employmentLength'].value_counts(dropna=False).sort_index()

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()


對earliesCreditLine進行預處理

data_train['earliesCreditLine'].sample(5)

for data in [data_train, data_test_a]:data['earliesCreditLine'] = data['earliesCreditLine'].apply(lambda s: int(s[-4:]))

6.4類別特征處理

# 部分類別特征 cate_features = ['grade', 'subGrade', 'employmentTitle', 'homeOwnership', 'verificationStatus', 'purpose', 'postCode', 'regionCode', \'applicationType', 'initialListStatus', 'title', 'policyCode'] for f in cate_features:print(f, '類型數:', data[f].nunique())

像等級這種類別特征,是有優先級的可以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}) # 類型數在2之上,又不是高維稀疏的,且純分類特征 for data in [data_train, data_test_a]:data = pd.get_dummies(data, columns=['subGrade', 'homeOwnership', 'verificationStatus', 'purpose', 'regionCode'], drop_first=True)

6.5異常值處理

檢測異常的方法一:均方差?
在統計學中,如果一個數據分布近似正態,那么大約 68% 的數據值會在均值的一個標準差范圍內,大約 95% 會在兩個標準差范圍內,大約 99.7% 會在三個標準差范圍內。

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

得到特征的異常值后可以進一步分析變量異常值和目標變量的關系

data_train = data_train.copy() for fea in numerical_fea:data_train = find_outliers_by_3segama(data_train,fea)print(data_train[fea+'_outliers'].value_counts())print(data_train.groupby(fea+'_outliers')['isDefault'].sum())print('*'*10)

例如可以看到異常值在兩個變量上的分布幾乎復合整體的分布,如果異常值都屬于為1的用戶數據里面代表什么呢?

#刪除異常值 for fea in numerical_fea:data_train = data_train[data_train[fea+'_outliers']=='正常值']data_train = data_train.reset_index(drop=True)

檢測異常的方法二:箱型圖
總結一句話:四分位數會將數據分為三個點和四個區間,IQR = Q3 -Q1,下觸須=Q1 ? 1.5x IQR,上觸須=Q3 + 1.5x IQR;

6.6數據分桶

特征分箱的目的:
從模型效果上來看,特征分箱主要是為了降低變量的復雜性,減少變量噪音對模型的影響,提高自變量和因變量的相關度。從而使模型更加穩定。

數據分桶的對象:
將連續變量離散化
將多狀態的離散變量合并成少狀態

分箱的原因:
數據的特征內的值跨度可能比較大,對有監督和無監督中如k-均值聚類它使用歐氏距離作為相似度函數來測量數據點之間的相似度。都會造成大吃小的影響,其中一種解決方法是對計數值進行區間量化即數據分桶也叫做數據分箱,然后使用量化后的結果。

分箱的優點:

處理缺失值:當數據源可能存在缺失值,此時可以把null單獨作為一個分箱。
處理異常值:當數據中存在離群點時,可以把其通過分箱離散化處理,從而提高變量的魯棒性(抗干擾能力)。例如,age若出現200這種異常值,可分入“age > 60”這個分箱里,排除影響。
業務解釋性:我們習慣于線性判斷變量的作用,當x越來越大,y就越來越大。但實際x與y之間經常存在著非線性關系,此時可經過WOE變換。
特別要注意一下分箱的基本原則:

(1)最小分箱占比不低于5%
(2)箱內不能全部是好客戶
(3)連續箱單調
固定寬度分箱

當數值橫跨多個數量級時,最好按照 10 的冪(或任何常數的冪)來進行分組:09、1099、100999、10009999,等等。固定寬度分箱非常容易計算,但如果計數值中有比較大的缺口,就會產生很多沒有任何數據的空箱子。

# 通過除法映射到間隔均勻的分箱中,每個分箱的取值范圍都是loanAmnt/1000 data['loanAmnt_bin1'] = np.floor_divide(data['loanAmnt'], 1000)## 通過對數函數映射到指數寬度分箱 data['loanAmnt_bin2'] = np.floor(np.log10(data['loanAmnt']))##分位數分箱 data['loanAmnt_bin3'] = pd.qcut(data['loanAmnt'], 10, labels=False)

6.7特征編碼

labelEncode 直接放入樹模型中

#label-encode:subGrade,postCode,title # 高維類別特征需要進行轉換 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 完成')

邏輯回歸等模型要單獨增加的特征工程

對特征做歸一化,去除相關性高的特征
歸一化目的是讓訓練過程更好更快的收斂,避免特征大吃小的問題
去除相關性是增加模型的可解釋性,加快預測過程。

# 舉例歸一化過程 #偽代碼 for fea in [要歸一化的特征列表]:data[fea] = ((data[fea] - np.min(data[fea])) / (np.max(data[fea]) - np.min(data[fea])))

6.8特征選擇

特征選擇技術可以精簡掉無用的特征,以降低最終模型的復雜性,它的最終目的是得到一個簡約模型,在不降低預測準確率或對預測準確率影響不大的情況下提高計算速度。特征選擇不是為了減少訓練時間(實際上,一些技術會增加總體訓練時間),而是為了減少模型評分時間。

特征選擇的方法:

1 Filter
方差選擇法
相關系數法(pearson 相關系數)
卡方檢驗
互信息法

2 Wrapper (RFE)
遞歸特征消除法

3 Embedded
基于懲罰項的特征選擇法
基于樹模型的特征選擇

方差選擇法

方差選擇法中,先要計算各個特征的方差,然后根據設定的閾值,選擇方差大于閾值的特征

from sklearn.feature_selection import VarianceThreshold #其中參數threshold為方差的閾值 VarianceThreshold(threshold=3).fit_transform(train,target_train)

相關系數法

Pearson 相關系數 皮爾森相關系數是一種最簡單的,可以幫助理解特征和響應變量之間關系的方法,該方法衡量的是變量之間的線性相關性。 結果的取值區間為 [-1,1] , -1 表示完全的負相關, +1表示完全的正相關,0 表示沒有線性相關。

from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr #選擇K個最好的特征,返回選擇特征后的數據 #第一個參數為計算評估特征是否好的函數,該函數輸入特征矩陣和目標向量, #輸出二元組(評分,P值)的數組,數組第i項為第i個特征的評分和P值。在此定義為計算相關系數 #參數k為選擇的特征個數SelectKBest(k=5).fit_transform(train,target_train)

本數據集中我們刪除非入模特征后,并對缺失值填充,然后用計算協方差的方式看一下特征間相關性,然后進行模型訓練

# 刪除不需要的數據 for data in [data_train, data_test_a]:data.drop(['issueDate'], axis=1,inplace=True)"縱向用缺失值上面的值替換缺失值" data_train = data_train.fillna(axis=0,method='ffill') x_train = data_train #計算協方差 data_corr = x_train.corrwith(data_train.isDefault) #計算相關性 result = pd.DataFrame(columns=['features', 'corr']) result['features'] = data_corr.index result['corr'] = data_corr.values# 當然也可以直接看圖 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)


恭喜你能夠看完這篇博客,相信你已經有點累了,加油!!!
這篇博客側重于數據分析與數據預處理,特征構造選擇,下篇才是重點。由于篇幅過長,寫作多有不便,未完結。點擊跳轉下一篇

總結

以上是生活随笔為你收集整理的【数据分析与挖掘实战】金融风控之贷款违约预测详解1(有代码和数据集)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。