第二章:端對端機器學習專案
第二章:端對端機器學習專案
這章節主要會帶大家實戰,快速完成第一個機器學習專案
第一步先確定要做甚麼類型的分析,書中舉例使用美國的房價預測,這邊我們直接使用台灣過去房價來跑分析,因此我們會有房子相關的label 以及價格,這表示我們可以使用回歸來去訓練資料。
要如何去評估一個模型表現?
以回歸模型來說,可以使用均方根誤差(RMSE),用平方差異的根號來判斷模型預測結果的差異,如果數值越大,表示誤差越大
為何RMSE比較小表現比較好:假設有兩個model 的預測結果如下實際: [4, 2, 5, 8]模型A的預測: [3.5, 2.5, 4.5, 7.5]模型B的預測: [2, 3, 6, 10]以肉眼觀察,我們會覺得模型A做出的預測比較貼近真實狀況來觀察兩個的RMSE:模型 A:差異 = [4 - 3.5, 2 - 2.5, 5 - 4.5, 8 - 7.5]差異 = [0.5, -0.5, 0.5, 0.5]平方差異 = [0.5^2, (-0.5)^2, 0.5^2, 0.5^2]平方差異 = [0.25, 0.25, 0.25, 0.25]計算方根MSE = (0.25 + 0.25 + 0.25 + 0.25) / 4MSE = 1 / 4MSE = 0.25開根號RMSE = √0.25RMSE = 0.5模型 B:差異 = [4 - 2, 2 - 3, 5 - 6, 8 - 10]差異 = [2, -1, -1, -2]平方差異= [2^2, (-1)^2, (-1)^2, (-2)^2]平方差異= [4, 1, 1, 4]計算方根MSE = (4 + 1 + 1 + 4) / 4MSE = 10 / 4MSE = 2.5開根號RMSE = √2.5RMSE ≈ 1.58比較以下發現,預測值越貼合真實,數值就越小A RMSE: 0.5B RMSE: 1.58
導入資料:¶
接下來就可以去網路下在資料來實作,這邊以台中房屋價格git
Clone 相關文件後就可以透過
house_data = pd.read_csv('house.csv',low_memory=False)house_data.head() # check part of data
house_data.head() 來觀察首幾行的長相
house_data.info() 來觀察資料集中有沒有缺失值
這邊的目的是先快速對你的資料有大致上的了解
資料清洗:¶
資料清洗的目的是讓你的資料更貼近用來訓練的模型,把不需要的資料丟棄
取決於每個人的策略,這邊的策略是想套用回歸模型去預測,因此我們最終需要數字型的資料,因此我們可以拆成
- 原先就是純數字
- 不需要的
- 日期格式,後續可以轉換成跟今日的差距月份
- 非純數字,但用於訓練,後續用one-hot encode去處理
col_is_numeric = ['主建物面積', '廳數', '房', '衛', '總價元','車位總價元', '附屬建物面積', '陽台面積', '土地', '建物', '車位', '土地面積', '建物面積',]col_to_drop = ['主要建材', '主要用途', '土地位置建物門牌', '移轉層次', '總樓層數', '都市土地使用分區']col_is_date = ['trade_date', 'build_date']col_one_hot_encode = ['交易標的','車位類別','鄉鎮市區','電梯','建物型態2','有無管理組織']
資料關聯性:¶
這邊也是跟資料清理有關,先觀察資料關聯性可以對資料有一些基本認識,例如這邊會發現資料都是左偏而不是預期的鐘型,推測是依些極端值導致(爬下來的資料本身有些資料也是相當異常),我們可以進一步把極端資料濾除。
columns_to_plot = list(df_to_train.columns)[:16]df_to_train[columns_to_plot].hist(bins=50, figsize=(20,15))
資料訓練:¶
我們用回歸去訓練模型跟檢視測試結果
首先是要把資料再次正規化,有些參數例如房價,基本百萬起跳,但土地/建物等又是個位數字,透過正規化我們可以讓參數跟參數間的scale相近。
再來我們透過train_test_split去拆分測試訓練集
呼叫model訓練後,再用測試集去預測,拿到預測資料y_pred,如此一來我們就可以去檢視先前說道的RMSE有多少
為了避免單一測試集的偏差,我們可以透過cross validation,呼叫cross_val_score,設定測試集cv=10組,去檢查模型給出的答案的穩定性,這邊基本在0.3~4之間。
# 把資料正規化scaler = RobustScaler()scaled_data = scaler.fit_transform(df_outliers_removed)df_to_train = pd.DataFrame(scaled_data, columns=df_outliers_removed.columns)# 首先先把用來input的資料跟要輸出的拆開col_for_x = [x for x in list(df_to_train.columns) if x!='總價元']X = df_to_train[col_for_x]y = df_to_train['總價元']# 拆分資料成訓練跟測試集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 呼叫linear regressionlinear = LinearRegression()linear.fit(X_train, y_train)# 去檢驗我們訓練出來的資料跟真實資料差異y_pred = linear.predict(X_test)mse = mean_squared_error(y_test, y_pred)rmse = np.sqrt(mse)print(f'Root Mean Squared Error: {rmse}') # 0.3588348979062755# 交叉驗證scores = cross_val_score(linear, X_test, y_test, scoring='neg_mean_squared_error', cv=10)linear_rmse_score = np.sqrt(-scores)print('交叉驗證結果: ', linear_rmse_score)# 交叉驗證結果: [0.40926753 0.36864691 0.37536512 0.34313871 0.36591691 0.3386185 0.34407896 0.32377041 0.34193852 0.3806813 ]
視覺化¶
最後在透過matplotlib去視覺化訓練跟預測結果,以這個模型來說,線性預測不是很好,一條曲線表現可能會更好
# 圖像化來看預測的跟實際值差異plt.figure(figsize=(10, 6))plt.scatter(y_test, y_pred, color='blue', label='Predicted vs Actual')plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--', label='Ideal Fit')plt.xlabel('Actual Prices')plt.ylabel('Predicted Prices')plt.title('Actual vs Predicted Prices')plt.legend()plt.show()
Comments
Loading comments…
Leave a Comment