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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

房价预测(基于决策树算法)

發(fā)布時(shí)間:2023/12/8 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 房价预测(基于决策树算法) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

預(yù)測(cè)波士頓房?jī)r(jià)


第一步. 導(dǎo)入數(shù)據(jù)

在這個(gè)項(xiàng)目中,將使用波士頓房屋信息數(shù)據(jù)來(lái)訓(xùn)練和測(cè)試一個(gè)模型,并對(duì)模型的性能和預(yù)測(cè)能力進(jìn)行評(píng)估。我們希望可以通過(guò)該模型實(shí)現(xiàn)對(duì)房屋的價(jià)值預(yù)估,提高房地產(chǎn)經(jīng)紀(jì)人的工作效率。

此項(xiàng)目的數(shù)據(jù)集來(lái)自kaggle原始數(shù)據(jù),未經(jīng)過(guò)任何處理。該數(shù)據(jù)集統(tǒng)計(jì)了2006年至2010年波士頓個(gè)人住宅銷(xiāo)售情況,包含2900多條觀測(cè)數(shù)據(jù)(其中一半是訓(xùn)練數(shù)據(jù),即我們的housedata.csv文件)。更多文檔信息可以參考作者的文檔,以及項(xiàng)目附件data_description.txt文件(特征描述文件)。

下面區(qū)域的代碼用以載入一些此項(xiàng)目所需的Python庫(kù)。

# 載入此項(xiàng)目需要的庫(kù) import numpy as np import pandas as pd import visuals as vs # Supplementary code 補(bǔ)充的可視化代碼import matplotlib.pyplot as plt import seaborn as sns plt.style.use('seaborn') # use seaborn style 使用seaborn風(fēng)格import warnings warnings.filterwarnings('ignore')%matplotlib inline print('你已經(jīng)成功載入所有庫(kù)!') 你已經(jīng)成功載入所有庫(kù)!

加載數(shù)據(jù)

# 載入波士頓房屋的數(shù)據(jù)集:使用pandas載入csv,并賦值到data_df data_df = pd.read_csv('housedata.csv')# 成功載入的話輸出訓(xùn)練數(shù)據(jù)行列數(shù)目 print("Boston housing dataset has {} data points with {} variables each.".format(*data_df.shape)) Boston housing dataset has 1460 data points with 81 variables each.

第二步. 數(shù)據(jù)分析

這個(gè)部分,將對(duì)已有的波士頓房地產(chǎn)數(shù)據(jù)進(jìn)行初步的觀察與處理。

由于這個(gè)項(xiàng)目的最終目標(biāo)是建立一個(gè)預(yù)測(cè)房屋價(jià)值的模型,需要將數(shù)據(jù)集分為特征(features)目標(biāo)變量(target variable)

  • 目標(biāo)變量:'SalePrice',是我們希望預(yù)測(cè)的變量。
  • 特征:除'SalePrice'外的屬性都是特征,它們反應(yīng)了數(shù)據(jù)點(diǎn)在某些方面的表現(xiàn)或性質(zhì)。

觀察數(shù)據(jù)

對(duì)波士頓房?jī)r(jià)的數(shù)據(jù)進(jìn)行觀察,從而掌握更多數(shù)據(jù)本身的信息。

(1)使用 head方法 打印并觀察前7條data_df數(shù)據(jù)

# 打印出前7條data_df print(data_df.head(7)) Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape \ 0 1 60 RL 65.0 8450 Pave NaN Reg 1 2 20 RL 80.0 9600 Pave NaN Reg 2 3 60 RL 68.0 11250 Pave NaN IR1 3 4 70 RL 60.0 9550 Pave NaN IR1 4 5 60 RL 84.0 14260 Pave NaN IR1 5 6 50 RL 85.0 14115 Pave NaN IR1 6 7 20 RL 75.0 10084 Pave NaN Reg LandContour Utilities ... PoolArea PoolQC Fence MiscFeature MiscVal \ 0 Lvl AllPub ... 0 NaN NaN NaN 0 1 Lvl AllPub ... 0 NaN NaN NaN 0 2 Lvl AllPub ... 0 NaN NaN NaN 0 3 Lvl AllPub ... 0 NaN NaN NaN 0 4 Lvl AllPub ... 0 NaN NaN NaN 0 5 Lvl AllPub ... 0 NaN MnPrv Shed 700 6 Lvl AllPub ... 0 NaN NaN NaN 0 MoSold YrSold SaleType SaleCondition SalePrice 0 2 2008 WD Normal 208500 1 5 2007 WD Normal 181500 2 9 2008 WD Normal 223500 3 2 2006 WD Abnorml 140000 4 12 2008 WD Normal 250000 5 10 2009 WD Normal 143000 6 8 2007 WD Normal 307000 [7 rows x 81 columns]

