机器学习笔记(一)基本概念

一、浅谈机器学习

1.1 机器学习简介

机器学习目的并不是为了得到最后的运算结果,而是对计算过程进行分析,总结出一套运算的规则。只要数据量足够多,运算规则就越准确。最后可以根据这套规则对没有通过验证的数据进行预算,得到预算后的值。只要使用的规则正确,预算的结果的正确率往往可以达到95%以上。 

1.1.1 机器学习的本质

基本思路无论使用什么样的算法和数据,机器学习的基本思路都可以归结为以下三个核心步骤。

图片

  • 问题抽象与数学建模:把现实生活中的问题抽象成数学模型,并且很清楚模型中不同参数的作用

  • 模型求解与学习:利用数学方法对这个数学模型进行求解,从而解决现实生活中的问题

  • 模型评估与反馈:评估这个数学模型,是否真正地解决了现实生活中的问题,以及解决的效果如何?

一、机器学习的本质

基本思路无论使用什么样的算法和数据,机器学习的基本思路都可以归结为以下三个核心步骤。

图片

  • 问题抽象与数学建模:把现实生活中的问题抽象成数学模型,并且很清楚模型中不同参数的作用

  • 模型求解与学习:利用数学方法对这个数学模型进行求解,从而解决现实生活中的问题

  • 模型评估与反馈:评估这个数学模型,是否真正地解决了现实生活中的问题,以及解决的效果如何?

1.1.2 机器学习的原理

机器学习的原理:机器学习是通过使用训练集数据,识别和提取特征,建立预测模型,并将所学规律应用于新数据进行预测或分类的过程。

图片

  • 训练集:提供标签化的数据,用于训练模型。例如,识字卡片帮助小朋友了解汉字与特征的关系。

  • 特征:数据中的可测量属性,用于区分不同类别。如“一条横线”帮助区分汉字“一”。

  • 建模:通过算法从数据中学习,构建预测模型。小朋友通过重复学习建立汉字认知模型。

  • 模型应用:学习到的规律用于新数据预测或分类。学会识字后,小朋友能识别并区分不同汉字。

机器学习的步骤收集数据、数据准备、选择模型、训练、评估、参数调整和预测。

图片

案例:机器学习通过酒精度和颜色来区分红酒和啤酒。

图片

  • 步骤1:收集数据

  • 任务:购买多种啤酒和红酒,并使用设备测量其颜色和酒精度。

  • 输出:创建一个包含颜色、酒精度和种类的数据表格。

  • 步骤2:数据准备

  • 任务:检查数据质量,可能需要进行数据清洗。

  • 数据划分:将数据分为训练集(60%)、验证集(20%)和测试集(20%)。

  • 步骤3:选择模型

  • 任务:根据问题的性质和数据特征选择一个合适的模型。

  • 示例:在本例中,由于只有两个特征(颜色和酒精度),可以选择一个简单的线性模型。

  • 步骤4:训练

  • 任务:使用训练集数据对模型进行训练。

  • 自动化:训练过程由机器自动完成,类似于解决数学问题。

  • 步骤5:评估

  • 任务:使用验证集和测试集评估模型的性能。

  • 评估指标:主要关注准确率、召回率和F值等指标。

  • 步骤6:参数调整

  • 任务:根据评估结果对模型参数进行调整,以优化性能。

  • 方法:通过人为地调整参数来改善模型表现。

  • 步骤7:预测

  • 任务:利用训练好的模型对新数据进行预测。

  • 应用场景:在本例中,可以输入新酒的颜色和酒精度,模型将预测其为啤酒或红酒。

1.2 深度学习简介

深度学习开始只是机器学习的一分支领域,它更强调从连续的层中进行学习,这种层级结构中的每一层代表不同程度的抽象,层级越高,抽象程度越大。这些层主要通过神经网络的模型学习得到的,最大的模型会有上百层之多。而最简单的神经网络分为输入层,中间层(中间层往往会包含多个隐藏层),输出层

经过多年的发展,深度学习的应用层面越来越广,从而诞生出 Tensorflow、Keras、Theano、CNTK 等框架的支持,逐渐发展形成独立的技术领域。根据不同的应用场景,深度学习又分为多层感知器MLP、深度神经网络DNN、卷积神经网络CNN、递归神经网络RNN、生成对抗网络BNN等多个方面。

1.3  机器学习分类

三、分类与算法

机器学习的分类:根据训练方法可以分为3大类,监督学习、非监督学习、强化学习。

从给定的训练数据集中学习出一个函数(模型参数),当新的数据到来时,可以根据这个函数预测结果。

监督学习(Supervised Learning):

  1. 标签信息: 监督学习使用带有标签的训练数据。这意味着每个训练样本都有一个相关联的标签,即对应的输出或目标值

  2. 任务类型: 监督学习用于解决分类回归等任务。在分类任务中,模型预测输入数据属于哪个类别;而在回归任务中,模型预测一个连续值。

  3. 学习过程: 模型通过学习输入与相应标签之间的关系来进行训练。算法通过最小化预测值与实际标签之间的差距来优化模型。

  4. 例子: 支持向量机(SVM)、决策树、神经网络等都是监督学习的例子。

