ML概论 Acemyzoe

机器学习和深度学习都是人工智能的形式。准确地说,深度学习是机器学习的一种特定形式。机器学习和深度学习都从训练和测试模型开始,并经过优化找到一个权重使模型效果更好。两者都可以处理数字(回归)和非数字(分类)问题,尽管在对象识别和语言翻译等多个应用领域中,深度学习模型往往比机器学习模型更适合。

机器学习说明

机器学习算法通常分为有监督的(训练数据有标记答案)和无监督的(可能存在的任何标签均未显示在训练算法中)。有监督的机器学习问题又分为分类(预测非数字答案,例如错过抵押贷款的可能性)和回归(预测数字答案,例如下个月在曼哈顿商店出售的小部件的数量)。

无监督学习可进一步分为聚类(查找类似对象的组,例如跑鞋,步行鞋和正装鞋),关联(查找对象的常见序列,例如咖啡和奶油)和降维(投影,特征选择) ,以及特征提取。

分类算法

分类问题是有监督的学习,要求在两个或多个类别之间进行选择,通常为每个类别提供概率。除了需要大量高级计算资源的神经网络和深度学习之外,最常见的算法是朴素贝叶斯,决策树,逻辑回归,K最近邻和支持向量机(SVM)。也可以使用集成方法(模型的组合),例如“随机森林”,其他“装袋”方法以及增强方法(例如,AdaBoost和XGBoost)。

回归算法

回归问题是有监督的学习,要求模型预测数字。最简单,最快的算法是线性(最小二乘)回归,但一般不应止步于此,因为它通常会返回一个中等的结果。其他常见的机器学习回归算法(缺少神经网络)包括朴素贝叶斯,决策树,K最近邻,LVQ(学习矢量量化),LARS套索,弹性网,随机森林,AdaBoost和XGBoost。值得注意的是,用于回归和分类的机器学习算法之间存在一些重叠。

聚类算法

聚类问题是一种无监督的学习问题,它要求模型查找相似数据点的组。最受欢迎的算法是K-Means聚类;其他包括均值漂移聚类,DBSCAN(基于噪声的应用程序基于空间的聚类),GMM(高斯混合模型)和HAC(分层聚类)。

降维算法

降维是一个无监督的学习,它要求模型删除或组合对结果影响很小或没有影响的变量。这通常与分类或回归结合使用。降维算法包括删除具有许多缺失值的变量,删除具有低方差的变量,决策树,随机森林,删除或组合具有高相关性的变量,后向特征消除,前向特征选择,因子分析和PCA(主成分分析)。

优化方法

训练和评估可以通过优化监督算法的参数权重,找到最适合数据真实性的一组值,从而将监督学习算法转变为模型。算法通常将最速下降的变量用于优化程序,例如随机梯度下降,它是从随机起始点多次执行的最速下降。

机器学习的数据清理

没有干净的原始数据,为了满足机器学习怼数据的要求,必须过滤数据。例如,

  • 1、查看数据,并排除所有缺少大量数据的列。
  • 2、再次查看数据,然后选择要用于预测的列(特征选择)。进行迭代时,可能需要更改此内容。在其余列中排除仍缺少数据的任何行。
  • 3、纠正明显的错别字并合并等效答案。
  • 4、排除数据超出范围的行。例如,如果您要分析纽约市内的出租车行程,则需要过滤出市区外边界以外的上,下纬度和经度行。

还可以做更多的事情,但这取决于收集的数据。这可能很乏味,但是如果在机器学习过程中设置了数据清理步骤,则可以随意修改并重复进行。

机器学习的数据编码和规范化

要将分类数据用于机器分类,需要将文本标签编码为另一种形式。有两种常见的编码。

一种是标签编码,这意味着每个文本标签值都用数字代替。另一种是一键编码,这意味着每个文本标签值都将变成具有二进制值(1或0)的列。大多数机器学习框架都具有进行转换的功能。通常,独热编码是首选,因为标签编码有时会使机器学习算法混淆,以为编码列应该是有序列表。