(2)Id特征對(duì)我們訓(xùn)練數(shù)據(jù)沒(méi)有任何用處,在data_df中使用drop方法刪除'Id'列數(shù)據(jù)

# 刪除data_df中的Id特征(保持?jǐn)?shù)據(jù)仍在data_df中,不更改變量名) data_df.drop('Id',axis=1,inplace=True)

(3)使用describe方法觀察data_df各個(gè)特征的統(tǒng)計(jì)信息:

data_df.describe() MSSubClassLotFrontageLotAreaOverallQualOverallCondYearBuiltYearRemodAddMasVnrAreaBsmtFinSF1BsmtFinSF2...WoodDeckSFOpenPorchSFEnclosedPorch3SsnPorchScreenPorchPoolAreaMiscValMoSoldYrSoldSalePricecountmeanstdmin25%50%75%max
1460.0000001201.0000001460.0000001460.0000001460.0000001460.0000001460.0000001452.0000001460.0000001460.000000...1460.0000001460.0000001460.0000001460.0000001460.0000001460.0000001460.0000001460.0000001460.0000001460.000000
56.89726070.04995810516.8280826.0993155.5753421971.2678081984.865753103.685262443.63972646.549315...94.24452146.66027421.9541103.40958915.0609592.75890443.4890416.3219182007.815753180921.195890
42.30057124.2847529981.2649321.3829971.11279930.20290420.645407181.066207456.098091161.319273...125.33879466.25602861.11914929.31733155.75741540.177307496.1230242.7036261.32809579442.502883
20.00000021.0000001300.0000001.0000001.0000001872.0000001950.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000001.0000002006.00000034900.000000
20.00000059.0000007553.5000005.0000005.0000001954.0000001967.0000000.0000000.0000000.000000...0.0000000.0000000.0000000.0000000.0000000.0000000.0000005.0000002007.000000129975.000000
50.00000069.0000009478.5000006.0000005.0000001973.0000001994.0000000.000000383.5000000.000000...0.00000025.0000000.0000000.0000000.0000000.0000000.0000006.0000002008.000000163000.000000
70.00000080.00000011601.5000007.0000006.0000002000.0000002004.000000166.000000712.2500000.000000...168.00000068.0000000.0000000.0000000.0000000.0000000.0000008.0000002009.000000214000.000000
190.000000313.000000215245.00000010.0000009.0000002010.0000002010.0000001600.0000005644.0000001474.000000...857.000000547.000000552.000000508.000000480.000000738.00000015500.00000012.0000002010.000000755000.000000

8 rows × 37 columns


數(shù)據(jù)預(yù)處理

數(shù)據(jù)不可能是百分百的‘干凈’數(shù)據(jù)(即有用數(shù)據(jù)),總會(huì)在采集整理時(shí)有些”失誤“、“冗余”,造成“臟”數(shù)據(jù),所以要從數(shù)據(jù)的正確性和完整性這兩個(gè)方面來(lái)清理數(shù)據(jù)。

  • 正確性:一般是指有沒(méi)有異常值,比如我們這個(gè)數(shù)據(jù)集中作者的文檔所說(shuō):
    I would recommend removing any houses with more than 4000 square feet from the data set (which eliminates these five unusual observations) before assigning it to students.
    建議我們?nèi)サ魯?shù)據(jù)中'GrLivArea'中超過(guò)4000平方英尺的房屋(具體原因可以參考文檔),當(dāng)然本數(shù)據(jù)集還有其他的異常點(diǎn),這里不再處理。
  • 完整性:采集或者整理數(shù)據(jù)時(shí)所產(chǎn)生的空數(shù)據(jù)造成了數(shù)據(jù)的完整性缺失,通常我們會(huì)使用一定的方法處理不完整的數(shù)據(jù)。在本例中,我們使用以下兩種方法,一是丟棄數(shù)據(jù),即選擇丟棄過(guò)多空數(shù)據(jù)的特征(或者直接丟棄數(shù)據(jù)行,前提是NA數(shù)據(jù)占比不多),二是填補(bǔ)數(shù)據(jù),填補(bǔ)的方法也很多,均值中位數(shù)眾數(shù)填充等等都是好方法。