无监督学习(Unsupervised Learning)

  1. 标签信息: 无监督学习使用没有标签的训练数据。训练样本不包含对应的输出或目标值。

  2. 任务类型: 无监督学习用于聚类、降维和关联规则挖掘等任务。在聚类任务中,算法试图将数据集中的样本分为不同的组;在降维任务中,算法试图减少数据的维度;在关联规则挖掘中,算法试图找到数据中的关联性。

  3. 学习过程: 模型在没有明确目标的情况下,自动发现数据中的结构和模式。它不需要事先知道正确的输出。

  4. 例子: K均值聚类、主成分分析(PCA)、Apriori算法等都是无监督学习的例子。

区别

  1. 数据标签: 监督学习使用带有标签的数据,而无监督学习使用没有标签的数据。

  2. 任务类型: 监督学习用于分类和回归等有标签任务,而无监督学习用于聚类、降维和关联规则挖掘等无标签任务。

  3. 学习过程: 监督学习侧重于模型预测与真实标签的关系,而无监督学习侧重于发现数据中的模式和结构,不依赖事先提供的输出信息。

2.1  监督学习

监督学习的训练集要求包括输入输出,也可以说是特征和目标。训练集中的目标是由人标注的。

从输入 / 输出中总结运算规律进行机械学习的算法叫做监督学习。在监督学习中,每个实例都是由一个输入对象(通常为矢量)和一个期望的输出值(也称为监督信号)组成。监督学习算法是分析该数据的输入对象与输出值 ,总结当中的运算规律并产生一个推断的逻辑,并可以把此逻辑用于映射出的新实例,对没有运算过的数据结果进行预测。
其过程就像读小学时候的数学应用题,课堂上老师会先讲解应用题的公式与计算方法,然后学生可以在做作业时根据此计算规律完成类似的题目。

常见的监督学习包含了线性回归、k近邻、朴素贝叶斯分类 、决策树、随机森林与梯度提升决策树、支持向量机等多种算法,在下面将用不同实例介绍其应用场景。

2.2  无监督学习

在非监督学习中,数据没有附带任何标签,学习过程中并不知道分类结果是否正确。

相比之下无监督学习只有输入数据,没有提供输出结果,只能通过计算评估其中的运行规律。

就好比在考试中遇到作业上没有做过的应用题,只能通过思考总结才能得出答案。它的最大挑战在于实例没有包含最终结果,所以无法在学习中评估算法是否学到了有用的东西。

常见的无监督学习分为聚类、降维两大类,包含了PCA(主成分分析)、NMF(非负矩阵分解)、t-SNE(流形学习)、k均值聚类、DBSCAN 等多种算法,

2.3 强化学习

  • 定义:智能体通过与环境互动,学习在不同状态下采取最佳行为以获得最大累积回报。

  • 示例:AlphaStar 通过强化学习训练,在星际争霸游戏中战胜职业选手。

  • 特点:模拟生物学习过程,有望实现更高智能,关注智能体的决策过程。

机器学习可分为监督学习与无监督学习两种

1.4 机器学习算法分类

传统机器学习算法主要包括以下五类: 

  • 回归:建立一个回归方程来预测目标值,用于连续型分布预测

  • 分类:给定大量带标签的数据,计算出未知标签样本的标签取值

  • 聚类:将不带标签的数据根据距离聚集成不同的簇,每一簇数据有共同的特征

  • 关联分析:计算出数据之间的频繁项集合

  • 降维:原高维空间中的数据点映射到低维度的空间中

二、基本概念

在机器学习里,每一行的数据实例被看作是一个样本,每一列的数据被看作是一个特征。学过面向对象开发的朋友应该好理解,这相当于一个类与其属性的关系。而监督学习是通过一系列样本计算,总结出特征与计算结果之间的关系,这被称为特征提取

2.1 分类与回归的区别

监督学习分成分类与回归两大类:分类与回归
分类的目标是预测类别标签,类似于通过人脸识别分出黄种人、白种人、黑种人。
回归的目标则是预测一个连续值,相当于数学里面的坐标图,它可以通过已有的数据计算出坐标的走向,从而对末知值进行预测。类似于气温预计,GDP增速预算。
其实区分分类与回归很简单,只要判断输出值是否具备连续性,具有连续性的就是回归,只有若干个固定值的就是分类。

2.2 数据划分

从监督学习的概念可以了解,其学习目标是要从已有的数据中总结出各个特征与结果之间的关系,然而这个计算模型的泛化能力如何,我们无法从已通过运算过的数据中得知。所以在运算前,一般会先对数据进行划分,一部分是训练数据,专门用作模型的学习,另一部分是测试数据,用作模型的测试其比例一般是75%对25%。
为了方便数据划分,sklearn 提供 train_test_split 函数方便日常使用,下一节将有介绍。

2.3  过拟合与欠拟合

对于训练数据最重要的目标是将其泛化,总结出每个特征的比重,因此并非正确率越高越好。

如果在训练过程中,得到的正确率是100%,然而在测试时候,正常率却很低,不能泛化到测试数据当中。这往往是因为训练过程中存在过似合,过度重视某些特征,而忽略某些关键因素。
相反,如果模型过分简单,考虑的因素太少,甚至导致在训练过程中的正确率就很低,这可能就是因为模型的欠拟合造成。