要将数字数据用于机器回归,通常需要将数据标准化。否则,具有较大范围的数字可能倾向于主导特征向量之间的欧几里得距离,其影响可能会以其他场为代价而被放大,并且最陡的下降优化可能会难以收敛。有多种方法可以对数据进行标准化和标准化以进行机器学习,包括最小-最大标准化,均值标准化,标准化以及按比例缩放到单位长度。此过程通常称为特征缩放。

机器学习的特征工程

特征是被观察的现象的个体可测量特性或特征。“特征”的概念与解释变量的概念有关,该解释变量在诸如线性回归之类的统计技术中使用。特征向量将单行的所有特征组合为数值向量。

选择特征的部分技术是选择一组最少的解释问题的自变量。如果两个变量高度相关,则要么需要将它们组合为一个功能,要么应将其删除。有时人们进行主成分分析以将相关变量转换为一组线性不相关变量。

人们用来构造新特征或降低特征向量维数的一些转换很简单。例如,Year of Birth从中减去Year of Death并构造Age at Death,这是寿命和死亡率分析的主要独立变量。在其他情况下,特征构造可能不是那么明显。

拆分数据以进行机器学习

在有监督的机器学习中,通常的做法是将数据集划分为子集,以进行训练,验证和测试。一种工作方式是将80%的数据分配给训练数据集,并将10%的数据分配给验证和测试数据集。(确切的划分是一个优先事项。)大部分训练是针对训练数据集进行的,而预测则是在每个时期结束时针对验证数据集进行的。

验证数据集中的错误可用于识别停止标准或驱动超参数调整。最重要的是,验证数据集中的错误怼找出模型是否过拟合训练数据有帮助。

通常在最终模型上对测试数据集进行预测。如果测试数据集从未用于训练,则有时称为保持数据集。

还有其他几种分割数据的方案。交叉验证是一种常见的技术,涉及将完整数据集重复拆分为训练数据集和验证数据集。在每个时期结束时,将对数据进行混洗并再次拆分。

机器学习库

在Python中,Spark MLlib和Scikit-learn是机器学习库的绝佳选择。在R中,一些机器学习包选项是CARAT,randomForest,e1071和KernLab。在Java中,不错的选择包括Java-ML,RapidMiner和Weka。

深度学习解释

深度学习是机器学习的一种形式,其中所训练的模型在输入和输出之间具有多个隐藏层。在大多数讨论中,深度学习意味着使用深度神经网络。但是,除了神经网络之外,还有一些算法可以使用其他类型的隐藏层来实现深度学习。

“人工”神经网络的思想可以追溯到1940年代。基本概念是,由相互连接的阈值开关构建的人工神经元网络可以像动物大脑和神经系统(包括视网膜)一样学习识别模式。

反向传播

基本上,通过在训练过程中同时激活两个神经元之间的连接来进行学习。在现代神经网络软件中,最常见的问题是使用称为误差,反向传播或BP的反向传播的规则来增加神经元之间连接的权重值。

人工神经网络中的神经元

神经元如何建模?每个都有一个传播函数,该函数通常使用加权和来转换连接的神经元的输出。传播函数的输出传递到激活函数,当其输入超过阈值时将激活。

神经网络中的激活函数

在1940年代和50年代,人工神经元使用了逐步激活功能,被称为感知器。现代神经网络可能会说他们正在使用感知器,但实际上具有平滑的激活函数,例如逻辑或乙状函数,双曲正切或整流线性单位(ReLU)。ReLU通常是快速收敛的最佳选择,尽管如果将学习速率设置得太高,它在训练过程中会出现神经元“死亡”的问题。

激活函数的输出可以传递到输出函数以进行其他整形。但是,输出函数通常是身份函数,这意味着激活函数的输出将传递到下游连接的神经元。

神经网络拓扑

现在我们了解了神经元,我们需要了解常见的神经网络拓扑。在前馈网络中,神经元被组织为不同的层:一个输入层,n个隐藏处理层和一个输出层。每层的输出仅进入下一层。