正確性方面

以下代碼將使用matplotlib庫(kù)中的scatter方法 繪制'GrLivArea'和'SalePrice'的散點(diǎn)圖,x軸為'GrLivArea',y軸為'SalePrice',觀察數(shù)據(jù)**

# 繪制散點(diǎn)圖 plt.scatter(data_df['GrLivArea'],data_df['SalePrice']) plt.xlabel('GrLivArea') plt.ylabel('SalePrice') plt.show()

**觀察所得:通過(guò)上圖我們可以看到那幾個(gè)異常值,即'GrLivArea'大于4000,但是'SalePrice'又極低的數(shù)據(jù),所以需要從data_df刪除這幾個(gè)異常值。

刪除后重新繪制'GrLivArea'和'SalePrice'的關(guān)系圖,確認(rèn)異常值已刪除。**

# 從data_df中刪除 GrLivArea大于4000 且 SalePrice低于300000 的值 index_del = data_df[(data_df['GrLivArea'] > 4000) & (data_df['SalePrice'] < 300000)].index data_df.drop(index=index_del, inplace=True)# 重新繪制GrLivArea和SalePrice的關(guān)系圖,確認(rèn)異常值已刪除 plt.scatter(data_df['GrLivArea'],data_df['SalePrice']) plt.xlabel('GrLivArea') plt.ylabel('SalePrice') plt.show()


完整性方面

篩選出過(guò)多空數(shù)據(jù)的特征,這個(gè)項(xiàng)目定為篩選出有超過(guò)25%為空數(shù)據(jù)的特征

limit_percent = 0.25 limit_value = len(data_df) * limit_percent # 統(tǒng)計(jì)并打印出超過(guò)25%的空數(shù)據(jù)的特征 list(data_df.columns[data_df.isna().sum() > limit_value]) ['Alley', 'FireplaceQu', 'PoolQC', 'Fence', 'MiscFeature']

接著,查看data_description.txt文件,就會(huì)發(fā)現(xiàn),這些并非一定是空缺數(shù)據(jù),而沒(méi)有游泳池,籬笆等也會(huì)用NA來(lái)表示,那么就不需要?jiǎng)h除這些特征了,而是用None來(lái)填充N(xiāo)A數(shù)據(jù)。

以下將使用fillna方法填充空數(shù)據(jù)。

# 確定所有空特征 missing_columns = list(data_df.columns[data_df.isnull().sum() != 0]) # 確定哪些是類(lèi)別特征,哪些是數(shù)值特征 missing_numerical = list(data_df[missing_columns].dtypes[data_df[missing_columns].dtypes != 'object'].index) missing_category = [i for i in missing_columns if i not in missing_numerical] print("missing_numerical:",missing_numerical) print("missing_category:",missing_category) missing_numerical: ['LotFrontage', 'MasVnrArea', 'GarageYrBlt'] missing_category: ['Alley', 'MasVnrType', 'BsmtQual', 'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinType2', 'Electrical', 'FireplaceQu', 'GarageType', 'GarageFinish', 'GarageQual', 'GarageCond', 'PoolQC', 'Fence', 'MiscFeature'] # 需要填充眾數(shù)的特征 fill_Mode = ['Electrical'] # 需要填充N(xiāo)one的特征 fill_None = ['Alley', 'MasVnrType', 'BsmtQual', 'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinType2', 'FireplaceQu', 'GarageType', 'GarageFinish', 'GarageQual', 'GarageCond', 'PoolQC', 'Fence', 'MiscFeature'] # 需要填充0的特征 fill_0 = ['GarageYrBlt'] # 需要填充中位數(shù)的特征 fill_median = ['LotFrontage', 'MasVnrArea']# 按需填補(bǔ)上面數(shù)據(jù) data_df[fill_Mode] = data_df[fill_Mode].fillna(data_df[fill_Mode].mode()) data_df[fill_None] = data_df[fill_None].fillna('None') data_df[fill_0] = data_df[fill_0].fillna(0) data_df[fill_median] = data_df[fill_median].fillna(data_df[fill_median].mean())

特征分析