过拟合 :训练误差小,泛化误差大

欠拟合:训练误差大,泛化误差大

所以在选择模型的时候,需要在过拟合与欠拟合之间作出权衡(如图)。

2.4 损失函数

损失函数一方面跟数学计算原理的应用关系比较密切,另一个方面它也是机器学习的基层原理,
 

在日常对数据模型的测试中,预测值与真实值总会存在一定的偏差,以直线方程 y=a*x+b 为例,如下图。在预测值 [x1,y1]  [x2,y2]  [x3,y3]  ....... [x(i),y(i)] 中,并非每个点与方程匹配,而是存在一定的误差。所以在测试中,当误差值最小时,可以看作这条直线的正确答案。

损失函数就是用来评价模型的预测值和真实值不一样的程度,当损失值越小,证明预计值越接近真实值,模型的训练程度就越好。为了让预测值 y^ (i)  尽量接近于真实值 y(i) ,学者提出了多个方法进行计算损失值,最常见的损失函数有均方误差(MSE)、交叉熵误差(CEE)等。

均方误差(MSE)

均方误差(MSE)中,因为每个预测值与真实值大小不同,为了解决差值的正负值之分,所以误差大小就用差值平方来表示,差值越小,平方值小,误差越小。
均方误差计算公式就是求预测值与真实值之间的方差平均值,如果均方误差越小,那就证明预测值越接近于真实值。

交叉熵误差(CEE)

交叉熵误差(CEE)的公式如下,其中 t=(t_{1},t_{2},...,t_{n}) 为实际的分类结果,y={y_{1},y_{2},...,y_{n}}  为预测的结果

把它用于分类模型时有一个很好的特性,可以真实的反应出真实分类结果和预测结果的误差,假设 t_{i}=1, 即真实的分类结果是 t_i, 则 交叉熵误差可以简化为  E=-logy_{i},那函数图像如下。可以看到,y_{i} 越接近 1,即预测结果和真实分类结果越接近,误差越接近0, 即误差越小。

关于损失函数有多种算法,下面介绍两种最常用也是最容易理解的算法:最小二乘法(OLS)与梯度下降法(GD)

 2.4.1 最小二乘法

最小二乘法是基于 MSE 均方误差而来,它的目标就是求出 n 个 y^ (i) 与 y(i) 误差值平方和最小时各常量参数的值。还是以上面提到的直线方程 y=a*x+b 为例,均方误差越小,证明预测值越接近于真实值,这时候只要求出最小均方误差时 a,b的值,也就可以得出此直线的方程。因为 n 是个常数,所以求最小均方误差的公式可以转化为求预测值 y^ (i) 与真实值之 y(i) 间的最小方差,这就是最小二乘法的由来。

 代入  y=a*x+b  后,计算公式可得到转换成下图,由于计算的是平方和,所以表达式必然存在最小值,通过偏导数为 0 时得极值的原理,可得到计算公式:

此时好办,最小二乘法已经变成高考的导数题,要了解求解过程的程序猿建议去复习一下高考时偏导数求解的方法(若怕麻烦通过几条简单的语法计算也可得到最终结果)。根据以下得出的公式,代入已知的数据点  [x1,y1]  [x2,y2]  [x3,y3]  ....... [x(i),y(i)]  便可得到最后的 a、b 参数值,最后把 a、b 值代入直线方程就是最终的答案。

第四节介绍的线性回归模型中,有部分就是使用最小二乘法来实现的,敬请留意。
当然,现实情形下数据模型是复杂的,不可能完全按照直线模型来走,所以复杂的线性模型还可以通过多次方程式,基函数,线性分割等多种方法来处理,在后面章节将会详细讲述。

2.4.2 梯度下降法

上面提到损失函数就是用来评价模型的预测值和真实值不一样的程度,损失值越小证明参数的预测值越接近于真实值。

梯度下降法就是用于求损失值最小时的参数值,相对于最小二乘法复杂的数学公式,它可以通过偏导数斜率的变化更形象地描述解决的过程。

先介绍梯度下降法用到的基本概念:
切线斜率:从数学的角度可知,一维函数在点 x 的导数叫做函数在点 x 的切线斜率,二维函数在点(x0,x1) 的偏导数称为点(x0,x1) 的切线斜率,如此类推。
鞍点:函数的极小值(最小值)被称为鞍点,从数学原理可知当到达鞍点时,切线斜率接近于 0。
梯度:以常用的二元方程 f(x0,x1)=x02+x12  为例子,把全部变量的偏导数(切线斜率)汇总成的向量称为梯度

下面以一个二次方程 f(x)=x2+1 为例,介绍一下如何通过梯度下降法求极值
首先,切线的斜率可以通过导数原理求得,例如 f(x) 分别经过点 A(- 4,17) ,B(- 5,26),此时会发现,两点之间的距离越小,它们所组成的直线就越接近于该点的切线。两点距离无限接近于0时,此时可认为这条直线就是该点的切线,这也是微积分的基本原理。

