草庐IT

[AI-ML]机器学习是什么?一起了解!(一)

SillyNorth 2023-03-28 原文

机器学习


简单的说,机器学习是一种让计算机系统从数据中学习并自动改进的算法。通俗地说,机器学习就是让计算机从数据中“学习”,并使用这些学习成果来做出决策或预测。

学术解释中,机器学习被定义为一种通过算法让计算机自动学习数据模型和模式,从而实现特定任务的技术。机器学习的主要目标是让计算机在未经过明确编程的情况下自动获取数据模型,从而能够识别、分类和预测未知的数据。

机器学习可以分为监督学习、无监督学习、半监督学习和强化学习等几种主要类型。

监督学习:

  • 线性回归(Linear Regression)
  • 逻辑回归(Logistic Regression)
  • 支持向量机(Support Vector Machine,SVM)
  • 决策树(Decision Tree)
  • 随机森林(Random Forest)
  • 梯度提升树(Gradient Boosting Tree)
  • 神经网络(Neural Networks)
  • 卷积神经网络(Convolutional Neural Networks,CNN)
  • 递归神经网络(Recurrent Neural Networks,RNN)
  • 长短时记忆网络(Long Short-Term Memory,LSTM)

无监督学习:

  • K均值聚类(K-means Clustering)
  • 层次聚类(Hierarchical Clustering)
  • 期望最大化算法(Expectation-Maximization,EM)
  • 主成分分析(Principal Component Analysis,PCA)
  • 自编码器(Autoencoder)
  • 受限玻尔兹曼机(Restricted Boltzmann Machine,RBM)

半监督学习:

  • 半监督分类(Semi-supervised Classification)
  • 标签传播(Label Propagation)
  • 生成式半监督学习(Generative Semi-supervised Learning)

线性回归(Linear Regression)

线性回归是一种广泛使用的机器学习算法,用于建立输入变量和输出变量之间线性关系的模型。它是一种有监督学习算法,常用于解决回归问题。

在线性回归中,我们尝试通过一个线性方程来描述输入变量与输出变量之间的关系,这个方程被称为线性回归模型。线性回归模型通常用最小二乘法来计算最佳拟合直线,即通过所有训练数据点的一条直线,使得这条直线到所有数据点的距离平方和最小化。在实际应用中,可以使用梯度下降等优化算法来训练模型。

线性回归可以用于多种任务,例如预测股票价格、房价、销售额等连续的数值型数据。除了标准的线性回归模型,还有一些变种,例如多元线性回归、逻辑回归等。
多元线性回归(Multiple Linear Regression)是线性回归的一个扩展,用于建立多个输入变量和输出变量之间线性关系的模型。在多元线性回归中,我们使用多个输入变量来预测一个输出变量。

多元线性回归(Multiple Linear Regression)

多元线性回归是线性回归的一个扩展,用于建立多个输入变量和输出变量之间线性关系的模型。在多元线性回归中,我们使用多个输入变量来预测一个输出变量。

多元线性回归的模型可以表示为:
y = β0 + β1x1 + β2x2 + ... + βnxn + ε
其中 y 是输出变量,x1, x2, ..., xn 是输入变量,β0, β1, β2, ..., βn 是模型的系数,ε 是误差项。

多元线性回归是一种常见的机器学习算法,它是线性回归的一种扩展形式。与简单线性回归只涉及一个自变量不同,多元线性回归可以处理多个自变量的情况。

在多元线性回归中,我们假设输入变量 x1, x2, ..., xn 与输出变量 y 之间存在线性关系。然后,通过给定的样本数据,使用最小二乘法或者其他优化算法来求解出系数 β0, β1, β2, ..., βn 的值,使得模型的预测值尽可能接近真实值。

需要注意的是,多元线性回归的一个前提假设是各个输入变量之间是独立的。如果输入变量之间存在高度相关的情况,那么模型的预测效果可能会变得不稳定。此外,还需要注意过拟合和欠拟合问题,避免模型在训练集和测试集上的表现出现过大的差异。

多元线性回归在实际应用中非常广泛,比如预测房价、销售额、股票价格等等。

逻辑回归(Logistic Regression)


逻辑回归是一种用于解决分类问题的机器学习算法。它基于线性回归模型,但是将输出变量限制在0和1之间,用于表示两个分类标签。逻辑回归常用于二分类问题,例如判断邮件是否是垃圾邮件、判断用户是否会购买某种产品等。

逻辑回归(Logistic Regression)是一种用于建立分类模型的机器学习算法。它将一组输入变量 x1, x2, ..., xn 映射到一个介于 0 和 1 之间的输出变量 y。逻辑回归模型可以表示为以下公式:

y = 1 / (1 + e-(b0 + b1*x1 + b2*x2 + ... + bn*xn))

其中,b0、b1、b2、...、bn 是模型的系数,e 是自然对数的底数。这个公式将线性回归的结果通过逻辑函数映射到了 0 和 1 之间,表示为概率值,可以用于分类问题。如果 y 大于 0.5,则将其分类为 1,否则分类为 0。

