摘要:到這里,我們經過以上步驟處理過的數據,就可以喂給分類器進行訓練了。一般來說,單個分類器的效果有限。我們會傾向于把多個分類器合在一起,做一個綜合分類器以達到最好的效果。比理論上更高級點,它也是攬來一把的分類器。
特征工程
我們注意到 MSSubClass 其實是一個 category 的值:
all_df["MSSubClass"].dtypes
有:
dtype("int64")
它不應該做為數值型的值進行統計。因此,進行強制類型轉換,把它變回 string:
df["MSSubClass"] =df["MSSubClass"].astype(str)
然后,統計其出現頻次:
all_df["MSSubClass"].value_counts()
就很清楚的了解 MSSubClass 特征了。
當我們用 numerical 來表達 categorical 的時候要注意,數字本身有大小的含義,所以亂用數字會給之后的模型學習帶來麻煩。這里我們可以用 One-Hot 的方法來表達 category。
pandas 自帶的get_dummies方法,可以做到一鍵 One-Hot:
pd.get_dummies(df["MSSubClass"], prefix="MSSubClass").head()
效果如下:
此時,MSSubClass 被我們分成了 12 列,每列代表一個 category,是為 1,否為 0。
所以,同理。接下來,我們需要把所有的 category 數據全部一鍵 One-Hot:
all_dummy_df = pd.get_dummies(df) all_dummy_df.head()
此時,數據長這樣子:
接下來,我們來處理 numerical 的數據。
首先查看 One-Hot 后的缺失值:
all_dummy_df.isnull().sum().sort_values(ascending=False).head(10)
我們需要對這些缺失值進行處理,這里采用平均值來填充空缺:
mean_cols = all_dummy_df.mean() all_dummy_df = all_dummy_df.fillna(mean_cols)
再次查看是否有缺失值:
all_dummy_df.isnull().sum().sum()
顯示為 0,即缺失值都已被填充。
到這里,我們經過以上步驟處理過的數據,就可以喂給分類器進行訓練了。為了讓數據更加規整化,數據間的差距不要太大,在一個標準分布內,也就是數據平滑化。我們對那些本來就是 numerical 的數據進行處理(與 One-Hot 的 0/1 數據不同)。
首先,我們來查看哪些是 numerical 的數據:
numeric_cols = df.columns[df.dtypes != "object"] numeric_cols
采用公式(X-X")/s,計算標準分布:
numeric_col_means = all_dummy_df.loc[:, numeric_cols].mean() numeric_col_std = all_dummy_df.loc[:, numeric_cols].std() all_dummy_df.loc[:, numeric_cols] = (all_dummy_df.loc[:, numeric_cols] - numeric_col_means) / numeric_col_std
得到的數據如下:
all_dummy_df.head()
以上就完成了對數據的處理。
建立模型首先,把數據集分回訓練集和測試集:
dummy_train_df = all_dummy_df.loc[train_df.index] dummy_test_df = all_dummy_df.loc[test_df.index]
首先采用 Ridge Regression 模型,因為對于多因子的數據集,這種模型可以方便的把所有的變量都一股腦的放進去,我們先用這種模型做實驗。
為了更好的使用 Sklearn,我在這里把 DataFrame 轉化成 Numpy Array(這一步不是必須):
X_train = dummy_train_df.values X_test = dummy_test_df.values
把數據放到模型里跑一遍,用 Sklearn 自帶的 cross validation 方法來測試模型:
from sklearn.linear_model import Ridge from sklearn.model_selection import cross_val_score alphas = np.logspace(-3, 2, 50) test_scores=[] for alpha in alphas: clf = Ridge(alpha) test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=10, scoring="neg_mean_squared_error")) test_scores.append(np.mean(test_score))
存下所有的 CV 值,看看哪個 alpha 值更好,也就是我們常說的調參數:
plt.plot(alphas, test_scores) plt.title("Alpha vs CV Error") plt.xlabel("alpha") plt.ylabel("CV Error")
可以看到,當 alpha 為 10 到 20 的時候,CV Error 達到最低 0.135 左右。也就是說大約 alpha = 15 的時候給了我們最好的結果。
一般來說,單個分類器的效果有限。我們會傾向于把多個分類器合在一起,做一個“綜合分類器”以達到最好的效果。所以接下來我們要做的事就是 ensemble。
Ensemble 的方法有 Bagging 和 Boosting 兩大類。Bagging 把很多的小分類器放在一起,每個訓練隨機的一部分數據,然后采用多數投票制把它們的最終結果綜合起來。Boosting 比 Bagging 理論上更高級點,它也是攬來一把的分類器。但是把他們線性排列。下一個分類器把上一個分類器分類得不好的地方加上更高的權重,這樣下一個分類器就能在這個部分學得更加“深刻”。下面我們分別來看一下。
Bagging
from sklearn.ensemble import BaggingRegressor from sklearn.model_selection import cross_val_score params = [1, 10, 15, 20, 25, 30, 40] test_scores = [] for param in params: clf = BaggingRegressor(n_estimators=param, base_estimator=ridge) test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=10, scoring="neg_mean_squared_error")) test_scores.append(np.mean(test_score)) plt.plot(params, test_scores) plt.title("n_estimator vs CV Error")
可以看到,我們用 15 個小的 ridge 分類器就達到了 0.134 以下的效果。
Boosting
from sklearn.ensemble import AdaBoostRegressor params = [10, 15, 20, 25, 30, 35, 40, 45, 50] test_scores = [] for param in params: clf = BaggingRegressor(n_estimators=param, base_estimator=ridge) test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=10, scoring="neg_mean_squared_error")) test_scores.append(np.mean(test_score)) plt.plot(params, test_scores) plt.title("n_estimator vs CV Error");
20 個小的 ridge 分類器的效果,達到了 0.133。
最后,祭出 xgboost 大殺器:
from xgboost import XGBRegressor params = [1,2,3,4,5,6] test_scores = [] for param in params: clf = XGBRegressor(max_depth=param) test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=10, scoring="neg_mean_squared_error")) test_scores.append(np.mean(test_score)) plt.plot(params, test_scores) plt.title("max_depth vs CV Error")
我們看到,當參數為 5 的時候,效果接近 0.125!
提交結果最后,我們將訓練好的模型對數據進行訓練:
xgb = XGBRegressor(max_depth=5) xgb.fit(X_train, y_train) y_xgb = np.expm1(xgb.predict(X_test)) submission_df = pd.DataFrame(data= {"Id" : test_df.index, "SalePrice": y_xgb})
最終,我們輸出的數據長這樣子:
submission_df.head()
將它存為.csv文件:
submission_df.to_csv("submission_xgb.csv",index=False)
提交到 kaggle 平臺的 Score 是 0.13942,排名在 50% 左右。整個過程沒有對特征信息進行太多的處理,還有太多需要改進的地方。
后記第一次完完整整的從頭到尾自己做了一個比賽,還是有太多地方淺淺略過,確實,如果只是調參跑模型的話,應該不是難事,但是如何獲得更好的效果,數據量大時現有的程序跑不動,需要改進算法等方面,還有太多值得學習的地方,因為這件事好像沒有一個最優結果,只有更優的結果。
不足之處,歡迎指正。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/44998.html
摘要:本次分享的項目來自的經典賽題房價預測。分為數據分析和數據挖掘兩部分介紹。本篇為數據分析篇。賽題解讀比賽概述影響房價的因素有很多,在本題的數據集中有個變量幾乎描述了愛荷華州艾姆斯住宅的方方面面,要求預測最終的房價。 本次分享的項目來自 Kaggle 的經典賽題:房價預測。分為數據分析和數據挖掘兩部分介紹。本篇為數據分析篇。 賽題解讀 比賽概述 影響房價的因素有很多,在本題的數據集中有 ...
摘要:提取出中的信息特征缺失值同樣,觀察的缺失值情況缺失值處理發現兩位都是女性。特征缺失值特征有的缺失值,較為嚴重,如果進行大量的填補會引入更多噪聲。因為缺失值也是一種值,這里將缺失值視為一種特殊的值來處理,并根據首個字符衍生一個新的特征。 作者:xiaoyu 微信公眾號:Python數據科學 知乎:python數據分析師 showImg(https://segmentfault.com/...
閱讀 1762·2021-11-24 09:39
閱讀 1551·2021-11-16 11:54
閱讀 3497·2021-11-11 16:55
閱讀 1655·2021-10-14 09:43
閱讀 1445·2019-08-30 15:55
閱讀 1233·2019-08-30 15:54
閱讀 3421·2019-08-30 15:53
閱讀 1338·2019-08-30 14:18