下面的例子就是实现上述的原理,画出与点(- 4,17)  间 x 轴的距离分别为 0.3、0.2、0.001,0.0001 的直线。调用 tangent()可以返回该直线的斜率,当 h 使用默认值 0.0001 值,该直线斜率已经无限接近于导数值(即切线斜率)。

class gradient_drop():
    def __init__(self):
        return

    def f(self, x):
        return x*x+1

    def polt_line(self):
        # 画出 y=x*x+1 图
        x = np.linspace(-5, 5, 100)
        plt.plot(x.reshape(-1, 1), self.f(x))
        plt.xlabel('x')
        plt.ylabel('f(x)')

    def tangent(self, x, h=0.0001):
        # 根据 y=ax+b 直线公式
        # 求导数,即切线斜率
        a = (self.f(x+h)-self.f(x))/h
        # 求截距
        b = self.f(x+h)-a*x+h
        # 划出切线
        self.plot_tangent(a, b)
        return a

    def plot_tangent(self, a, b):
        # 划出直线 y=ax+b
        x = np.linspace(-5, -1, 100)
        y = a*x+b
        plt.plot(x.reshape(-1, 1), y, '--')

gradientdrop = gradient_drop()
gradientdrop.plot_line()
# 分别以 h 等于 -0.3,-0.2,-0.001, 0.0001求斜率
# 将发现 h 越小,所得斜率越接于近切线斜率
for h in [-0.3, -0.2, 0.001, 0.0001]:
    print('h={0}, tangent={1}'.format(h, gradientdrop.tangent(-4, h)))
plt.show()
#在这个字符串中,{0} 和 {1} 是占位符,分别表示要插入的第一个和第二个变量。
#format() 方法中的参数 h 和 gradientdrop.tangent(-4,h) 分别对应这两个占位符的位置。

运行结果

梯度下降法最终的目标是求得切线斜率接近无限于0时的数据点(鞍点), 所以函数可以使用最简单的方法,使取值沿着当前梯度方向不断前进,然后重复计算梯度。通过此递归方式,切线斜率就是无限接近于0。
用数学公式表达如下图,η 表示学习率,学习率可以根据实际需要而改变,将学习率乘以该点的切线斜率代表学习量。

根据此公式,可以在上面的代码中加入一个简单的方法gradient(),以 0.01 的学习率,重复1000次进行计算。随着梯度不断地下降,x 坐标就会根据学习量不断接近鞍点,在重复1000后可以看到在数据点(0,1)处的切线斜率 tangent 为 -1.0098588631990424e-08,已无限接近于 0 ,此时鞍点的函数值 f(x)=1 就是此函数的最小值。

class gradient_drop():
    def __init__(self):
        return

    def f(self, x):
        return x*x+1

    def plot_line(self):
        # 画出 y=x*x+1 图
        x = np.linspace(-5, 5, 100)
        plt.plot(x.reshape(-1, 1), self.f(x))
        plt.xlabel('x')
        plt.ylabel('f(x)')

    def tangent(self, x, h=0.0001):
        # 根据 y=ax+b 直线公式
        # 求导数(切线斜率)
        a = (self.f(x+h)-self.f(x))/h
        # 求截距
        b = self.f(x+h)-a*x+h
        # 随机画出切线
        n = np.random.randint(100)
        if n == 5:
            self.plot_tangent(a, b)
        return a

    def plot_tangent(self, a, b):
        # 划出切线 y=ax+b
        x = np.linspace(-5, 1, 100)
        y = a*x+b
        plt.plot(x.reshape(-1, 1), y, '--')

    def gradient(self, x, rate=0.01, n=1000):
        # 学习率默认为0.01,默认重复1000次
        for i in range(n):
            x -= self.tangent(x) * rate
            print('x={0}, f(x)={1}, tangent slope={2}'.format(x, self.f(x), self.tangent(x)))

gradientdrop = gradient_drop()
gradientdrop.plot_line()
# 使用学习率默认0.01,默认重复1000次求出鞍点
gradientdrop.gradient(-3)
plt.show()
运行结果

到此不防思考一下使用梯度下降法找到鞍点的目标是什么,其实只要把简单的二次方程 f(x) 替换成为损失函数便会豁然开朗。以均方误差 MSE 为例,当找到鞍点,意味着找到函数最小值,即在该点时均方误差最小,在这点得到的参数值就是该函数的常量。
同样以最小二乘法中的直线 y=a*x+b 为例,把代码稍微修改一下。首先把方程改为均方误差公式,通过 sympy 包中的函数 diff 分别对 a,b 求偏导数,把学习率设置为0.01,训练1000次,a,b的默认初始值均为 1。使用 sklearn 中的测试数据 make_regression 进行训练,最后画出该直线并输出斜率和截距。

梯度下降法的步骤如下:

  1. 初始化参数:选择初始参数值。目标函数是 损失函数

  2. 计算梯度:计算目标函数相对于参数的梯度(导数),即确定当前参数值的下降方向。

  3. 更新参数:根据梯度和学习率的乘积,更新参数值,以便沿着梯度的反方向移动一小步。学习率决定了每次更新的步长大小。参数新​=参数旧​−学习率×偏导数

  4. 重复步骤2和3,直到满足停止条件,例如达到最大迭代次数或参数变化小于某个阈值。