有這么一句話在業(yè)界廣泛流傳:特征數(shù)據(jù)決定了機(jī)器學(xué)習(xí)的上限,而模型和算法只是逼近這個(gè)上限而已。特征工程,是整個(gè)數(shù)據(jù)分析過(guò)程中不可缺少的一個(gè)環(huán)節(jié),其結(jié)果質(zhì)量直接關(guān)系到模型效果和最終結(jié)論。從上面兩步中我們得到了“干凈”的數(shù)據(jù),但是data_df總共有81個(gè)特征,應(yīng)當(dāng)剔除那些無(wú)關(guān)緊要的特征(噪聲),使用真正關(guān)鍵的特征來(lái)進(jìn)行模型訓(xùn)練。現(xiàn)在需要我們對(duì)這些龐大的數(shù)據(jù)進(jìn)行分析,提取出與目標(biāo)最為關(guān)聯(lián)的數(shù)據(jù)。

繪制'SalePrice'的直方圖,觀察該直方圖屬于什么分布

# 繪制直方圖 plt.hist(data_df['SalePrice']) plt.xlabel('SalePrice') plt.show()

觀察結(jié)論:'SalePrice'屬于正偏態(tài)分布。


如果特征極其多,很難清晰的看到特征與目標(biāo)變量之間的關(guān)系,就需要利用統(tǒng)計(jì)知識(shí)來(lái)進(jìn)行多變量分析了。常用的方法可使用熱圖heatmap結(jié)合corr方法來(lái)進(jìn)行客觀分析,熱圖Heatmap可以用顏色變化來(lái)反映變量之間的相關(guān)性二維矩陣或說(shuō)相關(guān)性表格中的數(shù)據(jù)信息,它可以直觀地將數(shù)據(jù)值的大小以定義的顏色深淺表示出來(lái)。

這個(gè)項(xiàng)目,為了簡(jiǎn)化訓(xùn)練,將以相關(guān)性絕對(duì)值大于0.5為界來(lái)選取所需要的特征。

corrmat = data_df.corr().abs() top_corr = corrmat[corrmat["SalePrice"]>0.5].sort_values(by = ["SalePrice"], ascending = False).index cm = abs(np.corrcoef(data_df[top_corr].values.T)) f, ax = plt.subplots(figsize=(20, 9)) sns.set(font_scale=1.3) hm = sns.heatmap(cm, cbar=True, annot=True,square=True, fmt='.2f', annot_kws={'size': 13}, yticklabels=top_corr.values, xticklabels=top_corr.values); data_df = data_df[top_corr]


接下來(lái),我們從創(chuàng)造性方面來(lái)對(duì)我們的特征進(jìn)行“改造”。

  • 創(chuàng)造性:創(chuàng)造性主要是說(shuō)兩種情況,一種是對(duì)現(xiàn)有數(shù)據(jù)的處理,比如對(duì)類(lèi)別的獨(dú)熱編碼(One-hotEncoder)或者標(biāo)簽編碼(LabelEncoder),數(shù)值的區(qū)間縮放,歸一化,標(biāo)準(zhǔn)化等等。另一種就是根據(jù)某一個(gè)或多個(gè)特征創(chuàng)造一個(gè)新的特征,例如某特征按組分類(lèi)(groupby)后,或者某些特征組合后來(lái)創(chuàng)造新特征等等。

因?yàn)楹Y選出來(lái)的特征都為數(shù)值類(lèi)型特征,所以只做標(biāo)準(zhǔn)化的操作:這個(gè)項(xiàng)目是一個(gè)回歸類(lèi)型的項(xiàng)目,而回歸算法對(duì)標(biāo)準(zhǔn)正態(tài)分步預(yù)測(cè)較為準(zhǔn)確,從目標(biāo)數(shù)據(jù)可以看出數(shù)據(jù)是一個(gè)偏態(tài)分布,那么將使用log將數(shù)據(jù)從偏態(tài)分布轉(zhuǎn)換為標(biāo)準(zhǔn)正態(tài)分布,最后進(jìn)行標(biāo)準(zhǔn)化。

from scipy.special import boxcox1p from sklearn.preprocessing import StandardScalerdata_df['SalePrice'] = np.log1p(data_df['SalePrice']) numeric_features = list(data_df.columns) numeric_features.remove('SalePrice') for feature in numeric_features:#all_data[feat] += 1data_df[feature] = boxcox1p(data_df[feature], 0.15)scaler = StandardScaler() scaler.fit(data_df[numeric_features]) data_df[numeric_features] = scaler.transform(data_df[numeric_features])

第三步. 建立模型

定義衡量標(biāo)準(zhǔn)

