机器学习python入门(一)

Selecting Data for Modeling

变量的选择,这里先不进行讲解,先用直觉选择几个变量。

import pandas as pd
melbourne_file_path = '../input/melbourne-housing-snapshot/melb_data.csv'
melbourne_data = pd.read_csv(melbourne_file_path)  ##dataframe类型的
melbourne_data.columns  ##查看数据集中所有列的列表。这是通过DataFrame.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')

对于缺失值的处理,之后讲解,现用最简单的方式:删除缺失值。

melbourne_data = melbourne_data.dropna(axis=0)

有许多方法可以选择数据的子集,我们之后讲解,我们现在只关注两种方法。
1.点符号Dot notation,用来选择“预测目标”
2.Selecting with a column list,用来选择“特征”

Selecting The Prediction Target

我们将使用点符号来选择我们想要预测的列,它被称为预测目标。按照惯例,预测目标是y。

y = melbourne_data.Price

Choosing “Features”

melbourne_features = ['Rooms', 'Bathroom', 'Landsize', 'Lattitude', 'Longtitude']

按照惯例,这个数据叫做X。

X = melbourne_data[melbourne_features]

使用describe 方法和head 方法来预测房价的数据:

X.describe()
        Rooms	    Bathroom	Landsize	Lattitude	Longtitude
count	6196.000000	6196.000000	6196.000000 6196.000000	6196.000000
mean	2.931407	1.576340	471.006940	-37.807904	144.990201
std	    0.971079	0.711362	897.449881	 0.075850	0.099165
min  	1.000000	1.000000	0.000000	-38.164920	144.542370
25% 	2.000000	1.000000	152.000000	-37.855438	144.926198
50% 	3.000000	1.000000	373.000000	-37.802250	144.995800
75% 	4.000000	2.000000	628.000000	-37.758200	145.052700
max	    8.000000	8.000000	37000.00000 -37.457090	145.526350
X.head()
   Rooms	Bathroom	Landsize	Lattitude	Longtitude
1	2	     1.0	     156.0	    -37.8079	 144.9934
2	3	     2.0	     134.0	    -37.8093	 144.9944
4	4	     1.0	     120.0	    -37.8072	 144.9941
6	3	     2.0	     245.0	    -37.8024	 144.9993
7	2	     1.0	     256.0	    -37.8060	 144.9954

使用这些命令可视化地检查数据是数据科学家工作的重要部分。您经常会在数据集中发现值得进一步检查的惊喜。

Building Your Model(决策树)

使用scikit-learn库创建模型。在编写代码时,这个库是作为sklearn编写的。Scikit-learn很容易成为建模数据类型的最流行库,通常存储在DataFrames中。
建立和使用模型的步骤是:
1.定义Define:它将是什么类型的模型?一个决策树吗?其他类型的模型?模型类型的其他一些参数也被指定。
2.拟合Fit:从提供的数据中捕获模式。这是建模的核心。
3.预测Predict
4.评估Evaluate:确定模型预测的准确性。
下面是一个用scikit-learn定义决策树模型的例子,并将其与特征和目标变量进行拟合。

from sklearn.tree import DecisionTreeRegressor

# Define model. Specify a number for random_state to ensure same results each run
melbourne_model = DecisionTreeRegressor(random_state=1)

# Fit model
melbourne_model.fit(X, y)
DecisionTreeRegressor(criterion='mse', max_depth=None, max_features=None,
                      max_leaf_nodes=None, min_impurity_decrease=0.0,
                      min_impurity_split=None, min_samples_leaf=1,
                      min_samples_split=2, min_weight_fraction_leaf=0.0,
                      presort=False, random_state=1, splitter='best')

许多机器学习模型在模型训练中允许一些随机性。为random_state指定一个数字可以确保在每次运行时得到相同的结果。这被认为是一种好的做法。您可以使用任何数字,而模型的质量并不完全取决于您所选择的值。
实际上,你应该对即将上市的新房子做出预测,而不是对我们已经有价格的房子做出预测。但是我们会对训练数据的前几行进行预测来看看predict函数是如何工作的。

print("Making predictions for the following 5 houses:")
print(X.head())
print("The predictions are")
print(melbourne_model.predict(X.head()))
Making predictions for the following 5 houses:
   Rooms  Bathroom  Landsize  Lattitude  Longtitude
