最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

畢業(yè)設(shè)計 金融大數(shù)據(jù)分析與可視化系統(tǒng)

2023-02-25 09:54 作者:丹成學(xué)長  | 我要投稿

0 前言

?? 這兩年開始畢業(yè)設(shè)計和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點,往往達不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長自己做的項目系統(tǒng)達不到老師的要求。

為了大家能夠順利以及最少的精力通過畢設(shè),學(xué)長分享優(yōu)質(zhì)畢業(yè)設(shè)計項目,今天要分享的是

?? ?金融大數(shù)據(jù)分析與可視化

??學(xué)長這里給一個題目綜合評分(每項滿分5分)

  • 難度系數(shù):3分

  • 工作量:3分

  • 創(chuàng)新點:3分

畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個人主頁

https://space.bilibili.com/33886978

1 金融風(fēng)控

  • 一.題目理解


    • 1.1.題目概況

    • 1.2數(shù)據(jù)概況

    • 1.3預(yù)測指標(biāo)

  • 二.數(shù)據(jù)來源

  • 三.查看數(shù)據(jù)

  • 四.分類指標(biāo)計算示例


    • 4.1混淆矩陣

    • 4.2準(zhǔn)確度

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

    • 4.4P-R曲線

    • 4.5ROC曲線

    • 4.6AUC曲線

    • 4.7KS值

  • 五.數(shù)據(jù)分析


    • 5.4.1單一變量分布可視化

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

    • 5.4.3時間格式數(shù)據(jù)處理及查看

    • 5.4.4掌握透視圖可以讓我們更好的了解數(shù)據(jù)

    • 5.4.5用pandas_profiling生成數(shù)據(jù)報告

    • 5.4.6總結(jié)

    • 5.3.1數(shù)值連續(xù)型變量分析

    • 5.3.2非數(shù)值類別型變量分析

    • 5.3.3總結(jié):

    • 5.1基本信息

    • 5.2查看數(shù)據(jù)集中特征缺失值,唯一值等

    • 5.3查看特征的數(shù)值類型有哪些,對象類型有哪些


    • 5.4變量分布可視化


  • 六.特征工程


    • 6.5異常值處理

    • 6.6數(shù)據(jù)分桶

    • 6.7特征編碼

    • 6.8特征選擇

    • 6.1導(dǎo)入包并讀取數(shù)據(jù)

    • 6.2數(shù)據(jù)預(yù)處理

    • 6.2缺失值填充

    • 6.3時間格式處理

    • 6.4類別特征處理


一.題目理解

1.1.題目概況

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

1.2數(shù)據(jù)概況

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

train.csv

id 為貸款清單分配的唯一信用證標(biāo)識

loanAmnt 貸款金額

term 貸款期限(year)

interestRate 貸款利率

installment 分期付款金額

grade 貸款等級

subGrade 貸款等級之子級

employmentTitle 就業(yè)職稱

employmentLength 就業(yè)年限(年)

homeOwnership 借款人在登記時提供的房屋所有權(quán)狀況

annualIncome 年收入

verificationStatus 驗證狀態(tài)

issueDate 貸款發(fā)放的月份

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

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

regionCode 地區(qū)編碼

dti 債務(wù)收入比

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

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

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

openAcc 借款人信用檔案中未結(jié)信用額度的數(shù)量

pubRec 貶損公共記錄的數(shù)量

pubRecBankruptcies 公開記錄清除的數(shù)量

revolBal 信貸周轉(zhuǎn)余額合計

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

totalAcc 借款人信用檔案中當(dāng)前的信用額度總數(shù)

initialListStatus 貸款的初始列表狀態(tài)

applicationType 表明貸款是個人申請還是與兩個共同借款人的聯(lián)合申請

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

title 借款人提供的貸款名稱

policyCode 公開可用的策略代碼=1新產(chǎn)品不公開可用的策略代碼=2

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

1.3預(yù)測指標(biāo)

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

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

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

在這里插入圖片描述
在這里插入圖片描述

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

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

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

在這里插入圖片描述

?

在這里插入圖片描述

三.查看數(shù)據(jù)


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)

在這里插入圖片描述


四.分類指標(biāo)計算示例

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準(zhǔn)確度


## 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

五.數(shù)據(jù)分析