在具有快捷连接的前馈网络中,某些连接可以跳过一个或多个中间层。在循环神经网络中,神经元可以直接或间接地通过下一层来影响自己。

训练神经网络

就像任何其他机器学习一样,可以进行神经网络的监督学习:向网络展示训练数据组,将网络输出与所需输出进行比较,生成误差向量,并基于误差向量对网络进行校正。在应用校正之前一起运行的一批训练数据称为时期。

对于那些对细节感兴趣的人,反向传播使用误差(或成本)函数相对于模型的权重和偏差的梯度来发现正确的方向,以最大程度地减少误差。两件事控制着校正的应用:优化算法和学习率变量。学习速率变量通常需要较小,以确保收敛并避免引起死的ReLU神经元。

神经网络优化器

神经网络的优化程序通常使用某种形式的梯度下降算法来驱动反向传播,通常采用一种机制来避免陷入局部最小值中,例如优化随机选择的微型批次(随机梯度下降)并将动量校正应用于梯度。一些优化算法还通过查看梯度历史记录(AdaGrad,RMSProp和Adam)来调整模型参数的学习率。

与所有机器学习一样,您需要对照单独的验证数据集检查神经网络的预测。否则,您可能会冒险创建仅记住其输入而不学会学习广义预测器的神经网络。

深度学习算法

用于实际问题的深度神经网络可能具有10层以上的隐藏层。它的拓扑可能很简单,也可能很复杂。

网络中的层越多,它可以识别的特征就越多。不幸的是,网络中的层越多,计算所需的时间就越长,并且训练起来就越困难。

卷积神经网络(CNN)通常用于机器视觉。卷积神经网络通常使用卷积,池化,ReLU,完全连接和丢失层来模拟视觉皮层。卷积层基本上采用许多小的重叠区域的积分。池化层执行非线性下采样的形式。ReLU层应用非饱和激活函数f(x)= max(0,x)。在完全连接的层中,神经元与上一层中的所有激活都具有连接。损失层使用Softmax或交叉熵损失函数进行分类,或使用欧几里得损失函数进行回归,计算网络训练如何惩罚预测标签与真实标签之间的偏差。

递归神经网络(RNN)通常用于自然语言处理(NLP)和其他序列处理,还有长短期记忆(LSTM)网络和基于注意力的神经网络。在前馈神经网络中,信息从输入经过隐藏层流到输出。这将网络限制为一次只能处理一个状态。

在递归神经网络中,信息通过一个循环循环,这使网络可以记住最近的先前输出。这样可以分析序列和时间序列。RNN有两个常见的问题:爆炸梯度(通过固定梯度很容易固定)和消失梯度(不太容易固定)。

在LSTM中,在两种情况下,网络都可以通过更改权重来忘记(控制)先前的信息并记住这些信息。这有效地为LSTM提供了长期和短期记忆,并解决了梯度消失的问题。LSTM可以处理数百个过去输入的序列。

注意模块是将权重应用于输入向量的通用门。分层的神经注意编码器使用多层注意模块来处理成千上万的过去输入。

不是神经网络的随机决策森林(RDF)对于一系列分类和回归问题很有用。RDF由多层构成,但不是神经元,而是由决策树构建,并输出各个树预测的统计平均值(分类模式或回归均值)。RDF的随机方面是对单个树使用引导聚合(也称为装袋),并为树获取特征的随机子集。

XGBoost(极限梯度增强)也不是一个深度神经网络,它是一种可扩展的,端到端的树增强系统,已针对许多机器学习挑战产生了最先进的结果。经常提到装袋和提振。区别在于,梯度树增强不是生成随机树的集合,而是从单个决策树或回归树开始,对其进行优化,然后从第一棵树的残差构建下一棵树。

一些最好的Python的深度学习框架是TensorFlow,Keras,PyTorch和MXNet。Deeplearning4j是最好的Java深度学习框架之一。ONNX和TensorRT是深度学习模型的运行时。

深度学习与机器学习