1      2       1.0     156.0   -37.8079    144.9934
2      3       2.0     134.0   -37.8093    144.9944
4      4       1.0     120.0   -37.8072    144.9941
6      3       2.0     245.0   -37.8024    144.9993
7      2       1.0     256.0   -37.8060    144.9954
The predictions are
[1035000. 1465000. 1600000. 1876000. 1636000.]

Model Validation

已经建立了一个模型。但它到底有多好呢?
下面我们将学习使用模型验证来度量模型的质量。度量模型质量是迭代地改进模型的关键。
我们可能想要评估您所构建的几乎每个模型。在大多数(尽管不是全部)应用程序中,模型质量的相关衡量标准是预测精度predictive accuracy。也就是,模型的预测是否接近实际情况。
许多人在衡量预测准确度时犯了一个巨大的错误。他们用训练数据进行预测,并将这些预测与训练数据中的目标值进行比较。我们马上就会看到这种方法的问题以及如何解决它,但是首先让我们考虑一下如何做这个。
首先需要以一种可以理解的方式对模型质量进行总结。如果你比较1万套房子的预测和实际房价,你很可能会发现预测好坏参半。查看包含10,000个预测值和实际值的列表是没有意义的。我们需要把它总结成一个单一的度量metric。
有许多衡量模型质量的度量,但是我们将从一个称为平均绝对误差Mean Absolute Error(也称为MAE)的度量开始。让我们从最后一个词误差error开始分解这个指标。
每栋房的预测误差为:

error=actual−predicted

所以,如果一栋房子花了15万美元你预测它会花10万美元误差是5万美元。
利用MAE度量,我们取每个误差的绝对值。这将把每个误差转换为一个正数。然后取绝对误差的平均值,这是我们对模型质量的衡量。用简单的英语来说:On average, our predictions are off by about X.
为了计算MAE,我们首先需要一个模型,即上面的决策树模型。
一旦我们有了一个模型,下面是我们如何计算平均绝对误差:

from sklearn.metrics import mean_absolute_error

predicted_home_prices = melbourne_model.predict(X)
mean_absolute_error(y, predicted_home_prices)
434.71594577146544

The Problem with “In-Sample” Scores

我们刚刚计算出的度量可以称为“样本内In-Sample”分数。我们使用单一的房屋“样本”来建立模型和评估它。这就是糟糕的原因
想象一下,在偌大的房地产市场上,门的颜色与房价无关。然而,在用于构建模型的数据示例中,所有带有绿色门的住宅都非常昂贵。模型的工作是找到预测房价的模式,所以它会看到这个模式,它总是会预测有绿色门的房屋的高价格。由于该模式是从训练数据中派生出来的,因此模型在训练数据中显示是准确的。但是如果这个模式在模型遇到新数据时不成立,那么这个模型在实际使用时就会非常不准确。
由于模型的实用价值来自于对新数据的预测,所以我们用没有用于构建模型的数据来衡量性能。要做到这一点,最直接的方法是从模型构建过程中排除一些数据,然后使用这些数据来测试模型在以前没有见过的数据上的准确性。此数据称为验证数据validation data.。

Code it

scikit-learn库有一个函数train_test_split,用于将数据分成两部分。我们将使用其中一些数据作为训练数据来拟合模型,我们将使用其他数据作为验证数据来计算mean_absolute_error.

from sklearn.model_selection import train_test_split

# split data into training and validation data, for both features and target
# The split is based on a random number generator. Supplying a numeric value to
# the random_state argument guarantees we get the same split every time we
# run this script.
train_X, val_X, train_y, val_y = train_test_split(X, y, random_state = 0)
# Define model
melbourne_model = DecisionTreeRegressor()
# Fit model
melbourne_model.fit(train_X, train_y)

# get predicted prices on validation data
val_predictions = melbourne_model.predict(val_X)
print(mean_absolute_error(val_y, val_predictions))
259556.7211103938

样本内数据的平均绝对误差大约是500美元。样本外超过25万美元。
这就是一个几乎完全正确的模型和一个不能用于大多数实际目的的模型之间的区别。作为参考,验证数据中的平均房屋价值是110万美元。所以新数据的误差大约是平均房屋价值的四分之一。
有很多方法可以改进这个模型,比如通过试验来发现更好的特征或不同的模型类型。

Experimenting With Different Models

