用python在kaggle上試了幾個project,有點體會,記錄下。
EDA,也就是對資料進行探索性的分析,一般就用到pandas和matplotlib就夠了。EDA一般包括:
每個feature的意義,feature的類型,比較有用的代碼如下
df.describe()
df['Category'].unique()
看是否存在missing value
df.loc[df.Dates.isnull(),'Dates']
每個特征下的資料分布,可以用boxplot或者hist來看
%matplotlib inline
import matplotlib.pyplot as plt
df.boxplot(column='Fare', by = 'Pclass')
plt.hist(df['Fare'], bins = 10, range =(df['Fare'].min(),df['Fare'].max()))
plt.title('Fare >distribution')
plt.xlabel('Fare')
plt.ylabel('Count of Passengers')
#如果變量是categorical的,想看distribution,則可以:
df.PdDistrict.value_counts().plot(kind='bar', figsize=(8,10))
如果想看幾個feature之間的聯立情況,則可以用pandas的groupby,
temp = pd.crosstab([df.Pclass, df.Sex], df.Survived.astype(bool))
temp.plot(kind='bar', stacked=True, color=['red','blue'], grid=False)
在這步完成之後,要對以下幾點有大緻了解
了解每個特征的意義
要知道哪些特征是有用的,這些特征哪些是直接可以用的,哪些需要經過變換才能用,為之後的特征工程做準備
資料預處理,就是将資料處理下,為模型輸入做準備,其中包括:
處理missing value:這裡學問有點深,如果各位有好的經驗可以跟我交流下。以我淺薄的經驗來說我一般會分情況處理
如果missing value占總體的比例非常小,那麼直接填入平均值或者衆數
如果missing value所占比例不算小也不算大,那麼可以考慮它跟其他特征的關系,如果關系明顯,那麼直接根據其他特征填入;也可以建立簡單的模型,比如線性回歸,随機森林等。
如果missing value所占比例大,那麼直接将miss value當做一種特殊的情況,另取一個值填入
處理Outlier:這個就是之前EDA的作用了,通過畫圖,找出異常值
處理categorical feature:一般就是通過dummy variable的方式解決,也叫one hot encode,可以通過pandas.get_dummies()或者 sklearn中preprocessing.OneHotEncoder(), 我個人傾向于用pandas的get_dummies()
看個例子吧,
dummy variable
将一列的month資料展開為了12列,用0、1代表類别。
另外在處理categorical feature有兩點值得注意:
如果特征中包含大量需要做dummy variable處理的,那麼很可能導緻得到一個稀疏的dataframe,這時候最好用下PCA做降維處理。
(更新)近期在kaggle成功的案例中發現,對于類别特征,在模型中加入tf-idf總是有效果的。
還有個方法叫“Leave-one-out” encoding,也可以處理類别特征種類過多的問題,實測效果不錯。
理論上來說,特征工程應該也歸屬于上一步,但是它太重要了,是以将它單獨拿出來。kaggle社群對特征工程的重要性已經達成了共識,可以說最後結果的好壞,大部分就是由特征工程決定的,剩下部分應該是調參和Ensemble決定。特征工程的好壞主要是由domain knowledge決定的,但是大部分人可能并不具備這種知識,那麼隻能盡可能多的根據原來feature生成新的feature,然後讓模型選擇其中重要的feature。這裡就又涉及到feature selection,
最常用的模型是Ensemble Model,比如 Random Forest,Gradient Boosting。當然在開始的時候,可以用點簡單的模型,一方面是可以作為底線threshold,另一方面也可以在最後作為Ensemble Model。
from sklearn.grid_search import GridSearchCV
from pprint import pprint
clf=RandomForestClassifier(random_state=seed)
parameters = {'n_estimators': [300, 500], 'max_features':[4,5,'auto']}
grid_search = GridSearchCV(estimator=clf,param_grid=parameters, cv=10, scoring='accuracy')
print("parameters:")
pprint(parameters)
grid_search.fit(train_x,train_y)
print("Best score: %0.3f" % grid_search.best_score_)
print("Best parameters set:")
best_parameters=grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
print("\t%s: %r" % (param_name, best_parameters[param_name]))
Model Ensemble有Bagging,Boosting,Stacking,其中Bagging和Boosting都算是Bootstraping的應用。Bootstraping的概念是對樣本每次有放回的抽樣,抽樣K個,一共抽N次。
Bagging:每次從總體樣本中随機抽取K個樣本來訓練模型,重複N次,得到N個模型,然後将各個模型結果合并,分類問題投票方式結合,回歸則是取平均值,e.g.Random Forest。
Boosting:一開始給每個樣本取同樣的權重,然後疊代訓練,每次對訓練失敗的樣本調高其權重。最後對多個模型用權重平均來結合,e.g. GBDT。
Bagging與Boosting的比較:在深入了解Bagging和Boosting後發現,bagging其實是用相同的模型來訓練随機抽樣的資料,這樣的結果是各個模型之間的bias差不多,variance也差不多,通過平均,使得variance降低(由算平均方差的公式可知),進而提高ensemble model的表現。而Boosting其實是一種貪心算法,不斷降低bias。
Stacking: 訓練一個模型來組合其他各個模型。首先先訓練多個不同的模型,然後再以之前訓練的各個模型的輸出為輸入來訓練一個模型,以得到一個最終的輸出。使用過stacking之後,發現其實stacking很像神經網絡,通過很多模型的輸出,建構中間層,最後用邏輯回歸講中間層訓練得到最後的結果。這裡貼一個例子供參考。
最後是我的兩點心得吧
設定random seed,使得你的模型reproduce,以Random Foreset舉例:
seed=0
每個project組織好檔案層次和布局,既友善與其他人交流,也友善自己。比如在一個project下,分設3個檔案夾,一個是input,放訓練資料、測試資料,一個model,放模型檔案,最後一個submission檔案,放你生成要送出的結果檔案。
這篇文章是參加kaggle之後的第一次總結,描述了下kaggle的步驟,通用的知識點和技巧。希望在未來一個月中,能把xgboost和stacking研究應用下,然後再來update。希望大家有什麼想法都能跟我交流下~~
update: 更新了關于類别特征的處理方式以及Boosting和Bagging的看法,還有stacking的内容。
轉自:https://www.jianshu.com/p/32def2294ae6