机器学习实战——基于Scikit-Learn和TensorFlow 阅读笔记 之 第二章:端到端的机器学习项目

《机器学习实战——基于Scikit-Learn和TensorFlow》
这是一本非常好的机器学习和深度学习入门书,既有基本理论讲解,也有实战代码示例。
我将认真阅读此书,并为每一章内容做一个知识笔记。
我会摘录一些原书中的关键语句和代码,若有错误请为我指出。

机器学习实战——基于Scikit-Learn和TensorFlow 阅读笔记 之 第二章:端到端的机器学习项目_第1张图片

目录

  • 第二章 端到端的机器学习项目
    • 1 使用真实数据
    • 2 观察大局
    • 3 框架问题
    • 4 选择性能指标
    • 5 检查假设
    • 6 获取数据
      • 6.1 创建工作区
      • 6.2 下载数据
      • 6.3 快速查看数据结构
      • 6.4 创建测试集
      • 6.5 从数据探索和可视化中获得洞见
      • 6.6 将地理数据可视化
      • 6.7 寻找相关属性
      • 6.8 试验不同属性的组合
    • 7 机器学习算法的数据准备
      • 7.1 数据清理
      • 7.2 处理文本和分类属性
      • 7.3 自定义转换器
      • 7.4 特征缩放
      • 7.5 转换流水线
    • 8 选择和训练模型
      • 8.1 培训和评估训练集
      • 8.2 使用交叉验证来进行更好的评估
    • 9 微调模型
      • 9.1 网格搜索
      • 9.2 随机搜索
      • 9.3 集成方法
      • 9.4 分析最佳模型及其错误
      • 9.5 通过测试集评估系统
    • 10 启动、监控和维护系统

第二章 端到端的机器学习项目

假设你是一个房地产公司最近新雇佣的数据科学家,需要根据数据来预测任意区域的房价中位数。

1 使用真实数据

  • 流行的开放数据库
    UC Irvine Machine Learning Repository:http://archive.ics.uci.edu/ml/
    Kaggle datasets:https://www.kaggle.com/datasets
    Amazon’s AWS datasets:http://aws.amazon.com/fr/datasets/
  • 元门户站点(它们会列出开放的数据库)
    http://dataportals.org/
    http://opendatamonitor.eu/
    http://quandl.com/
  • 其他一些列出许多流行的开放数据存储库的页面(似乎已失效)
    Wikipedia’s list of Machine Learning datasets:https://goo.gl.SJHN2k
    Quora.com question:http://goo.gl/zDR78y
    Datasets subreddit:https://www.reddit.com/r/datasets

2 观察大局

习惯良好的数据科学家,要做的第一件事是拿出机器学习项目清单。

3 框架问题

第一个问题:业务目标是什么?
=> 输出对一个房价中位数的预测,用于下游机器学习系统。

第二个问题: 当前的解决方案。
=>专家使用复杂的规则来手动估计。

第三个问题:机器学习的框架是什么?
可以参考机器学习的分类,回答 我们的机器学习模型应该属于什么分类。
该问题是监督式学习任务,且预测属于回归任务。不需要对变化数据做出特别调整,数据量不大,只需要批量学习。

4 选择性能指标

回归问题的典型性能衡量指标是均方根误差(RMSE),它测量的是预测过程中,预测错误的 标准偏差
R M S E ( X , h ) = 1 / m ∑ i = 1 m h ( x ( i ) − y ( i ) ) 2 RMSE(X,h)=\sqrt{1/m\sum_{i=1}^m{h(x^{(i)}-y^{(i)})^2}} RMSE(X,h)=1/mi=1mh(x(i)y(i))2
其中:
m是测量RMSE所使用的数据集中实例的数量
x ( i ) x^{(i)} x(i)是数据集中,第i个实例的所有特征值的向量(标签特征除外)
y ( i ) y^{(i)} y(i)是标签(也就是我们期待该实例的输出值)
X是数据中所有实例的所有特征值的矩阵(标记特征除外)。每个实例为一行,也就是说第i行等于 x ( i ) x^{(i)} x(i)的转置矩阵,记作 ( x ( i ) ) T (x^{(i)})^{T} (x(i))T
h是系统的预测函数,也称为一个假设。当给定系统一个实例的特征向量 x ( i ) x^{(i)} x(i),它会输出一个预测值 y ^ ( 1 ) = h ( x ( 1 ) ) = 158400 \hat{y}^{(1)}=h(x^{(1)})=158 400 y^(1)=h(x(1))=158400,该区域的预测误差为 y ^ ( 1 ) − y ( 1 ) = 2000 \hat{y}^{(1)}-y^{(1)}=2000 y^(1)y(1)=2000
RMSE(X, h)是使用假设h再示例上测量的成本函数。