现在我们已经有了一种可靠的方法来度量模型的准确性,我们可以使用其他模型进行试验,看看哪个模型能给出最好的预测。但是对于模型你有什么选择呢?
在scikit-learn的文档中,您可以看到决策树模型有许多选项。最重要的选项决定了树的深度。回想一下,树的深度是在进行预测之前进行的分割的度量。
在实践中,一棵树在顶层(所有的房子)和一片叶子之间有10个分叉并不少见。随着树变得更深,数据集被分割成带有更少房屋的叶子。如果一个树只有一次分裂,它将数据分成两组。如果每一组再分开,就得到4组房子。再把这些分开就会产生8组。如果我们在每一层增加更多的隔板,使组数翻倍,到第十层的时候,就会有一组房子了。这是1024的叶子。
当我们把房子分成许多片叶子时,每片叶子上的房子也会减少。房子很少的树叶会做出非常接近这些房子的实际价值的预测,但他们可能做出非常不可靠的新数据的预测(因为每个预测都是基于少数房子)。
这种现象叫做过拟合overfitting,即模型与训练数据几乎完美匹配,但在验证和其他新数据方面表现不佳。另一方面,如果我们把树做得很浅,就不会把房子分成不同的组。在极端的情况下,如果一棵树只把房子分成2或4间,那么每一组仍然有各种各样的房子。即使在训练数据中,结果预测对大多数房子来说可能都很遥远(同样的原因,它在验证中也会很糟糕)。当一个模型未能捕捉到数据中重要的区别和模式时,它甚至在训练数据中表现也很差,这被称为欠拟合underfitting
由于我们关心新数据的准确性,我们从验证数据中估计,我们希望找到欠拟合和过拟合之间的最佳点。

Example

有几种方法可以控制树的深度,其中许多方法允许通过树的某些路径具有比其他路径更大的深度。但是max_leaf_nodes参数提供了一种非常明智的方法来控制过拟合和欠拟合。我们允许模型生成的叶子越多,我们就从欠拟合区域向过拟合区域移动的越多。
我们可以使用效用函数utility function来帮助比较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中。
我们可以使用for循环来比较使用max_leaf_nodes的不同值构建的模型的准确性。

# compare MAE with differing values of 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))
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是叶节点的最佳数量。

Conclusion(overfitting, underfitting)

这里的结论是:模型可能会遭受以下两种情况

  • 过拟合:捕捉将来不会重现的虚假模式,从而导致预测不那么准确。
  • 欠拟合:未能捕捉到相关模式,再次导致预测不准确。
    我们使用模型训练中不使用的验证数据来衡量候选模型的准确性。这让我们可以。尝试许多候选模型,并保留最好的一个。

Random Forest model(随机森林)

决策树给我们带来了一个困难的决定。一棵有很多叶子的树会过拟合,因为每一个预测都是来自于它叶子上的几所房子的历史数据。但是,只有很少叶子的浅树表现会很差,因为它无法捕捉到原始数据中的许多差别。
即使是当今最复杂的建模技术也面临着欠拟合和过拟合之间的紧张关系。但是,许多模型都有聪明的想法,可以带来更好的性能。我们将以随机森林为例。
随机森林使用许多树,它通过平均每个组成树的预测来进行预测。它通常比单一决策树具有更好的预测精度,并且在默认参数下工作得很好。如果我们继续建模,我们可以学习更多性能更好的模型,但是其中许多模型对于获得正确的参数非常敏感。

Example

我们已经多次看到了加载数据的代码。在数据加载结束时,我们有以下变量

  • train_X
  • val_X
  • rain_y
  • val_y
    我们构建了一个随机森林模型,类似于我们在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))
/opt/conda/lib/python3.6/site-packages/sklearn/ensemble/forest.py:245: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.
  "10 in version 0.20 to 100 in 0.22.", FutureWarning)
202888.18157951365

Conclusion

可能还有进一步改进的空间,但这已经比25万的最佳决策树错误有了很大的改进。有一些参数允许你改变随机森林的性能,就像我们改变单个决策树的最大深度一样。但随机森林模型的最佳特性之一是,即使不进行调优,它们通常也能合理地工作。
我们将很快了解XGBoost模型,使用正确的参数进行良好调优后,该模型提供了更好的性能(但是需要一些技能来获得正确的模型参数)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值