class gradient_drop():
    def __init__(self, train_x, train_y):
        # 定义测试数据
        self.x = train_x
        self.y = train_y
        return

    def mes(self, a, b):
        # 均方误差计算公式
        return mean((self.y-a*self.x-b)**2)

    def partial_derivative(self, a, b):
        # 求 mes(a,b)对 a,b 的偏导数
        partial_derivative_a = sp.diff(self.mes(a, b), a)
        partial_derivative_b = sp.diff(self.mes(a, b), b)
        return [partial_derivative_a, partial_derivative_b]

    def gradient(self, rate=0.01, n=1000):
        # 学习率默认为0.01,默认重复1000次
        # 把 y=a*x+b 参数 a,b 的初始值设为 1,1
        a1 = 1
        b1 = 1
        # 默认训练1000次,找到最小均方误差时的 a,b 值
        for i in range(n):
            deri = self.partial_derivative(a1, b1)
            a1 -= deri[0].subs({a: a1, b: b1}) * rate
            b1 -= deri[1].subs({a: a1, b: b1}) * rate
        # 输出直线参数 a,b 值
        print('y=a*x+b\n  a={0},b={1}'.format(a1, b1))
        return [a1, b1]

    def plot_line(self, param):
        # 根据a,b参数值划出直线 y=a*x+b
        x = np.linspace(-3, 3, 100)
        y = param[0]*x + param[1]
        plt.plot(x, y, 'r')
        plt.legend(['train data', 'line'])

# 输入测试数据
X, y = dataset.make_regression(n_features=1, noise=5)
gradient_drop = gradient_drop(np.squeeze(X), y)
# 画出数据点
plt.plot(X, y, '.')
# 训练数据找出最小均方误差时的参数 a,b 值
param = gradient_drop.gradient()
# 画出训练后的直线
gradient_drop.plot_line(param)
plt.show()

运行结果

可见计算后的直线与训练库中的点已相当接近,使用梯度下降法只需要牢记一点:计算目标是求出鞍点,在损失值最低时的参数值就是该函数的常量。下面介绍到的 SGD 模型正是使用梯度下降法进行计算,后面将有详细说明。
对损失函数就介绍到这里,希望对各位的理解有所帮助。

三、常用方法介绍

Scikit-Learn 是目录最常用的机器学习库,所以在本文当中大部实例都是运用当中的方法完成。
在 sklearn.datasets 中包含了大量的数据集,可为运算提供测试案例。例如鸢尾花数据集 load_iris()、癌症数据集 load_breast_cancer()、波士顿放假数据集 load_boston() 这些都是各大技术文章里常用的数据集,为了方便阅读下面大部分的例子中都会用到这些数据作为例子进行解说。

3.1  train_test_split 方法

train_test_split 方法是用于将数据集划分为训练集和测试集的函数。

这个方法通常在机器学习库(如Scikit-learn)中提供,其功能是将数据集按照指定的比例或数量划分为训练集和测试集。

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

 train_test_split( * arrays,  test_size=None,  train_size=None, random_state=None, shuffle=True,stratify=None)

  • arrays要划分的数据集,可以是列表、NumPy数组、SciPy稀疏矩阵或Pandas的数据框。

  • test_size测试集的大小。可以是浮点数、整数或None,默认为None。

        ①若为浮点时,表示测试集占总样本的百分比

        ②若为整数时,表示测试样本样本数

        ③若为None时,test size自动设置成0.25

  • train_size训练集的大小。可以是浮点数、整数或None,默认为None。含义与 test_size 类似。

  • random_state随机种子,用于控制数据的随机划分。可以是整数、RandomState实例或None,默认为None。

        ①若为None时,每次生成的数据都是随机,可能不一样

        ②若为整数时,每次生成的数据都相同 (,如果你需要多次运行同样的实验,或者                 在不同的环境中重复实验,你会得到相同的训练集和测试集划分,从而可以确保实验                 结果的可重现性。)

  • stratify用于处理不均衡数据集,可以是类似数组或None。

        ①若为None时,划分出来的测试集或训练集中,其类标签的比例也是随机的

        ②若不为None时,划分出来的测试集或训练集中,其类标签的比例同输入的数组中                   类标签的比例相同,用于处理不均衡数据集

    在一个垃圾邮件分类器的任务中,我们的目标是根据邮件的内容将其分类为"垃圾邮件"或"非垃圾邮件"。在这种情况下,"垃圾邮件"和"非垃圾邮件"就是类别标签。在 train_test_split 方法中,stratify 参数的作用是保持划分后训练集和测试集中类标签的分布与原始数据集中的类标签分布相同。

from sklearn.datasets import make_wave
from sklearn.model_selection import train_test_split

# 将1000个数据集按照默认比例划分为训练集和测试集
X, y = make_wave(n_samples=1000)
X_train, X_test, y_train, y_test = train_test_split(X, y)

# train_size 和 test_size 默认值为 75% 和 25%
# 所以上面的例子与下面的例子得到的结果相同
X, y = make_wave(n_samples=1000)
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.75, test_size=0.25)