当有很多离群区域时,你可以考虑使用平均绝对误差(也称为平均绝对偏差)。
M A E ( X , h ) = 1 / m ∑ i = 1 m ∣ h ( x ( i ) − y ( i ) ) ∣ MAE(X,h)=1/m \sum_{i=1}^m{ \left| h(x^{(i)}-y^{(i)}) \right| } MAE(X,h)=1/mi=1mh(x(i)y(i))

它们都是测量两个向量之间的距离。预测向量和目标值向量。
距离或范数的测度方式:
计算平方和的跟(RMSE)对应欧几里得范数,l2范数。
计算绝对值的综合(MAE)对应l1范数,或称曼哈顿距离。
l0给出的是向量的基数(即元素的数量),l无穷则给出了向量中的最大绝对值。
范数指数越高,则越关注大的价值,忽视小的价值。

5 检查假设

列举和验证到目前为止(由你或者其他人)做出的假设,这可以才初期检查出严重问题。

6 获取数据

6.1 创建工作区

首先安装python。

为机器学习的代码和数据集创建一个工作区目录。

安装一些python模块:Jupyter,Pandas,NumPy,Matplotlib,Scikit-Learn。

使用命令 jupyter notebook来启动Jupyter,浏览器通过 http://loaclhost:8888/ 可访问该服务器。

点击New,选择python版本,创建一个Python笔记本。

6.2 下载数据

编写一个小脚本,需要数据时直接运行获取,方便实时更新。

import os
import tarfile
from six.moves import urllib

DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml/master/"
HOUSING_PATH = os.path.join("datasets", "housing")
HOUSING_URL = DOWNLOAD_ROOT + "datasets/housing/housing.tgz"

def fetch_housing_data(housing_url=HOUSING_URL, housing_path=HOUSING_PATH):
    if not os.path.isdir(housing_path):
        os.makedirs(housing_path)
    tgz_path = os.path.join(housing_path, "housing.tgz")
    urllib.request.urlretrieve(housing_url, tgz_path)
    housing_tgz = tarfile.open(tgz_path)
    housing_tgz.extractall(path=housing_path)
    housing_tgz.close()

使用pandas加载数据:

import pandas as pd

def load_housing_data(housing_path=HOUSING_PATH):
    csv_path = os.path.join(housing_path, "housing.csv")
    return pd.read_csv(csv_path)

6.3 快速查看数据结构

查看数据的属性类型,属性数量。

import pandas as pd

def load_housing_data(housing_path=HOUSING_PATH):
    csv_path = os.path.join(housing_path, "housing.csv")
    return pd.read_csv(csv_path)
    
housing = load_housing_data()
housing.head()

housing.info()

housing["ocean_proximity"].value_counts()

housing.describe()

%matplotlib inline
import matplotlib.pyplot as plt
housing.hist(bins=50, figsize=(20,15))
save_fig("attribute_histogram_plots")
plt.show()

6.4 创建测试集

先创建一个测试集,并放置一旁。
因为浏览测试集数据容易跌入某个看似有趣的数据模式,进而选择某个特殊的机器学习模型。然后当再使用测试集对泛化误差进行估算时,估计结果将会过于乐观,该系统启动后的表现将不如预期那般优秀。这叫做 窥探偏误

import numpy as np

# For illustration only. Sklearn has train_test_split()
def split_train_test(data, test_ratio):
    shuffled_indices = np.random.permutation(len(data))
    test_set_size = int(len(data) * test_ratio)
    test_indices = shuffled_indices[:test_set_size]
    train_indices = shuffled_indices[test_set_size:]
    return data.iloc[train_indices], data.iloc[test_indices]

为保证每次运行的数据分割结果一致,可以使用:

# to make this notebook's output identical at every run
np.random.seed(42)

或
import hashlib

def test_set_check(identifier, test_ratio, hash=hashlib.md5):
    return hash(np.int64(identifier)).digest()[-1] < 256 * test_ratio
from zlib import crc32

def test_set_check(identifier, test_ratio):
    return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32

def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio))
    return data.loc[~in_test_set], data.loc[in_test_set]

分层抽样的测试集中的比例分布与完整数据集中的分布几乎一致,而纯随机抽样的测试集结果则出现了重大偏离。

分层抽样
from sklearn.model_selection import StratifiedShuffleSplit

split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_index, test_index in split.split(housing, housing["income_cat"]):
    strat_train_set = housing.loc[train_index]
    strat_test_set = housing.loc[test_index]

