歡迎來到機器學習工程師納米學位的第一個項目!在此文件中,有些示例代碼已經提供給你,但你還須要實現更多的功能來讓項目成功運行。除非有明確要求,你無須修改任何已給出的代碼。以編程練習開始的標題表示接下來的內容中有須要你必須實現的功能。每一部分都會有詳細的指導,須要實現的部分也會在註釋中以TODO標出。請仔細閱讀全部的提示!javascript
除了實現代碼外,你還必須回答一些與項目和實現有關的問題。每個須要你回答的問題都會以'問題 X'爲標題。請仔細閱讀每一個問題,而且在問題後的'回答'文字框中寫出完整的答案。你的項目將會根據你對問題的回答和撰寫代碼所實現的功能來進行評分。css
提示:Code 和 Markdown 區域可經過 Shift + Enter 快捷鍵運行。此外,Markdown能夠經過雙擊進入編輯模式。html
在這個項目中,你將利用馬薩諸塞州波士頓郊區的房屋信息數據訓練和測試一個模型,並對模型的性能和預測能力進行測試。經過該數據訓練後的好的模型能夠被用來對房屋作特定預測---尤爲是對房屋的價值。對於房地產經紀等人的平常工做來講,這樣的預測模型被證實很是有價值。html5
此項目的數據集來自UCI機器學習知識庫(數據集已下線)。波士頓房屋這些數據於1978年開始統計,共506個數據點,涵蓋了麻省波士頓不一樣郊區房屋14種特徵的信息。本項目對原始數據集作了如下處理:java
'MEDV'
值爲50.0的數據點被移除。 這極可能是因爲這些數據點包含遺失或看不到的值。'RM'
值爲8.78. 這是一個異常值,已經被移除。'RM'
, 'LSTAT'
,'PTRATIO'
以及'MEDV'
特徵是必要的,其他不相關特徵已經被移除。'MEDV'
特徵的值已通過必要的數學轉換,能夠反映35年來市場的通貨膨脹效應。運行下面區域的代碼以載入波士頓房屋數據集,以及一些此項目所需的Python庫。若是成功返回數據集的大小,表示數據集已載入成功。python
# 載入此項目所須要的庫
import numpy as np
import pandas as pd
import visuals as vs # Supplementary code
# 檢查你的Python版本
from sys import version_info
if version_info.major != 2 and version_info.minor != 7:
raise Exception('請使用Python 2.7來完成此項目')
# 讓結果在notebook中顯示
%matplotlib inline
# 載入波士頓房屋的數據集
data = pd.read_csv('housing.csv')
prices = data['MEDV']
features = data.drop('MEDV', axis = 1)
# 完成
print "Boston housing dataset has {} data points with {} variables each.".format(*data.shape)
在項目的第一個部分,你會對波士頓房地產數據進行初步的觀察並給出你的分析。經過對數據的探索來熟悉數據可讓你更好地理解和解釋你的結果。jquery
因爲這個項目的最終目標是創建一個預測房屋價值的模型,咱們須要將數據集分爲特徵(features)和目標變量(target variable)。linux
'RM'
, 'LSTAT'
,和 'PTRATIO'
,給咱們提供了每一個數據點的數量相關的信息。'MEDV'
,是咱們但願預測的變量。他們分別被存在features
和prices
兩個變量名中。android
你的第一個編程練習是計算有關波士頓房價的描述統計數據。咱們已爲你導入了numpy
,你須要使用這個庫來執行必要的計算。這些統計數據對於分析模型的預測結果很是重要的。 在下面的代碼中,你要作的是:css3
prices
中的'MEDV'
的最小值、最大值、均值、中值和標準差;#TODO 1
#目標:計算價值的最小值
minimum_price = np.min(prices)
#目標:計算價值的最大值
maximum_price = np.max(prices)
#目標:計算價值的平均值
mean_price = np.average(prices)
#目標:計算價值的中值
median_price = np.median(prices)
#目標:計算價值的標準差
std_price = np.std(prices)
#目標:輸出計算的結果
print "Statistics for Boston housing dataset:\n"
print "Minimum price: ${:,.2f}".format(minimum_price)
print "Maximum price: ${:,.2f}".format(maximum_price)
print "Mean price: ${:,.2f}".format(mean_price)
print "Median price ${:,.2f}".format(median_price)
print "Standard deviation of prices: ${:,.2f}".format(std_price)
如前文所述,本項目中咱們關注的是其中三個值:'RM'
、'LSTAT'
和'PTRATIO'
,對每個數據點:
'RM'
是該地區中每一個房屋的平均房間數量;'LSTAT'
是指該地區有多少百分比的業主屬因而低收入階層(有工做但收入微薄);'PTRATIO'
是該地區的中學和小學裏,學生和老師的數目比(學生/老師
)。憑直覺,上述三個特徵中對每個來講,你認爲增大該特徵的數值,'MEDV'
的值會是增大仍是減少呢?每個答案都須要你給出理由。
提示:你預期一個'RM'
值是6的房屋跟'RM'
值是7的房屋相比,價值更高仍是更低呢?
增大RM的值會,MEDV會增大,由於其餘量不變的狀況下,增長房間數量,通常是增大了房屋面積,則房子價格會更高。增大LSTAT,低收入階層比例增長,則房屋的價格會更低。增大PTRATIO,學生和老師的數目比增長,則意味着這邊學校少,因此房子價格會更低。
接下來,你須要把波士頓房屋數據集分紅訓練和測試兩個子集。一般在這個過程當中,數據也會被重排列,以消除數據集中因爲順序而產生的誤差。 在下面的代碼中,你須要
使用 sklearn.model_selection
中的 train_test_split
, 將features
和prices
的數據都分紅用於訓練的數據子集和用於測試的數據子集。
train_test_split
中的 random_state
,這會確保結果的一致性;# TODO 2
# 提示: 導入train_test_split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(features, prices, test_size=0.2, random_state=42)
將數據集按必定比例分爲訓練用的數據集和測試用的數據集對學習算法有什麼好處?
若是用模型已經見過的數據,例如部分訓練集數據進行測試,又有什麼壞處?
提示: 若是沒有數據來對模型進行測試,會出現什麼問題?
將數據隨機分紅訓練集合測試集,算法用訓練集進行訓練,將訓練出來的模型運用到驗證集上來優化模型。將最終優化完的模型運用到測試集進行測試,查看模型是否準確。
若用模型已經見過的數據進行測試,可能對這些數據已經擬合的很好,但模型的適用性不強,若出現未見過的數據就可能出現大的方差,出現過擬合的狀況。
若是不能對模型的訓練和測試的表現進行量化地評估,咱們就很難衡量模型的好壞。一般咱們會定義一些衡量標準,這些標準能夠經過對某些偏差或者擬合程度的計算來獲得。在這個項目中,你將經過運算決定係數 R2 來量化模型的表現。模型的決定係數是迴歸分析中十分經常使用的統計信息,常常被看成衡量模型預測能力好壞的標準。
R2的數值範圍從0至1,表示目標變量的預測值和實際值之間的相關程度平方的百分比。一個模型的R2 值爲0還不如直接用平均值來預測效果好;而一個R2 值爲1的模型則能夠對目標變量進行完美的預測。從0至1之間的數值,則表示該模型中目標變量中有百分之多少可以用特徵來解釋。模型也可能出現負值的R2,這種狀況下模型所作預測有時會比直接計算目標變量的平均值差不少。
在下方代碼的 performance_metric
函數中,你要實現:
sklearn.metrics
中的 r2_score
來計算 y_true
和 y_predict
的R2值,做爲對其表現的評判。score
變量中。或
# TODO 3
# 提示: 導入r2_score
def performance_metric(y_true, y_predict):
"""計算並返回預測值相比於預測值的分數"""
from sklearn.metrics import r2_score
score = r2_score(y_true, y_predict)
return score
# TODO 3 可選
# 不容許導入任何計算決定係數的庫
def performance_metric2(y_true, y_predict):
"""計算並返回預測值相比於預測值的分數"""
score = None
return score
假設一個數據集有五個數據且一個模型作出下列目標變量的預測:
真實數值 | 預測數值 |
---|---|
3.0 | 2.5 |
-0.5 | 0.0 |
2.0 | 2.1 |
7.0 | 7.8 |
4.2 | 5.3 |
你以爲這個模型已成功地描述了目標變量的變化嗎?若是成功,請解釋爲何,若是沒有,也請給出緣由。
提示:運行下方的代碼,使用performance_metric
函數來計算模型的決定係數。
# 計算這個模型的預測結果的決定係數
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)
我認爲成功,由於從上面的R^2爲0.923能夠看出很接機1,R^2越接近1對目標變量預測越完美
在項目的第四步,咱們來看一下不一樣參數下,模型在訓練集和驗證集上的表現。這裏,咱們專一於一個特定的算法(帶剪枝的決策樹,但這並非這個項目的重點),和這個算法的一個參數 'max_depth'
。用所有訓練集訓練,選擇不一樣'max_depth'
參數,觀察這一參數的變化如何影響模型的表現。畫出模型的表現來對於分析過程十分有益,這可讓咱們看到一些單看結果看不到的行爲。
下方區域內的代碼會輸出四幅圖像,它們是一個決策樹模型在不一樣最大深度下的表現。每一條曲線都直觀得顯示了隨着訓練數據量的增長,模型學習曲線的在訓練集評分和驗證集評分的變化,評分使用決定係數R2。曲線的陰影區域表明的是該曲線的不肯定性(用標準差衡量)。
運行下方區域中的代碼,並利用輸出的圖形回答下面的問題。
# 根據不一樣的訓練集大小,和最大深度,生成學習曲線
vs.ModelLearning(X_train, y_train)
選擇上述圖像中的其中一個,並給出其最大深度。隨着訓練數據量的增長,訓練集曲線的評分有怎樣的變化?驗證集曲線呢?若是有更多的訓練數據,是否能有效提高模型的表現呢?
提示:學習曲線的評分是否最終會收斂到特定的值?
選擇第一個,其max_depth=1,隨着訓練數據量的增長,訓練集曲線的評分先降低後趨於穩定,降低幅度遞減,驗證集曲線的評分先增長後趨於穩定,增長幅度遞減。從上面評分趨於收斂,增長訓練數據對其模型影響不是很大。
下列代碼內的區域會輸出一幅圖像,它展現了一個已經通過訓練和驗證的決策樹模型在不一樣最大深度條件下的表現。這個圖形將包含兩條曲線,一個是訓練集的變化,一個是驗證集的變化。跟學習曲線類似,陰影區域表明該曲線的不肯定性,模型訓練和測試部分的評分都用的 performance_metric
函數。
運行下方區域中的代碼,並利用輸出的圖形並回答下面的兩個問題。
# 根據不一樣的最大深度參數,生成複雜度曲線
vs.ModelComplexity(X_train, y_train)
當模型以最大深度 1訓練時,模型的預測是出現很大的誤差仍是出現了很大的方差?當模型以最大深度10訓練時,情形又如何呢?圖形中的哪些特徵可以支持你的結論?
提示: 你如何得知模型是否出現了誤差很大或者方差很大的問題?
當模型以最大深度1訓練時,模型出現很大的誤差,當模型以最大深度10訓練時,模型出現了很大的方差。圖中同一最大深度下訓練評分和驗證評分的距離,還有R^2的值
結合問題 5 中的圖,你認爲最大深度是多少的模型可以最好地對未見過的數據進行預測?你得出這個答案的依據是什麼?
4,最大深度增長過程當中R^2增長,當最大深度超過4的時候,驗證評分降低,說明已經出現過擬合的狀況。
什麼是網格搜索法?如何用它來優化模型?
嘗試各類可能的參數值,而後進行交叉驗證,使用交叉驗證評估模型。網格就是不少參數進行組合,它搜索的是一個算法在咱們給定參數下的全部可能的組合。經過GridSearchCV使用提供的全部參數不斷造成組合,最後根據結果判斷選擇哪一個參數。
'cv_results_'
屬性能告訴咱們什麼?提示: 在下面 fit_model函數最後加入 print pd.DataFrame(grid.cv_results_)
能夠幫你查看更多信息。
將訓練數據集隨機分紅k份,每次將其中的一份做爲驗證集,剩下的k-1份做爲訓練集,此爲K折交叉驗證法。Split dataset into k consecutive folds (without shuffling by default). k折默認是順序切分。
GridSearchCV用於系統地遍歷多種參數組合,經過交叉驗證肯定最佳效果參數。
GridSearchCV中的'cvresults'屬性鍵爲列標題,值爲列的dict。能夠導入到DataFrame中。告訴咱們平均值、標準差、交叉驗證等一系列的分數和計算時間。
網格搜索時不使用交叉驗證,則模型不夠穩定,只有這一次部分數據做爲驗證集,若是驗證集不具表明性,就會影響模型在未知數據上的表現。若使用交叉驗證,則所有數據均可進行驗證。而交叉驗證很大程度上避免因樣本劃分不合理致使選擇了錯誤的參數。
在這個練習中,你將須要將所學到的內容整合,使用決策樹算法訓練一個模型。爲了得出的是一個最優模型,你須要使用網格搜索法訓練模型,以找到最佳的 'max_depth'
參數。你能夠把'max_depth'
參數理解爲決策樹算法在作出預測前,容許其對數據提出問題的數量。決策樹是監督學習算法中的一種。
在下方 fit_model
函數中,你須要作的是:
'cross_validator'
變量: 使用 sklearn.model_selection
中的 KFold
建立一個交叉驗證生成器對象;'regressor'
變量: 使用 sklearn.tree
中的 DecisionTreeRegressor
建立一個決策樹的迴歸函數;'params'
變量: 爲 'max_depth'
參數創造一個字典,它的值是從1至10的數組;'scoring_fnc'
變量: 使用 sklearn.metrics
中的 make_scorer
建立一個評分函數; 將 ‘performance_metric’
做爲參數傳至這個函數中;'grid'
變量: 使用 sklearn.model_selection
中的 GridSearchCV
建立一個網格搜索對象;將變量'regressor'
, 'params'
, 'scoring_fnc'
和 'cross_validator'
做爲參數傳至這個對象構造函數中;若是你對python函數的默認參數定義和傳遞不熟悉,能夠參考這個MIT課程的視頻。
# TODO 4
#提示: 導入 'KFold' 'DecisionTreeRegressor' 'make_scorer' 'GridSearchCV'
from sklearn.model_selection import KFold
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import fbeta_score, make_scorer
from sklearn.model_selection import GridSearchCV
def fit_model(X, y):
""" 基於輸入數據 [X,y],利於網格搜索找到最優的決策樹模型"""
cross_validator = KFold(n_splits=10)
regressor = DecisionTreeRegressor(random_state=0)
params = {'max_depth':range(1,11)}
scoring_fnc = make_scorer(performance_metric)
grid = GridSearchCV(regressor, params, scoring_fnc, cv = cross_validator)
# 基於輸入數據 [X,y],進行網格搜索
grid = grid.fit(X, y)
# 返回網格搜索後的最優模型
return grid.best_estimator_
在這個練習中,你將須要將所學到的內容整合,使用決策樹算法訓練一個模型。爲了得出的是一個最優模型,你須要使用網格搜索法訓練模型,以找到最佳的 'max_depth'
參數。你能夠把'max_depth'
參數理解爲決策樹算法在作出預測前,容許其對數據提出問題的數量。決策樹是監督學習算法中的一種。
在下方 fit_model
函數中,你須要作的是:
‘max_depth’
的可選值 1~10,構造對應模型# TODO 4 可選
'''
不容許使用 DecisionTreeRegressor 之外的任何 sklearn 庫
提示: 你可能須要實現下面的 cross_val_score 函數
def cross_val_score(estimator, X, y, scoring = performance_metric, cv=3):
""" 返回每組交叉驗證的模型分數的數組 """
scores = [0,0,0]
return scores
'''
def fit_model2(X, y):
""" 基於輸入數據 [X,y],利於網格搜索找到最優的決策樹模型"""
#最優交叉驗證分數對應的最優模型
best_estimator = None
return best_estimator
最優模型的最大深度(maximum depth)是多少?此答案與你在問題 6所作的猜想是否相同?
運行下方區域內的代碼,將決策樹迴歸函數代入訓練數據的集合,以獲得最優化的模型。
# 基於訓練數據,得到最優模型
optimal_reg = fit_model(X_train, y_train)
# 輸出最優模型的 'max_depth' 參數
print "Parameter 'max_depth' is {} for the optimal model.".format(optimal_reg.get_params()['max_depth'])
此答案和問題6猜想相同,都是4
當咱們用數據訓練出一個模型,它如今就可用於對新的數據進行預測。在決策樹迴歸函數中,模型已經學會對新輸入的數據提問,並返回對目標變量的預測值。你能夠用這個預測來獲取數據未知目標變量的信息,這些數據必須是不包含在訓練數據以內的。
想像你是一個在波士頓地區的房屋經紀人,並期待使用此模型以幫助你的客戶評估他們想出售的房屋。你已經從你的三個客戶收集到如下的資訊:
特徵 | 客戶 1 | 客戶 2 | 客戶 3 |
---|---|---|---|
房屋內房間總數 | 5 間房間 | 4 間房間 | 8 間房間 |
社區貧困指數(%被認爲是貧困階層) | 17% | 32% | 3% |
鄰近學校的學生-老師比例 | 15:1 | 22:1 | 12:1 |
你會建議每位客戶的房屋銷售的價格爲多少?從房屋特徵的數值判斷,這樣的價格合理嗎?爲何?
提示:用你在分析數據部分計算出來的統計信息來幫助你證實你的答案。
運行下列的代碼區域,使用你優化的模型來爲每位客戶的房屋價值作出預測。
# 生成三個客戶的數據
client_data = [[5, 17, 15], # 客戶 1
[4, 32, 22], # 客戶 2
[8, 3, 12]] # 客戶 3
# 進行預測
predicted_price = optimal_reg.predict(client_data)
for i, price in enumerate(predicted_price):
print "Predicted selling price for Client {}'s home: ${:,.2f}".format(i+1, price)
預測客戶1的價格爲$403,025.00
預測客戶2的價格爲$237,478.72
預測客戶3的價格爲$931,636.36
從特徵看,此價格合理,客戶3貧困指數很低,房間總數多,老師多,因此房價最高,而客戶2房間最少,貧困指數最高,而且老師少,因此房價最低,客戶1居中。
從上面獲得的結果能夠看到,3個客戶的價格都在最小值$105,000.00和最大值$1,024,800.00之間,3個客戶的平均值爲$524,046.69因爲客戶量少,和前面總體的平均值有偏差。此爲合理。
你剛剛預測了三個客戶的房子的售價。在這個練習中,你將用你的最優模型在整個測試數據上進行預測, 並計算相對於目標變量的決定係數 R2的值**。
#TODO 5
# 提示:你可能須要用到 X_test, y_test, optimal_reg, performance_metric
# 提示:你可能須要參考問題10的代碼進行預測
# 提示:你可能須要參考問題3的代碼來計算R^2的值
predicted_price = optimal_reg.predict(X_test)
r2 = performance_metric(y_test,predicted_price)
print "Optimal model has R^2 score {:,.2f} on test data".format(r2)
你剛剛計算了最優模型在測試集上的決定係數,你會如何評價這個結果?
# 請先註釋掉 fit_model 函數裏的全部 print 語句
vs.PredictTrials(features, prices, fit_model, client_data)
簡單地討論一下你建構的模型可否在現實世界中使用?
提示:回答如下幾個問題,並給出相應結論的理由:
可能不適用,隨着時間的變化,影響房價的因素也在發生改變
不足夠,年輕人的比例、房屋建造時間等其餘特徵也會影響房價
不能,地區的不一樣購房的政策不一樣,不適用於小鄉鎮
不合理,影響房價的因素不少,好比,該地區政策、該地區教育水平等。
(本題結果不影響項目是否經過)經過上面的實踐,相信你對機器學習的一些經常使用概念有了很好的領悟和掌握。但利用70年代的波士頓房價數據進行建模的確對咱們來講意義不是太大。如今你能夠把你上面所學應用到北京房價數據集中 bj_housing.csv
。
免責聲明:考慮到北京房價受到宏觀經濟、政策調整等衆多因素的直接影響,預測結果僅供參考。
這個數據集的特徵有:
目標變量:
你能夠參考上面學到的內容,拿這個數據集來練習數據分割與重排、定義衡量標準、訓練模型、評價模型表現、使用網格搜索配合交叉驗證對參數進行調優並選出最佳參數,比較二者的差異,最終得出最佳模型對驗證集的預測分數。
# TODO 6
# 你的代碼
你成功的用新的數據集構建了模型了嗎?他能對測試數據進行驗證嗎?它的表現是否符合你的預期?交叉驗證是否有助於提高你模型的表現?
提示:若是你是從零開始構建機器學習的代碼會讓你一時以爲無從下手。這時不要着急,你要作的只是查看以前寫的代碼,把每一行都看明白,而後逐步構建你的模型。當中遇到什麼問題也能夠在咱們論壇尋找答案。也許你會發現你所構建的模型的表現並無達到你的預期,這說明機器學習並不是是一項簡單的任務,構建一個表現良好的模型須要長時間的研究和測試。這也是咱們接下來的課程中會逐漸學到的。