机器学习工程师纳米学位
模型评价与验证
项目 1: 预测波士顿房价
欢迎来到机器学习工程师纳米学位的第一个项目!在此文件中,有些示例代码已经提供给你,但你还需要实现更多的功能来让项目成功运行。除非有明确要求,你无须修改任何已给出的代码。以编程练习开始的标题表示接下来的内容中有需要你必须实现的功能。每一部分都会有详细的指导,需要实现的部分也会在注释中以TODO标出。请仔细阅读所有的提示!
除了实现代码外,你还必须回答一些与项目和实现有关的问题。每一个需要你回答的问题都会以'问题 X'为标题。请仔细阅读每个问题,并且在问题后的'回答'文字框中写出完整的答案。你的项目将会根据你对问题的回答和撰写代码所实现的功能来进行评分。
提示:Code 和 Markdown 区域可通过 Shift + Enter 快捷键运行。此外,Markdown可以通过双击进入编辑模式。
第一步. 导入数据
在这个项目中,你将利用马萨诸塞州波士顿郊区的房屋信息数据训练和测试一个模型,并对模型的性能和预测能力进行测试。通过该数据训练后的好的模型可以被用来对房屋做特定预测---尤其是对房屋的价值。对于房地产经纪等人的日常工作来说,这样的预测模型被证明非常有价值。
此项目的数据集来自UCI机器学习知识库(数据集已下线)。波士顿房屋这些数据于1978年开始统计,共506个数据点,涵盖了麻省波士顿不同郊区房屋14种特征的信息。本项目对原始数据集做了以下处理:
- 有16个
'MEDV'值为50.0的数据点被移除。 这很可能是由于这些数据点包含遗失或看不到的值。 - 有1个数据点的
'RM'值为8.78. 这是一个异常值,已经被移除。 - 对于本项目,房屋的
'RM','LSTAT','PTRATIO'以及'MEDV'特征是必要的,其余不相关特征已经被移除。 -
'MEDV'特征的值已经过必要的数学转换,可以反映35年来市场的通货膨胀效应。
运行下面区域的代码以载入波士顿房屋数据集,以及一些此项目所需的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)
Boston housing dataset has 489 data points with 4 variables each.
第二步. 分析数据
在项目的第一个部分,你会对波士顿房地产数据进行初步的观察并给出你的分析。通过对数据的探索来熟悉数据可以让你更好地理解和解释你的结果。
由于这个项目的最终目标是建立一个预测房屋价值的模型,我们需要将数据集分为特征(features)和目标变量(target variable)。
-
特征
'RM','LSTAT',和'PTRATIO',给我们提供了每个数据点的数量相关的信息。 -
目标变量:
'MEDV',是我们希望预测的变量。
他们分别被存在features和prices两个变量名中。
编程练习 1:基础统计运算
你的第一个编程练习是计算有关波士顿房价的描述统计数据。我们已为你导入了numpy,你需要使用这个库来执行必要的计算。这些统计数据对于分析模型的预测结果非常重要的。 在下面的代码中,你要做的是:
- 计算
prices中的'MEDV'的最小值、最大值、均值、中值和标准差; - 将运算结果储存在相应的变量中。
#TODO 1
#目标:计算价值的最小值
minimum_price = np.min(prices)
#目标:计算价值的最大值
maximum_price = np.max(prices)
#目标:计算价值的平均值
mean_price = np.mean(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)
Statistics for Boston housing dataset:
Minimum price: 105,000.00 Maximum price:1,024,800.00
Mean price: 454,342.94 Median price438,900.00
Standard deviation of prices: $165,171.13
问题 1 - 特征观察
如前文所述,本项目中我们关注的是其中三个值:'RM'、'LSTAT' 和'PTRATIO',对每一个数据点:
-
'RM'是该地区中每个房屋的平均房间数量; -
'LSTAT'是指该地区有多少百分比的业主属于是低收入阶层(有工作但收入微薄); -
'PTRATIO'是该地区的中学和小学里,学生和老师的数目比(学生/老师)。
凭直觉,上述三个特征中对每一个来说,你认为增大该特征的数值,'MEDV'的值会是增大还是减小呢?每一个答案都需要你给出理由。
提示:你预期一个'RM' 值是6的房屋跟'RM' 值是7的房屋相比,价值更高还是更低呢?
问题 1 - 回答:
增大RM值,MEDV值会增大,因为房间数量增大,房屋面积基本也增大,造价就高,导致房价更高;
增大LSTAT值,MEDAV值会减小,因为低收入人数比例越多,能够买的起高房价的就越少,所有该地区普遍房价会低,也可以认为因为房价低,才导致很多低收入群到这来;
增大PTRATIO值,MEDAV值会减小,因为学生多老师少,可能是该地区比较贫困,居民收入偏低,学生家长请不起更多老师;而地区越发达,学生家长就越能请的起老师,实现一对一教学,也居民收入也越高,自然房子购买力更足,房价更高。
编程练习 2: 数据分割与重排
接下来,你需要把波士顿房屋数据集分成训练和测试两个子集。通常在这个过程中,数据也会被重排列,以消除数据集中由于顺序而产生的偏差。 在下面的代码中,你需要
使用 sklearn.model_selection 中的 train_test_split, 将features和prices的数据都分成用于训练的数据子集和用于测试的数据子集。
- 分割比例为:80%的数据用于训练,20%用于测试;
- 选定一个数值以设定
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=40)
问题 2 - 训练及测试
将数据集按一定比例分为训练用的数据集和测试用的数据集对学习算法有什么好处?
如果用模型已经见过的数据,例如部分训练集数据进行测试,又有什么坏处?
提示: 如果没有数据来对模型进行测试,会出现什么问题?
问题 2 - 回答:
将数据集按一定比例训练和测试的好处是:训练出的模型可以用测试数据来验证,能够很好的验证模型对新样本的泛化能力,若数据不划分全部用于训练,虽然训练样本多,模型能更好的优化参数,但是没有测试数据验证模型对新样本的预测效果,很难让我们做出决策,如何对模型改进。
如果用训练的数据进行模型预测,效果肯定和训练精度相同,但是无法判断对新样本的预测能力,即泛化能力未知
第三步. 模型衡量标准
在项目的第三步中,你需要了解必要的工具和技巧来让你的模型进行预测。用这些工具和技巧对每一个模型的表现做精确的衡量可以极大地增强你预测的信心。
编程练习3:定义衡量标准
如果不能对模型的训练和测试的表现进行量化地评估,我们就很难衡量模型的好坏。通常我们会定义一些衡量标准,这些标准可以通过对某些误差或者拟合程度的计算来得到。在这个项目中,你将通过运算决定系数 R2 来量化模型的表现。模型的决定系数是回归分析中十分常用的统计信息,经常被当作衡量模型预测能力好坏的标准。
R2的数值范围从0至1,表示目标变量的预测值和实际值之间的相关程度平方的百分比。一个模型的R2 值为0还不如直接用平均值来预测效果好;而一个R2 值为1的模型则可以对目标变量进行完美的预测。从0至1之间的数值,则表示该模型中目标变量中有百分之多少能够用特征来解释。模型也可能出现负值的R2,这种情况下模型所做预测有时会比直接计算目标变量的平均值差很多。
在下方代码的 performance_metric 函数中,你要实现:
- 使用
sklearn.metrics中的r2_score来计算y_true和y_predict的R2值,作为对其表现的评判。 - 将他们的表现评分储存到
score变量中。
或
- (可选) 不使用任何外部库,参考决定系数的定义进行计算,这也可以帮助你更好的理解决定系数在什么情况下等于0或等于1。
# TODO 3
# 提示: 导入r2_score
from sklearn.metrics import r2_score
def performance_metric(y_true, y_predict):
"""计算并返回预测值相比于预测值的分数"""
score = r2_score(y_true,y_predict)
return score
# TODO 3 可选
# 不允许导入任何计算决定系数的库
def performance_metric2(y_true, y_predict):
"""计算并返回预测值相比于预测值的分数"""
lens = len(y_true)
y_mean = sum(y_true)/float(lens)
sume,sumt = 0,0
for i in range(lens):
sumt += (y_true[i] - y_mean)**2
sume += (y_true[i] - y_predict[i])**2
score = 1-sume/float(sumt)
return score
问题 3 - 拟合程度
假设一个数据集有五个数据且一个模型做出下列目标变量的预测:
| 真实数值 | 预测数值 |
|---|---|
| 3.0 | 2.5 |
| -0.5 | 0.0 |
| 2.0 | 2.1 |
| 7.0 | 7.8 |
| 4.2 | 5.3 |
你觉得这个模型已成功地描述了目标变量的变化吗?如果成功,请解释为什么,如果没有,也请给出原因。
提示:运行下方的代码,使用performance_metric函数来计算模型的决定系数。
# 计算这个模型的预测结果的决定系数
score = performance_metric2([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.
问题 3 - 回答:
成功。因为模型的测定系数比较高,而且从数据上也能看出来,预测值和真实值的变化趋势一致,且误差较小。
第四步. 分析模型的表现
在项目的第四步,我们来看一下不同参数下,模型在训练集和验证集上的表现。这里,我们专注于一个特定的算法(带剪枝的决策树,但这并不是这个项目的重点),和这个算法的一个参数 'max_depth'。用全部训练集训练,选择不同'max_depth' 参数,观察这一参数的变化如何影响模型的表现。画出模型的表现来对于分析过程十分有益,这可以让我们看到一些单看结果看不到的行为。
学习曲线
下方区域内的代码会输出四幅图像,它们是一个决策树模型在不同最大深度下的表现。每一条曲线都直观得显示了随着训练数据量的增加,模型学习曲线的在训练集评分和验证集评分的变化,评分使用决定系数R2。曲线的阴影区域代表的是该曲线的不确定性(用标准差衡量)。
运行下方区域中的代码,并利用输出的图形回答下面的问题。
# 根据不同的训练集大小,和最大深度,生成学习曲线
vs.ModelLearning(X_train, y_train)
image.png
问题 4 - 学习曲线
选择上述图像中的其中一个,并给出其最大深度。随着训练数据量的增加,训练集曲线的评分有怎样的变化?验证集曲线呢?如果有更多的训练数据,是否能有效提升模型的表现呢?
提示:学习曲线的评分是否最终会收敛到特定的值?
问题 4 - 回答:
max_depth=3图,随着训练数据量的增加,训练曲线评分逐渐降低并趋于平稳,验证曲线则随着数据量增加评分初始变大趋势较快,一定程度后相对平稳不变。
按照当前趋势来看,模型评分已经趋于平稳,如果再增加更多的训练数据,还是无法让模型表现有较大提高。
学习曲线评分最终会收敛到特定值,或者特定值上下浮动一点点.
复杂度曲线
下列代码内的区域会输出一幅图像,它展示了一个已经经过训练和验证的决策树模型在不同最大深度条件下的表现。这个图形将包含两条曲线,一个是训练集的变化,一个是验证集的变化。跟学习曲线相似,阴影区域代表该曲线的不确定性,模型训练和测试部分的评分都用的 performance_metric 函数。
运行下方区域中的代码,并利用输出的图形并回答下面的两个问题。
# 根据不同的最大深度参数,生成复杂度曲线
vs.ModelComplexity(X_train, y_train)
image.png
问题 5 - 偏差(bias)与方差(variance)之间的权衡取舍
当模型以最大深度 1训练时,模型的预测是出现很大的偏差还是出现了很大的方差?当模型以最大深度10训练时,情形又如何呢?图形中的哪些特征能够支持你的结论?
提示: 你如何得知模型是否出现了偏差很大或者方差很大的问题?
问题 5 - 回答:
深度1训练时,模型预测出现很大偏差;从训练得分很低可以看出,出现欠拟合现象,模型方向不对会出现较大偏差;
深度10训练时,模型预测出现较大方差;从训练得分比较高,而预测得分却逐渐下降能够看出,说明此时出现了过拟合现象。
问题 6- 最优模型的猜测
结合问题 5 中的图,你认为最大深度是多少的模型能够最好地对未见过的数据进行预测?你得出这个答案的依据是什么?
问题 6 - 回答:
从图可知,最大深度为4时,模型能够更好的预测。依据是深度为4时,模型训练得分相对较高,且增加深度,模型训练得分提高不多,而同时,预测得分在深度4时达到最高,然后随着深度增加,预测得分逐渐下降,出现过拟合现象,因此深度=4是最优点。
第五步. 选择最优参数
问题 7- 网格搜索(Grid Search)
什么是网格搜索法?如何用它来优化模型?
问题 7 - 回答:
网格搜索法是通过交叉验证的方式进行给定参数遍历,获得最优参数的模型。
使用它来优化模型,先定义需要的模型方法和模型参数可能的选项,再定义交叉验证的次数CV,然后输入数据进行训练遍历参数得到最优结果
问题 8 - 交叉验证
- 什么是K折交叉验证法(k-fold cross-validation)?
- GridSearchCV是如何结合交叉验证来完成对最佳参数组合的选择的?
-
GridSearchCV中的
'cv_results_'属性能告诉我们什么? - 网格搜索时如果不使用交叉验证会有什么问题?交叉验证又是如何解决这个问题的?
提示: 在下面 fit_model函数最后加入 print pd.DataFrame(grid.cv_results_) 可以帮你查看更多信息。
问题 8 - 回答:
K折交叉验证是将训练数据分为K等份,用K-1份进行训练,剩下的1份进行测试,循环遍历K次,每次预测数据都是K份中的一份且不重复,最后统计所有测试结果。
GridSearchCV通过给定参数项,分别遍历每种参数组合,且用交叉验证方式进行训练测试,最终得到模型效果最优组合的参数。
GridSearchCV中
'cv_results_'告诉了我们深度从1到10的每个深度下进行交叉验证的结果,每个深度下交叉验证得到的参数总体有:交叉验证训练时间和测试时间(mean_fit_time mean_score_time);每次交叉验证分别的训练得分和测试得分(split0/1/2_train_score split0/1/2_test_score),以及它们平均得分(mean_test_score mean_train_score);训练和测试结果的标准差(std_test_score std_train_score)及所用时间(std_fit_time std_score_time)等网格搜索如果不用交叉验证,寻找的参数可能不是最优参数组合,因为交叉验证通过整体数据的预测效果来进行评估,而不是只用部分数据,部分数据有可能质量不是很好,容易产生较大偏差。
编程练习 4:训练最优模型
在这个练习中,你将需要将所学到的内容整合,使用决策树算法训练一个模型。为了得出的是一个最优模型,你需要使用网格搜索法训练模型,以找到最佳的 '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 make_scorer
from sklearn.model_selection import GridSearchCV
def fit_model(X, y):
""" 基于输入数据 [X,y],利于网格搜索找到最优的决策树模型"""
cross_validator = KFold(n_splits=3, random_state=None,shuffle=False)
regressor = DecisionTreeRegressor()
params = {'max_depth':[1,2,3,4,5,6,7,8,9,10]}
scoring_fnc = make_scorer(performance_metric)
grid = GridSearchCV(regressor,params,scoring_fnc,cv=cross_validator)
# 基于输入数据 [X,y],进行网格搜索
grid = grid.fit(X, y)
# 返回网格搜索后的最优模型
print pd.DataFrame(grid.cv_results_)
# print grid.best_estimator_
return grid.best_estimator_
编程练习 4:训练最优模型 (可选)
在这个练习中,你将需要将所学到的内容整合,使用决策树算法训练一个模型。为了得出的是一个最优模型,你需要使用网格搜索法训练模型,以找到最佳的 '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]
lens = len(y)
rs = range(lens)
r = lens/3
for i in range(cv):
rst = rs[i*r:(i+1)*r]
if i == cv-1:
rst = rs[i*r:]
regressor = DecisionTreeRegressor(max_depth=estimator)
x_trains = [X[j] for j in rs if j not in rst]
y_trains = [y[j] for j in rs if j not in rst]
x_tests = [X[j] for j in rs if j in rst]
y_tests = [y[j] for j in rs if j in rst]
regressor.fit(x_trains, y_trains)
y_predicts = regressor.predict(x_tests)
scores[i] = performance_metric(y_tests,y_predicts)
return scores
def fit_model2(X, y):
""" 基于输入数据 [X,y],利于网格搜索找到最优的决策树模型"""
depths = [1,2,3,4,5,6,7,8,9,10]
temp = 0
for estimator in depths:
scores = cross_val_score(estimator, X,y,)
score_sum = sum(scores)
if temp < score_sum:
temp = score_sum
#最优交叉验证分数对应的最优模型
best_estimator = estimator
return best_estimator
问题 9 - 最优模型
最优模型的最大深度(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'])
mean_fit_time mean_score_time mean_test_score mean_train_score
0 0.001667 0.000667 0.423056 0.477615
1 0.001667 0.001000 0.667136 0.737779
2 0.001000 0.001000 0.753049 0.839994
3 0.001000 0.000000 0.787261 0.882550
4 0.001000 0.000000 0.772829 0.911707
5 0.001000 0.000333 0.755171 0.942524
6 0.001000 0.000333 0.751411 0.961338
7 0.001000 0.000667 0.736549 0.975306
8 0.001000 0.001000 0.724552 0.984313
9 0.001333 0.000000 0.735817 0.989817
param_max_depth params rank_test_score split0_test_score
0 1 {u'max_depth': 1} 10 0.398589
1 2 {u'max_depth': 2} 9 0.623309
2 3 {u'max_depth': 3} 4 0.713617
3 4 {u'max_depth': 4} 1 0.761932
4 5 {u'max_depth': 5} 2 0.752009
5 6 {u'max_depth': 6} 3 0.727003
6 7 {u'max_depth': 7} 5 0.735676
7 8 {u'max_depth': 8} 6 0.699118
8 9 {u'max_depth': 9} 8 0.694437
9 10 {u'max_depth': 10} 7 0.708495
split0_train_score split1_test_score split1_train_score
0 0.483877 0.444084 0.467059
1 0.762738 0.685361 0.721768
2 0.854399 0.762281 0.832283
3 0.897438 0.790892 0.876487
4 0.919756 0.779438 0.909010
5 0.944621 0.758533 0.941908
6 0.964120 0.758993 0.959693
7 0.975513 0.770641 0.974556
8 0.984385 0.739268 0.984944
9 0.989626 0.772538 0.990397
split2_test_score split2_train_score std_fit_time std_score_time
0 0.426682 0.481908 4.713142e-04 4.713704e-04
1 0.693075 0.728831 4.713142e-04 1.123916e-07
2 0.783552 0.833302 0.000000e+00 0.000000e+00
3 0.809154 0.873726 1.123916e-07 0.000000e+00
4 0.787200 0.906353 0.000000e+00 0.000000e+00
5 0.780195 0.941044 1.123916e-07 4.713704e-04
6 0.759684 0.960200 0.000000e+00 4.713704e-04
7 0.740176 0.975848 1.123916e-07 4.714827e-04
8 0.740184 0.983611 0.000000e+00 1.123916e-07
9 0.726628 0.989429 4.713704e-04 0.000000e+00
std_test_score std_train_score
0 0.018760 0.007507
1 0.031268 0.017883
2 0.029302 0.010194
3 0.019460 0.010587
4 0.015114 0.005794
5 0.021858 0.001524
6 0.011172 0.001978
7 0.029329 0.000547
8 0.021380 0.000546
9 0.026954 0.000418
Parameter 'max_depth' is 4 for the optimal model.
</pre>
问题 9 - 回答:
最优模型最大深度是4,和问题6中相同。
第六步. 做出预测
当我们用数据训练出一个模型,它现在就可用于对新的数据进行预测。在决策树回归函数中,模型已经学会对新输入的数据提问,并返回对目标变量的预测值。你可以用这个预测来获取数据未知目标变量的信息,这些数据必须是不包含在训练数据之内的。
问题 10 - 预测销售价格
想像你是一个在波士顿地区的房屋经纪人,并期待使用此模型以帮助你的客户评估他们想出售的房屋。你已经从你的三个客户收集到以下的资讯:
| 特征 | 客戶 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)
Predicted selling price for Client 1's home: 411,096.00 Predicted selling price for Client 2's home:219,961.54
Predicted selling price for Client 3's home: $955,500.00
问题 10 - 回答:
建议客户1房屋销售价格为 411,096这个价格合理,该地区贫困指数适中,地区房价总体属于中等,并且boston整体平均价格为 454,342 该价格和平均价格相当,略低于平均价。
建议客户2房屋销售价格为 219,961这个价格合理,boston房价最低价为 105,000.而该地区较贫困,该房屋房间也较少,所以房价相对较低,但高于boston房价最低价,不属于异常值。
建议客户3房屋销售价格为 921,900该地区较为富有,且该房子房间数量较多,学生比例也少,且低于boston的最高价( 1,024,800),这个价格不属于异常值。
编程练习 5
你刚刚预测了三个客户的房子的售价。在这个练习中,你将用你的最优模型在整个测试数据上进行预测, 并计算相对于目标变量的决定系数 R2的值**。
#TODO 5
# 提示:你可能需要用到 X_test, y_test, optimal_reg, performance_metric
# 提示:你可能需要参考问题10的代码进行预测
# 提示:你可能需要参考问题3的代码来计算R^2的值
y_predict = optimal_reg.predict(X_test)
r2 = performance_metric(y_test,y_predict)
print "Optimal model has R^2 score {:,.2f} on test data".format(r2)
Optimal model has R^2 score 0.80 on test data
问题11 - 分析决定系数
你刚刚计算了最优模型在测试集上的决定系数,你会如何评价这个结果?
问题11 - 回答
决定系数为0.8,是一个相对比较高的得分,房屋价格相当于有80%的概率推测准确。
模型健壮性
一个最优的模型不一定是一个健壮模型。有的时候模型会过于复杂或者过于简单,以致于难以泛化新增添的数据;有的时候模型采用的学习算法并不适用于特定的数据结构;有的时候样本本身可能有太多噪点或样本过少,使得模型无法准确地预测目标变量。这些情况下我们会说模型是欠拟合的。
问题 12 - 模型健壮性
模型是否足够健壮来保证预测的一致性?
提示: 执行下方区域中的代码,采用不同的训练和测试集执行 fit_model 函数10次。注意观察对一个特定的客户来说,预测是如何随训练数据的变化而变化的。
# 请先注释掉 fit_model 函数里的所有 print 语句
vs.PredictTrials(features, prices, fit_model, client_data)
Trial 1: 411,000.00 Trial 2:411,417.39
Trial 3: 415,800.00 Trial 4:428,316.00
Trial 5: 413,334.78 Trial 6:411,931.58
Trial 7: 399,663.16 Trial 8:407,232.00
Trial 9: 402,531.82 Trial 10:413,700.00
Range in prices: $28,652.84
</pre>
问题 12 - 回答:
模型足够健壮。偏差在7%以内波动
问题 13 - 实用性探讨
简单地讨论一下你建构的模型能否在现实世界中使用?
提示:回答以下几个问题,并给出相应结论的理由:
- 1978年所采集的数据,在已考虑通货膨胀的前提下,在今天是否仍然适用?
- 数据中呈现的特征是否足够描述一个房屋?
- 在波士顿这样的大都市采集的数据,能否应用在其它乡镇地区?
- 你觉得仅仅凭房屋所在社区的环境来判断房屋价值合理吗?
问题 13 - 回答:
今天仍然适用。不管过去还是现在,该三大特征是影响房屋主要特征,而将通货膨胀已经考虑进去,则预测的是房屋的价格相当于其价值。
呈现的特征足够描述一个房屋,但是可能还有其他特征也很重要,比如:地段因素、人口数量等
不能应用于其他乡镇地区,因为乡镇地区的地价特征、政府政策特征等与大都市有较大差别,该些特征也很多程度影响房价。
不合理,社区环境受到社区管理、人口素质、天气状况等系列影响,社区环境相关性不是很强,有一定的随机性,很难用来判断房屋价值。
可选问题 - 预测北京房价
(本题结果不影响项目是否通过)通过上面的实践,相信你对机器学习的一些常用概念有了很好的领悟和掌握。但利用70年代的波士顿房价数据进行建模的确对我们来说意义不是太大。现在你可以把你上面所学应用到北京房价数据集中 bj_housing.csv。
免责声明:考虑到北京房价受到宏观经济、政策调整等众多因素的直接影响,预测结果仅供参考。
这个数据集的特征有:
- Area:房屋面积,平方米
- Room:房间数,间
- Living: 厅数,间
- School: 是否为学区房,0或1
- Year: 房屋建造时间,年
- Floor: 房屋所处楼层,层
目标变量:
- Value: 房屋人民币售价,万
你可以参考上面学到的内容,拿这个数据集来练习数据分割与重排、定义衡量标准、训练模型、评价模型表现、使用网格搜索配合交叉验证对参数进行调优并选出最佳参数,比较两者的差别,最终得出最佳模型对验证集的预测分数。
# TODO 6
# 载入房屋的数据集
data = pd.read_csv('bj_housing.csv')
prices = data['Value']
features = data.drop('Value', axis = 1)
print "Boston housing dataset has {} data points with {} variables each.".format(*data.shape)
# 分割数据
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=40)
# 基于训练数据,获得最优模型
optimal_reg = fit_model(X_train, y_train)
print "Parameter 'max_depth' is {} for the optimal model.".format(optimal_reg.get_params()['max_depth'])
# 模型预测
y_predict = optimal_reg.predict(X_test)
r2 = performance_metric(y_test,y_predict)
print "Optimal model has R^2 score {:,.2f} on test data".format(r2)
Boston housing dataset has 9999 data points with 7 variables each.
Parameter 'max_depth' is 5 for the optimal model.
Optimal model has R^2 score 0.63 on test data
问题14 - 北京房价预测
你成功的用新的数据集构建了模型了吗?他能对测试数据进行验证吗?它的表现是否符合你的预期?交叉验证是否有助于提升你模型的表现?
提示:如果你是从零开始构建机器学习的代码会让你一时觉得无从下手。这时不要着急,你要做的只是查看之前写的代码,把每一行都看明白,然后逐步构建你的模型。当中遇到什么问题也可以在我们论坛寻找答案。也许你会发现你所构建的模型的表现并没有达到你的预期,这说明机器学习并非是一项简单的任务,构建一个表现良好的模型需要长时间的研究和测试。这也是我们接下来的课程中会逐渐学到的。
问题14 - 回答
成功构建模型,决定系数为0.63,验证效果不是很理想。











网友评论