用python轻松理解机器学习

本文介绍了机器学习的四个分支:监督、无监督、自监督和强化学习,强调了评估模型的重要性,如留出验证和K折验证。讨论了数据预处理的必要性,包括向量化、值标准化和处理缺失值。此外,重点讲解了正则化方法,如L1和L2正则化,以及如何通过dropout来降低过拟合。最后,概述了机器学习的通用工作流程,包括数据准备、模型开发和正则化策略。
摘要由CSDN通过智能技术生成

概述

一. 机器学习的四个分支

1.监督学习,主要有分类和回归,还有其他变体(序列生成、语法树预测、目标检测、图像分割)。
2.无监督学习

  • 目的:数据可视化、数据压缩、数据去噪、更好地理解数据中的相关性
  • 方法:降维和聚类

3.自监督学习:是没有人工标注的标签的监督学习,可以将它看作没有人类参与的监督学习。标签 仍然存在(因为总要有什么东西来监督学习过程),但它们是从输入数据中生成的,通常是使用启发式算法生成的。
比如,自编码器,它生成的目标就是未经修改的输入。还有,给定视频中过去的帧来预测下一帧,或者给定文本中前面的词来预测下一个词,都是自监督学习的例子(也属于时序监督学习)。
4.强化学习:智能体接收有关其环境的信息,并学会选择使某种奖励最大化的行动。

二.评估机器学习模型(降低过拟合以及将泛化能力最大化)

1.简单的留出验证
在这里插入图片描述
代码清单4-1 留出验证

num_validation_samples = 10000
#打乱数据
np.random.shuffle(data) 
#定义验证集
validation_data = data[:num_validation_samples]
data = data[num_validation_samples:]
#定义训练集
training_data = data[:]
model = get_model()
model.train(training_data)
validation_score = model.evaluate(validation_data)
# 现在你可以调节模型、重新训练、评估,然后再次调节……
model = get_model()
model.train(np.concatenate([training_data,
validation_data]))
test_score = model.evaluate(test_data)

这是最简单的评估方法,但有一个缺点:如果可用的数据很少,那么可能验证集和测试集
包含的样本就太少,从而无法在统计学上代表数据。这个问题很容易发现:如果在划分数据前
进行不同的随机打乱,最终得到的模型性能差别很大。

2.k折验证
K 折验证(K-fold validation)将数据划分为大小相同的K 个分区。对于每个分区i,在剩
余的K-1 个分区上训练模型,然后在分区i 上评估模型。最终分数等于K 个分数的平均值。对
于不同的训练集- 测试集划分,如果模型性能的变化很大,那么这种方法很有用。与留出验证
一样,这种方法也需要独立的验证集进行模型校正。
示意图如下
在这里插入图片描述
代码清单4-2 K 折交叉验证

k = 4
num_validation_samples = len(data) // k

np.random.shuffle(data)

validation_scores = []
for fold in range(k):
#选择验证数据分区
  validation_data = data[num_validation_samples * fold:
  num_validation_samples * (fold + 1)]
  #使用剩余数据作为训练数据。注意,+ 运算符是列表合并,不是求和
  training_data = data[:num_validation_samples * fold] +
  data[num_validation_samples * (fold + 1):]

#创建一个全新的模型实例(未训练)  
  model = get_model()
  model.train(training_data)
  validation_score = model.evaluate(validation_data)
  validation_scores.append(validation_score)

#最终验证分数:K 折验证分数的平均值
validation_score = np.average(validation_scores)

#在所有非测试数据上训练最终模型
model = get_model()
model.train(data)
test_score = model.evaluate(test_data)
  1. 带有打乱数据的重复K 折验证
    如果可用的数据相对较少,而你又需要尽可能精确地评估模型,那么可以选择带有打乱数
    据的重复K 折验证(iterated K-fold validation with shuffling)。我发现这种方法在Kaggle 竞赛中
    特别有用。具体做法是多次使用K 折验证,在每次将数据划分为K 个分区之前都先将数据打乱。
    最终分数是每次K 折验证分数的平均值。注意,这种方法一共要训练和评估P×K 个模型(P
    是重复次数),计算代价很大。