# 为了每次测试得到相同的数据集,可以将 RandomState 设置为相同的值
# 只要 RandomState 相同,则产生的数据集相同
# 因为 RandomState 默认为空,因此在不填写的情况下,每次产生的数据集都是随机数据
X, y = make_wave(n_samples=1000)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

3.2 predict 方法与 accuracy_score 方法

在分类模型中,通常使用 predict(selt, X:any)方法预测新数据的标签,通常在完成训练后,就是通过此方法输入测试数据,把计算结果与测试结果进行对比。
accuracy_score 主要用于对比预测结果的准备率
下面的代码就是最简单的流程,先划分训练数据与测试数据,然后选择模型,输入训练数据进行泛化,输入测试数据求出计算结果,最后把计算结果与已有的测试结果进行对比,查看其正确率。

复制代码

 1     X,y=make_blobs(n_samples=150,n_features=2)
 2     #划分训练数据与测试数据
 3     X_train,X_test,y_train,y_test=train_test_split(X,y)
 4     #绑定模型
 5     knn_classifier=KNeighborsClassifier(n_neighbors=7)
 6     #输入训练数据
 7     knn_classifier.fit(X_train,y_train)
 8     #运行测试数据
 9     y_model=knn_classifier.predict(X_test)
10     #把运行结果与测试结果进行对比
11     print(accuracy_score(y_test,y_model))        

复制代码

3.3 score 方法

在回归模型当中,由于测试结果并非固定值,所以一般通过使用 score(self, X, y, sample_weight=None) 方法,通过对 R^2(判定系数)来衡量与目标均值的对比结果。
R^2=1,则表示模型与数据完成吻合,如果R^2为负值,侧表示模型性能非常差。

1     X,y=make_wave(1000)
2     X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0)
3     linearReg=LinearRegression()
4     linearReg.fit(X_train,y_train)
5     print(linearReg.score(X_train,y_train))

 3.4 numpy.meshgrid 方法

生成网格点矩阵坐标,往往用于对平面内数据的预测值进行评估。生成一定范围内的网格数据,再把数据代入公式内进行计算,得到预测结果。

1 x=np.array([1,2,3])
2 y=np.array([4,5])
3 #显示网格矩阵坐标
4 X,Y=np.meshgrid(x,y)
5 print('X:\n '+str(X))
6 print('Y:\n '+str(Y))

运行结果

3.5 contour 和 contourf 方法

pyplot 的 contour 和 contourf 方法都是画三维等高线图的,不同点在于contour 是绘制轮廓线,contourf 会填充轮廓。本文在分类模型中,将会大量地使用此方法,让各位可以更直观的看到模型预测值的分布。
pyplot.contour (X,Y,Z,levels , linestyles,alpha,cmap )

X、Y :  必须是 2-D,且形状与 Z 相同。
Z:绘制轮廓的高度值。
levels:int 数组,可选填,确定需要显示的轮廓线区域的数量和位置。例如: levels = [-2,-1,0,1,2] 表示显示从-2级到2级的线区轮廓。
linestyles:数组,可选填,确定线条形状,例如:linestyles = [ '--' , '-' , '=' ] 。
alpha: 透明度
cmap:颜色

复制代码

1 def f(x,y):
2     return 3*x**2+x+y**+1
3 
4 x=np.linspace(-3,3,100)
5 y=np.linspace(-3,15,100)
6 X,Y=np.meshgrid(x,y)
7 plt.contourf(X,Y,f(X,Y))
8 plt.show()

复制代码

运行结果

3.6 decision_function 方法

在分类模型中,通常使用 decision_function(self, X) 方法计算预测新数据的距离值。
与 predict 方法不同的是:predict 得到的标签值, decision_function 得到的是与分隔超平面的距离值。

复制代码

 1     # 训练数据
 2     X,y=dataset.make_blobs(centers=2,random_state=2,n_features=2)
 3     # 使用 LinearSVC 模型,设置 C=100
 4     linear=LinearSVC(C=100)
 5     linear.fit(X,y)
 6     # 画出数据点
 7     plt.scatter(X[:,0],X[:,1],c=y,marker='^',s=50)
 8     # 建立网格数据
 9     xx=np.linspace(-5,6,2)
10     yy=np.linspace(-13,3,2)
11     XX,YY=np.meshgrid(xx,yy)
12     ZZ=np.c_[XX.ravel(),YY.ravel()]
13     # 根据网络数据推算出预测值
14     zz=linear.decision_function(ZZ)
15     aa=linear.predict(ZZ)
16     print('predict: '+str(aa))
17     print('decision_function:'+str(zz))

复制代码

运行结果

predict 得到的最终的分类结果:0或1,而 decision_function 得到的是与分隔平面的距离,正值代表分类是 1,负值代表分类为 0,值越大代表与分隔面的距离越大。

3.7 confusion_matrix 混淆矩阵

在数据分析的过程中,往往需要观察各分类数据的占比,准确数,错误数等相关信息,为此 sklearn 特意预备了混沌矩阵 confusion_matrix 函数帮助分析数据,完成分析后用 Seaborn 把图画出来。
下面的例子就可以通过混淆矩阵把测试中的 0,1,2,3 ..... 9 的数字分布数量很明确显示出来。

