日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据科学竞赛-房价预测

發布時間:2024/4/11 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据科学竞赛-房价预测 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

房價預測

簡介

這是Kaggle上的一個Getting Started級別的新手賽,主要為房價預測的回歸賽。具體比賽的級別之分,可以查看我關于Kaggle介紹的博客。詳細的思路均在Notebook中標注,本文不多贅述過多理論思路,具體可以查看我之前關于數據挖掘賽的思路博客。共提交了兩次,baseline和final兩個版本,final版本參考了Kaggle上部分人的stacking思路。本文只簡述Final版本的思路,baseline版本比較簡單,可以在文末給出的Github地址找到源碼。

數據獲取

官方給出了數據,可以在Kernel(現Notebook)中直接訪問該數據集,也可以下載到本地,官方給出了下載地址。

數據的大致分為下面四個文件,官方給出了文件說明。

具體的表頭屬性的含義可以在data_description.txt查看,這對數據預處理和特征構造階段尤其重要。

探索性數據分析

只是進行了一些必要的EDA操作。

離群點分析

fig, ax = plt.subplots() ax.scatter(x=df_train['GrLivArea'], y=df_train['SalePrice']) plt.xlabel('GrLivArea') plt.xlabel('SalePrice') plt.show() # 該離群點可以刪除是因為確實離群范圍過大,嚴重影響模型擬合,不是所有的離群點都應該刪除的 df_train = df_train.drop(df_train[(df_train['GrLivArea'] > 4000)&(df_train['SalePrice']<300000)].index)

目標分布分析

sns.distplot(df_train['SalePrice'], fit=norm) # 使用正態分布擬合數據 (mu, sigma) = norm.fit(df_train['SalePrice']) # 對樣本進行擬合,得到最合適的采樣數據的概率密度函數的系數 plt.legend(['Normal dist. ($\mu=$ {:.2f} and $\sigma=$ {:.2f} )'.format(mu, sigma)], loc='best') plt.ylabel('Frequency') plt.title('SalePrice distribution')fig = plt.figure() res = probplot(df_train['SalePrice'], plot=plt) plt.show()

空值分析

all_data_null = df_all.isnull().sum() / len(df_all) * 100 # 統計各列的空值數目 all_data_null = all_data_null[all_data_null>0].sort_values(ascending=False) miss_data = pd.DataFrame({'MissRatio': all_data_null}) miss_data.head(30)

相關性分析

corr_mat = df_train.corr() plt.subplots(figsize=(16, 8)) sns.heatmap(corr_mat, vmax=0.9, square=True)

特征工程

這一步是整個流程費時最久的,進行了大量的屬性處理和理解。

空值處理

一般不會對空值記錄進行刪除,這會造成信息的大量丟失,最合理的做法是依照說明文件,對各屬性進行理解,選擇最合適的填充方法進行空值填充。

# 按照說明文件,PoolQC為空表示沒有泳池,考慮到該列較高的缺失率以及大多數房子都是沒有泳池的,直接None填充 df_all['PoolQC'] = df_all['PoolQC'].fillna("None") # 下面幾項均可以按照說明文件,直接填None cols = ['MiscFeature', 'Alley', 'Fence', 'FireplaceQu', 'GarageType', 'GarageFinish', 'GarageQual', 'GarageCond'] for col in cols:df_all[col] = df_all[col].fillna("None") # 街道面積與同社區的其他房屋的街道面積類似,取所有鄰居中位數即可 df_all["LotFrontage"] = df_all.groupby("Neighborhood")["LotFrontage"].transform(lambda x: x.fillna(x.median())) # 根據屬性含義,下面的屬性直接填0 cols = ['GarageYrBlt', 'GarageArea', 'GarageCars', 'BsmtFinSF1', 'BsmtFinSF2', 'BsmtUnfSF','TotalBsmtSF', 'BsmtFullBath', 'BsmtHalfBath'] for col in cols:df_all[col] = df_all[col].fillna(0) # 下面的屬性為空表示無值 cols = ['BsmtQual', 'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinType2'] for col in cols:df_all[col] = df_all[col].fillna('None') # 下面兩個屬性為NA最可能意味空值 df_all["MasVnrType"] = df_all["MasVnrType"].fillna("None") df_all["MasVnrArea"] = df_all["MasVnrArea"].fillna(0) # 眾數填,RL最合適 df_all['MSZoning'] = df_all['MSZoning'].fillna(df_all['MSZoning'].mode()[0]) # 該屬性只有三個不同值,其余均為一個結果,該列對模型擬合沒有太大意義,刪除即可 df_all = df_all.drop(columns=['Utilities'], axis=1) # 根據說明,Typ代表典型值 df_all["Functional"] = df_all["Functional"].fillna("Typ") # 經過分析,下面的屬性均眾數填充即可 cols = ['Electrical', 'KitchenQual', 'Exterior1st', 'Exterior2nd', 'SaleType'] for col in cols:df_all[col] = df_all[col].fillna(df_all[col].mode()[0]) # 填None df_all['MSSubClass'] = df_all['MSSubClass'].fillna("None")