4.评估模型的注意事项
需要注意:

  • 数据代表性。你希望训练集和测试集都能够代表当前数据。例如,你想要对数字图像进行分类,而图像样本是按类别排序的,如果你将前80% 作为训练集,剩余20% 作为测试集,那么会导致训练集中只包含类别0~ 7,而测试集中只包含类别8 ~ 9。这个错误看起来很可笑,却很常见。因此,在将数据划分为训练集和测试集之前,通常应该随机打乱数据。
  • 时间箭头。如果想要根据过去预测未来(比如明天的天气、股票走势等),那么在划分数据前你应该随机打乱数据,因为这么做会造成时间泄露(temporal leak):你的模型将在未来数据上得到有效训练。在这种情况下,你应该始终确保测试集中所有数据的时间都晚于训练集数据。
  • 数据冗余。如果数据中的某些数据点出现了两次(这在现实中的数据里十分常见),那么打乱数据并划分成训练集和验证集会导致训练集和验证集之间的数据冗余。从效果上来看,你是在部分训练数据上评估模型,这是极其糟糕的!一定要确保训练集和验证集之间没有交集。

1.神经网络的数据预处理(目的是使原始数据更适于用神经网络处理)

  • 向量化:输入和目标都必须是浮点数张量。
  • 值标准化:举两个例子,在mnist手写库中,开始时图像数据被编码为0~255范围内的整数,表示灰度值,那么在输入网络前,你需要将其转换为float32格式并除以255,这样就得到0 ~1范围内的浮点数。另一个例子是波士顿房价,在预测房价时,开始时特征有不同的取值范围,有些特征是较小的浮点数,有些特征是相对较大的整数。将这一数据输入网络之前,你需要对其标准化,使其均值为0,标准差为1。
    一般来说,将取值相对较大的数据(比如多位整数,比网络权重的初始值大很多)或异质数(heterogeneous data,比如数据的一个特征在0~ 1 范围内,另一个特征在100 ~200 范围内)输入到神经网络中是不安全的。这么做可能导致较大的梯度更新,进而导致网络无法收敛。为了让网络的学习变得更容易,输入数据应该具有以下特征。
    (1) 取值较小:大部分值都应该在 0~1 范围内。
    (2)同质性(homogenous):所有特征的取值都应该在大致相同的范围内。
    此外,下面这种更严格的标准化方法也很常见,而且很有用,虽然不一定总是必需的(例如,
    对于数字分类问题就不需要这么做)。
    (1)将每个特征分别标准化,使其平均值为 0。
    (2)将每个特征分别标准化,使其标准差为 1。
    这对于Numpy 数组很容易实现。
#假设x 是一个形状为(samples,features) 的二维矩阵
x -= x.mean(axis=0)
x /= x.std(axis=0)
  • 处理缺失值
    你的数据中有时可能会有缺失值。例如在房价的例子中,第一个特征(数据中索引编号为0 的列)是人均犯罪率。如果不是所有样本都具有这个特征的话,怎么办?那样你的训练数据或测试数据将会有缺失值。
    一般来说,对于神经网络,将缺失值设置为0 是安全的,只要0 不是一个有意义的值。网络能够从数据中学到0 意味着缺失数据,并且会忽略这个值。
    注意,如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络
    不可能学会忽略缺失值。在这种情况下,你应该人为生成一些有缺失项的训练样本:多次复制
    一些训练样本,然后删除测试数据中可能缺失的某些特征。

2.特征工程
是对数据进行硬编码的变换(不是模型学到的)。本质是用更简单的方式表述问题,它需要深入理解问题。
使用特征工程的原因有两点:
(1)用更少的资源 (2)用更少的数据