如果不能對(duì)模型的訓(xùn)練和測(cè)試的表現(xiàn)進(jìn)行量化地評(píng)估,就很難衡量模型的好壞。通常需要定義一些衡量標(biāo)準(zhǔn),這些標(biāo)準(zhǔn)可以通過(guò)對(duì)某些誤差或者擬合程度的計(jì)算來(lái)得到。在這個(gè)項(xiàng)目中,將通過(guò)運(yùn)算決定系數(shù) R2R^2R2 來(lái)量化模型的表現(xiàn)。模型的決定系數(shù)是回歸分析中十分常用的統(tǒng)計(jì)信息,經(jīng)常被當(dāng)作衡量模型預(yù)測(cè)能力好壞的標(biāo)準(zhǔn)。

R2R^2R2 的數(shù)值范圍從0至1,表示目標(biāo)變量的預(yù)測(cè)值和實(shí)際值之間的相關(guān)程度平方的百分比。一個(gè)模型的 R2R^2R2 值為0還不如直接用平均值來(lái)預(yù)測(cè)效果好;而一個(gè) R2R^2R2 值為1的模型則可以對(duì)目標(biāo)變量進(jìn)行完美的預(yù)測(cè)。從0至1之間的數(shù)值,則表示該模型中目標(biāo)變量中有百分之多少能夠用特征來(lái)解釋。模型也可能出現(xiàn)負(fù)值的 R2R^2R2,這種情況下模型所做預(yù)測(cè)有時(shí)會(huì)比直接計(jì)算目標(biāo)變量的平均值差很多。


在下方代碼的 performance_metric 函數(shù)中,將實(shí)現(xiàn):

  • 使用 sklearn.metrics 中的 r2_score 來(lái)計(jì)算 y_true 和 y_predict 的 R2R^2R2 值,作為對(duì)其表現(xiàn)的評(píng)判。
  • 將他們的表現(xiàn)評(píng)分儲(chǔ)存到 score 變量中。
# 引入 'r2_score' from sklearn.metrics import r2_scoredef performance_metric(y_true, y_predict):""" Calculates and returns the performance score between true and predicted values based on the metric chosen. """# 計(jì)算 'y_true' 與 'y_predict' 的r2值score = r2_score(y_true, y_predict) # 返回這一分?jǐn)?shù)return score

擬合程度

假設(shè)一個(gè)數(shù)據(jù)集有五個(gè)數(shù)據(jù)且某一模型做出下列目標(biāo)變量的預(yù)測(cè):

真實(shí)數(shù)值預(yù)測(cè)數(shù)值
3.02.5
-0.50.0
2.02.1
7.07.8
4.25.3

提示R2R^2R2 分?jǐn)?shù)是指可以從自變量中預(yù)測(cè)的因變量的方差比例。 換一種說(shuō)法:

  • R2R^2R2 為0意味著因變量不能從自變量預(yù)測(cè)。
  • R2R^2R2 為1意味著可以從自變量預(yù)測(cè)因變量。
  • R2R^2R2 在0到1之間表示因變量可預(yù)測(cè)的程度。
  • R2R^2R2 為0.40意味著 Y 中40%的方差可以從 X 預(yù)測(cè)。

下方的代碼將使用 performance_metric 函數(shù)來(lái)計(jì)算 y_true 和 y_predict 的決定系數(shù)。

# 計(jì)算這一模型的表現(xiàn) score = performance_metric([3, -0.5, 2, 7, 4.2], [2.5, 0.0, 2.1, 7.8, 5.3]) print("Model has a coefficient of determination, R^2, of {:.3f}.".format(score)) Model has a coefficient of determination, R^2, of 0.923.

結(jié)論:這個(gè)模型已經(jīng)成功地描述目標(biāo)變量的變化了。因?yàn)?span id="ozvdkddzhkzd" class="katex--inline">R2R^2R2 分?jǐn)?shù)已高達(dá)0.923,說(shuō)明因變量的可預(yù)測(cè)程度非常高。


數(shù)據(jù)分割與重排

接下來(lái),將分割波士頓房屋數(shù)據(jù)集,包括特征與目標(biāo)變量、訓(xùn)練集和測(cè)試集。通常在這個(gè)過(guò)程中,數(shù)據(jù)也會(huì)被重排,以消除數(shù)據(jù)集中由于順序而產(chǎn)生的偏差。

將data_df分割為特征和目標(biāo)變量