通常,经典(非深度)机器学习算法比深度学习算法训练和预测速度快得多。一个或多个CPU通常足以训练经典模型。深度学习模型通常需要诸如GPU,TPU或FPGA之类的硬件加速器进行培训,并且还需要大规模部署。没有它们,模型将需要几个月的训练时间。

对于许多问题,一些经典的机器学习算法将产生一个“足够好”的模型。对于其他问题,过去经典的机器学习算法效果不佳。

深度学习通常会受到攻击的一个领域是自然语言处理,其中包括语言翻译,自动摘要,共指解析,语篇分析,形态分割,命名实体识别,自然语言生成,自然语言理解,词性标记,情感分析和语音识别。

深度学习的另一个主要领域是图像分类,其中包括具有定位,对象检测,对象分割,图像样式转换,图像着色,图像重建,图像超分辨率和图像合成的图像分类。

此外,深度学习已成功用于预测分子将如何相互作用,以帮助制药公司设计新药,搜索亚原子颗粒并自动解析用于构建人脑三维地图的显微镜图像。

continual learning

持续学习:可塑性(学习新知识的能力)和稳定性(旧知识的记忆能力)

用已有的斧头解决问题

针对训练方法(是否使用dropout)和不同的激活函数(logistic sigmoid/ rectified linear/ LWTA/ Maxout)对灾难性遗忘问题的影响。

dropout:网络中有非常多的连接,每一次参数更新的时候,随机的对这些连接做mask,mask掉的权重参数置零,不参与网络更新。dropout强迫网络把每一层的模式相对均匀的记忆在各个,相当于增加了模型的鲁棒性神经元中,使用dropout训练的模型size远大于不加dropout的模型大小。

造新斧头解决问题

Regularization:在网络参数更新的时候增加限制,使得网络在学习新任务的时候不影响之前的知识。

Ensembling :当模型学习新任务的时候,增加新的模型(可以是显式或者隐式的方式),使得多个任务实质还是对应多个模型,最后把多个模型的预测进行整合。

Rehearsal:在模型学习新任务的同时混合原来任务的数据,让模型能够学习新任务的同时兼顾的考虑旧任务。

Dual-memory:设计了两个网络,一个是fast-memory(短时记忆),另一个slow-memory(长时记忆),新学习的知识存储在fast memory中,fast-memory不断的将记忆整合transfer到slow-memory中。

Sparse-coding: 灾难性遗忘是因为模型在学习新任务(参数更新)时,把对旧任务影响重大的参数修改了。如果我们在模型训练的时候,人为的让模型参数变得稀疏(把知识存在少数的神经元上),就可以减少新知识记录对旧知识产生干扰的可能性。

batch_size

  • 样本集小(<2000),直接使用batch梯度下降法,即btachsize=样本集大小。
  • 样本集较大,一般为64-512。以128为分界线,测试64、256的训练效果。

  • minbatch,选取为32或更小一些。选取为1,做纯SGD,磨低error。

数据预处理

归一化

from sklearn import preprocessing
import numpy as np
 
x = np.array([[3., -1., 2., 613.],
              [2., 0., 0., 232],
              [0., 1., -1., 113],
              [1., 2., -3., 489]])
# 归一化
# MinMaxScaler方法归一到[0,1],默认是对每一列做这样的归一化操作
min_max_scaler = preprocessing.MinMaxScaler()
x_minmax = min_max_scaler.fit_transform(x)
# MaxAbsScaler方法归一到[-1,1]
max_abs_scaler = preprocessing.MaxAbsScaler()
x_train_maxsbs = max_abs_scaler.fit_transform(x)

标准化

数据分析的过程中,比如线性规划这一类的分析,如果有些特征的数值远远高于或低于其他数值,通常称之为独立点、异常值或噪点,那么对于受噪点影响较大的模型就无法正确地去学习其他特征。

Standardization标准化:将特征数据的分布调整成标准正太分布,也叫高斯分布,过程为两步:去均值的中心化(均值变为0);方差的规模化(方差变为1)。