3.过拟合与欠拟合
目的:是得到良好的泛化。
为了防止模型从训练数据中学到错误或无关紧要的模式,最优解决方法是获取更多的训练数据。次优解决方法是调节模型允许存储的信息量,或对模型允许存储的信息加以约束。(优化过程会迫使模型集中学习最重要的模式。)
降低过拟合的方法叫正则化,几种常见的正则化方法:

  • 减小网络大小:可学习参数的个数通常被称为模型的容量,我们应该在容量过大与容量不足之间找到一个折中。
  • 添加权重正则化:奥卡姆剃刀原理,简单模型比复杂模型更不容易过拟合。
    一种常见的降低过拟合的方法就是强制让模型权重只能取较小的值,从而限制模型的复杂度,这使得权重值的分布更加规则。这叫权重正则化。实现方法是向损失函数中添加与较大权重值相关的成本。这个成本有两种形式。
    (1)L1正则化:添加的成本与权重系数的绝对值[权重的L1范数]成正比。
    (2)L2正则化:添加的成本与权重系数的平方[权重的L2范数]成正比。神经网络的L2正则化也叫权重衰减

在Keras 中,添加权重正则化的方法是向层传递权重正则化项实例(weight regularizer
instance)作为关键字参数。

代码清单4-6 向模型添加L2 权重正则化
from keras import regularizers
model = models.Sequential()
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

l2(0.001) 的意思是该层权重矩阵的每个系数都会使网络总损失增加0.001*weight_coefficient_value。注意,由于这个惩罚项只在训练时添加,所以这个网络的训练损失会比测试损失大很多。
你还可以用Keras 中以下这些权重正则化项来代替L2 正则化。

代码清单4-7 Keras 中不同的权重正则化项
from keras import regularizers
#L1正则化
regularizers.l1(0.001)
#同时做L1和L2正则化
regularizers.l1_l2(l1=0.001, l2=0.001)
  • 添加dropout正则化
    使用dropout,就是在训练过程中随机将该层的一些输出特征舍弃(设置为0)。原来是向量[0.2,0.5,1.3,0.8,1.1],使用dropout后,这个向量会有几个随机的元素变成0,比如[0,0.5,1.3,0,1.1]。
    dropout比率是被设为0的特征所占的比例,通常在0.2~0.5之间。
    测试时,将输出按dropout比率缩小。这里乘以0.5
    layer_output *= 0.5 (测试时)
    layer_output /= 0.5(注意,是成比例放大而不是成比例缩小)
    在这里插入图片描述
    让我意识到,在每个样本中随机删除不同的部分神经元,可以阻止它们的阴谋,因此可以降低过拟合。核心思想是在层的输出值中引入噪声

三.机器学习的通用工作流程

  • 定义问题,收集数据集:非平稳问题
  • 选择衡量成功的指标:
    1.对于平衡分类问题(每个类别的可能性相同),精度和接收者操作特征曲线下面积(area
    under the receiver operating characteristic curve,ROC AUC)是常用的指标。
    2.对于类别不平衡的问题,可以适用准确率和召回率。
    3.对于排序问题或多标签分类,可以使用平均准确率均值(mean average precision)。
  • 确定评估方法
    1.留出验证集
    2.K折交叉验证
    3.重复的K折验证
  • 准备数据
  • 开发比基准更好的模型:目标是为了获得统计功效。需要选择三个关键参数。
    1.最后一层的激活。它对网络输出进行有效的限制。例如,IMDB 分类的例子在最后一层使用了sigmoid,回归的例子在最后一层没有使用激活,等等。
    2.损失函数。它应该匹配你要解决的问题的类型。例如,IMDB 的例子使用 binary_crossentropy、回归的例子使用mse,等等。
    3.优化配置。你要使用哪种优化器?学习率是多少?大多数情况下,使用 rmsprop 及其
    默认的学习率是稳妥的。
    在这里插入图片描述
  • 扩大模型规模:开发过拟合的模型
    1.添加更多的层。
    2.让每一层变得更大。
    3.训练更多的轮次。
  • 模型正则化与调节超参数
    1.添加dropout。
    2.尝试不同的架构:增加或减少层数。
    3.添加L1和/或L2正则化。
    4.尝试不同的超参数(比如每层的单元个数或优化器的学习率),以找到最佳配置。
    5.(可选)反复做特征工程:添加新特征或删除没有信息量的特征。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值