屬性變換

這一步主要將字符型數據進行自然數編碼,onehot編碼之類的,最終產生全部為數值的數據。

# 部分看起來數值型的變量,其實取值只有幾種,轉換為分類變量合適一些 df_all['MSSubClass'] = df_all['MSSubClass'].apply(str) df_all['OverallCond'] = df_all['OverallCond'].astype(str) df_all['YrSold'] = df_all['YrSold'].astype(str) df_all['MoSold'] = df_all['MoSold'].astype(str) # 將部分分類變量轉化為數值型 from sklearn.preprocessing import LabelEncoder cols = ('FireplaceQu', 'BsmtQual', 'BsmtCond', 'GarageQual', 'GarageCond', 'ExterQual', 'ExterCond','HeatingQC', 'PoolQC', 'KitchenQual', 'BsmtFinType1', 'BsmtFinType2', 'Functional', 'Fence', 'BsmtExposure', 'GarageFinish', 'LandSlope','LotShape', 'PavedDrive', 'Street', 'Alley', 'CentralAir', 'MSSubClass', 'OverallCond', 'YrSold', 'MoSold') for col in cols:lbl = LabelEncoder() lbl.fit(list(df_all[col].values)) df_all[col] = lbl.transform(list(df_all[col].values))# labelencoder不會像get_dummies那樣生成多個屬性 df_all.shape

屬性構造

有理由的對已有特征進行組合,構造對模型有效的新特征。本賽題只構建了房屋全面積這個屬性。隨后,對所有特征進行高偏特征的Box-Cox變換,具體查看源碼。

# 根據經驗,面積對于房價的影響時非常大的,構造房屋總面積這個屬性 df_all['TotalArea'] = df_all['TotalBsmtSF'] + df_all['1stFlrSF'] + df_all['2ndFlrSF']

模型構建

本部分還是采用挖掘賽常用的思路,對若模型結果進行集成,主要使用的是Stacking方法。

平均模型

# 采用stacking方法 class StackingAveragedModels(BaseEstimator, RegressorMixin, TransformerMixin):def __init__(self, base_models, meta_model, n_folds=5):self.base_models = base_modelsself.meta_model = meta_modelself.n_folds = n_foldsdef fit(self, X, y):self.base_models_ = [list() for x in self.base_models]self.meta_model_ = clone(self.meta_model)kfold = KFold(n_splits=self.n_folds, shuffle=True, random_state=156)out_of_fold_predictions = np.zeros((X.shape[0], len(self.base_models)))for i, model in enumerate(self.base_models):for train_index, holdout_index in kfold.split(X, y):instance = clone(model)self.base_models_[i].append(instance)instance.fit(X[train_index], y[train_index])y_pred = instance.predict(X[holdout_index])out_of_fold_predictions[holdout_index, i] = y_predself.meta_model_.fit(out_of_fold_predictions, y)return selfdef predict(self, X):meta_features = np.column_stack([np.column_stack([model.predict(X) for model in base_models]).mean(axis=1)for base_models in self.base_models_ ])return self.meta_model_.predict(meta_features)stacked_averaged_models = StackingAveragedModels(base_models = (ENet, GBoost, KRR, ABR), meta_model = lasso) score = rmse_cv(stacked_averaged_models) print("Stacking Averaged models score: {:.4f} ({:.4f})".format(score.mean(), score.std()))
  • 集成的模型具有不錯的效果。

多模型加權組合

將多個集成模型,分別為采用Stacking的自定義模型,采用Boosting的Xgboost和Lightgbm進行結果加權組合。

print("Final RMSE Loss in training dataset", rmse(y_train, stacked_train_pred*0.70+xgb_train_pred*0.15+lgb_train_pred*0.15))

加權組合的結果如下,看起來不錯,這就是最后提交的模型。

模型應用

使用模型進行預測,測試集的處理同訓練集。final版本的提交達到了top10%,由于這里只是使用最簡單的幾種模型stacking,嘗試更多的模型和參數調整會獲得更好的結果。(調參只是“錦上添花”)

提交結果

  • baseline
  • final

補充說明

項目的源碼和數據集都上傳到我的Github,歡迎查看。文章同步到我的個人博客網站,歡迎查看其他文章。如有錯誤,歡迎指正。

總結

以上是生活随笔為你收集整理的数据科学竞赛-房价预测的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。