print("标准化之前的方差:", x.mean(axis=0))
print("标准化之前的标准差:", x.std(axis=0))
# 标准化
# scale方法,默认按照列进行标准化
x_scale = preprocessing.scale(x)
print("\n------------------\n标准化结果:\n", x_scale)
print("\n标准化之后的方差:", x_scale.mean(axis=0))
print("标准化之后的标准差:", x_scale.std(axis=0))

合并数据

堆叠合并

pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
          keys=None, levels=None, names=None, verify_integrity=False,copy=True)
# objs:表示需要合并的表的组合[d1, d2],接收多个Series, DataFrame, Panel 的组合,无默认;
# axis:默认为0,axis=0表示做列对齐,列名一致的话,将后表数据添加到前表的下几行;
#              axis=1表示做行对齐,行标签一致的话,将后表的数据添加到前表的后几列;
# join:默认为outer,接收‘inner’或‘outer’,表示取交集或并集;

# 纵向合并(concat或者append)
pd.concat([d1,d2], axis = 0, join='outer', sort=False)
d1.append(d2, sort=False) # append 方法对应的是 concat 函数中 axis = 0, join='outer' 的情况

主键合并

前后两个表按照一个或者多个键匹配的方式连接起来,一般是以某一或多列为键,匹配其他列,很类似 SQL 中的 join。

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, 
         right_index=False,sort=False,suffixes=('_x', '_y'), copy=True,
         indicator=False,validate=None)
# left, right:分别表示需要匹配的左表和右表,可接收的数据类型为 DataFrame;
# how:表示左右表的连接方式,默认为 inner ,可接收的取值为 left、right、inner、outer;
# on:表示左右表的连接主键,两个表的主键名称一致的时候才可以使用 on 参数,不一致时需使用left_on			right_on参数, on 参数默认为None,可接收的数据类型为 str 或 sequence
# left_on,right_on:分别表示左表和右表的连接主键,默认为None,可接收的数据类型为 str 或 sequence 
# sort:表示是否对合并后的数据进行排序,默认为False,可接收的数据类型为boolean 

# join 函数要求两个主键的名称必须相同
data1.join(data2, on=None,how='inner', lsuffix='', rsuffix='', sort=False)

重叠合并

同样一份数据存储在两张表中,将其中一个表的数据补充进另外一个表中,生成相对完整的数据。

data1.combine_first(data2)

模型调优

判断模型优劣:通过模型训练跑代码,我们可以分别从训练集和测试集上看到这个模型造成的损失大小(loss),还有它的精确率(accuracy)。

深度学习模型的调优主要包括定义函数、模型在训练集和测试集拟合效果、交叉验证、激活函数和优化算法的选择等。

  1. 分析数据集的特征,选择适合的函数以及优化器。
  2. 模型在训练集上的效果达到理想,模型优化方向:激活函数(activation function)、学习率(learning rate)。
  3. 模型在测试集上的拟合程度更为重要,模型优化方向:正则化(regularization)、丢弃参数(dropout)、提前停止训练(early stopping)。

定义模型函数

衡量方法通常用到真实f与预测f*的方差(variance)和偏差(bias),模型的偏差相当于与目标的偏离程度,而方差就是数据之间的分散程度。

最后对数据集的拟合程度可分为4种情况。如下:

bias/variance low high
low 模型过于复杂 (low,high)
high 模型过于简单 (high,low) ×函数完全与模型不匹配

小偏差,大方差(low,high):所谓模型过拟合,在训练数据上得到好的效果,而在测试集上效果并不满意。

优化方向:增加数据量、数据正则化处理。增加数据可以提高模型的鲁棒性,不被特殊数据影响整个模型的偏向;正则化是另一种方法,为了减小variance,但直接影响到bias,需要权衡。

大偏差,小方差(high,low):模型过于简单,在训练上没有得到好的效果。

优化方向:增加模型参数(特征),更好去拟合数据。

损失函数

损失函数用来评价模型的预测值真实值不一样的程度,损失函数越好,通常模型的性能越好。

tain loss & test loss