# 分割 labels = data_df['SalePrice'] #TODO:提取SalePrice作為labels features = data_df.drop(['SalePrice'], axis=1) #TODO:提取除了SalePrice以外的特征賦值為features

下方代碼將實(shí)現(xiàn):

  • 使用 sklearn.model_selection 中的 train_test_split, 將 features 和 prices 的數(shù)據(jù)都分成用于訓(xùn)練的數(shù)據(jù)子集和用于測(cè)試的數(shù)據(jù)子集。
    • 分割比例為:80%的數(shù)據(jù)用于訓(xùn)練,20%用于測(cè)試;
    • 選定一個(gè)數(shù)值以設(shè)定 train_test_split 中的 random_state ,這會(huì)確保結(jié)果的一致性;
  • 將分割后的訓(xùn)練集與測(cè)試集分配給 X_train, X_test, y_train 和 y_test。
# 引入 'train_test_split' from sklearn.model_selection import train_test_split# 打亂并分割訓(xùn)練集與測(cè)試集 X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=1)# 成功~ print("Training and testing split was successful.") Training and testing split was successful.

訓(xùn)練及測(cè)試

  • 將數(shù)據(jù)集按一定比例分為訓(xùn)練用的數(shù)據(jù)集和測(cè)試用的數(shù)據(jù)集對(duì)學(xué)習(xí)算法能在一定程度上避免過(guò)擬合。

  • 如果用模型已經(jīng)見(jiàn)過(guò)的數(shù)據(jù),例如部分訓(xùn)練集數(shù)據(jù)進(jìn)行測(cè)試,會(huì)使得計(jì)算準(zhǔn)確率時(shí),這個(gè)得分會(huì)不可靠。



第四步. 分析模型的表現(xiàn)

在項(xiàng)目的第四步,我們來(lái)觀察不同參數(shù)下,模型在訓(xùn)練集和驗(yàn)證集上的表現(xiàn)。這里,我們專注于一個(gè)特定的算法(帶剪枝的決策樹(shù)DecisionTreeRegressor)和這個(gè)算法的一個(gè)參數(shù) 'max_depth'。
接下來(lái),用全部訓(xùn)練集訓(xùn)練,選擇不同'max_depth' 參數(shù),觀察這一參數(shù)的變化如何影響模型的表現(xiàn)。并畫(huà)出模型的表現(xiàn)來(lái)分析。


學(xué)習(xí)曲線

下方區(qū)域內(nèi)的代碼會(huì)輸出四幅圖像,它們是一個(gè)決策樹(shù)模型在不同最大深度下的表現(xiàn)。每一條曲線都直觀得顯示了隨著訓(xùn)練數(shù)據(jù)量的增加,模型學(xué)習(xí)曲線在訓(xùn)練集評(píng)分和驗(yàn)證集評(píng)分的變化,評(píng)分使用決定系數(shù) R2R^2R2。曲線的陰影區(qū)域代表的是該曲線的不確定性(用標(biāo)準(zhǔn)差衡量)。

# Produce learning curves for varying training set sizes and maximum depths vs.ModelLearning(features, labels)

學(xué)習(xí)曲線結(jié)論觀察

  • 對(duì)于上述圖像中的最大深度為 3 的那個(gè),隨著訓(xùn)練數(shù)據(jù)量的增加,訓(xùn)練集曲線的評(píng)分減少,驗(yàn)證集曲線的增加。
  • 如果有更多的訓(xùn)練數(shù)據(jù),也無(wú)法提升模型的表現(xiàn),因訓(xùn)練集曲線和驗(yàn)證集曲線已相交在一個(gè)數(shù)值。

復(fù)雜度曲線

下列代碼內(nèi)的區(qū)域會(huì)輸出一幅圖像,它展示了一個(gè)已經(jīng)經(jīng)過(guò)訓(xùn)練和驗(yàn)證的決策樹(shù)模型在不同最大深度條件下的表現(xiàn)。這個(gè)圖形將包含兩條曲線,一個(gè)是訓(xùn)練集的變化,一個(gè)是驗(yàn)證集的變化。跟學(xué)習(xí)曲線相似,陰影區(qū)域代表該曲線的不確定性,模型訓(xùn)練和測(cè)試部分的評(píng)分都用的 performance_metric 函數(shù)。

vs.ModelComplexity(X_train, y_train)


偏差(bias)與方差(variance)之間的權(quán)衡取舍

