機器學習實戰⑴之線性迴歸預測房價
機器學習
一般來說,一個學習問題通常會考慮一系列 n 個 樣本 資料,然後嘗試預測未知資料的屬性。 如果每個樣本是 多個屬性的資料,比如說是一個多維記錄),就說它有許多“屬性”,或稱 features(特徵) 。
我們可以將學習問題分為幾大類:
- [監督學習]其中資料帶有一個附加屬性,即我們想要預測的結果值。這個問題可以是:
> [分類]: 樣本屬於兩個或更多個類,我們想從已經標記的資料中學習如何預測未標記資料的類別。 分類問題的一個例子是手寫數字識別,其目的是將每個輸入向量分配給有限數目的離散類別之一。 我們通常把分類視作監督學習的一個離散形式(區別於連續形式),從有限的類別中,給每個樣本貼上正確的標籤。 > [迴歸]: 如果期望的輸出由一個或多個連續變數組成,則該任務稱為 *迴歸* 。 迴歸問題的一個例子是預測鮭魚的長度是其年齡和體重的函式。
- [無監督學習]其中訓練資料由沒有任何相應目標值的一組輸入向量x組成。這種問題的目標可能是在資料中發現彼此類似的示例所聚成的組,這種問題稱為 [聚類], 或者,確定輸入空間內的資料分佈,稱為 [密度估計],又或從高維資料投影資料空間縮小到二維或三維以進行 視覺化 。
訓練集和測試集
機器學習是從資料的屬性中學習,並將它們應用到新資料的過程。 這就是為什麼機器學習中評估演算法的普遍實踐是把資料分割成 訓練集 (我們從中學習資料的屬性)和 測試集 (我們測試這些性質)。
機器學習實戰
-
第一步:載入相應包和所需的資料集
我們這裡選的是sklearn包,此包是python中比較常用的機器學習整合包,可以滿足大多數模型需求。
# -*- coding: utf-8 -*- """ Created on Thu Oct 18 13:43:44 2018 @author: Administrator """ % reset -f % clear # In[*] ##########第一步匯入包和資料 # In[*] from sklearn.model_selection import cross_val_score from sklearn import linear_model from sklearn import metrics import matplotlib.pyplot as plt import pandas as pd import numpy as np import seaborn as sns import os os.chdir("C:\\Users\\Administrator\\Desktop\\all") # In[*] train = pd.read_csv('train.csv',header = 0,index_col=0) test= pd.read_csv('test.csv',header = 0,index_col=0) # In[*] sns.distplot(train["SalePrice"]) plt.show()

我們可以看到訓練集train的房屋售價分佈相對均勻
-
第二步 刪減和目標變數低相關的屬性
# In[*] ##########第二步刪減和目標變數低相關的屬性 # In[*] data = train.corr() sns.heatmap(data) plt.show() # In[*] data = train.corr() data["SalePrice"].sort_values()
KitchenAbvGr-0.135907 EnclosedPorch-0.128578 MSSubClass-0.084284 OverallCond-0.077856 YrSold-0.028923 LowQualFinSF-0.025606 MiscVal-0.021190 BsmtHalfBath-0.016844 BsmtFinSF2-0.011378 3SsnPorch0.044584 MoSold0.046432 PoolArea0.092404 ScreenPorch0.111447 BedroomAbvGr0.168213 BsmtUnfSF0.214479 BsmtFullBath0.227122 LotArea0.263843 HalfBath0.284108 OpenPorchSF0.315856 2ndFlrSF0.319334 WoodDeckSF0.324413 LotFrontage0.351799 BsmtFinSF10.386420 Fireplaces0.466929 MasVnrArea0.477493 GarageYrBlt0.486362 YearRemodAdd0.507101 YearBuilt0.522897 TotRmsAbvGrd0.533723 FullBath0.560664 1stFlrSF0.605852 TotalBsmtSF0.613581 GarageArea0.623431 GarageCars0.640409 GrLivArea0.708624 OverallQual0.790982 SalePrice1.000000 Name: SalePrice, dtype: float64