6.5 从数据探索和可视化中获得洞见

把测试集放在一边,能探索的只有训练集。

先创建一个副本,这样随便尝试而不会损害训练集。

housing = strat_train_set.copy()

6.6 将地理数据可视化

人脑善于从图片中发现模式,但是也需要使用合适的可视化参数。

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.1)
save_fig("better_visualization_plot")

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4,
    s=housing["population"]/100, label="population", figsize=(10,7),
    c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True,
    sharex=False)
plt.legend()
save_fig("housing_prices_scatterplot")

6.7 寻找相关属性

可以计算出 ***标准相关系数(皮尔逊相关系数)***,相关系数越接近1越正相关,越接近-1越负相关,接近0说明二者相关程度弱。

相关系数
corr_matrix = housing.corr()

注意:
相关系数仅测量线性相关性,可能彻底遗漏非线性相关性。

6.8 试验不同属性的组合

此过程中,可以清理异常数据、发现有趣联系、转换处理重尾。

此外还可以构想新的可能属性。

本轮探索重要的是加深理解,为下一步做准备。

7 机器学习算法的数据准备

7.1 数据清理

缺失值处理方法:

  • 放弃这些相应的地区
  • 放弃这个属性
  • 将缺失值设置为某个值(0、平均数或者中位数都可以)
缺失值处理
sample_incomplete_rows.dropna(subset=["total_bedrooms"])    # option 1

sample_incomplete_rows.drop("total_bedrooms", axis=1)       # option 2

median = housing["total_bedrooms"].median()
sample_incomplete_rows["total_bedrooms"].fillna(median, inplace=True) # option 3
sample_incomplete_rows

7.2 处理文本和分类属性

机器学习算法易于和数字打交道,可以先将文本其转换为数字。
可使用LabelEncoder或独热编码OneHotEncoder。

7.3 自定义转换器

需要创建一个类,然后应用三个方法:fit()、transform()、fit_transform()。

7.4 特征缩放

最小 - 最大化缩放(归一化)
将值缩放到0-1之间。
将值减去最小值并除以最大值和最小值的差。
MinMaxScaler

标准化
减去平均值,然后除以方差,从而使得结果的分布具备单位方差。
不绑定缩放范围,可能带来问题,但是受异常值影响更小。

7.5 转换流水线

流水线使数据转换以正确的顺序来执行。
代码略。

8 选择和训练模型

8.1 培训和评估训练集

使用不同的模型来评估。
筛选出几个适合的模型,并保存模型参数。

8.2 使用交叉验证来进行更好的评估

使用交叉验证,K-折交叉验证:将数据随机分割成十个不同的子集,每个子集称为一个折叠(fold),然后对决策树模型进行十次训练和评估——每次挑选一个折叠进行评估,使用另外的九个折叠进行训练。

9 微调模型

9.1 网格搜索

使用Scikit-Learn的GridSearchCV来帮助找到最好的超参数。

from sklearn.model_selection import GridSearchCV

param_grid = [
    # try 12 (3×4) combinations of hyperparameters
    {'n_estimators': [3, 10, 30], 'max_features': [2, 4, 6, 8]},
    # then try 6 (2×3) combinations with bootstrap set as False
    {'bootstrap': [False], 'n_estimators': [3, 10], 'max_features': [2, 3, 4]},
  ]

forest_reg = RandomForestRegressor(random_state=42)
# train across 5 folds, that's a total of (12+6)*5=90 rounds of training 
grid_search = GridSearchCV(forest_reg, param_grid, cv=5,
                           scoring='neg_mean_squared_error', return_train_score=True)
grid_search.fit(housing_prepared, housing_labels)

9.2 随机搜索

当超参数的搜索范围较大时,使用RansomizedSearchCV来代替网格搜索。

9.3 集成方法

将表现最优的模型组合起来。

9.4 分析最佳模型及其错误

比如RandomForestRegressor可以指出每个属性的相对重要程度,以此判断并删去一些不重要的 属性。

9.5 通过测试集评估系统

只需要从测试集中获取预测器和标签,运行full_pipeline来转换数据。

尽管测试集可能表现较差,但是此时不要试图修改超参数,因为在新的数据集上只会泛化得更糟糕。

10 启动、监控和维护系统

编写监控代码,定期检查系统的实时性能。

对系统的预测结果进行抽样并评估。

评估输入系统的数据的质量。

使用新鲜的数据定期训练模型,过程尽可能自动化。

你可能感兴趣的:(机器学习实战——基于Scikit-Learn和TensorFlow 阅读笔记 之 第二章:端到端的机器学习项目)