提示: 高偏差表示欠擬合(模型過(guò)于簡(jiǎn)單),而高方差表示過(guò)擬合(模型過(guò)于復(fù)雜,以至于無(wú)法泛化)。

觀察結(jié)論:

  • 當(dāng)模型以最大深度 1訓(xùn)練時(shí),模型的預(yù)測(cè)出現(xiàn)了很大的偏差。
  • 當(dāng)模型以最大深度10訓(xùn)練時(shí),模型的預(yù)測(cè)出現(xiàn)了很大的方差。
  • 當(dāng)模型以最大深度 1訓(xùn)練時(shí),訓(xùn)練集得分和驗(yàn)證集得分都較低,可見(jiàn)是欠擬合的情況。當(dāng)模型以最大深度10訓(xùn)練時(shí),訓(xùn)練集得分極高和驗(yàn)證集得分不太高,而兩個(gè)得分相差甚大,可見(jiàn)是過(guò)擬合的情況。

最優(yōu)模型的猜測(cè)

  • 結(jié)合復(fù)雜度曲線,可見(jiàn)最大深度是 4 的模型能夠最好地對(duì)未見(jiàn)過(guò)的數(shù)據(jù)進(jìn)行預(yù)測(cè)。
  • 依據(jù):隨著最大深度的增加,訓(xùn)練集得分和驗(yàn)證集得分都在增加,但當(dāng)最大深度超過(guò)4后,驗(yàn)證集得分反而有下降的趨勢(shì),說(shuō)明模型變得越來(lái)越復(fù)雜,逐漸變得過(guò)擬合。


第五步. 評(píng)估模型的表現(xiàn)

在項(xiàng)目的最后一節(jié)中,將構(gòu)建一個(gè)模型,并使用 fit_model 中的優(yōu)化模型去預(yù)測(cè)客戶特征集。


網(wǎng)格搜索(Grid Search)

  • 網(wǎng)格搜索法是窮舉所有參數(shù)的組合,找出使模型得分最高的那個(gè)組合。比如在決策樹(shù)模型里,分別用幾個(gè)不同的深度參數(shù)去訓(xùn)練模型并計(jì)算其測(cè)試集得分,測(cè)試集得分最高模型對(duì)應(yīng)的深度參數(shù)便是最優(yōu)參數(shù)。
  • 優(yōu)化模型方法:嘗試所有參數(shù)的組合,以發(fā)現(xiàn)能使模型性能最好的參數(shù)組合。

交叉驗(yàn)證

  • K折交叉驗(yàn)證法(k-fold cross-validation)是隨機(jī)將訓(xùn)練集劃分成K份,依次將其中的一份作為驗(yàn)證集,其余的作為訓(xùn)練集,訓(xùn)練K個(gè)模型,最后選擇模型表現(xiàn)得最好的那一個(gè)。
  • GridSearchCV 是通過(guò)交叉驗(yàn)證得到每個(gè)參數(shù)組合的得分,以確定最優(yōu)的參數(shù)組合。
  • GridSearchCV 中的'cv_results_'屬性能生成一個(gè)字典,記錄每組網(wǎng)格參數(shù)每次的訓(xùn)練結(jié)果,包括訓(xùn)練/驗(yàn)證時(shí)間、訓(xùn)練/驗(yàn)證評(píng)估分?jǐn)?shù)以及相關(guān)時(shí)間和評(píng)分的統(tǒng)計(jì)信息。
  • K折交叉驗(yàn)證可以盡可能地嘗試所有的數(shù)據(jù)集劃分方式,使網(wǎng)格搜索的結(jié)果可信度更高。K折交叉驗(yàn)證取多次結(jié)果的平均值可以避免樣本劃分不合理的情況。

訓(xùn)練最優(yōu)模型

在這一步中,將使用決策樹(shù)算法訓(xùn)練一個(gè)模型。為了得出的是一個(gè)最優(yōu)模型,需要使用網(wǎng)格搜索法訓(xùn)練模型,以找到最佳的 'max_depth' 參數(shù)。可以把'max_depth' 參數(shù)理解為決策樹(shù)算法在做出預(yù)測(cè)前,允許其對(duì)數(shù)據(jù)提出問(wèn)題的數(shù)量。