逻辑回归的训练过程通常采用最大似然估计方法。给定一个训练集,我们希望找到一组系数 b0、b1、b2、...、bn,使得模型对于训练集的预测值 y 与实际值 t 的差别最小。具体地,我们定义一个损失函数(loss function):

L(b0, b1, b2, ..., bn) = -1/N * sum(t * log(y) + (1-t) * log(1-y))

其中,N 是训练集中样本的数量,t 是实际的标签值(0 或 1),y 是模型对该样本的预测值。该损失函数称为交叉熵(cross-entropy)损失函数,它刻画了模型预测值与实际标签值之间的差异。我们的目标是找到一组系数 b0、b1、b2、...、bn,使得损失函数最小。这可以通过梯度下降(gradient descent)算法来实现。梯度下降算法是一种迭代算法,每次迭代通过计算损失函数对系数的偏导数来更新系数的值,直到达到收敛条件。

当我们使用逻辑回归进行分类时,我们假设输出变量Y服从伯努利分布,其参数p与输入变量x有关,我们需要估计p值。因为p的取值是0到1之间的实数,所以我们需要一个函数f(x) 将输入x映射到0到1之间的实数。这个函数就是逻辑函数(logistic function),也叫sigmoid函数,可以表示为:
sigmoid 函数的定义为:

sigmoid(z) = 1 / (1 + e-z)

其中,z 表示输入变量的线性组合,即:

z = β0 + β1x1 + β2x2 + ... + βnxn

y 表示输出变量的概率值,β0, β1, β2, ..., βn 表示模型的系数,x1, x2, ..., xn 表示输入变量,ε 表示误差项。

支持向量机(Support Vector Machine,SVM)

支持向量机是一种二分类模型,其基本模型定义在特征空间上的间隔最大的线性分类器,通过非线性变换,支持向量机可以学习非线性模型。支持向量机最早是针对线性可分情形提出的,通过软间隔最大化可以推广到线性不可分情形。

在支持向量机中,将特征空间上的点看作是定义在这个空间上的向量,将分类问题转化为在特征空间中寻找最优的分离超平面(最大间隔超平面)。最大间隔超平面是指,能够将特征空间中不同类别的样本分隔开,并且两侧的样本到超平面的距离(即间隔)最大。

对于线性可分情形,最大间隔超平面是唯一的,支持向量机通过学习最大间隔超平面得到一个分类模型。而对于线性不可分情形,需要通过引入“软间隔”(即允许部分样本分类错误)或者通过映射到高维特征空间进行非线性分类,来解决这个问题。

支持向量机的优点是可以处理高维度数据,对于训练数据量不大的情况下也有很好的表现。其缺点是对于大规模的数据集训练较慢,且对于噪声较多的数据集可能会出现过拟合的情况。

随机森林(Random Forest)

随机森林(Random Forest)是一种集成学习(Ensemble Learning)方法,它基于决策树(Decision Tree)构建。随机森林通过在数据集上随机抽取特征和样本来构建多个决策树,然后对这些决策树进行投票或取平均值来得出最终的预测结果。

随机森林的主要优点包括:

随机抽样使得随机森林对于异常值和噪声具有很好的鲁棒性;
可以处理高维数据,并且不需要进行特征选择;
在训练过程中,随机森林可以评估特征的重要性程度。
随机森林的缺点包括:

随机森林对于高度相关的特征可能会产生偏差;
随机森林的训练时间比较长,特别是对于大规模数据集来说。
随机森林的核心思想是:通过组合多个决策树,来降低单个决策树的过拟合和泛化能力不足的问题。在构建随机森林的过程中,通常会随机抽取特征和样本,以增加决策树之间的差异性。当进行预测时,随机森林会将所有决策树的预测结果进行综合,以得出最终的预测结果。

随机森林的训练过程通常包括以下步骤:

从训练集中随机抽取 m 个样本和 \(n\) 个特征,其中 \(m\) 是样本数量,\(n\) 是特征数量;
使用这 \(m\) 个样本和 \(n\) 个特征来训练一个决策树;
重复步骤 1 和 2,构建 \(k\) 个决策树;
对于回归问题,将 \(k\) 个决策树的预测结果取平均值,对于分类问题,将 \(k\) 个决策树的预测结果进行投票,以得出最终的预测结果。
随机森林中的一个重要参数是决策树的数量 \(k\),通常需要通过交叉验证等方法来选择最优的 \(k\)。此外,随机森林还可以通过评估特征的重要性程度来进行特征选择。

当建立随机森林模型时,通常需要确定一些参数。以下是几个重要的参数:

