1. 程式人生 > >學習筆記(六)(預測貸款使用者是否會逾期)資料分析的簡單處理

學習筆記(六)(預測貸款使用者是否會逾期)資料分析的簡單處理

資料的簡單處理

學習筆記(六)資料分析的簡單處理

資料是金融資料,我們要做的是預測貸款使用者是否會逾期,表格中,status是標籤:0表示未逾期,1表示逾期。
Misson1 - 構建邏輯迴歸模型進行預測
Misson2 - 構建SVM和決策樹模型進行預測
Misson3 - 構建xgboost和lightgbm模型進行預測
Mission4 - 記錄五個模型關於precision,rescore,f1,auc,roc的評分表格,畫出auc和roc曲線圖
Mission5 - 關於資料型別轉換以及缺失值處理(嘗試不同的填充看效果)以及你能借鑑的資料探索

特徵工程初步的處理

參考文章:特徵工程基本流程
                特徵工程專題

  1. 資料採集 / 清洗 / 取樣
  2. 特徵處理
  3. 特徵選擇

1. 資料預覽

由於資料特徵比較多,因此需要對資料的概況進行預覽
   1. 包的匯入

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.preprocessing import StandardScaler
import
seaborn as sns from scipy.interpolate import lagrange

   2.讀取檔案

# 開啟檔案
datanew = pd.read_csv('F:/ziliao/data/data2.csv', encoding='gbk')
# 檢視所有資料的型別
datanew.info()

這裡查看了特徵的資料型別:
在這裡插入圖片描述

2. 資料型別的轉化

   日期格式資料的處理

參考:pandas學習
pd.to_datetime 用於將各種日期字串轉換成標準的 datetime64 型別。日期型別的 Series 都會有一個 dt 屬性,從中可以獲取到有關日期時間的資訊

date_temp = pd.DataFrame()
date_temp['first_transaction_time_year'] = pd.to_datetime(datanew[
    'first_transaction_time']).dt.year
date_temp['first_transaction_time_month'] = pd.to_datetime(datanew[
    'first_transaction_time']).dt.month
date_temp['first_transaction_time_day'] = pd.to_datetime(datanew[
    'first_transaction_time']).dt.day
date_temp['latest_query_time_year'] = pd.to_datetime(datanew[
    'latest_query_time']).dt.year
date_temp['latest_query_time_month'] = pd.to_datetime(datanew[
    'latest_query_time']).dt.month
date_temp['latest_query_time_day'] = pd.to_datetime(datanew[
    'latest_query_time']).dt.day
date_temp['loans_latest_time_year'] = pd.to_datetime(datanew[
    'loans_latest_time']).dt.year
date_temp['loans_latest_time_month'] = pd.to_datetime(datanew[
    'loans_latest_time']).dt.month
date_temp['loans_latest_time_day'] = pd.to_datetime(datanew[
    'loans_latest_time']).dt.day
date_temp.fillna(date_temp.median(), inplace=True)  ##直接以中位數來替換NAN值

   並刪除原本的時間序列特徵的列

# 刪除日期
datanew.drop(["id_name","first_transaction_time","latest_query_time","loans_latest_time"], axis=1, inplace=True)

   無關特徵值的查詢並刪除

   刪除對結果影響不大的特徵

for cl in datanew.columns:
    count = datanew[cl].count()
    if len(list(datanew[cl].unique())) in [1, count, count-1]:
        datanew.drop(cl, axis=1, inplace=True)

   資料的離散化

      其中reg_preference_for_tra:出現四個值;對reg_preference_for_trad 的處理 【對映】
      境外=1 一線=5 二線=2 三線 =3 其他=4

n = set(datanew['reg_preference_for_trad'])
dic = {}
for i, j in enumerate(n):
    dic[j] = i
datanew['reg_preference_for_trad'] = datanew['reg_preference_for_trad'].map(dic)

3. 填充缺失值

參考:訓練模型填充空值(fill null)的幾種方法

# “student_feature”只有1 和NA 因此將其NA變為0
datanew['student_feature'] = datanew['student_feature'].fillna(0)

其餘NA值選擇了兩種:
(1)使用中位數進行插值

# 使用中位數進行插值
datanew.fillna(datanew.median(), inplace=True)

(2)使用拉格朗日插值(不知道為什麼,效果不好)

%%time
# 使用拉格朗日插值

