乐趣区

关于机器学习:机器学习SVM

前言
  • SVM(反对向量机)是一种罕用的机器学习算法,用于分类和回归剖析。它的次要目标是寻找一个最优超平面,将不同属性的数据分成不同的类别。SVM 是一种无效的分类器,因为它能够解决高维数据,并且能够应用核函数解决非线性可分的数据。
SVM 思维
  • 它的核心思想是通过 将数据映射到高维空间来找到一个最优的超平面
  • SVM 通过找到反对向量来定义最优超平面。反对向量是最靠近超平面的数据点,它们对于定义超平面的地位和方向起着重要的作用。因而,SVM 寻找最优超平面的过程能够简化为找到可能最大化反对向量到最优超平面的间隔的超平面。
SVM 流程
  1. 数据预处理

    在应用 SVM 之前,须要对数据进行预处理,包含数据荡涤、特征选择和特征提取等。此外,还须要将数据分为训练集和测试集。

  2. 特色映射

    SVM 的核心思想是通过将数据映射到高维空间来找到一个最优的超平面。因而,在这一步中,须要将数据通过核函数进行映射,将原始数据映射到高维空间。

  3. 寻找最优超平面

    在映射到高维空间后,SVM 须要寻找一个最优的超平面,将数据分成不同的类别。为了找到最优超平面,须要确定一些参数,如 C(惩办系数)和 γ(核函数的参数),以最大化分类器的准确性。

  4. 分类

    在训练好分类器后,须要应用测试数据集对分类器进行测试,并计算分类器的准确率和召回率等指标。

SVM 优缺点
  • 长处

    • 高维数据处理能力:SVM 能够很好地解决高维数据,并且能够应用核函数解决非线性可分的数据,因而实用于解决许多理论问题。
    • 鲁棒性:SVM 对于噪声数据有很好的解决能力,因为它只关注最靠近超平面的数据点。
    • 实用于小样本:SVM 只须要找到反对向量而不是所有的数据点,因而实用于解决小样本问题。
    • 可调参数:SVM 具备许多可调参数,如 C(惩办系数)和 γ(核函数的参数),以最大化分类器的准确性。
  • 毛病

    • 计算复杂度高:在解决大规模数据时,SVM 的计算复杂度较高,因而训练工夫较长。
    • 须要抉择适当的核函数:抉择适当的核函数对于 SVM 的性能十分重要,但这往往须要进行肯定的试验和调整。
    • 对缺失数据敏感:SVM 对于缺失数据比拟敏感,因而须要在预处理数据时进行解决。
  • 总结

    • SVM 在解决高维数据和非线性数据时表现出色,并且对于噪声数据和小样本问题也有很好的成果。然而,SVM 的计算复杂度较高,并且须要抉择适当的核函数,因而在理论利用中须要认真思考其优缺点,以抉择适合的机器学习算法。
底层代码实现
import numpy as np

class SVM:
    def __init__(self, learning_rate=0.01, lambda_param=0.01, n_iters=1000):
        self.lr = learning_rate       # 学习率
        self.lambda_param = lambda_param    # 正则化参数
        self.n_iters = n_iters         # 迭代次数
        self.w = None       # 参数 w
        self.b = None       # 参数 b

    def fit(self, X, y):
        n_samples, n_features = X.shape

        # 将标签 y 转换为{-1, 1},便于后续计算
        y_ = np.where(y <= 0, -1, 1)

        self.w = np.zeros(n_features)   # 初始化参数 w 为全零向量
        self.b = 0                      # 初始化参数 b 为 0

        # 应用梯度降落法求解最优参数 w 和 b
        for _ in range(self.n_iters):
            for idx, x_i in enumerate(X):
                condition = y_[idx] * (np.dot(x_i, self.w) - self.b) >= 1   # 判断样本点是否位于 Margin 之内
                if condition:
                    self.w -= self.lr * (2 * self.lambda_param * self.w)   # 如果在 Margin 之内,更新参数 w
                else:
                    self.w -= self.lr * (2 * self.lambda_param * self.w - np.dot(x_i, y_[idx]))   # 如果在 Margin 之外,更新参数 w 和 b
                    self.b -= self.lr * y_[idx]     # 更新参数 b

    def predict(self, X):
        approx = np.dot(X, self.w) - self.b   # 计算样本点到超平面的间隔
        return np.sign(approx)    # 返回样本点的类别,即其符号

__init__ 函数中,定义了学习率、正则化参数和迭代次数等超参数。

fit 函数中,应用梯度降落法求解最优参数 w 和 b,其中当样本点位于 Margin 之外时,更新参数 w 和 b。

predict 函数中,计算样本点与超平面的间隔,并返回其符号作为预测后果。

退出移动版