緒論
本篇針對Kaggle上面的競賽進行簡單的資料處理介紹。這次的主題是Enron Fraud Dataset 安隆公司詐欺案資料集,下面為主題簡介。
安隆公司曾是一間能源公司,2001 年破產前是世界上最大的電力、天然氣及電信公司之一。擁有上千億資產的公司於 2002 年竟然在短短幾周內宣告破產,才揭露其財報在多年以來均是造假的醜聞。在本資料集中你將會扮演偵探的角色,透過高層經理人內部的 mail 來往的情報以及薪資、股票等財務特徵,訓練出一個機器學習模型來幫忙你找到可疑的詐欺犯罪者是誰! 我們已經先幫你找到幾位犯罪者 (Person-of-Interest, poi) 與清白的員工,請利用這些訓練資料來訓練屬於自己的詐欺犯機器學習模型吧!特徵工程(Feature Engineering)。
特徵說明
有關財務的特徵: [‘salary’, ‘deferral_payments’, ‘total_payments’, ‘loan_advances’, ‘bonus’, ‘restricted_stock_deferred’, ‘deferred_income’, ‘total_stock_value’, ‘expenses’, ‘exercised_stock_options’, ‘other’, ‘long_term_incentive’, ‘restricted_stock’, ‘director_fees’] (單位皆為美元)。更詳細的特徵說明請參考 enron61702insiderpay.pdf 的最後一頁(請至Data頁面參考該PDF檔)
有關 email 的特徵: [‘to_messages’, ‘email_address’, ‘from_poi_to_this_person’, ‘from_messages’, ‘from_this_person_to_poi’, ‘shared_receipt_with_poi’] (除了 email_address,其餘皆為次數)
嫌疑人的標記,也就是我們常用的 **y**。POI label: [‘poi’] (boolean, represented as integer)
我們也建議你對既有特徵進行一些特徵工程如 rescale, transform ,也試著發揮想像力與創意,建立一些可以幫助找到嫌疑犯的特徵,增進模型的預測能力。
資料預處理與特徵工程
首先,取得的Data後的第一步是觀察資料,一般來說建議將資料轉成DataFrame(Pandas),並觀察欄位,看是否需要填補空值,大部分資料科學的比賽所提供的檔案為csv檔,其檔案較小,在Python中也較容易轉換成需要的格式。
import copy
import warnings
warnings.filterwarnings('ignore')
import os
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import GradientBoostingClassifier我大概介紹一下我import 的packages的用途。import os 是將桌面路徑資料讀進Jupyter Notebook,Import pandas 是方便轉換成欄位格式,Import numpy方便之後進行矩陣運算。機器學習主要都使用sklearn的套件,sklearn提供許多機器學習的演算法可供我們使用。由於我們待會的特徵工程會將數值的資料欄位進行標準化,因此需要import sklearn.preprocessing。這次的題目是要預測員工是否可能為嫌疑犯,因此預測的結果為分類(Classification),後面所訓練的機器學習模型使用的也是Classification Models。
#觀察欄位以及匯進資料-training data
df_train = pd.read_csv('~/Desktop/kaggle_3/train_data.csv')
df_train.columns
#匯進測試集並觀察其資料欄位
df_test = pd.read_csv('~/Desktop/kaggle_3/test_features.csv')
df_answer = pd.DataFrame()
df_answer['name'] = df_test['name']
df_test.shapeMachine Learning在切分資料的時候大部分會切分成- X_train,Y_train(訓練模型)以及X_test,Y_test(預測資料)。
#從training data 取出預預測的欄位也就是 Poi
# poi 欄位內為true,false 因此需轉換成0或1的形式,這邊使用label encodingtrain_y = df_train['poi']
df_train = df_train.drop(['poi'],axis=1)
train_y = LabelEncoder().fit_transform(train_y)
接下來將開始進行特徵工程,本篇並不會做過於複雜的特徵工程,在特徵選擇上我只採用數值型。
#只留下來數值型特徵
num_features = []
for dtype,feature in zip(df_train.dtypes,df_train.columns):
if dtype == 'float64' or dtype == 'int64':
num_features.append(feature)df_train = df_train[num_features]
train_num = train_y.shape[0]
將數值型特徵處理完後,須觀察其欄位中是否有空值,並進行空值填補。一般來說,空值填補須依照該領域專家建議進行填補,有時候過於直觀的填入隨機值可能會影響模型預測的準確率。
#資料空值填補 -1
df_m1 = df_train.fillna(-1)
df_m1 = StandardScaler().fit_transform(df_m1)
train_x = df_m1[:train_num]
estimator = LogisticRegression()#其中cv = 10 為交叉驗證(幫助選擇模型)的組評測次數,並取其平均
cross_val_score(estimator,train_x,train_y,cv=10).mean()output:
0.8765151515151516
分類演算法有許多種,本篇我會使用到 Logistic Regression 和以及 Gradient Boosting Classifier,若有興趣可以自行參考文章。
df_m1 = df_train.fillna(-1)
df_m1 = StandardScaler().fit_transform(df_m1)
train_x = df_m1[:train_num]
clf = GradientBoostingClassifier()
clf.fit(train_x,train_y)
#此段在之後會幫助我們進行超參數調整
output:
GradientBoostingClassifier(criterion='friedman_mse', init=None,
learning_rate=0.1, loss='deviance', max_depth=3,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=100,
n_iter_no_change=None, presort='auto', random_state=None,
subsample=1.0, tol=0.0001, validation_fraction=0.1,
verbose=0, warm_start=False)
訓練完之後,將測試資料丟到訓練後的模型進行預測。由於測試資料及有文字型資料,因此也須進行資料處理。
test_feature = []
for dtype,feature in zip(df_test.dtypes,df_test.columns):
if dtype == 'float64' or dtype == 'int64':
test_feature.append(feature)
df_test = df_test[test_feature]
df_test = df_test.fillna(-1)
test_x = StandardScaler().fit_transform(df_test)#預測結果
y_prediction = clf.predict_proba(test_x)
最後只要將結果轉換成Kaggle要求的格式並計算AUC就大功告成了。

結語
由於我們只簡單地進行特徵工程,也並未進行超參數調整,因此分數僅約0.83,若有興趣提高預測分數,可以進行不同的模型訓練,並加入文字型欄位的處理(one-hot encoding)。