# 自定義插值函式
def inter_column(s,n,k=5):
    y = s[list(range(n-k,n))+list(range(n+1,n+1+k))]
    y = y[y.notnull()]
    return lagrange(y.index, list(y))(n)
# 逐個元素判斷是否需要插值
for j in datanew.columns:
    for k in range(len(datanew)):
        if (datanew[j].isnull())[k]:
            datanew[j][k] = inter_column(datanew[j], k)
            
# 效果很差

4. 異常值的處理

參考文章:異常值處理參考1
                  異常值處理參考2

(一). 異常值的分佈圖像
        舉兩個例子

  1. pawns_auctions_trusts_consume_last_1_month列
    畫圖參考:https://www.cnblogs.com/jin-liang/p/9011771.html
sns.stripplot(x='status',y='pawns_auctions_trusts_consume_last_1_month',data=datanew) 

在這裡插入圖片描述

  1. consume_mini_time_last_1_month列
    在這裡插入圖片描述

(二) 異常值的處理方法

  1. 標準差上下三倍絕對中位差之間屬於正常點
# 異常值變動方法
def check_outlier(total_data):
    # 2.標準差上下三倍絕對中位差之間屬於正常點(相對較差)
    median = np.median(total_data)
    b = 1.4826 #這個值應該是看需求加的,有點類似加大波動範圍之類的
    mad = b * np.median(np.abs(total_data-median))
    lower_limit = median - (3*mad)
    upper_limit = median + (3*mad)

    total_data[total_data > upper_limit] = upper_limit
    total_data[total_data < lower_limit] = lower_limit
 
    return total_data
 
# 對進行缺失值填充後的資料集進行極端值修正
X_num_cl = pd.DataFrame()
for col in datanew.columns:
    X_num_cl[col] = check_outlier(datanew[col])
datanew = X_num_cl

  1. 平均值上下三倍標準差之間屬於正常點
std = np.std(total_data)
    mean = np.mean(total_data)
    b = 3
    lower_limit = mean-b*std
    upper_limit = mean+b*std
  1. 箱型圖提供了一個識別異常值的標準,即大於或小於箱型圖設定的上下界的數值即為異常值:上四分位我們設為 U,表示的是所有樣本中只有1/4的數值大於U 。同理,下四分位我們設為 L,表示的是所有樣本中只有1/4的數值小於L我們設上四分位與下四分位的插值為IQR,即:IQR=U-L。那麼,上界為 U+1.5IQR ,下界為: L - 1.5IQR。箱型圖選取異常值比較客觀,在識別異常值方面有一定的優越性。
 # 1.上界為 U+1.5IQR ,下界為: L - 1.5IQR(相對以下兩種方法較好)
    b = 1.5
    q25, q75 = total_data.quantile(q=[0.25, 0.75])
    iqr = q75 - q25
    top = q75 + b * iqr
    bottom = q25 - b * iqr
    
    total_data[total_data > top] = top
    total_data[total_data < bottom] = bottom

5. 資料合併

將處理後的日期資料和datanew進行合併

datafinal = pd.concat([datanew,date_temp], axis=1)

6. 資料歸一化並測試

   資料歸一化

"""
1.3 資料集的切分
"""
X_train, X_test, y_train, y_test = train_test_split(datafinal, datafinal['status'],test_size=0.3, random_state=666)
X_train.drop(["status"],axis=1,inplace=True)
X_test.drop(["status"],axis=1,inplace=True)
"""
1.4標準化資料,方差為1,均值為零
"""
standardScaler = StandardScaler()
X_train_fit = standardScaler.fit_transform(X_train)
X_test_fit = standardScaler.transform(X_test)

   模型測試

之前缺失值處理為0,異常值未處理的結果:之前的程式碼
在這裡插入圖片描述
缺失值簡單處理,異常值簡單處理後的結果:
在這裡插入圖片描述
可以看出AUC有那麼一點點提升。

   存在的問題與不足

問題:

  1. 以上處理異常值的三種方法對結果影響的差距有點大。原因還待研究。
  2. 使用拉格朗日插值(不知道為什麼,效果不好)

不足:
    3. seaborn不熟悉,所以沒有在圖上進行真正的分析
    4. 資料處理和特徵工程這一塊基本是小白所以蒐集到的知識點比較散碎。還有待加強學習