欢迎来到机器学习的预测波士顿房价项目!在此文件中,有些示例代码已经提供给你,但你还需要实现更多的功能来让项目成功运行。除非有明确要求,你无须修改任何已给出的代码。以编程练习开始的标题表示接下来的内容中有需要你必须实现的功能。每一部分都会有详细的指导,需要实现的部分也会在注释中以TODO标出。请仔细阅读所有的提示!
除了实现代码外,你还必须回答一些与项目和实现有关的问题。每一个需要你回答的问题都会以'问题 X'为标题。请仔细阅读每个问题,并且在问题后的'回答'文字框中写出完整的答案。你的项目将会根据你对问题的回答和撰写代码所实现的功能来进行评分。
提示:Code 和 Markdown 区域可通过 Shift + Enter 快捷键运行。此外,Markdown可以通过双击进入编辑模式。
在这个项目中,你将利用马萨诸塞州波士顿郊区的房屋信息数据训练和测试一个模型,并对模型的性能和预测能力进行测试。通过该数据训练后的好的模型可以被用来对房屋做特定预测---尤其是对房屋的价值。对于房地产经纪等人的日常工作来说,这样的预测模型被证明非常有价值。
此项目的数据集来自UCI机器学习知识库(数据集已下线)。波士顿房屋这些数据于1978年开始统计,共506个数据点,涵盖了麻省波士顿不同郊区房屋14种特征的信息。本项目对原始数据集做了以下处理:
'MEDV'
值为50.0的数据点被移除。 这很可能是由于这些数据点包含遗失或看不到的值。'RM'
值为8.78. 这是一个异常值,已经被移除。'RM'
, 'LSTAT'
,'PTRATIO'
以及'MEDV'
特征是必要的,其余不相关特征已经被移除。'MEDV'
特征的值已经过必要的数学转换,可以反映35年来市场的通货膨胀效应。运行下面区域的代码以载入波士顿房屋数据集,以及一些此项目所需的 Python 库。如果成功返回数据集的大小,表示数据集已载入成功。
In [ ]:
# Import libraries necessary for this project
import numpy as np
import pandas as pd
from sklearn.model_selection import ShuffleSplit
# Import supplementary visualizations code visuals.py
import visuals as vs
# Pretty display for notebooks
%matplotlib inline
# Load the Boston housing dataset
data = pd.read_csv('housing.csv')
prices = data['MEDV']
features = data.drop('MEDV', axis = 1)
# Success
print("Boston housing dataset has {} data points with {} variables each.".format(*data.shape))
In [ ]:
# TODO: Minimum price of the data
minimum_price = None
# TODO: Maximum price of the data
maximum_price = None
# TODO: Mean price of the data
mean_price = None
# TODO: Median price of the data
median_price = None
# TODO: Standard deviation of prices of the data
std_price = None
# Show the calculated statistics
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))
如果不能对模型的训练和测试的表现进行量化地评估,我们就很难衡量模型的好坏。通常我们会定义一些衡量标准,这些标准可以通过对某些误差或者拟合程度的计算来得到。在这个项目中,你将通过运算决定系数 $R^2$ 来量化模型的表现。模型的决定系数是回归分析中十分常用的统计信息,经常被当作衡量模型预测能力好坏的标准。
$R^2$ 的数值范围从0至1,表示目标变量的预测值和实际值之间的相关程度平方的百分比。一个模型的 $R^2$ 值为0还不如直接用平均值来预测效果好;而一个 $R^2$ 值为1的模型则可以对目标变量进行完美的预测。从0至1之间的数值,则表示该模型中目标变量中有百分之多少能够用特征来解释。模型也可能出现负值的 $R^2$,这种情况下模型所做预测有时会比直接计算目标变量的平均值差很多。
在下方代码的 performance_metric
函数中,你要实现:
sklearn.metrics
中的 r2_score
来计算 y_true
和 y_predict
的 $R^2$ 值,作为对其表现的评判。score
变量中。
In [ ]:
# TODO: Import 'r2_score'
def performance_metric(y_true, y_predict):
""" Calculates and returns the performance score between
true and predicted values based on the metric chosen. """
# TODO: Calculate the performance score between 'y_true' and 'y_predict'
score = None
# Return the score
return score
假设一个数据集有五个数据且一个模型做出下列目标变量的预测:
真实数值 | 预测数值 |
---|---|
3.0 | 2.5 |
-0.5 | 0.0 |
2.0 | 2.1 |
7.0 | 7.8 |
4.2 | 5.3 |
你觉得这个模型已成功地描述了目标变量的变化吗?如果成功,请解释为什么,如果没有,也请给出原因。
提示1:运行下方的代码,使用 performance_metric
函数来计算 y_true
和 y_predict
的决定系数。
提示2:$R^2$ 分数是指可以从自变量中预测的因变量的方差比例。 换一种说法:
In [ ]:
# Calculate the performance of this model
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))
接下来,你需要把波士顿房屋数据集分成训练和测试两个子集。通常在这个过程中,数据也会被重排列,以消除数据集中由于顺序而产生的偏差。 在下面的代码中,你需要
sklearn.model_selection
中的 train_test_split
, 将 features
和 prices
的数据都分成用于训练的数据子集和用于测试的数据子集。train_test_split
中的 random_state
,这会确保结果的一致性;X_train
, X_test
, y_train
和 y_test
。
In [ ]:
# TODO: Import 'train_test_split'
# TODO: Shuffle and split the data into training and testing subsets
X_train, X_test, y_train, y_test = (None, None, None, None)
# Success
print("Training and testing split was successful.")
In [ ]:
# Produce learning curves for varying training set sizes and maximum depths
vs.ModelLearning(features, prices)
In [ ]:
vs.ModelComplexity(X_train, y_train)
'cv_results_'
属性能告诉我们什么?提示:在解释k-fold交叉验证时,一定要理解'k'是什么,和数据集是如何分成不同的部分来进行训练和测试的,以及基于'k'值运行的次数。 在考虑k-fold交叉验证如何帮助网格搜索时,你可以使用特定的数据子集来进行训练与测试有什么缺点,以及K折交叉验证是如何帮助缓解这个问题。
在这个练习中,你将需要将所学到的内容整合,使用决策树算法训练一个模型。为了得出的是一个最优模型,你需要使用网格搜索法训练模型,以找到最佳的 'max_depth'
参数。你可以把'max_depth'
参数理解为决策树算法在做出预测前,允许其对数据提出问题的数量。决策树是监督学习算法中的一种。
另外,你会发现在实现的过程中是使用ShuffleSplit()
作为交叉验证的另一种形式(参见'cv_sets'变量)。虽然它不是你在问题8中描述的K-fold交叉验证方法,但它同样非常有用!下面的ShuffleSplit()
实现将创建10个('n_splits')混洗集合,并且对于每个混洗集,数据的20%('test_size')将被用作验证集合。当您在实现代码的时候,请思考一下它与K-fold cross-validation
的不同与相似之处。
请注意,ShuffleSplit
在 Scikit-Learn
版本0.17和0.18中有不同的参数。对于下面代码单元格中的 fit_model
函数,您需要实现以下内容:
'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课程的视频。
In [ ]:
# TODO: Import 'make_scorer', 'DecisionTreeRegressor', and 'GridSearchCV'
def fit_model(X, y):
""" Performs grid search over the 'max_depth' parameter for a
decision tree regressor trained on the input data [X, y]. """
# Create cross-validation sets from the training data
# sklearn version 0.18: ShuffleSplit(n_splits=10, test_size=0.1, train_size=None, random_state=None)
# sklearn versiin 0.17: ShuffleSplit(n, n_iter=10, test_size=0.1, train_size=None, random_state=None)
cv_sets = ShuffleSplit(n_splits=10, test_size=0.20, random_state=42)
# TODO: Create a decision tree regressor object
regressor = None
# TODO: Create a dictionary for the parameter 'max_depth' with a range from 1 to 10
params = {}
# TODO: Transform 'performance_metric' into a scoring function using 'make_scorer'
scoring_fnc = None
# TODO: 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 'cv_sets' respectively.
grid = None
# Fit the grid search object to the data to compute the optimal model
grid = grid.fit(X, y)
# Return the optimal model after fitting the data
return grid.best_estimator_
In [ ]:
# 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']))
In [ ]:
# Produce a matrix for client data
client_data = [[5, 17, 15], # Client 1
[4, 32, 22], # Client 2
[8, 3, 12]] # Client 3
# Show predictions
for i, price in enumerate(reg.predict(client_data)):
print("Predicted selling price for Client {}'s home: ${:,.2f}".format(i+1, price))
In [ ]:
# TODO Calculate the r2 score between 'y_true' and 'y_predict'
r2 = None
print("Optimal model has R^2 score {:,.2f} on test data".format(r2))
In [ ]:
vs.PredictTrials(features, prices, fit_model, client_data)
当你完成了以上所有的代码和问题,你需要将 iPython Notebook 导出 HTML,导出方法:在左上角的菜单中选择 File -> Download as -> HTML (.html)。当你提交项目时,需要包含可运行的 .ipynb 文件和导出的 HTML 文件。