Kaggle
在這一個 Kaggle Challenge中,Santander提供了20萬筆的Train Data以及20萬筆的Test Data,希望Kagglers可以減構出一個模型來預測他們客戶是否能夠跟Santander進行交易。
在這邊,我選擇以Gabriel Preda的Kernel來進行第一次的Kaggle Case研讀,也藉此了解一般在進行EDA以及Feature Engineering時可能會遇到的方法及解決的方式。
在這邊他大概以幾個大方向來依序做處理:
import gc
import os
import logging
import datetime
import warnings
import numpy as np
import pandas as pd
import seaborn as sns
import lightgbm as lgb
from tqdm import tqdm_notebook
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
from sklearn.metrics import roc_auc_score, roc_curve
from sklearn.model_selection import StratifiedKFold
warnings.filterwarnings('ignore')
從這邊我們大概可以看到在後面的Code裡面大概會用到那些模組、工具 ( 不過 Gabriel Preda的這一連串匯入中,有些本次似乎用不到。 )
會用 os 模組做一些系統操作 ( EX: 讀取檔案…)、numpy及pandas則是數據處理的好幫手、seaborn及matplotlib處理視覺化、roc_auc_score用來評估、StratifiedKFold用來驗證,最後此次用的 Model 則是 lightgbm
而這一整份的模組或許也可以當作我們的一份必備清單,日後是否有需要增減再做調整。
%%time
train_df = pd.read_csv("train.csv")
test_df = pd.read_csv("test.csv")
這裡,我將kaggle提供的檔案跟這個ipynb檔放在一起,所以在讀取的時候就很簡單,直接讀取就可以。若不同資料夾存放則可使用os模組進行讀取 [1]
train_df.shape, test_df.shape
train_df.head()
test_df.head()
以上這三個算是很基本的資料檢視過程,觀察筆數、看看Train & Test 的各個欄位。也可以在此時簡單的看看資料數據是否有很嚴重的缺失值。
從這個例子來看,我們可以瞭解幾件事情 :
Train & Test資料差在 target,這的確可以理解,我們要利用訓練資料訓練出一套模型,再來對測試資料進行測試,看看準確度到多少,這便是我們要做的事情,而 Test 資料的 target 只有 Kaggle 才有,當我們最終答案上傳,他們會立刻進行比對,可以即時的告知我們結果。
def missing_data(data):
total = data.isnull().sum()
#Pandas通常使用.isnull()來找缺失值,.sum()則是計算缺失的數量
percent = (data.isnull().sum()/data.isnull().count()*100)
tt = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
# pd.concat(objs合併的東西,axis合併的方向,keys索引)
types = []
for col in data.columns:
dtype = str(data[col].dtype)
types.append(dtype)
tt['Types'] = types
return(np.transpose(tt))
missing_data(train_df)
missing_data(test_df)
檢查缺失值在整個資料處理的過程中,往往會是一個非常重要的步驟,缺失值數量過多,則跑出來的模型的擬合狀況會非常差,在這個Case裡面,很幸運地並沒有任何的缺失值在其中。
(這蠻可惜的,畢竟如何填補、修改、刪除缺失值也是需要很多的技巧,只能等之後的Case再來學習了)
Gabriel Preda的這個缺失值計算函數 (後面很多自訂函數亦然) 我認為是一個可以共通的方式,可以記下來以便未來處理不同Case可以使用
%%time
train_df.describe()
%time
test_df.describe()
DataFrame.describe()
是一個非常好用的工具之一,可以一次將整個表格的統計量呈現出來,而這些統計量可以很清楚的呈現這些資料的分布及特性。
在這邊我們可以知道幾個狀況 :
def plot_feature_scatter(df1, df2, features):
i = 0
sns.set_style('whitegrid')
plt.figure()
fig, ax = plt.subplots(4,4,figsize=(14,14))
for feature in features:
i += 1
plt.subplot(4,4,i)
plt.scatter(df1[feature], df2[feature], marker='+')
plt.xlabel(feature, fontsize=9)
plt.show();
features = ['var_0', 'var_1','var_2','var_3', 'var_4', 'var_5', 'var_6', 'var_7',
'var_8', 'var_9', 'var_10','var_11','var_12', 'var_13', 'var_14', 'var_15',
]
plot_feature_scatter(train_df[::20],test_df[::20], features)
這裡的部分,主要是把剛剛觀察的現象做一個視覺化的處理來確認我們的「觀察」是有根據的。從這裏的圖片看來,不管哪一個欄位,在兩個部分的資料的分布都算集中。
( 意即 : 在這40萬筆資料中,每一筆的資料的各個欄位/特徵大概都在某些範圍內不會有太大的異常值 )
有兩個問題大家可以思考一下 :
1. 圖片中每一個點代表的意思是什麼?[2]
2. 假如出現完全零散不集中、或是呈現特殊集中方式代表的意義是什麼 ?
sns.countplot(train_df['target'])
print("There are {}% target values with 1".format(100 * train_df["target"].value_counts()[1]/train_df.shape[0]))
#train_df["target"].value_counts()[1] return "1" 有多少個
#train_df.shape[0] return 列數
遇到了一個大難題,這是一個 unbalence 的情況。
之所以會困難是因為,如果我們訓練出一個模型,只會把所有資料無差別分類成 target 0 (Dummy classifier),這樣的準確率也會接近90%,這會影響我們評估這個模型的好壞。(這也是為什麼在最前面我們發現他選擇使用roc_auc_score, roc_curve來做為評估模型的指標)
嗯,很順利的現在進行了1/3…
存放於不同資料夾的檔案讀取
dpath=os.path.abspath("待讀取資料的絕對路徑(不含檔案本身)") #資料夾位置
fpath=os.path.join(dpath,"檔名(含副檔名)") #檔案位置
a_train=pd.read_csv(fpath) #讀檔
這個問題我其實思考了一陣子,我們稍微更改一下code你就能知道這代表什麼了:
features = ['var_0', 'var_1','var_2','var_3', 'var_4', 'var_5', 'var_6',
'var_7', 'var_8', 'var_9', 'var_10','var_11','var_12', 'var_13', 'var_14', 'var_15',
]
plot_feature_scatter(train_df[0:1],test_df[0:1], features)
我們就只取一個點來看看會是什麼
你看出來了嗎 ?
圖中的每一個點,代表的就是Training Data跟Test Data相對應index資料的特徵值。
拿第一個子圖來說,那一點代表的就是
index=0 時 Training Data var_0=8.9255 (X軸) ;
index=0 時 Test Data var_0= 11.0656 (Y軸) ↩︎