分类算法
分类算法的目标是构建一个模型,用于将新的、未见过的数据点分配到预定义的类别中。
逻辑回归 (Logistic Regression)
尽管它的名字中带有”回归”二字,但逻辑回归实际上是一种用于分类的监督学习算法,尤其在处理二分类问题时表现出色。
逻辑回归是一种预测分析,它通过分析现有数据(自变量),来预测一个离散的、分类型的结果(因变量)。最常见的应用是二分类问题,例如预测一封邮件是否为垃圾邮件(是/否)、一个用户是否会点击广告(点击/不点击)、一个肿瘤是恶性的还是良性的(恶性/良性)。
它的核心思想是:将输入的特征(features)进行线性组合,然后通过一个特殊的非线性函数——Sigmoid函数,将结果映射到 (0,1) 的区间内,这个结果可以被解释为”属于某个类别的概率”。
核心原理
逻辑回归的实现主要包含两个关键部分:预测函数和决策边界。
预测函数:从线性回归到逻辑回归
线性回归模型通常表示为:
y = θ0 + θ1x1 + θ2x2 + ⋯ + θnxn = θTx
这里,y 的输出是连续的,可以是任何数值。但对于分类问题,我们需要一个介于0和1之间的概率值。
为了解决这个问题,逻辑回归引入了 Sigmoid 函数(也称为 Logistic 函数)。
操作:将线性回归的输出 z = θTx 作为 Sigmoid 函数的输入。
目的:Sigmoid 函数能将任何实数输入”压缩”到 (0,1) 的范围内,这个输出值在逻辑回归中被赋予了概率的意义。
Sigmoid 函数的公式如下:
将 z = θTx 代入,我们就得到了逻辑回归的预测函数(假设函数) hθ(x):
这个 hθ(x) 的输出值,就代表了给定输入 x 时,预测结果为正类(Positive Class, 通常记为 1) 的概率。例如,hθ(x) = 0.7 意味着模型预测该样本有70%的概率属于类别1。
逻辑回归和线性回归的根本区别就是, 逻辑回归在线性回归的基础上,通过一个 Sigmoid 函数的”包装”,巧妙地将一个回归问题转化为了一个分类问题。
决策边界 (Decision Boundary)
有了概率之后,我们如何做出最终的分类决策呢?这就需要一个决策边界来建立一个明确的规则,将模型输出的概率值转化为最终的分类结果。
通常我们设定一个阈值(Threshold),最常用的阈值是 0.5。
如果 hθ(x) ≥ 0.5,则预测类别为 1 (正类)。
如果 hθ(x) < 0.5,则预测类别为 0 (负类)。
观察 Sigmoid 函数 g(z) 的图像可以发现:
- 当 z ≥ 0 时,g(z) ≥ 0.5。
- 当 z < 0 时,g(z) < 0.5。
因此,决策边界实际上是由 z = 0 这条线决定的,也就是由 θTx = 0 决定的。
θTx = 0
这个方程定义了一个超平面(在二维空间中是一条直线,三维中是一个平面),它将特征空间一分为二,一边是预测为1的区域,另一边是预测为0的区域。这个超平面就是模型的决策边界。
重要提示:决策边界是模型属性(由参数 θ 决定),而不是数据集的属性。模型训练的过程,本质上就是在寻找最佳的参数 θ 来确定这个决策边界的位置和方向。
如何训练模型:代价函数与梯度下降
找到了模型的表达形式,接下来的问题是:如何确定最佳的参数 θ 呢?答案是通过最小化一个代价函数 (Cost Function) 来学习。
代价函数 (Cost Function)
对于逻辑回归,我们不能使用线性回归中的均方误差(MSE)作为代价函数,因为当它与 Sigmoid 函数结合时,会形成一个非凸函数,存在很多局部最优解,不利于优化。
因此,逻辑回归采用对数损失函数 (Log Loss),也称为二元交叉熵 (Binary Cross-Entropy)。
对于单个训练样本 (x, y),其代价定义如下:
这个分段函数可以优雅地合并成一个表达式:
Cost(hθ(x), y) = −ylog (hθ(x)) − (1 − y)log (1 − hθ(x))
这个代价函数具有良好的数学特性。
- 当真实标签 y = 1 时,如果模型预测的概率 hθ(x) 越接近1,代价就越接近0;如果预测越接近0,代价就趋于无穷大,从而对模型进行”惩罚”。
- 当真实标签 y = 0 时,逻辑正好相反。
这样的设计确保了代价函数是一个凸函数,只有一个全局最优解。
对于整个训练集(m个样本),总的代价函数 J(θ) 是所有样本代价的平均值:
优化算法:梯度下降 (Gradient Descent)
我们的目标是找到使 J(θ) 最小的参数 θ。梯度下降是最常用的优化算法之一。
我们会从一个随机的 θ 值开始,迭代地更新 θ 的值,每次都沿着代价函数梯度的反方向(即下降最快的方向)移动一小步。通过迭代,逐步逼近代价函数的最小值点,从而找到最优的参数 θ。
θ 的更新规则如下:
其中:
- α 是学习率 (Learning Rate),控制每一步更新的步长。
是代价函数对参数 θj 的偏导数(梯度)。
经过数学推导,逻辑回归代价函数的梯度可以被简化为:
所以,梯度下降的最终更新规则是:
这个过程会一直重复,直到 θ 的值收敛,即代价函数不再显著下降。
逻辑回归的优劣势
优势 (Pros)
- 模型简单,速度快:实现简单,计算开销小,训练速度快,易于并行化。
- 可解释性强:参数 θ 的大小可以直观地反映不同特征对最终结果的影响程度,方便解释。
- 输出结果是概率:不仅能给出分类结果,还能得到属于该类的概率,这在很多场景下非常有用(如风险评估)。
- 对数据要求低:不需要满足严格的统计假设,如正态分布等。
劣势 (Cons)
- 容易欠拟合:模型形式相对简单,处理复杂非线性关系的能力有限,可能导致欠拟合。
- 对特征工程要求高:需要手动进行特征组合和筛选,对数据中的非线性关系需要进行转换。
- 假设特征间线性关系:它假设数据在”对数几率”(log-odds)上是线性的,如果这个假设不成立,模型表现会很差。
- 对多重共线性敏感:如果特征之间高度相关,模型的稳定性和解释性会受到影响。
K-近邻 (K-Nearest Neighbors, KNN)
KNN 是一种监督学习算法,既可以用于分类任务,也可以用于回归任务。它的核心思想可以用一句非常朴素的话来概括:“近朱者赤,近墨者黑”。一个样本的类别,由它在特征空间中最邻近的 K 个邻居来决定。
同时, KNN 是一种基于实例的学习 (Instance-based Learning),也常被称为”懒惰学习” (Lazy Learning) 算法。
“基于实例”的含义:算法不会从训练数据中学习一个明确的判别函数(像逻辑回归那样得到一个参数化的模型 hθ(x))。相反,它只是简单地将整个训练数据集存储起来。
“懒惰学习”的含义:它在训练阶段 (Training Phase) 不做任何计算,没有任何”学习”过程。所有的计算都推迟到预测阶段 (Prediction Phase),即当一个新数据点需要被预测时,算法才开始工作。
- 这与逻辑回归、线性回归等”积极学习” (Eager Learning) 算法形成鲜明对比,后者在训练阶段会努力学习出一个模型参数。
核心工作原理
KNN 的工作流程非常直观,可以分解为以下三个核心要素:距离度量、K 值的选择、以及决策规则。
距离度量 (Distance Metric)
为了找到新数据点的”邻居”,我们首先需要一种方法来衡量样本之间的”距离”或”相似度”。
- 操作:当一个未标记的新数据点出现时,算法会计算它与训练集中每一个数据点之间的距离。
- 目的:量化样本在特征空间中的远近关系。距离越小,代表两个样本越相似。
最常用的距离度量是欧几里得距离 (Euclidean Distance),也就是我们在二维或三维空间中熟悉的直线距离。对于两个样本点 x = (x1, x2, …, xn) 和 y = (y1, y2, …, yn),它们之间的欧几里得距离为:
除了欧氏距离,还有其他距离度量方法,如曼哈顿距离 (Manhattan Distance)、闵可夫斯基距离 (Minkowski Distance) 等,可以根据数据的特性来选择。
重要提示:由于距离计算对数据的尺度非常敏感(例如,一个以”米”为单位的特征会比一个以”厘米”为单位的特征在数值上小很多),因此在使用 KNN 之前,对数据进行归一化 (Normalization) 或标准化 (Standardization) 通常是一个至关重要的预处理步骤。
K 值的选择
K 值代表我们要选择新数据点周围邻居的数量。这是一个需要我们手动指定的超参数。
操作:在计算完新数据点与所有训练样本的距离后,我们对这些距离进行排序,并选出距离最近的 K 个样本,作为它的”邻居”。
目的:K 值的选择直接决定了模型的复杂度和预测结果,对模型的性能有重大影响。
较小的 K 值:模型会变得非常复杂,容易受到噪声数据的影响。例如,如果 K=1,新样本的类别将完全由距离它最近的一个点决定,这可能导致过拟合 (Overfitting)。
较大的 K 值:模型会变得相对简单。如果 K 值过大(例如等于训练样本总数),模型可能会忽略数据中局部的、有意义的模式,导致欠拟合 (Underfitting)。
选择最佳 K 值通常需要通过交叉验证等方法来评估不同 K 值下的模型性能。
决策规则 (Decision Rule)
找到了 K 个最近的邻居之后,我们如何利用它们来对新数据点进行预测呢?这取决于任务是分类还是回归。
用于分类任务 (KNN Classification):
- 决策规则:采用“少数服从多数”的投票原则。
- 过程:查看这 K 个邻居分别属于哪个类别,然后选择其中出现次数最多的那个类别作为新数据点的预测类别。例如,如果 K=5,其中有 3 个邻居是”A类”,2 个邻居是”B类”,那么新数据点就被预测为”A类”。
用于回归任务 (KNN Regression):
- 决策规则:采用“取平均值”的方法。
- 过程:将这 K 个邻居的数值(因变量的值)取平均值(或中位数),将这个平均值作为新数据点的预测值。例如,如果 K=5,这 5 个邻居的房价分别是 100万, 102万, 98万, 105万, 99万,那么新数据点的预测房价就是这五个数的平均值,即 100.8万。
KNN算法的优劣势
优势 (Pros)
- 模型简单,易于理解和实现:算法的直觉性非常强,没有复杂的数学理论。
- 无需训练:作为一种”懒惰学习”算法,它不需要耗时的训练过程。
- 对数据分布没有假设:作为非参数模型,它不对数据的底层分布做任何假设,因此能适用于各种形状的决策边界。
- 可以处理多分类问题:天然支持多分类任务,无需像某些算法一样做特殊处理。
- 对异常值不敏感:在投票或取平均值的机制下,少数异常邻居点对最终结果的影响有限。
劣势 (Cons)
- 计算成本高,预测慢:在预测阶段,需要计算新样本与所有训练样本的距离,当数据集很大时,这会非常耗时。
- 对内存需求大:需要存储整个训练数据集,对内存占用较大。
- 对 K 值的选择敏感:K 值的选择对结果影响巨大,需要仔细调试。
- 对不平衡样本敏感:如果某些类别的样本数量远多于其他类别,投票时会占据优势,导致预测偏向多数类。
- 对特征尺度和无关特征敏感:距离计算会受到特征尺度的巨大影响,且高维空间中”距离”的定义可能会变得不那么有意义(维度灾难)。
支持向量机 (Support Vector Machine, SVM)
支持向量机 (Support Vector Machine, SVM)是一种经典的有监督学习算法,尤其在处理分类和回归问题上表现出色。它的核心思想非常直观且优雅:在数据点中寻找一个能够将不同类别分得最开、最完美的决策边界。
核心思想:最大化”间隔” (Margin)
想象一下,你有一些黑白两种颜色的豆子散落在桌面上,你需要画一条直线将它们分开。通常,你可能可以画出很多条线都能完成这个任务。但哪一条是最好的呢?
SVM 的回答是:那条距离两边最近的豆子都最远的线是最好的。换句话说,这条线为两个类别创造了尽可能宽的”缓冲地带”或”街道”。这个”缓冲地带”的宽度,在SVM的术语里被称为间隔 (Margin)。
SVM 的目标就是找到这个间隔最大的决策边界。这个决策边界在二维空间里是一条直线,在三维空间里是一个平面,在更高维的空间中则被称为超平面 (Hyperplane)。
一个更大的间隔意味着我们对分类结果有更高的置信度。这个决策边界对于新的、未知的数据点具有更强的泛化能力,不容易因为数据的轻微扰动而产生误分类。
关键概念:支持向量 (Support Vectors)
在定义这个最大间隔时,你会发现,Margin的边界正好是由距离决策边界最近的那些数据点”支撑”起来的。这些位于间隔边界上的关键数据点,就被称为支持向量 (Support Vectors)。
支持向量的独特之处在于:
- 决定性作用:整个SVM模型只由支持向量决定。决策边界的位置完全取决于这些支持向量,而与其他数据点无关。
- 高效性:即使训练数据集中有成千上万个点,真正对模型起作用的可能只有一小部分, 即支持向量。这使得SVM在存储和计算上都非常高效。
你可以想象,只要这些”支撑”边界的点不移动,无论你增加或移动多少其他远离边界的点,决策边界都不会发生任何改变。
核函数 (Kernel Function)
到目前为止,我们讨论的都是数据点可以用一条直线(或一个平面)完美分开的情况,这被称为线性可分。但如果数据是类似一三象限和二四象限的点,我们便无法用一条直线将两者分开。这就是非线性数据。
SVM 通过一个非常巧妙的”核技巧 (Kernel Trick)“来解决这个问题。
核心思想:如果我们无法在当前维度上分割数据,那么我们可以将数据映射到一个更高的维度空间,在那里它们可能就变得线性可分了。
一个直观的例子:想象一下在一张纸上(二维空间)有一些无法用直线分开的红点和蓝点。现在,你突然把这张纸向上弯曲,变成一个三维的曲面。从上往下看,这些点可能就神奇地可以用一个平面分开了。
核函数是SVM中用于将低维数据映射到高维空间的一种数学工具。它允许SVM处理非线性边界的问题,通过将数据点从低维空间映射到高维空间,从而在新的空间中找到一个线性决策边界。
常见的核函数 (Kernel Functions):
- 线性核 (Linear Kernel):实际上就是不进行映射,用于处理本身就线性可分的数据。
- 多项式核 (Polynomial Kernel):将数据映射到多项式空间。
- 高斯径向基函数核 (Radial Basis Function, RBF Kernel):这是最常用、最强大的核函数之一。它能将数据映射到无限维空间,可以处理非常复杂的非线性边界。
代码实现
1 | # 导入必要的库, svc 是 Support Vector Classifier的缩写 |
SVM 的优缺点
优点
- 在高维空间中非常有效:尤其当特征维度数量大于样本数量时。
- 模型高效:由于只依赖于支持向量,模型占用的内存较少。
- 泛化能力强:最大化间隔的原则使其不容易过拟合,对未知数据的预测能力强。
- 通用性强:通过使用不同的核函数,可以灵活地解决各种线性和非线性问题。
缺点
- 对大规模训练样本效率不高:当训练样本数量巨大时(例如几十万甚至上百万),其计算复杂度会急剧增加。
- 对参数和核函数的选择敏感:SVM的表现很大程度上依赖于核函数的选择以及一些超参数(如正则化参数C)的设定,需要通过交叉验证等方式进行仔细的调优。
- 对缺失数据敏感:需要预先对数据进行完整的预处理。
- 输出不直接包含概率:SVM的原始输出是类别的硬划分,而不是一个点属于某个类别的概率。虽然有方法可以进行扩展,但不是其原生功能。
决策树 (Decision Tree)
决策树是一种监督学习算法,同样可以用于分类和回归任务。它的模型结构非常直观,就像一个倒立的树,或者说是一个流程图。
它的核心思想是通过一系列的“问题”或“决策”来对数据进行划分,最终导向一个结论。整个模型呈树形结构,包含以下几个关键部分:
- 根节点 (Root Node):代表整个数据集,是树的起点。
- 内部节点 (Internal Node):代表一个特征或属性上的判断。每个内部节点都会引出两个或多个分支。
- 分支 (Branch):代表基于内部节点判断的输出结果。 叶节点 (Leaf Node):代表最终的决策结果(在分类任务中是类别,在回归任务中是数值)。
从根节点到任何一个叶节点的路径,都构成了一条决策规则。
想象一下你决定“今天是否出门打篮球”的过程,这本身就是一个决策树:
- 根节点:开始决策。
- 第一个内部节点(问题):“今天下雨吗?”
- 分支 (是):如果下雨,导向叶节点 -> “不打球”。
- 分支 (否):如果不下雨,进入下一个内部节点。
- 第二个内部节点(问题):“有朋友一起吗?”
- 分支 (是):如果有,导向叶节点 -> “去打球”。
- 分支 (否):如果没有,导向叶节点 -> “不打球”。
这个简单的流程就构成了一个决策树。机器学习中的决策树构建过程,就是让算法自动地、基于数据去学习出这样一个最优的决策流程。
随机森林 (Random Forest)
随机森林是决策树的“进化版”。它通过一种巧妙的集成思想,克服了单个决策树容易过拟合的缺点,从而在各种任务中都表现出极高的准确性和稳定性。
随机森林是一种集成学习 (Ensemble Learning) 方法。集成学习的核心思想是“三个臭皮匠,顶个诸葛亮”——即通过构建并结合多个学习器(或模型)来完成学习任务,以获得比单一学习器更好的性能。
它构建了多棵决策树,并将它们集成为一个“森林”。在进行预测时,森林中的每一棵树都会独立地给出一个预测结果,最后算法会综合所有树的预测来得出最终结论。
- 对于分类任务:采用投票法,选择得票最多的类别作为最终结果。
- 对于回归任务:采用平均法,将所有树的预测值取平均作为最终结果。
这个“森林”不是由一堆相同的树组成的,而是由许多各不相同、具有多样性的决策树构成的。正是这种多样性,使得随机森林具有强大的泛化能力和鲁棒性。