5.1基本信息


data_train.info()

在這里插入圖片描述

總體粗略的查看數(shù)據(jù)集各個特征的一些基本統(tǒng)計量


data_train.describe()

在這里插入圖片描述

? ? ?

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

在這里插入圖片描述

5.2查看數(shù)據(jù)集中特征缺失值,唯一值等

查看缺失值


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.

上面得到訓(xùn)練集有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的個數(shù)打印,主要的目的在于查看某一列nan存在的個數(shù)是否真的很大,如果nan存在的過多,說明這一列對label的影響幾乎不起作用了,可以考慮刪掉。如果缺失值很小一般可以選擇填充。

  • 另外可以橫向比較,如果在數(shù)據(jù)集中,某些樣本數(shù)據(jù)的大部分列都是缺失的且樣本足夠的情況下可以考慮刪除。

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

查看訓(xùn)練集測試集中特征屬性只有一值的特征


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.

總結(jié):

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

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

  • 特征一般都是由類別型特征和數(shù)值型特征組成,而數(shù)值型特征又分為連續(xù)型和離散型

  • 類別型特征有時具有非數(shù)值關(guān)系,有時也具有數(shù)值關(guān)系。比如‘grade’中的等級A,B,C等,是否只是單純的分類,還是A優(yōu)于其他要結(jié)合業(yè)務(wù)判斷。

  • 數(shù)值型特征本是可以直接入模的,但往往風(fēng)控人員要對其做分箱,轉(zhuǎn)化為WOE編碼進而做標(biāo)準(zhǔn)評分卡等操作。從模型效果上來看,特征分箱主要是為了降低變量的復(fù)雜性,減少變量噪音對模型的影響,提高自變量和因變量的相關(guān)度。從而使模型更加穩(wěn)定。


    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

在這里插入圖片描述

? ? ?

#過濾數(shù)值型類別特征
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)
? ? ? ? ? ?continue
? ? ? ?numerical_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數(shù)值連續(xù)型變量分析


#每個數(shù)字特征得分布可視化
# 這里畫圖估計需要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")

在這里插入圖片描述

圖片數(shù)量有點多,暫時放置幾張

  • 查看某一個數(shù)值型變量的分布,查看變量是否符合正態(tài)分布,如果不符合正太分布的變量可以log化后再觀察下是否符合正態(tài)分布。

  • 如果想統(tǒng)一處理一批數(shù)據(jù)變標(biāo)準(zhǔn)化 必須把這些之前已經(jīng)正態(tài)化的數(shù)據(jù)提出

  • 正態(tài)化的原因:一些情況下正態(tài)非正態(tài)可以讓模型更快的收斂,一些模型要求數(shù)據(jù)正態(tài)(eg. GMM、KNN),保證數(shù)據(jù)不要過偏態(tài)即可,過于偏態(tài)可能會影響模型預(yù)測結(jié)果。


    #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非數(shù)值類別型變量分析


data_train['grade'].value_counts()

在這里插入圖片描述

? ? ?

data_train['subGrade'].value_counts()

在這里插入圖片描述

? ? ?

data_train['employmentLength'].value_counts()

? ? ?

data_train['issueDate'].value_counts()

5.3.3總結(jié):

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

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

其次查看連續(xù)型變量在不同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’這個特征每種類別的數(shù)量**
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時間格式數(shù)據(jù)處理及查看


#轉(zhuǎn)化成時間格式 ?issueDateDT特征表示數(shù)據(jù)日期離數(shù)據(jù)集中日期最早的日期(2007-06-01)的天數(shù)
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

#轉(zhuǎn)化成時間格式
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.days

plt.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掌握透視圖可以讓我們更好的了解數(shù)據(jù)


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

5.4.5用pandas_profiling生成數(shù)據(jù)報告


import pandas_profiling

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

5.4.6總結(jié)

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

六.特征工程

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

6.2數(shù)據(jù)預(yù)處理

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

首先我們查找出數(shù)據(jù)中的對象特征和數(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)

6.2缺失值填充

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

data_train = data_train.fillna(0)

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

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

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

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


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

? ? ?

#按照平均數(shù)填充數(shù)值型特征
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())
#按照眾數(shù)填充類別型特征
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時間格式處理