該圖為屬性之間的相關係數,我們需要做的是刪除掉與預測目標不相關或者低相關的變數。(一般來說我們同時也應該刪除掉用來預測的變數之間高度相關的變數),所以我們刪除了BsmtHalfBath,'BsmtFinSF2', '3SsnPorch', 'MoSold', 'PoolArea', 'ScreenPorch'這幾個與預測目標低相關的變數。
# In[*] train = train.drop(['BsmtHalfBath', 'BsmtFinSF2', '3SsnPorch', 'MoSold', 'PoolArea', 'ScreenPorch', 'BedroomAbvGr'], axis=1) test = test.drop(['BsmtHalfBath', 'BsmtFinSF2', '3SsnPorch', 'MoSold', 'PoolArea', 'ScreenPorch', 'BedroomAbvGr'], axis=1)
我們來挑幾個變數,看一下變數與目標的相關
# In[*] sns.lmplot(x="OverallQual", y="SalePrice", data=train,fit_reg=False,scatter=True) plt.show() # In[*] sns.lmplot(x="TotalBsmtSF", y="SalePrice", data=train,fit_reg=False,scatter=True) plt.show()


-
第三步 刪減和填充缺失值
# In[*] ##########第三步刪減和填充缺失值 # In[*] # In[*] for col in train.columns: if train[col].isnull().sum() > 0: print (col, train[col].isnull().sum()) # In[*] train = train.drop(["MiscFeature", "PoolQC", "Alley", "Fence",'FireplaceQu' ], axis=1) test = test.drop(["MiscFeature", "PoolQC", "Alley", "Fence",'FireplaceQu' ], axis=1) # In[*] print(train.describe()) # In[*] all_data = pd.concat((train, test)) # In[*] for col in train.columns: if train[col].isnull().sum() > 0: if train[col].dtypes == 'object': val = all_data[col].dropna().value_counts().idxmax() train[col] = train[col].fillna(val) else: val = all_data[col].dropna().mean() train[col] = train[col].fillna(val) # In[*] for col in test.columns: if test[col].isnull().sum() > 0: if test[col].dtypes == 'object': val = all_data[col].dropna().value_counts().idxmax() test[col] = test[col].fillna(val) else: val = all_data[col].dropna().mean() test[col] = test[col].fillna(val) # In[*] for col in all_data.select_dtypes(include = [object]).columns: train[col] = train[col].astype('category', categories = all_data[col].dropna().unique()) test[col] = test[col].astype('category', categories = all_data[col].dropna().unique()) # In[*] for col in train.columns: if train[col].dtype.name == 'category': tmp = pd.get_dummies(train[col], prefix = col) train = train.join(tmp) train = train.drop(col, axis=1) # In[*] for col in test.columns: if test[col].dtype.name == 'category': tmp = pd.get_dummies(test[col], prefix = col) test = test.join(tmp) test = test.drop(col, axis=1) # In[*] for col in train.columns: if train[col].isnull().sum() > 0: print (col, train[col].isnull().sum()) # In[*]
這一步的主要工作是刪減和填充缺失值,首先是檢視資料每一列缺失值的情況,我將其中缺失值大於一半觀察值的屬性刪除掉。然後填充缺失值,填充的時候,數字型屬性是用的中位值,而字串型別的屬性用的是最多的值
-
第四步 建立線性迴歸預測模型
# In[*] ##########第四步建立線性迴歸預測模型 # In[*] # In[*] lr = linear_model.LinearRegression() X = train.drop("SalePrice", axis=1) y = np.log(train["SalePrice"]) score = cross_val_score(lr, X,y, scoring='mean_squared_error') # In[*] print(score) # In[*] lr = lr.fit(X, y) results = lr.predict(test) final = np.exp(results)
-
第五步 儲存預測結果
# In[*] ##########第五步儲存預測結果 submission = pd.DataFrame() submission['Id'] = test.index submission['SalePrice'] = final submission.to_csv("submission1.csv", index= False)