sklearn快速入门教程
在这一步结束时,您将了解欠拟合和过拟合的概念,并将能够应用这些想法使您的模型更准确。
用不同的模型做实验
现在,您已经有了一种可靠的方法来测量模型的准确性,您可以使用其他模型进行实验,看看哪个模型给出了最好的预测。但是,对于模型,你有什么选择呢?
你可以在scikit-learn的文档中,决策树模型有很多参数供选择(比你想要多)。最重要的参数决定了树的深度。回顾 本课程的第一部分,一棵树的深度是衡量它在做出预测之前进行了多少次分裂的一个指标。这是一棵相对较浅的树。
实际上,一棵树的顶层(所有房屋)和一片叶子之间有10道裂缝并不罕见。随着树越来越深,数据集会被切成树叶,房屋越来越少。如果一棵树只有一次拆分,它会将数据分成两组。如果每一组再分开,我们将得到4组房子。再次拆分每个组将创建8个组。如果我们通过在每一层添加更多的分割来将组数增加一倍,到第10层时,我们将拥有
(
2
10
)
(2^{10} )
(210)组房屋。那是1024片树叶。
当我们把房子分成许多片叶子时,每片叶子上的房子也就更少了。房屋很少的树叶会做出非常接近这些房屋实际价值的预测,但它们可能会对新数据做出非常不可靠的预测(因为每个预测只基于少数房屋)。
这是一种称为过度拟合的现象,模型与训练数据几乎完美匹配,但在验证和其他新数据方面表现不佳。另一方面,如果我们把树弄得很浅,它就不会把房子分成很明显的一组。
在极端情况下,如果一棵树只把房子分成2或4间,每组仍然有各种各样的房子。即使在培训数据中,大多数房屋的预测结果也可能相去甚远(出于同样的原因,在验证方面也会很糟糕)。当一个模型未能捕捉到数据中的重要差异和模式,因此即使在训练数据中也表现不佳时,这被称为欠拟合。
由于我们关心新数据的准确性(我们根据验证数据进行估计),我们希望找到欠拟合和过度拟合之间的最佳点。从视觉上看,我们想要下图中(红色)验证曲线的低点。
举个例子
有几种方法可以控制树的深度,许多方法允许通过树的某些路径比其他路径具有更大的深度。但是max_leaf_nodes
参数提供了一种非常合理的方法来控制过拟合与欠拟合。我们允许模型制作的叶子越多,我们从上图中的欠拟合区域移动到过拟合区域的次数就越多。
我们可以使用工具函数来帮助比较max_leaf_nodes
不同值的MAE
分数:
from sklearn.metrics import mean_absolute_error
from sklearn.tree import DecisionTreeRegressor
def get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y):
model = DecisionTreeRegressor(max_leaf_nodes=max_leaf_nodes, random_state=0)
model.fit(train_X, train_y)
preds_val = model.predict(val_X)
mae = mean_absolute_error(val_y, preds_val)
return(mae)
使用您已经看到(并且已经编写)的代码将数据加载到train_X、val_X、train_y和val_y中。
# 加载包
import pandas as pd
# 加载数据
melbourne_file_path = '../input/melbourne-housing-snapshot/melb_data.csv'
melbourne_data = pd.read_csv(melbourne_file_path)
# 过滤缺失值的行
filtered_melbourne_data = melbourne_data.dropna(axis=0)
# 选择目标和特征
y = filtered_melbourne_data.Price
melbourne_features = ['Rooms', 'Bathroom', 'Landsize', 'BuildingArea',
'YearBuilt', 'Lattitude', 'Longtitude']
X = filtered_melbourne_data[melbourne_features]
from sklearn.model_selection import train_test_split
# 拆分训练和验证数据,具有相同的特征和目标
train_X, val_X, train_y, val_y = train_test_split(X, y,random_state = 0)
我们可以使用for循环来比较用max_leaf_nodes
的不同值构建的模型的精度。
# 不同的max_leaf_nodes对应不同的 MAE
for max_leaf_nodes in [5, 50, 500, 5000]:
my_mae = get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y)
print("Max leaf nodes: %d \t\t Mean Absolute Error: %d" %(max_leaf_nodes, my_mae))
Max leaf nodes: 5 Mean Absolute Error: 347380
Max leaf nodes: 50 Mean Absolute Error: 258171
Max leaf nodes: 500 Mean Absolute Error: 243495
Max leaf nodes: 5000 Mean Absolute Error: 254983
在列出的选项中,500是最佳叶片数。
结论
以下是要点:不同模型可能会遭受以下两种情况:
- 过拟合:捕捉未来不会再次出现的虚假模式,导致预测不太准确,或
- 欠拟合:未能捕捉相关模式,再次导致预测不准确。
我们使用模型训练中未使用的验证数据来衡量候选模型的准确性。这让我们可以尝试许多候选模型,并保留最好的模型。
轮到你了
尝试 优化之前构建的模型。
以下为练习部分
扼要重述
你您已经建立了第一个模型,现在是时候优化树的大小,以做出更好的预测。运行此单元格以设置上一步停止的编码环境。
# Code you have previously used to load data
import pandas as pd
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
# Path of the file to read
iowa_file_path = '../input/home-data-for-ml-course/train.csv'
home_data = pd.read_csv(iowa_file_path)
# Create target object and call it y
y = home_data.SalePrice
# Create X
features = ['LotArea', 'YearBuilt', '1stFlrSF', '2ndFlrSF', 'FullBath', 'BedroomAbvGr', 'TotRmsAbvGrd']
X = home_data[features]
# Split into validation and training data
train_X, val_X, train_y, val_y = train_test_split(X, y, random_state=1)
# Specify Model
iowa_model = DecisionTreeRegressor(random_state=1)
# Fit Model
iowa_model.fit(train_X, train_y)
# Make validation predictions and calculate mean absolute error
val_predictions = iowa_model.predict(val_X)
val_mae = mean_absolute_error(val_predictions, val_y)
print("Validation MAE: {:,.0f}".format(val_mae))
# Set up code checking
from learntools.core import binder
binder.bind(globals())
from learntools.machine_learning.ex5 import *
print("\nSetup complete")
Validation MAE: 29,653
Setup complete
练习
你可以自己编写get_mae
函数。不过,现在我们会提供的。这与您在上一课中读到的函数相同。运行以下单元格。
def get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y):
model = DecisionTreeRegressor(max_leaf_nodes=max_leaf_nodes, random_state=0)
model.fit(train_X, train_y)
preds_val = model.predict(val_X)
mae = mean_absolute_error(val_y, preds_val)
return(mae)
第一步:比较不同树的大小
编写一个循环,从一组可能的值中为max_leaf_nodes
尝试以下值。
对max_leaf_nodes
的每个值调用get_mae
函数。以某种方式存储输出,使您可以选择max_leaf_nodes
的值,从而为数据提供最精确的模型。
candidate_max_leaf_nodes = [5, 25, 50, 100, 250, 500]
# 书写循环,从候选节点 max_leaf_nodes 中找到理想的树的大小
_____
# 存储最佳max_leaf_nodes(从5、25、50、100、250或500)中找到
best_tree_size = ____
# 检查答案
step_1.check()
第二步:用所有数据拟合模型
你知道最好的树的大小。如果您打算在实践中部署此模型,则可以通过使用所有数据并保持树的大小,使其更加准确。也就是说,既然已经做出了所有建模决策,就不需要保留验证数据。
#您在上次练习中导入了 DecisionTreeRegressor
#该代码已复制到上面的设置代码中。所以,没必要再次导入
# 填写最佳参数
# final_model = DecisionTreeRegressor(____)
# 取消注释接下来的两行并拟合最终模型
# final_model.fit(____, ____)
# 检查答案
step_2.check()
您已经调整了此模型并改进了结果。但我们仍在使用决策树模型,按照现代机器学习标准,这些模型并不十分复杂。在下一步中,您将学习使用随机林来进一步改进模型。
继续
准备好了吗? 进入 随机森林 部分
练习答案
# step 1:
# 这里是一个简短的解决方案,其中包含对字典格式的理解。
# 课程给出了如何使用显式循环实现这一点的示例。
scores = {leaf_size: get_mae(leaf_size, train_X, val_X, train_y, val_y) for leaf_size in candidate_max_leaf_nodes}
best_tree_size = min(scores, key=scores.get)
# 以下是本人写的参考答案
x={}
for node in candidate_max_leaf_nodes:
x[node]=get_mae(node,train_X, val_X, train_y, val_y)
best_tree_size = min(x,key=x.get)
# step 2:
# 填写最佳参数
final_model = DecisionTreeRegressor(max_leaf_nodes=best_tree_size, random_state=1)
# 最终拟合模型
final_model.fit(X, y)