加州房价预测
文章目錄
- 一、項目概覽
- 二、劃定問題
- 三、選擇性能指標
- 四、核實假設
- 五、獲取數(shù)據
- 六、創(chuàng)建測試集
- 七、數(shù)據探索和可視化、發(fā)現(xiàn)規(guī)律
- 八、查找關聯(lián)
- 九、屬性組合實驗
- 十、為機器學習算法準備數(shù)據
- 1、數(shù)據清洗
- 2、處理文本和類別屬性
- 3、添加附加屬性
- 4、特征縮放
- 5、轉換流水線
- 十一、選擇并訓練模型
- 1、在訓練集上訓練和評估
- 2、利用交叉驗證來評估模型
- 3、模型微調
- 4、用測試集評估系統(tǒng)
- 5、啟動、監(jiān)控、維護系統(tǒng)
一、項目概覽
利用加州普查數(shù)據,建立一個加州房價模型。
目標:模型利用該數(shù)據進行學習,然后根據其他指標,預測任何街區(qū)的房價中位數(shù)
二、劃定問題
建立模型不可能是最終目標,而是公司的受益情況,這決定了如何劃分問題,選擇什么算法,評估模型的指標和微調等等
你建立的模型的輸出(一個區(qū)的房價中位數(shù))會傳遞給另一個機器學習系統(tǒng),也有其他信號傳入該系統(tǒng),從而確定該地區(qū)是否值得投資。
設計系統(tǒng):
1、劃定問題:監(jiān)督與否、強化學習與否、分類與否、批量學習或線上學習
2、確定問題:典型的監(jiān)督學習任務,多變量的回歸問題,樣本數(shù)據不多可以使用批量學習。
三、選擇性能指標
回歸問題的典型指標是均方根誤差(RMSE),均方根誤差測量的是系統(tǒng)預測誤差的標準差:
RMSE(X,h)=1m∑i=1m(h(Xi)?y(i))2RMSE(X,h)=\sqrt{\frac{1}{m}\sum_{i=1}^m(h(X^i)-y^{(i)})^2}RMSE(X,h)=m1?i=1∑m?(h(Xi)?y(i))2?
四、核實假設
最好列出并核對迄今做出的假設,這樣可以盡早發(fā)現(xiàn)嚴重的問題,例如,系統(tǒng)輸出的街區(qū)房價會傳入到下游的機器學習系統(tǒng),我們假設這些價格確實會被當做街區(qū)房價使用,但是如果下游系統(tǒng)將價格轉化為分類(便宜、昂貴、中等等),然后使用這些分類來進行判定的話,就將回歸問題變?yōu)榉诸悊栴},能否獲得準確的價格已經不是很重要了。
五、獲取數(shù)據
使用pandas加載數(shù)據的話,獲得一個包含所有數(shù)據的DataFrame對象,DataFrame對象是表格型的數(shù)據結構,提供有序的列和不同類型的列值。
housing.head():查看前5行
housing.info():方法可以快速查看數(shù)據的描述,特別是總行數(shù)、每個屬性的類型和非空值的數(shù)量
housing["ocean_proximity"].value_counts():查看非數(shù)值的項,也就是距離大海距離的項包含哪些屬性,每個屬性包含多少個街區(qū)
housing.describe():方法查看數(shù)值屬性的概括(均值、方差、最大最小、分位數(shù)等)
housing.hist():柱狀圖
六、創(chuàng)建測試集
測試集在這個階段就要進行分割,因為如果查看了測試集,就會不經意的按照測試集中的規(guī)律來選擇某個特定的機器學習模型,當再使用測試集進行誤差評估的時候,就會發(fā)生過擬合,在實際系統(tǒng)中表現(xiàn)很差。
隨機挑選一些實例,一般是數(shù)據集的20%
1、隨機劃分20%為測試集:
from sklearn.model_selection import train_test_split train_set,test_set=train_test_split(housing,test_size=0.2,random_state=42)隨機劃分的特點:
隨機的取樣方法,當數(shù)據集很大的時候,尤其是和屬性數(shù)量相比很大的時候,通常是可行的,但是如果數(shù)據集不大,就會有采樣偏差的風險,出現(xiàn)訓練和測試數(shù)據分布差距太大的問題。
當一個調查公司想要對1000個人進行調查,不能是隨機取1000個人,而是要保證有代表性,美國人口的51.3%是女性,48.7%是男性,所以嚴謹?shù)恼{查需要保證樣本也是這樣的比例:513名女性,487名男性,這稱為分層采樣。
2、分層抽樣
將人群分成均勻的子分組,稱為分層,從每個分層去取合適數(shù)量的實例,保證測試集對總人數(shù)具有代表性。
可以利用和最終的房屋價值中位數(shù)的關聯(lián)最大的特征作為分層抽樣的標準。
此處收入的中位數(shù)對最終結果的預測很重要,所以利用不同收入分布來劃分測試集,保證劃分之后,每個收入層級的頻率分布基本保持不變。
收入中位數(shù)是連續(xù)值,利用收入中位數(shù)/1.5,ceil()對值進行舍入,以產生離散的分類,然后將所有大于5的分類歸類于分類5
根據收入分類,進行分層采樣,使用sklearn的stratifiedShuffleSplit類
分層抽樣可以使得測試集和原始的數(shù)據集在重要特征的分布上基本一致。
七、數(shù)據探索和可視化、發(fā)現(xiàn)規(guī)律
將地理位置、房價等因素和輸出的標簽做一個可視化,查看其分布狀況。
八、查找關聯(lián)
1、person系數(shù)
因為數(shù)據集并不是很大,所以可以使用corr()的方法來計算出每對屬性間的標準相關系數(shù),也稱為person相關系數(shù)
corr_matrix=housing.corr() corr_matrix["median_house_value"].sort_values(ascending=False)輸出:
median_house_value 1.000000 median_income 0.687160 total_rooms 0.135097 housing_median_age 0.114110 households 0.064506 total_bedrooms 0.047689 population -0.026920 longitude -0.047432 latitude -0.142724 Name: median_house_value, dtype: float64可以看出median_income和最終的輸出結果的相關程度很高
2、scatter_matrix()函數(shù):
可以繪制每個數(shù)值屬性對每個其他數(shù)值屬性的圖,因為現(xiàn)在有11個數(shù)值屬性,可以得到 112=121112=121 張圖,所以只關注幾個和房價中位數(shù)最有可能相關的屬性。
最有希望用來預測房價中位數(shù)的屬性是收入中位數(shù),因此將這張圖放大:
該圖說明了幾點:
-
首先,相關性非常高,可以清晰的看到向上的趨勢,并且數(shù)據點不是很分散
-
其次,圖中在280000美元、350000美元、450000美元、500000美元都出現(xiàn)了水平線,可以去除對應的街區(qū),防止過擬合
九、屬性組合實驗
創(chuàng)建三個新特征:
roomes_per_household
bedrooms_per_rooms
population_per_household
housing["roomes_per_household"]=housing["total_rooms"]/housing["households"] housing["bedrooms_per_rooms"]=housing["total_bedrooms"]/housing["total_rooms"] housing["population_per_household"]=housing["population"]/housing["households"] corr_matrix=housing.corr() corr_matrix["median_house_value"].sort_values(ascending=False)# False:降序輸出:
median_house_value 1.000000 median_income 0.687160 roomes_per_household 0.146285 total_rooms 0.135097 housing_median_age 0.114110 households 0.064506 total_bedrooms 0.047689 population_per_household -0.021985 population -0.026920 longitude -0.047432 latitude -0.142724 bedrooms_per_rooms -0.259984 Name: median_house_value, dtype: float64與總房間數(shù)或臥室數(shù)相比,新的特征“每個房子中的臥室數(shù) bedrooms_per_room”屬性與房價中位數(shù)的關聯(lián)更強,也就是臥室數(shù)/總房間數(shù)的比例越低,房價就越高,每戶的房間數(shù)也比街區(qū)的總房間數(shù)更有信息,也就是房屋越大,房價就越高。
這一步的數(shù)據探索不必非常完備,此處的目的是有一個正確的開始,快速發(fā)現(xiàn)規(guī)律,以得到一個合理的原型。
十、為機器學習算法準備數(shù)據
為機器學習算法準備數(shù)據,不用手工來做,你需要寫一些函數(shù),理由如下:
-
函數(shù)可以讓你在任何數(shù)據集上方便的進行重復數(shù)據轉換
-
可以慢慢建立一個轉換函數(shù)庫,可以在未來的項目中重復使用
-
在將數(shù)據傳給算法之前,你可以在實時系統(tǒng)中使用這些函數(shù)
-
可以讓你方便的嘗試多種數(shù)據轉換,查看哪些轉換方法結合起來效果最好
先回到干凈的訓練集,將預測量和標簽分開,因為我們不想對預測量和目標值應用相同的轉換(注意drop創(chuàng)建了一份數(shù)據的備份,而不影響strat_train_set):
housing=strat_train_set.drop("median_house_value",axis=1) housing_labels=strat_train_set["median_house_value"].copy()1、數(shù)據清洗
大多數(shù)機器學習算法不能處理缺失的特征,因此創(chuàng)建一些函數(shù)來處理特征缺失的問題,前面的total_bedrooms有一些缺失值,有三個解決問題的方法:
-
去掉對應街區(qū):housing.dropna()
-
去掉整個屬性:housing.drop()
-
進行賦值(0、平均值、中位數(shù)):housing.fillna(median)
sklearn提供了一個方便的類來處理缺失值:Imputer
- 首先,創(chuàng)建一個Imputer示例,指定用某屬性的中位數(shù)來替換該屬性所有的缺失值
- 因為只有數(shù)值屬性才能算出中位數(shù),需要創(chuàng)建一份不包括文本屬性ocean_proximity的數(shù)據副本
- 最后,利用fit()方法將imputer實例擬合到訓練數(shù)據
- 現(xiàn)在就是用該“訓練過的”imputer來對訓練集進行轉換,將缺失值替換為中位數(shù):
2、處理文本和類別屬性
前面,我們丟棄了類別屬性ocean_proximity,因為它是一個文本屬性,不能計算出中位數(shù),大多數(shù)機器學習算法喜歡和數(shù)字打交道,所以讓我們把這些文本標簽轉化為數(shù)字。
① 利用轉換器LabelEncoder,將四個值轉換為0,1,2,3
這種方法會出現(xiàn)不同的大小影響判斷的情況,所以引入二元屬性。
② 獨熱編碼
3、添加附加屬性
4、特征縮放
屬性量度差距過大的話,機器學習性能下降,梯度下降尋找最優(yōu)解的過程不穩(wěn)定且很耗時。
兩種常見的方法讓所有的屬性具有相同的量度:
-
線性歸一化(MinMaxScalar)
-
標準化(StandardScalar)
注意:縮放器之能向訓練集擬合,而不是向完整的數(shù)據集,只有這樣才能轉化訓練集和測試集
5、轉換流水線
數(shù)據處理過程中,存在許多數(shù)據轉換步驟,需要按照一定的順序進行執(zhí)行,sklearn提供了類——Pipeline來進行一系列轉換,
十一、選擇并訓練模型
前面限定了問題、獲得了數(shù)據、探索了數(shù)據、采樣了測試集,寫了自動化的轉換流水線來清理和為算法準備數(shù)據,現(xiàn)在可以選擇并訓練一個機器學習模型了。
1、在訓練集上訓練和評估
(1)線性回歸模型
from sklearn.linear_model import LinearRegression lin_reg=LinearRegression() lin_reg.fit(housing_prepared,housing_labels)RMSE=68628,結果并不好,大多數(shù)街區(qū)的房價中位數(shù)位于120000-265000美元之間,因此預測誤差68628并不能讓人滿意,這是一個欠擬合的例子,所以我們要選擇更好的模型進行預測,也可以添加更多的特征,等等。
(2)決策樹
from sklearn.tree import DecisionTreeRegressor tree_reg=DecisionTreeRegressor() tree_reg.fit(housing_prepared,housing_labels)RMSE=0,過擬合
2、利用交叉驗證來評估模型
評估決策樹模型的一種方法是用函數(shù)train_test_split來分割訓練集,得到一個更小的訓練集和一個驗證集,然后用更小的訓練集來訓練模型,用驗證集進行評估。
另一種方法是使用交叉驗證功能,下面的代碼采用了k折交叉驗證(k=10),每次用一個折進行評估,用其余九個折進行訓練,結果是包含10個評分的數(shù)組。
from sklearn.model_selection import cross_val_score scores=cross_val_score(tree_reg,housing_prepared,housing_labels,scoring="neg_mean_squared_error",cv=10) scores tree_rmse_scores=np.sqrt(-scores)輸出:
array([ -4.69780143e+09, -4.53079547e+09, -5.09684731e+09,-4.76712153e+09, -5.10478677e+09, -5.49833181e+09,-5.11203877e+09, -4.83185329e+09, -5.95294534e+09,-4.98684497e+09])查看得分函數(shù):
def display_scores(scores):print("Scores:", scores)print("Mean:", scores.mean())print("Standard deviation:", scores.std()) display_scores(tree_rmse_scores)輸出:
Scores: [ 68416.06869621 67700.71364388 70107.46534824 68567.8343617671987.47320813 74458.15245677 70294.48853581 71217.5750103476961.44182696 70069.50630652] Mean: 70978.0719395 Standard deviation: 2723.10200089交叉驗證不僅可以讓你得到模型性能的評估,還能測量評估的準確性,也就是標準差,決策樹的評分大約是70978,波動為±2723,如果只有一個驗證集就得不到這些信息,但是交叉驗證的代價是訓練了模型多次,不可能總是這樣
(3)隨機森林
from sklearn.ensemble import RandomForestRegressorforest_reg=RandomForestRegressor(random_state=42) forest_reg.fit(housing_prepared,housing_labels) from sklearn.model_selection import cross_val_score forest_scores=cross_val_score(forest_reg,housing_prepared,housing_labels,scoring="neg_mean_squared_error",cv=10) forest_rmse_scores=np.sqrt(-forest_scores) display_scores(forest_rmse_scores)輸出:
Scores: [ 51650.94405471 48920.80645498 52979.16096752 54412.7404202150861.29381163 56488.55699727 51866.90120786 49752.2459953755399.50713191 53309.74548294] Mean: 52564.1902524 Standard deviation: 2301.87380392隨機森林看起來不錯,但是訓練集的評分仍然比驗證集評分低很多,解決過擬合可以通過簡化模型,給模型加限制,或使用更多的訓練數(shù)據來實現(xiàn)。
可以嘗試機器學習算法的其他類型的模型(SVM、神經網絡等)
3、模型微調
假設現(xiàn)在有了一個列表,列表里有幾個希望的模塊,你現(xiàn)在需要對它們進行微調,下面有幾種微調的方法。
(1)網格搜索
可以使用sklearn的GridSearchCV來做這項搜索工作:
from sklearn.model_selection import GridSearchCVparam_grid=[{'n_estimators':[3,10,30],'max_features':[2,4,6,8]},{'bootstrap':[False],'n_estimators':[3,10],'max_features':[2,3,4]},]# 3棵樹、10棵樹、30棵樹集成 # 最大特征數(shù):2/4/6/8 forest_reg=RandomForestRegressor() grid_search=GridSearchCV(forest_reg,param_grid,cv=5,scoring='neg_mean_squared_error') grid_search.fit(housing_prepared,housing_labels)注意:
param_grid:
-
首先評估所有的列在第一個dict中的n_estimators和max_features的3x4=12種組合
-
之后嘗試第二個dict中超參數(shù)的2x3=6種組合,這次會將超參數(shù)bootstrap設為False而不是True
總之,網格搜索會探索12+6=18種RandomForestRegressor的超參數(shù)組合,會訓練每個模型5次,因為是5折交叉驗證,也就是總共訓練18x5=90輪,最終得到最佳參數(shù)組合。
利用grid_search.best_params_得到最佳估計參數(shù):{'max_features': 8, 'n_estimators': 30}
grid_search.best_estimator_也可以得到最佳估計器:
RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,max_features=8, max_leaf_nodes=None, min_impurity_split=1e-07,min_samples_leaf=1, min_samples_split=2,min_weight_fraction_leaf=0.0, n_estimators=30, n_jobs=1,oob_score=False, random_state=None, verbose=0, warm_start=False)如果GridSearchCV是以默認值refit=True開始運行的,則一旦用了交叉驗證找到了最佳估計器,就會在整個訓練集上重新訓練。
得到評估得分:
cvres=grid_search.cv_results_ for mean_score,params in zip(cvres["mean_test_score"],cvres["params"]):print(np.sqrt(-mean_score),params)輸出:
64215.557922 {'n_estimators': 3, 'max_features': 2} 55714.8764381 {'n_estimators': 10, 'max_features': 2} 53079.4656786 {'n_estimators': 30, 'max_features': 2} 60922.7203346 {'n_estimators': 3, 'max_features': 4} 52804.3071875 {'n_estimators': 10, 'max_features': 4} 50617.4676308 {'n_estimators': 30, 'max_features': 4} 59157.2838878 {'n_estimators': 3, 'max_features': 6} 52452.1859118 {'n_estimators': 10, 'max_features': 6} 50004.9240828 {'n_estimators': 30, 'max_features': 6} 58781.2418874 {'n_estimators': 3, 'max_features': 8} 51669.9337736 {'n_estimators': 10, 'max_features': 8} 49905.3850728 {'n_estimators': 30, 'max_features': 8} 62068.9023546 {'bootstrap': False, 'n_estimators': 3, 'max_features': 2} 53842.6681258 {'bootstrap': False, 'n_estimators': 10, 'max_features': 2} 59645.8537753 {'bootstrap': False, 'n_estimators': 3, 'max_features': 3} 52778.2491624 {'bootstrap': False, 'n_estimators': 10, 'max_features': 3} 59149.2314414 {'bootstrap': False, 'n_estimators': 3, 'max_features': 4} 51774.2952583 {'bootstrap': False, 'n_estimators': 10, 'max_features': 4}該例子中,我們通過設定超參數(shù)max_features為8,n_estimators為30,得到了最佳方案,RMSE的值為49959,這比之前使用默認超參數(shù)的值52634要好。
(2)隨機搜索
當探索相對較少的組合時,網格搜索還可以,但是當超參數(shù)的搜索空間很大的時候,最好使用RandomizedSearchCV,該類不是嘗試所有可能的組合,而是通過選擇每個超參數(shù)的一個隨機值的特定數(shù)量的隨機組合,該方法有兩個優(yōu)點:
-
如果你讓隨機搜索運行,比如1000次,它會探索每個超參數(shù)的1000個不同的值,而不是像網格搜索那樣,只搜索每個超參數(shù)的幾個值
-
可以方便的通過設定搜索次數(shù),控制超參數(shù)搜索的計算量
(3)集成方法
另一種微調系統(tǒng)的方法是將表現(xiàn)最好的模型組合起來,組合之后的性能通常要比單獨的模型要好,特別是當單獨模型的誤差類型不同的時候。
4、用測試集評估系統(tǒng)
調節(jié)完系統(tǒng)之后,終于有了一個性能足夠好的系統(tǒng),現(xiàn)在就可以用測試集評估最后的模型了:從測試集得到預測值和標簽
運行full_pipeline轉換數(shù)據,調用transform(),再用測試集評估最終模型:
final_model=grid_search.best_estimator_X_test=strat_test_set.drop("median_house_value",axis=1) y_test=strat_test_set["median_house_value"].copy()X_test_prepared=full_pipeline.transform(X_test) final_predictions=final_model.predict(X_test_prepared) final_mse=mean_squared_error(y_test,final_predictions) final_rmse=np.sqrt(final_mse) final_rmse輸出:47997.889508495638
5、啟動、監(jiān)控、維護系統(tǒng)
(1)啟動
需要為實際生產做好準備,特別是接入輸入數(shù)據源,并編寫測試
(2)監(jiān)控
需要監(jiān)控代碼,以固定間隔檢測系統(tǒng)的實時表現(xiàn),當發(fā)生下降時觸發(fā)警報,這對于捕捉突然的系統(tǒng)崩潰性能下降十分重要,做監(jiān)控很常見,因為模型會隨著數(shù)據的演化而性能下降,除非模型用新數(shù)據定期訓練。
評估系統(tǒng)的表現(xiàn)需要對預測值采樣并進行評估,通常人為分析,需要將人工評估的流水線植入系統(tǒng)
(3)維護
數(shù)據的分布是變化的,數(shù)據會更新,要通過監(jiān)控來及時的發(fā)現(xiàn)數(shù)據的變化,做模型的優(yōu)化。
總結
- 上一篇: 投影仪闪屏怎么办
- 下一篇: 全军出击模拟器无法开枪怎么回事