目录
一、模型如何工作
介绍
我们将从机器学习模型如何工作以及如何使用的概述开始。如果你以前做过统计建模或机器学习,这可能会让你觉得很基本。别担心,我们很快就会开发出功能强大的模型。
本微课程将让您在经历以下场景时构建模型:
你表弟在房地产上投机赚了几百万美元。因为你对数据科学的兴趣,他愿意和你成为商业伙伴。他会提供资金,你会提供模型来预测各种房子的价值。
你问你的表弟他过去是如何预测房地产价值的。他说这只是直觉。但更多的质疑表明,他已经从过去看到的房屋中识别出了价格模式,并利用这些模式对他正在考虑的新房进行了预测。
机器学习也是这样。我们将从一个称为决策树的模型开始。有一些更奇特的模型可以给出更准确的预测。但是决策树很容易理解,它们是数据科学中一些最佳模型的基本构建块。
为了简单起见,我们将从最简单的决策树开始。
它只把房子分为两类。所考虑的任何房屋的预计价格是同一类别房屋的历史平均价格。
我们利用数据来决定如何将房屋分成两组,然后再次确定每组的预测价格。从数据中捕获模式的这一步骤称为拟合或训练模型。用于拟合模型的数据称为训练数据。
模型的拟合细节(例如如何分割数据)非常复杂,我们将在以后保存它。模型拟合后,可以将其应用于新数据,以预测额外住房的价格。
改进决策树
以下两个决策树中,哪一个更可能来自房地产培训数据的拟合?
左边的决策树(决策树1)可能更有意义,因为它抓住了一个现实,即卧室多的房子往往比卧室少的房子售价更高。这个模型最大为的缺点是没有捕捉到影响房价的大多数因素,比如浴室数量、地段大小、位置等。
你可以用一棵有更多“分裂”的树来捕捉更多的因子,这些被称为“更深”的树。一个决策树,也考虑到每个房子的总面积地段可能看起来像这样:
你可以通过决策树来预测任何房子的价格,总是根据房子的特征选择相应的路径。房子的预计价格在树的底部。我们在底部做预测的那一点叫做叶子。
叶上的拆分和值将由数据决定,因此是时候检查将使用的数据了。
二、基础数据探索
使用Pandas熟悉你的数据
任何机器学习项目的第一步都是熟悉数据。你要用Pandas来做这个。Pandas是科学家用来探索和处理数据的主要工具。大多数人在代码中将熊猫缩写为pd。我们用命令来做这件事Pandas最重要的部分是数据框架。数据保存您可能认为是表的数据类型。这类似于Excel中的工作表,或SQL数据库中的表。
Pandas有强大的方法对于你将要做的带有这类数据的大部分事情。
import pandas as pd
例如,我们将查看澳大利亚墨尔本房价数据。在实际操作中,您将将相同的过程应用于新的数据集,该数据集在爱荷华有房价。
示例(墨尔本)数据位于文件路径
../input/melbourne-housing-snapshot/melb_data.csv
我们使用以下命令加载和浏览数据:
# 将文件路径保存到变量以便于访问
melbourne_file_path = '../input/melbourne-housing-snapshot/melb_data.csv'
# 读取数据并将数据存储在名为“u data”的数据表中
melbourne_data = pd.read_csv(melbourne_file_path)
# 打印墨尔本数据中的数据摘要
melbourne_data.describe()
解释数据描述
结果显示原始数据集中每列有8个数字。第一个数字,count,显示有多少行没有丢失值。
缺少值的原因有很多。例如,当测量一间卧室的房子时,不会收集第二间卧室的大小。我们将回到丢失数据的主题。
第二个值是平均值,也就是平均值。在这种情况下,std是标准差,它度量值在数值上的分布情况。
要解释最小值、25%、50%、75%和最大值,请想象将每列从最低值排序到最高值。第一个(最小的)值是最小值。如果你在列表中遍历四分之一,你会发现一个大于25%的值小于75%的值。这是25%的值(发音为“第25百分位”)。第50百分位和第75百分位的定义类似,最大值是最大值。
三、你的第一个机器学习模型
为建模选择数据
数据集有太多的变量,容易将我们绕晕,甚至无法很好地打印出来。你如何将大量的数据缩减到你能理解的东西上?
我们将从使用直觉来选择几个变量开始。后面的课程将向您展示统计技术,以自动确定变量的优先级。
要选择变量/列,我们需要查看数据集中所有列的列表。这是通过DataFrame的columns属性(下面的代码的底线)完成的。
输入:
import pandas as pd
melbourne_file_path = '../input/melbourne-housing-snapshot/melb_data.csv'
melbourne_data = pd.read_csv(melbourne_file_path)
melbourne_data.columns
输出:
Index(['Suburb', 'Address', 'Rooms', 'Type', 'Price', 'Method', 'SellerG',
'Date', 'Distance', 'Postcode', 'Bedroom2', 'Bathroom', 'Car',
'Landsize', 'BuildingArea', 'YearBuilt', 'CouncilArea', 'Lattitude',
'Longtitude', 'Regionname', 'Propertycount'],
dtype='object')
#墨尔本的数据有一些缺失的值(有些房子的一些变量没有被记录下来)
#我们将在后面的教程中学习如何处理缺少的值。
#您的爱荷华数据在您使用的列中没有缺少的值。
#因此,我们现在将采取最简单的选择,从我们的数据中删除房屋。
#代码是:
#dropna删除缺失的值(将na视为“不可用”)
melbourne_data = melbourne_data.dropna(axis=0)
有许多方法可以选择数据的子集。Pandas课程将更深入地讨论这些问题,但我们现在将重点讨论两种方法。
1.点符号,我们用来选择“预测目标”
2.用列列表选择,我们用它来选择“特征”
选择预测目标
你可以用点符号写出一个变量。这一列存储在一个系列中,大致上类似于只有一列数据的数据集。
我们将使用点表示法来选择要预测的列,这称为预测目标。按照惯例,预测目标称为y。所以我们需要在墨尔本数据中保存房价的代码是
y = melbourne_data.Price
选择“特征”
输入到我们模型中的列(后来用来做预测)被称为“特征”。在我们的例子中,这些列将被用来确定房价。有时,您将使用除目标之外的所有列作为特征。其他时候你最好少用一些功能。
现在,我们将构建一个只有一些特性的模型。稍后您将看到如何迭代和比较使用不同特性构建的模型。
我们通过在括号内提供列名称列表来选择多个功能。列表中的每一项都应该是一个字符串(带引号)。
举个例子:
melbourne_features = ['Rooms', 'Bathroom', 'Landsize', 'Lattitude', 'Longtitude']
按照惯例,这个数据叫做X。
X = melbourne_data[melbourne_features]
让我们快速回顾一下我们将使用descripe方法和head方法预测房价的数据,其中显示了前几行。
X.describe()
X.head()
用这些命令直观地检查数据是数据科学家工作的一个重要部分。您经常会在数据集中发现值得进一步检查的惊喜。
构建模型
您将使用scikit-learn学习库来创建模型。在编码时,这个库被写成sklearn,正如您将在示例代码中看到的那样。scikit-learn是最流行的库,用于建模通常存储在数据帧中的数据类型。
构建和使用模型的步骤包括:
定义:它将是什么类型的模型?决策树?其他类型的模型?还指定了模型类型的其他一些参数。
Fit:从提供的数据中捕获模式。这是模特的核心。
预测:听起来就是这样
评估:确定模型预测的准确性。
下面是一个使用scikit-learn定义决策树模型并使用特征和目标变量对其进行拟合的示例。
from sklearn.tree import DecisionTreeRegressor
#定义模型。为随机状态指定一个数字,以确保每次运行的结果相同
墨尔本炣模型=决策树生成器(随机状态=1)
#拟合模型
melbourne_model.fit(X, y)
许多机器学习模型都允许模型训练具有一定的随机性。为随机状态指定一个数字可以确保每次运行得到相同的结果。这被认为是一种良好的做法。您可以使用任何数字,而模型的质量将不会完全取决于您选择的值。
我们现在有了一个合适的模型,可以用来做预测。
实际上,你会希望对即将上市的新房做出预测,而不是我们已经有了价格的房子。但我们将对训练数据的前几行进行预测,以了解预测函数是如何工作的。
print("Making predictions for the following 5 houses:")
print(X.head())
print("The predictions are")
print(melbourne_model.predict(X.head()))
四、模型验证
你已经建立了一个模型。但是有多好呢?
在本课程中,您将学习如何使用模型验证来度量模型的质量。度量模型质量是迭代改进模型的关键。
什么是模型验证
您将希望评估几乎所有您构建的模型。在大多数(尽管不是所有)应用中,模型质量的相关度量是预测精度。换句话说,模型的预测是否会接近实际发生的情况。
许多人在测量预测精度时犯了一个巨大的错误。他们用训练数据进行预测,并将这些预测与培训数据中的目标值进行比较。您将看到这种方法的问题以及如何在一瞬间解决它,但是让我们考虑一下我们如何先这样做。
首先,您需要将模型质量总结为一种可以理解的方法。如果你比较10000套房子的预测值和实际的房屋价值,你可能会发现好的和坏的预测的混合。查看一个10000个预测值和实际值的列表将是毫无意义的。我们需要将这一点总结为一个单一的度量。
有许多度量来总结模型质量,但是我们将从一个叫做平均绝对错误(也称为MAE)开始。让我们从最后一个单词error开始分解这个度量。
每个房屋的预测误差为:
error=actual−predicted
所以,如果一栋房子花了15万美元,而你预测它会花10万美元,那么误差就是5万美元。
对于MAE度量,我们取每个误差的绝对值。这会将每个错误转换为正数。然后取这些绝对误差的平均值。这是我们衡量模型质量的标准。用简单的英语,可以说
平均来说,我们的预测偏离了X左右。
为了计算MAE,我们首先需要一个模型。它内置于下面的隐藏单元格中,您可以通过单击“代码”按钮查看该单元格。
# 加载数据
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.tree import DecisionTreeRegressor
# 定义模型
melbourne_model = DecisionTreeRegressor()
# 拟合模型
melbourne_model.fit(X, y)
一旦我们有了一个模型,下面是我们如何计算平均绝对误差:
from sklearn.metrics import mean_absolute_error
predicted_home_prices = melbourne_model.predict(X)
mean_absolute_error(y, predicted_home_prices)
“样本内”分数的问题
我们刚刚计算的指标可以称为“样本内”得分。我们使用了一个房子的“样本”来建立模型和评估它。这就是为什么这不好。
试想,在庞大的房地产市场上,门的颜色与房价无关。
然而,在你用来建立模型的数据样本中,所有有绿色门的房子都非常昂贵。这个模型的工作是找到预测房价的模式,所以它会看到这个模式,而且它总是会预测有绿门的房子的高价格。
由于该模式是从训练数据中派生出来的,因此该模型在训练数据中看起来是准确的。
但是,如果在模型看到新数据时这种模式不成立,那么在实际应用中,该模型将非常不准确。
由于模型的实际价值来自于对新数据的预测,因此我们衡量了未用于构建模型的数据的性能。最直接的方法是从模型构建过程中排除一些数据,然后使用这些数据来测试模型对以前从未见过的数据的准确性。这些数据称为验证数据。
编码它
scikit学习库有一个函数train_test_split,将数据分成两部分。我们将使用其中一些数据作为训练数据来拟合模型,并使用其他数据作为验证数据来计算平均绝对误差。
代码如下:
#将数据拆分为特性和目标的培训和验证数据
#分割基于随机数生成器。向提供数值
#随机的状态参数保证我们每次得到相同的分割
#运行此脚本。
train_X, val_X, train_y, val_y = train_test_split(X, y, random_state = 0)
#定义模型
melbourne_model = DecisionTreeRegressor()
#拟合模型
melbourne_model.fit(train_X, train_y)
#根据验证数据获取预测价格
val_predictions = melbourne_model.predict(val_X)
print(mean_absolute_error(val_y, val_predictions))
哇!
样本数据的平均绝对误差约为500美元。样品外的价值超过25万美元。
这就是几乎完全正确的模型和无法用于大多数实际用途的模型之间的区别。作为参考,验证数据中的平均房屋价值为110万美元。因此,新数据的误差约为房屋平均价值的四分之一。
有许多方法可以改进此模型,例如尝试寻找更好的特性或不同的模型类型。
五、欠拟合和过拟合
在这一步的最后,您将了解欠拟合和过拟合的概念,并且您将能够应用这些思想使您的模型更精确。
试验不同的模型
现在,您已经有了一种可靠的方法来衡量模型的准确性,您可以用其他模型进行实验,看看哪种模型给出了最好的预测。但是,你有什么替代模型呢?
您可以在scikitlearn的文档中看到,决策树模型有许多选项(比您长期想要或需要的更多)。最重要的选项决定了树的深度。回想一下这个微课程的第一课,一棵树的深度是一个衡量它在做出预测之前分裂多少次的指标。这是一棵相对较浅的树
实际上,一棵树的顶层(所有的房子)和一片叶子之间有10个裂口并不少见。随着树越来越深,数据集被切成叶子,房子越来越少。如果一棵树只有一次分裂,它会把数据分成两组。如果每一组再分开,我们会得到4组房子。再把每一个分开会产生8个组。如果我们通过在每一层增加更多的分割来增加一倍的组数,到第10层时,我们将有210组房子。一共有1024片叶子。
当我们把房子分成许多叶子时,每片叶子上的房子也就少了。房子很少的树叶会做出非常接近这些房子实际价值的预测,但它们可能会对新数据做出非常不可靠的预测(因为每个预测都只基于几个房子)。
这种现象称为过度拟合,模型与训练数据几乎完美匹配,但在验证和其他新数据方面表现不佳。另一方面,如果我们把树弄得很浅,就不会把房子分成很明显的一组。
在极端情况下,如果一棵树只把房子分成2或4间,那么每一组房子的种类仍然很多。结果的预测可能对大多数房屋来说是遥远的,甚至在训练数据中也是如此(出于同样的原因,在验证中也是不好的)。当一个模型不能捕捉到数据中的重要差别和模式,因此即使在训练数据中也表现不佳时,称为欠拟合。
因为我们关心新数据的准确性,我们根据验证数据进行估计,所以我们希望找到欠拟合和过拟合之间的最佳点。从视觉上看,我们需要(红色)验证曲线的低点
例子
控制树的深度有几种方法,许多方法允许通过树的某些路由比其他路由具有更大的深度。但是max\u leaf\u 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节点值建立的模型的精度。
# 比较MAE与max_leaf_nodes的不同值
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))
在列出的选项中,500是最佳的叶子数。
结论
以下是要点:模型可能会遭受以下两种情况之一:
过拟合:捕捉未来不会再出现的虚假模式,导致预测不太准确,或者
欠拟合:未能捕捉到相关模式,再次导致预测不太准确。
我们使用模型训练中未使用的验证数据来衡量候选模型的准确性。这让我们可以尝试许多候选模型并保留最好的模型。
六、随机森林
介绍
决策树留给你一个艰难的决定。一棵长着很多叶子的大树会过适,因为每一个预测都来自于它叶子上仅有的几栋房子的历史数据。但是一棵叶子很少的浅树的表现会很差,因为它不能捕捉到原始数据中那么多的差异。
即使是今天最复杂的建模技术也面临着这种不合身和过度合身之间的紧张关系。但是,许多模型都有可以带来更好性能的聪明想法。我们将以随机森林为例。
随机林使用多棵树,通过平均每个组成树的预测值来进行预测。它通常比单一的决策树具有更好的预测精度,并且可以很好地处理缺省参数。如果您继续建模,您可以学习更多性能更好的模型,但其中许多模型对获得正确的参数非常敏感。
例子
您已经看过几次加载数据的代码了。在数据加载结束时,我们有以下变量:
- 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)
# 筛选缺少值的行
melbourne_data = melbourne_data.dropna(axis=0)
# 选择目标和特征
y = melbourne_data.Price
melbourne_features = ['Rooms', 'Bathroom', 'Landsize', 'BuildingArea',
'YearBuilt', 'Lattitude', 'Longtitude']
X = 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)
我们构建了一个随机森林模型,类似于我们在scikit learn中构建决策树的方式—这次使用的是RandomForestRegressor类,而不是DecisionTreeRegressor。
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error
forest_model = RandomForestRegressor(random_state=1)
forest_model.fit(train_X, train_y)
melb_preds = forest_model.predict(val_X)
print(mean_absolute_error(val_y, melb_preds))
结论
可能还有进一步改进的空间,但这比最佳决策树错误250000有很大的改进。有一些参数允许您更改随机林的性能,就像我们更改单个决策树的最大深度一样。但是随机森林模型的一个最好的特性是,即使没有这种调整,它们也能正常工作。
七、机器学习比赛
机器学习比赛是一个很好的方式来提高你的数据科学技能和衡量你的进步。