train loss 不断下降,test loss不断下降,说明网络仍在学习;(最好的) train loss 不断下降,test loss趋于不变,说明网络过拟合;(max pool或者正则化) train loss 趋于不变,test loss不断下降,说明数据集100%有问题;(检查dataset) train loss 趋于不变,test loss趋于不变,说明学习遇到瓶颈,需要减小学习率或批量数目;(减少学习率) train loss 不断上升,test loss不断上升,说明网络结构设计不当,训练超参数设置不当,数据集经过清洗等问题。(最不好的情况)

交叉验证(Cross-validation)

在训练一个模型时候,通常会将数据分为:训练集,测试集,开放集(小型训练集)。

十折交叉验证:每一轮训练取9份数据作为训练集,1份作为测试集。每一轮的1份训练集与测试集对换,10轮后实现了所有数据都作为样本训练,所得到的模型避免了过拟合与低拟合的问题。

优化算法

常用优化算法有:Gradient descent,Stochastic gradient descent,Adagrad,Adam,RMSprop。

激活函数(activation)

根据训练任务选择合适的激活函数,比如任务是二分类、多分类等。

常用的激活函数有:sigmoid、tanh、relu、softmax。

  功能特点
sigmoid 平滑函数,连续可导,适合二分类,存在梯度消失问题。
tanh 与sigmoid相同的缺点,存在梯度消失,梯度下降的速度变慢。一般用在二分问题输出层,不在隐藏层中使用。
relu ReLU在神经网络中使用最广泛的激活函数。根据图像x负半轴的特点,relu不会同时激活所有的神经元,如果输入值是负的,ReLU函数会转换为0,而神经元不被激活。这意味着,在一段时间内,只有少量的神经元被激活,神经网络的这种稀疏性使其变得高效且易于计算。
softmax 归一化指数函数。它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。softmax通常在分类器的输出层使用。

dropout

当模型在训练集上得到较好的效果,而在测试集效果并不乐观,此时使用dropout对训练时候的参数进行优化调整(减少训练时候的参数),在学习过程中通过将隐含层的部分权重或输出随机归零,降低节点间的相互依赖性,使得模型在测试集上得到较好的结果的一种方法。

解决深度神经网络的过拟合(overfitting)和梯度消失(gradient vanishing)问题。

early stopping

在训练时候观察模型在training-set和testing-set上的损失(loss),训练时候在训练集上可能不是最好的效果但在测试集上损失误差更小,所以需要提前停止保证了模型预测得到较好的结果。

Tricks

总则:data > model > feature engineering > ensemble

Bias

​ 在训练数据上面,我们可以进行交叉验证(Cross-Validation)。

​ K-fold Cross Validation(K 折交叉验证):初始采样分割成 K 个子样本,一个单独的子样本被保留作为验证模型的数据,其他 K-1 个样本用来训练。交叉验证重复 K 次,每个子样本验证一次,平均 K 次的结果或者使用其它结合方式,最终得到一个单一估测。

当 K 值大的时候, 我们会有更少的 Bias(偏差)、更多的 Variance(方差)。 当 K 值小的时候, 我们会有更多的 Bias(偏差)、更少的 Variance。

​ Bias和Variance是针对Generalization(一般化,泛化)来说的。

​ 在机器学习中,我们用训练数据集去训练(学习)一个model(模型),通常的做法是定义一个Loss function(误差函数),通过将这个Loss(或者叫error)的最小化过程,来提高模型的性能(performance)。然而我们学习一个模型的目的是为了解决实际的问题(或者说是训练数据集这个领域(field)中的一般化问题),单纯地将训练数据集的loss最小化,并不能保证在解决更一般的问题时模型仍然是最优,甚至不能保证模型是可用的。这个训练数据集的loss与一般化的数据集的loss之间的差异就叫做generalization error。

generalization error又细分为Bias和Variance两个部分。

Bias是 “用所有可能的训练数据集训练出的所有模型的输出的平均值” 与 “真实模型”的输出值之间的差异; Variance则是“不同的训练数据集训练出的模型”的输出值之间的差异。