n_estimators: 随机森林中决策树的数量。
max_depth: 决策树的最大深度。如果设为None,则决策树会一直生长,直到叶子节点中只剩下少于min_samples_split个样本点。
min_samples_split: 内部节点(非叶子节点)进行划分所需的最小样本数。
min_samples_leaf: 叶子节点中需要至少包含的样本数。
max_features: 每个决策树在拆分节点时考虑的最大特征数。
bootstrap: 布尔值,表示是否在建立每个决策树时使用随机有放回抽样。
以上参数中,n_estimators和max_features对于随机森林的性能影响最大。一般情况下,增加n_estimators可以提高模型的准确度,但同时也增加了计算复杂度和内存消耗;max_features的增加可以增加随机性,避免过拟合,但是在特征数量非常多的情况下,选择适当的max_features可能会提高性能。

除了上述参数外,随机森林还可以通过OOB(out-of-bag)误差评估模型的性能,以及通过特征重要性(feature importance)选择重要的特征。
以下是一个简单的随机森林的Python样例:

# 导入需要的库
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

# 读取数据
data = pd.read_csv('data.csv')

# 将数据集分为训练集和测试集
train_data, test_data, train_label, test_label = train_test_split(data.iloc[:, :-1], data.iloc[:, -1], test_size=0.2, random_state=42)

# 创建随机森林模型
rf = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)

# 训练模型
rf.fit(train_data, train_label)

# 预测测试集数据
predict_label = rf.predict(test_data)

# 计算模型准确率
accuracy = accuracy_score(test_label, predict_label)

# 输出准确率
print('Accuracy:', accuracy)

代码中用到的库及其作用:

pandas:用于数据处理,可以读取和处理数据;
sklearn:用于机器学习,包含了多种算法和模型;
train_test_split:用于将数据集分为训练集和测试集,其中test_size参数表示测试集所占比例;
RandomForestClassifier:随机森林分类器模型,n_estimators表示森林中树的数量,max_depth表示每棵树的最大深度;
accuracy_score:用于计算模型的准确率;
print:用于输出结果。
简单解释一下代码的流程:

首先读取数据,可以是csv、excel等格式的文件;
然后将数据集分为训练集和测试集,其中test_size参数表示测试集所占比例,random_state参数表示随机数生成器的种子,用于保证每次运行的结果一致;
接着创建一个随机森林模型,其中n_estimators表示森林中树的数量,max_depth表示每棵树的最大深度;
使用训练集对模型进行训练;
对测试集进行预测,并计算模型的准确率;
最后输出准确率。

梯度提升树(Gradient Boosting Tree,GBT)


梯度提升树(Gradient Boosting Tree,GBT)是一种集成学习方法,也是一种基于决策树的回归和分类算法。与随机森林不同,GBT的每棵决策树是通过利用先前树的残差来构建的。

具体来说,在GBT中,我们首先拟合一个简单的基础模型(例如,一个单节点的决策树)来预测目标变量。然后,我们计算残差(目标值减去预测值)并使用残差来训练另一棵树。接着,我们将新树的预测值与先前的预测值相加,并再次计算残差。我们继续这个过程,直到达到预定的树的数量或训练误差已经无法减小为止。

在预测阶段,GBT将所有树的预测值相加以获得最终的预测值。因为每棵树的预测值只是先前预测值和新树预测值的加和,所以预测结果是一种“加权投票”的形式。

GBT是一种强大的算法,通常在各种回归和分类问题上都能表现良好。与其他机器学习算法一样,GBT需要仔细调整其超参数,以获得最佳性能。
梯度提升树的主要思想是迭代地训练决策树,并将每个新的决策树的预测结果与真实值之间的误差用来训练下一个决策树。这种迭代的过程类似于梯度下降,因此称为“梯度提升”。具体地,梯度提升树的算法流程如下:

1.初始化:将所有样本的真实值作为初始预测值 \(\hat{y}_0\)

2.迭代生成决策树:依次生成多棵决策树 \(h_1, h_2, \dots, h_M\),并将它们的预测结果累加起来,得到最终的预测值 \(\hat{y}M\)。每次生成新的决策树时,都要使它的预测结果尽可能地接近真实值 \(y\),即对训练集的残差进行拟合,其中残差 \(r_i = y_i - \hat{y}{i, m-1}\)

3.计算残差:对于第 \(m\) 棵树,计算每个样本的残差 \(r_{i,m} = y_i - \hat{y}{i,m-1}\),其中 \(\hat{y}{i,m-1}\) 是前 \(m-1\) 棵树对样本 \(i\) 的预测值。

4.拟合残差:用残差作为新的响应变量,训练一棵新的决策树 \(h_m\)

5.更新预测值:将新生成的决策树的预测结果加到前面的预测结果中,得到新的预测值 \(\hat{y}m = \hat{y}{m-1} + h_m\)

6.重复步骤 3-5,直到达到预设的树的数量或者训练误差满足某个停止条件为止。

梯度提升树是一种强大的预测模型,通常在各种回归和分类问题上表现良好。与随机森林相比,梯度提升树更加灵活,能够更好地适应复杂的非线性关系。但是,与随机森林相比,梯度提升树的训练时间更长,并且更容易过拟合。因此,在选择模型时需要根据具体的问题进行权衡。

有关[AI-ML]机器学习是什么?一起了解!(一)的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  7. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  8. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  9. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  10. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

随机推荐