經過房價預測入門Kaggle

 

  今天看了個新聞,說是中國社會科學院城市發展與環境研究所及社會科學文獻出版社共同發佈《房地產藍皮書:中國房地產發展報告No.16(2019)》指出房價上漲7.6%,看得我都坐不住了,這房價上漲何時是個頭啊。爲了讓本身之後租得起房,我仍是好好努力吧。因而我打開了Kaggle,準備上手第一道題,正巧發現有個房價預測,可能這是命運的安排吧......算法

1、下載數據

  進入到 kaggle 後要先登陸,須要注意的是,註冊的時候有一個驗證,要FQ纔會顯示驗證信息。app

      

  

  下載好數據以後,大體看一下數據的狀況,在對應題目的頁面也有關於數據屬性的一些解釋,看一下對應數據表明什麼。測試

2、數據預處理

 提取 y_train 並作相應處理

  先導入須要用到的包,經過 pandas 的 read_csv(filename, index_col=0) 分別將測試集和訓練集導入。完了以後,咱們把訓練集裏的「SalePrice」取出來,查看它的分佈狀況並做一下處理。ui

y_train = train_data.pop('SalePrice')
y_train.hist()

            

  因而可知數據並不平滑,所以須要將其正態化,正態化可使數據變得平滑,目的是穩定方差,直線化,使數據分佈正態或者接近正態。正態化能夠用 numpy 的 log1p() 處理。log1p(y_train) 能夠理解爲 log 1 plus,即 log(y_train + 1)。正態化以前,先看一下若是正態化以後的價格分佈。spa

      

  這樣的分佈就很好了,所以咱們經過 numpy 的 log1p() 將 y_train 正態化。3d

y_train = np.log1p(y_train)

 將去掉 SalePrice 的訓練集和測試集合並

  爲了將兩個數據集一塊兒處理,減小重複的步驟,將兩個數據集合並再處理。使用 pandas 的 concat() 將訓練集和測試集合並起來並看一下合併後的數據的行數和列數,以確保正確合併。code

data = pd.concat((train_data, test_data), axis=0)
data.shape

 特徵處理

  數據集中有幾個跟年份有關的屬性,分別是:blog

  • YrSold: 售出房子的年份;
  • YearBuilt:房子建成的年份;
  • YearRemodAdd:裝修的年份;
  • GarageYrBlt:車庫建成的年份

  算出跟售出房子的時間差,並新生成單獨的列,而後刪除這些年份get

data.eval('Built2Sold = YrSold-YearBuilt', inplace=True)
data.eval('Add2Sold = YrSold-YearRemodAdd', inplace=True)
data.eval('GarageBlt = YrSold-GarageYrBlt', inplace=True)
data.drop(['YrSold', 'YearBuilt', 'YearRemodAdd', 'GarageYrBlt'], axis=1, inplace=True)

  接下來進行變量轉換,因爲有一些列是類別型的,但因爲pandas的特性,數字符號會被默認成數字。好比下面三列,是以數字來表示等級的,但被認爲是數字,這樣就會使得預測受到影響。input

  • OverallQual: Rates the overall material and finish of the house
  • OverallCond: Rates the overall condition of the house
  • MSSubClass: The building class

  這三個至關因而等級和類別,只不過是用數字來當等級的高低而已。所以咱們要把這些轉換成 string

data['OverallQual'] = data['OverallQual'].astype(str)
data['OverallCond'] = data['OverallCond'].astype(str)
data['MSSubClass'] = data['MSSubClass'].astype(str)

 把category的變量轉變成numerical 

  咱們能夠用One-Hot的方法來表達category。pandas自帶的get_dummies方法,能夠一鍵作到One-Hot。

  這裏按個人理解解釋一下One-Hot:好比說有一組自擬的數據 data,其中 data['學歷要求']有'大專', '本科', '碩士', '不限'。但data['學歷要求']=='本科',則他能夠用字典表示成這樣{'大專': 0, '本科':1, '碩士':0, '不限':0},用向量表示爲[0, 1, 0, 0]

dummied_data = pd.get_dummies(data)

      

 處理numerical變量

  category變量處理好了以後,就該輪到numerical變量了。查看一下缺失值狀況。

dummied_data.isnull().sum().sort_values(ascending=False).head()

           

  上面的數據顯示的是每列對應的缺失值狀況,對於缺失值,須要進行填充,可使用平均值進行填充。

mean_cols = dummied_data.mean()
dummied_data = dummied_data.fillna(mean_cols)

 標準差標準化

  缺失值處理完畢,因爲有一些數據的值比較大,特別是比起 one-hot 後的數值 0 和 1,那些幾千的值就相對比較大了。所以對數值型變量進行標準化。

numerical_cols = data.columns[data.dtypes != 'object']  # 數據爲數值型的列名
num_cols_mean = dummied_data.loc[:, numerical_cols].mean()
num_cols_std = dummied_data.loc[:, numerical_cols].std()
dummied_data.loc[:, numerical_cols] = (dummied_data.loc[:, numerical_cols] - num_cols_mean) / num_cols_std

  到這裏,數據處理算是完畢了。雖然這樣處理還不夠完善,後面若是技術再精進一點可能會從新弄一下。接下來須要將數據集分開,分紅訓練集合測試集。

X_train = dummied_data.loc[train_data.index].values
X_test = dummied_data.loc[test_data.index].values

3、建模預測

  因爲這是一個迴歸問題,我用 sklearn.selection 的 cross_val_score 試了嶺迴歸(Ridge Regression)、BaggingRegressor 以及 XGBoost。且不說集成算法比單個迴歸模型好,XGBoost  不愧是 Kaggle 神器,效果比 BaggingRegressor 還要好不少。安裝 XGBoost  的過程就不說了,安裝好以後導入包就好了,可是咱們還要調一下參。

params = [6,7,8]
scores = []
for param in params:
    model = XGBRegressor(max_depth=param)
    score = np.sqrt(-cross_val_score(model, X_train, y_train, cv=10, scoring='neg_mean_squared_error'))
    scores.append(np.mean(score))
plt.plot(params, scores)

          

  可見當 max_depth = 7 的時候,錯誤率最低。接下來就是建模訓練預測了。

xgbr = XGBRegressor(max_depth=7)
xgbr.fit(X_train, y_train)
y_prediction = np.expm1(xgbr.predict(X_test))

  獲得結果以後,將結果保存爲 .csv 文件,由於 kaggle 的提交要求是 csv 文件,能夠到 kaggle 看一下提交要求,前面下載的文件裏面也有一份提交樣式,照它的格式保存文件就行了。

submitted_data = pd.DataFrame(data= {'Id' : test_data.index, 'SalePrice': y_prediction})
submitted_data.to_csv('./input/submission.csv', index=False)  # 將預測結果保存到文件

 4、提交結果

      

       

  提交的時候也要FQ,纔會上傳文件。到這裏就結束了。

 

  想要第一時間獲取更多有意思的推文,可關注公衆號: Max的平常操做

                            

相關文章
相關標籤/搜索