复制代码

 1     (X_train, y_train), (X_test, y_test) = keras.datasets.mnist.load_data()
 2     # 把28*28图像数据进行转换
 3     X_train = X_train.reshape(-1, 784)
 4     X_test = X_test.reshape(-1, 784)
 5     # 使用SGDClassfier模式,使用多核计算,学习率为0.01
 6     sgd_classifier = SGDClassifier(learning_rate='constant', early_stopping=True,
 7                                    eta0=0.001, loss='squared_hinge',
 8                                    n_jobs=-1, max_iter=10000)
 9     sgd_classifier.fit(X_train, y_train)
10     y_model=sgd_classifier.predict(X_test)
11     #建立混淆矩阵
12     mat=confusion_matrix(y_test,y_model)
13     #显示分类数据的测试分布
14     heatmap(mat,square=True,annot=True,fmt='d')
15     plt.show()

复制代码

运行结果

3.8 validation_curve 验证曲线

上一节曾经讲过,要提高模型的质量,应该在过拟合跟欠拟合当中,选择一个平衡点。
有见及此,为了更直观地了解模型的质量,sklearn 特意准备了 validation_curve 方法 ,可以更直观与观察到验证曲线的示意图。

validation_curve(estimator, X, y, *, param_name, param_range, groups=None, 
     cv=None, scoring=None, n_jobs=None, pre_dispatch="all",
     verbose=0, error_score=np.nan, fit_params=None)

  • estimator:实现了fit 和 predict 方法的对象
  • X : 训练的向量
  • y : 目标相对于X分类或回归
  • param_name:将被改变的变量名称
  • param_range:param_name对应的变量的取值
  • cv:如果传入整数,测试数据将分成对应的分数,其中一份作为cv集,其余n-1作为traning(默认为3份)

只需要简单地绑定模型,输入数据,便可得到模型的准确率变化曲线

复制代码

 1     # validation_curve 绑定 SVC
 2     X, y = load_digits(return_X_y=True)
 3     param_range = np.logspace(-6, -1, 5)
 4     train_scores, test_scores = validation_curve(
 5         SVC(), X, y, param_name="gamma", param_range=param_range,
 6         scoring="accuracy", n_jobs=1)
 7     #训练数据与测试数据的平均得分
 8     train_scores_mean = np.mean(train_scores, axis=1)
 9     test_scores_mean = np.mean(test_scores, axis=1)
10     #显示数据
11     plt.title("Validation Curve with SVM")
12     plt.xlabel(r"$\gamma$")
13     plt.ylabel("Score")
14     plt.ylim(0.0, 1.1)
15     lw = 2
16     plt.semilogx(param_range, train_scores_mean, label="Training score",
17                  color="darkorange", lw=lw)
18     plt.semilogx(param_range, test_scores_mean, label="Cross-validation score",
19                  color="navy", lw=lw)
20     plt.legend(loc="best")
21     plt.show()

复制代码

运行结果

下面的章节开始介绍  sklearn 中监督学习的一些常用模型,可能模型的使用方法基本一致,看起来似乎千篇一律。实则不然,因为机器学习与一般的开发不一样,主要是了解不同模型的运算规则和适用场景。从原理中理解实质,希望读者能够明白。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/572101.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux编译和NXP官方系统移植

文章目录 一、Linux安装环境配置二、Linux编译流程三、单个.dtb文件编译方法1.修改顶层makefile2.编译设备树文件3.验证 四、NXP官方Linux系统移植1.将NXP官方Linux系统导入到Ubuntu系统中2.解压系统3.编译系统4.验证5.在NXP官方系统中添加自己的板子 五、 CPU 主频和网络驱动修…

数据赋能(67)——概念:数据变现

数据变现是指通过某种方式将数据转化为实际的收益或绩效。数据变现的方式多种多样,可以根据不同的应用场景和业务需求进行选择和组合。 数据变现的主要方式如下: 数据销售与租赁 组织直接出售原始数据或经过处理、整合后的数据给需要的组织或个人。组织…

视频高效批量剪辑视频,支持批量给视频进行添加新封面,让视频制作效率飙升

在当下这个视频内容爆炸的时代,无论是企业宣传、产品推广还是个人创作,高质量、高效率的视频制作都显得尤为重要。但是,传统的视频剪辑方式往往耗时耗力,效率低下,让人头疼不已。如何快速、高效地制作、编辑和推广&…

ETL工具-nifi干货系列 第十七讲 nifi Input PortOut Port 实战教程

1、端口(Port),包含输入端口(Input Port)和输出端口(Out Port ) 使用一个或多个处理组构建的数据流需要一种方式将处理组连接到其他数据流组件。 处理组和处理组之间可以通过使用端口来进行连…

OpenCV实现霍夫变换

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV 如何实现边缘检测器 下一篇 :OpenCV 实现霍夫圆变换 目标 在本教程中,您将学习如何: 使用 OpenCV 函数 HoughLines()和 HoughLinesP()检测图像中的线条。…

YASKAWA安川机器人DX100轴板维修故障细节分享