#轉(zhuǎn)化成時間格式
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)造時間特征
? ?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 s
? ?else:
? ? ? ?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進行預(yù)處理


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, '類型數(shù):', data[f].nunique())

像等級這種類別特征,是有優(yōu)先級的可以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)

6.5異常值處理

檢測異常的方法一:均方差? ? 在統(tǒng)計學(xué)中,如果一個數(shù)據(jù)分布近似正態(tài),那么大約 68% 的數(shù)據(jù)值會在均值的一個標(biāo)準(zhǔn)差范圍內(nèi),大約 95% 會在兩個標(biāo)準(zhǔn)差范圍內(nèi),大約 99.7% 會在三個標(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 * 3
? ?lower_rule = data_mean - outliers_cut_off
? ?upper_rule = data_mean + outliers_cut_off
? ?data[fea+'_outliers'] = data[fea].apply(lambda x:str('異常值') if x > upper_rule or x < lower_rule else '正常值')
? ?return data

得到特征的異常值后可以進一步分析變量異常值和目標(biāo)變量的關(guān)系


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)

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


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

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

6.6數(shù)據(jù)分桶

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

數(shù)據(jù)分桶的對象: ? 將連續(xù)變量離散化 ? 將多狀態(tài)的離散變量合并成少狀態(tài)

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

分箱的優(yōu)點:

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

(1)最小分箱占比不低于5% ? (2)箱內(nèi)不能全部是好客戶 ? (3)連續(xù)箱單調(diào) ? 固定寬度分箱

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


# 通過除法映射到間隔均勻的分箱中,每個分箱的取值范圍都是loanAmnt/1000
data['loanAmnt_bin1'] = np.floor_divide(data['loanAmnt'], 1000)

## 通過對數(shù)函數(shù)映射到指數(shù)寬度分箱
data['loanAmnt_bin2'] = np.floor(np.log10(data['loanAmnt']))

##分位數(shù)分箱
data['loanAmnt_bin3'] = pd.qcut(data['loanAmnt'], 10, labels=False)

6.7特征編碼

labelEncode 直接放入樹模型中


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

在這里插入圖片描述

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

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


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

6.8特征選擇

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

特征選擇的方法:

1 Filter ? 方差選擇法 ? 相關(guān)系數(shù)法(pearson 相關(guān)系數(shù)) ? 卡方檢驗 ? 互信息法

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

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

方差選擇法

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


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

相關(guān)系數(shù)法

Pearson 相關(guān)系數(shù) 皮爾森相關(guān)系數(shù)是一種最簡單的,可以幫助理解特征和響應(yīng)變量之間關(guān)系的方法,該方法衡量的是變量之間的線性相關(guān)性。 結(jié)果的取值區(qū)間為 [-1,1] , -1 表示完全的負(fù)相關(guān), +1表示完全的正相關(guān),0 表示沒有線性相關(guān)。


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

SelectKBest(k=5).fit_transform(train,target_train)

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


# 刪除不需要的數(shù)據(jù)
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
#計算協(xié)方差
data_corr = x_train.corrwith(data_train.isDefault) #計算相關(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)

在這里插入圖片描述

? 恭喜你能夠看完這篇博客,相信你已經(jīng)有點累了,加油!!! ? 這篇博客側(cè)重于數(shù)據(jù)分析與數(shù)據(jù)預(yù)處理,特征構(gòu)造選擇,下篇才是重點。由于篇幅過長,寫作多有不便,未完結(jié)。


最后

畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個人主頁

https://space.bilibili.com/33886978

畢業(yè)設(shè)計 金融大數(shù)據(jù)分析與可視化系統(tǒng)的評論 (共 條)

分享到微博請遵守國家法律
高尔夫| 沙洋县| 重庆市| 邵阳市| 太白县| 红桥区| 读书| 陇川县| 九江市| 肇东市| 甘洛县| 大悟县| 沐川县| 教育| 高州市| 道真| 行唐县| 吴川市| 漳平市| 定西市| 抚顺县| 高碑店市| 岢岚县| 北宁市| 徐汇区| 姜堰市| 东兰县| 岐山县| 郓城县| 青州市| 德惠市| 全椒县| 双桥区| 大名县| 仪征市| 徐汇区| 皋兰县| 佛山市| 金乡县| 尖扎县| 达拉特旗|