學習筆記(六)(預測貸款使用者是否會逾期)資料分析的簡單處理
資料的簡單處理
學習筆記(六)資料分析的簡單處理
資料是金融資料,我們要做的是預測貸款使用者是否會逾期,表格中,status是標籤:0表示未逾期,1表示逾期。
Misson1 - 構建邏輯迴歸模型進行預測
Misson2 - 構建SVM和決策樹模型進行預測
Misson3 - 構建xgboost和lightgbm模型進行預測
Mission4 - 記錄五個模型關於precision,rescore,f1,auc,roc的評分表格,畫出auc和roc曲線圖
Mission5 - 關於資料型別轉換以及缺失值處理(嘗試不同的填充看效果)以及你能借鑑的資料探索
特徵工程初步的處理
- 資料採集 / 清洗 / 取樣
- 特徵處理
- 特徵選擇
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. 填充缺失值
# “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. 異常值的處理
(一). 異常值的分佈圖像
舉兩個例子
- 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)
- consume_mini_time_last_1_month列
(二) 異常值的處理方法
- 標準差上下三倍絕對中位差之間屬於正常點
# 異常值變動方法
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
- 平均值上下三倍標準差之間屬於正常點
std = np.std(total_data)
mean = np.mean(total_data)
b = 3
lower_limit = mean-b*std
upper_limit = mean+b*std
- 箱型圖提供了一個識別異常值的標準,即大於或小於箱型圖設定的上下界的數值即為異常值:上四分位我們設為 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有那麼一點點提升。
存在的問題與不足
問題:
- 以上處理異常值的三種方法對結果影響的差距有點大。原因還待研究。
- 使用拉格朗日插值(不知道為什麼,效果不好)
不足:
3. seaborn不熟悉,所以沒有在圖上進行真正的分析
4. 資料處理和特徵工程這一塊基本是小白所以蒐集到的知識點比較散碎。還有待加強學習