在下方 fit_model 函數(shù)中,將實(shí)現(xiàn):

  • 定義 'cross_validator' 變量: 使用 sklearn.model_selection 中的 KFold 創(chuàng)建一個(gè)交叉驗(yàn)證生成器對(duì)象;
  • 定義 'regressor' 變量: 使用 sklearn.tree 中的 DecisionTreeRegressor 創(chuàng)建一個(gè)決策樹(shù)的回歸函數(shù);
  • 定義 'params' 變量: 為 'max_depth' 參數(shù)創(chuàng)造一個(gè)字典,它的值是從1至10的數(shù)組;
  • 定義 'scoring_fnc' 變量: 使用 sklearn.metrics 中的 make_scorer 創(chuàng)建一個(gè)評(píng)分函數(shù);
    將 ‘performance_metric’ 作為參數(shù)傳至這個(gè)函數(shù)中;
  • 定義 'grid' 變量: 使用 sklearn.model_selection 中的 GridSearchCV 創(chuàng)建一個(gè)網(wǎng)格搜索對(duì)象;將變量'regressor', 'params', 'scoring_fnc'和 'cross_validator' 作為參數(shù)傳至這個(gè)對(duì)象構(gòu)造函數(shù)中;
  • # Import 'make_scorer', 'DecisionTreeRegressor', and 'GridSearchCV' from sklearn.metrics import make_scorer from sklearn.tree import DecisionTreeRegressor from sklearn.model_selection import GridSearchCV from sklearn.model_selection import KFolddef fit_model(X, y):""" Performs grid search over the 'max_depth' parameter for a decision tree regressor trained on the input data [X, y]. """cross_validator = KFold(n_splits=10)# Create a decision tree regressor objectregressor = DecisionTreeRegressor(random_state=1)# Create a dictionary for the parameter 'max_depth' with a range from 1 to 10params = {'max_depth':[i for i in range(1, 11)]}# Transform 'performance_metric' into a scoring function using 'make_scorer' scoring_fnc = make_scorer(performance_metric)# Create the grid search cv object --> GridSearchCV()# Make sure to include the right parameters in the object:# (estimator, param_grid, scoring, cv) which have values 'regressor', 'params', 'scoring_fnc', and 'cross_validator' respectively.grid = GridSearchCV(regressor, params, scoring_fnc, cv = cross_validator)# Fit the grid search object to the data to compute the optimal modelgrid = grid.fit(X, y)# Return the optimal model after fitting the datareturn grid.best_estimator_

    第六步. 做出預(yù)測(cè)

    當(dāng)我們用數(shù)據(jù)訓(xùn)練出一個(gè)模型,它就可用于對(duì)新的數(shù)據(jù)進(jìn)行預(yù)測(cè)。在我們的例子–決策樹(shù)回歸函數(shù)中,模型已經(jīng)學(xué)會(huì)對(duì)新輸入的數(shù)據(jù)“提問(wèn)”,并返回對(duì)目標(biāo)變量的預(yù)測(cè)值。現(xiàn)在可以用這些預(yù)測(cè)來(lái)獲取未知目標(biāo)變量的數(shù)據(jù)的信息,但是,輸入的新數(shù)據(jù)必須不能是已有訓(xùn)練數(shù)據(jù)之中的。


    最優(yōu)模型

    下方代碼將決策樹(shù)回歸函數(shù)代入訓(xùn)練數(shù)據(jù)的集合,以得到最優(yōu)化的模型。

    # Fit the training data to the model using grid search reg = fit_model(X_train, y_train)# Produce the value for 'max_depth' print("Parameter 'max_depth' is {} for the optimal model.".format(reg.get_params()['max_depth'])) Parameter 'max_depth' is 6 for the optimal model.

    最終,使用確認(rèn)好的參數(shù)來(lái)對(duì)測(cè)試數(shù)據(jù)進(jìn)行預(yù)測(cè),并來(lái)看看訓(xùn)練結(jié)果如何。

    depth = 6 regressor = DecisionTreeRegressor(max_depth = depth) regressor.fit(X_train, y_train) y_pred = regressor.predict(X_test) score = performance_metric(y_test, y_pred) print("The R2 score is ",score) The R2 score is 0.7520017488593774

    訓(xùn)練結(jié)果情況:

    • 模型的效果并不理想。

    • 改進(jìn):1、需要更多的特征來(lái)訓(xùn)練模型;2、數(shù)據(jù)預(yù)處理時(shí),空值的填充用錯(cuò)數(shù)值;3、試試換成線性回歸模型。

    總結(jié)

    以上是生活随笔為你收集整理的房价预测(基于决策树算法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。