随着科技的日新月异,机器人在工业生产中扮演的角色愈发重要。而作为机器人的“大脑”——电路板,其稳定运作对整个系统的可靠性至关重要。面对可能出现的YASKAWA安川机器人DX100轴板故障,如何快速、准确地诊断问题并予以解决呢?下…

数据结构之常见排序算法

目录 一、排序中的概念 二、常见排序算法--升序 1、插入排序 (1)直接插入排序 (2)希尔排序 2、选择排序 (1)单指针选择排序 (2)双指针选择排序 (3)堆…

日志集中审计系列(5)--- LogAuditor接收USG设备日志

日志集中审计系列(5)--- LogAuditor接收USG设备日志 前言拓扑图设备选型组网需求配置思路操作步骤结果验证前言 近期有读者留言:“因华为数通模拟器仅能支持USG6000V的防火墙,无法支持别的安全产品,导致很多网络安全的方案和产品功能无法模拟练习,是否有真机操作的实验或…

文旅强势复苏 苏州金龙新V系客车助力湖北“文旅升级”

2024年4月24日,苏州金龙携多款新V系客车登陆素有九省通衢之称的湖北武汉,在当地文旅行业,刮起一场客运品质升级之风。作为“五一”出行热门城市、自然人文资源丰富的旅游大省,武汉乃至湖北旅游市场堪称客运产品的试金石&#xff0…

赵磊老师:共同的利益和文化理念契合才是两项留人的重要法宝

优秀人才对企业的发展与影响毋庸置疑,优秀人才的流失往往直接带来业绩的损失,甚至导致企业从此一蹶不振,当然一个组织也需要大量的执行者,通过执行者的辛劳工作,使其为客户创造价值的想法变成产品,变成产生…

shellshock题解思路分享

shellshock 考查bash远程任意代码执行漏洞。 可以看到含有bash文件,使用以下命令测试bash是否受shellshock影响 env x() { :;}; echo test ./bash -c:test受影响,执行bash远程任意代码执行漏洞 env x() { :;}; /bin/cat flag ./shellshock具体可以看…

海南封关怎么看?win战略会任志雄解析

今年海南自由贸易港建设也进入了新阶段:将在2025年年底前适时启动全岛封关运作,封关后的海南将以全新姿态迎接更广泛的发展机遇。 封关在即,企业有何感受?还有哪些准备工作?封关后的海南将呈现怎样的状态?近日,红星资本局记者深入实地了解海南自贸港如何成型起势。 利好当…

劳保工具佩戴监测识别摄像机

随着工业生产技术的不断进步和劳动保护意识的提高,劳保工具的佩戴已成为维护工人安全健康的重要环节。为了更好地监测和识别工人是否正确佩戴劳保工具,以及工作场所是否存在安全隐患,智能劳保工具佩戴监测识别摄像机应运而生。这种摄像机结合…

嵌入式Linux driver开发实操(十八):Linux音频ALSA开发

应用程序程序员应该使用库API,而不是内核API。alsa库提供了内核API 100%的功能,但增加了可用性方面的主要改进,使应用程序代码更简单、更美观。未来的修复程序或兼容性代码可能会放在库代码中,而不是放在内核驱动程序中。 使用ALSA API和libasound进行简单的声音播放: /*…

遥控车模的电机控制器

一、项目简介 基于CH32V103单片机结合RTT开发一套无刷电机无感矢量控制器,使用无感矢量控制无刷电机具有噪音小、控制线性度好、电机效率高等优点。使用三相全桥电路将直流电转换为交流电驱动无刷电机,利用串联电阻和差分采样电路采集UV两相的电流信号。…

智慧码头港口:施工作业安全生产AI视频监管与风险预警平台方案

一、建设思路 随着全球贸易的快速发展,港口作为连接海洋与内陆的关键节点,其运营效率和安全性越来越受到人们的关注。为了提升港口的运营效率和安全性,智慧港口视频智能监控系统的建设显得尤为重要。 1)系统架构设计 系统应该采…

[计算机效率] 网站推荐:其它类(找台词、表格转换)

4.9 其它 4.9.1 找台词 找台词网(http://www.zhaotaici.cn/)是一个专为电影电视剧爱好者打造的台词搜索引擎网站。它的核心功能是帮助用户快速查找特定电影或电视剧中的台词,并提供详细的上下文信息。 在使用找台词网时,用户只需…

docker的默认路径存储不足

docker的默认路径存储不足 添加磁盘 [rootlocalhost ~]# fdisk -l磁盘 /dev/sda:42.9 GB, 42949672960 字节,83886080 个扇区 Units 扇区 of 1 * 512 512 bytes 扇区大小(逻辑/物理):512 字节 / 512 字节 I/O 大小(最小/最佳)&#xff1a…

一网打尽 Rust 语法

❝ 悲观者永远正确,而乐观者永远前行 ❞ 大家好,我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder 前言 在之前的Rust学习专栏中,由于受制与文章的脉络,我们只能从概念到使用场景进行事无巨细的解释。相当…

伪分布Hadoop下安装Hive

一、下载并安装Mysql (1)下载mysql安装包(mysql-8.0.26-1.el7.x86_64.rpm-bundle.tar) 下载官网:MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/ &…