机器学习之支持向量机

简介

支持向量机(Support Vector Machine,简称 SVM)是一种非常强大且灵活的监督学习算法,用于分类和回归任务。其基本思想是在特征空间中找到一个最优的超平面,将不同类别的样本分开,并且使得超平面与最近的样本点的距离(也称为间隔)最大化。

以下是支持向量机的一些关键概念:

  1. 超平面(Hyperplane):在一个n维空间中,超平面是一个n-1维的平面,它将空间划分为两个部分。在二维空间中,超平面是一条直线,而在三维空间中,超平面是一个平面。

  2. 间隔(Margin):超平面与离它最近的样本点之间的距离称为间隔。SVM 的目标是最大化间隔,以提高分类的鲁棒性。

  3. 支持向量(Support Vectors):支持向量是离超平面最近的那些点。这些点决定了超平面的位置,并且在计算间隔和决定分类边界时起到重要作用。

  4. 核技巧(Kernel Trick):在低维特征空间中可能无法线性分割样本,这时可以使用核技巧将样本映射到高维特征空间中,从而实现在高维空间中线性分割样本的目的。常用的核函数包括线性核、多项式核、高斯核等。

  5. 正则化参数(Regularization Parameter):用于控制模型的复杂度,避免过拟合。正则化参数越大,模型的复杂度越低,反之亦然。

SVM 在解决线性和非线性分类问题上表现出色,并且对于高维数据集的处理效果也很好。其应用领域涵盖图像分类、文本分类、生物信息学、金融数据分析等多个领域。

原理

SVM的基本原理是找到一个最优的超平面,将不同类别的样本点分开,并使超平面与最近的样本点的距离最大化。
通过最大化间隔,提高分类的鲁棒性。

代码实现

  • 生成数据集
def generate_data(samples):
    # 生成随机特征
    X = np.random.rand(samples, 2) * 10

    # 根据新规则生成标签,x1 + x2 > 5 为类别1
    y = np.zeros(samples)
    for i in range(samples):
        if X[i, 0] + X[i, 1] > 10:
            y[i] = 1

    return X, y
  • 划分数据集
def split_data(X, y, rate):
    #调整标签数组的形状
    y.resize((y.size, 1))
    #合并特征和标签
    data = np.concatenate((X, y), axis=1)
    #打乱数据
    np.random.shuffle(data)

    test_len = y.size - int(rate * y.size)

    return data[:test_len, :2], data[test_len:, :2], data[:test_len, 2], data[test_len:, 2]
  • 向量机训练模型
class SupportVectorMachine:
    def __init__(self, learning_rate=0.01, num_iterations=1000, C=1.0):
        self.learning_rate = learning_rate
        self.num_iterations = num_iterations
        self.C = C
        self.weights = None
        self.bias = None

    def fit(self, X, y):
        num_samples, num_features = X.shape

        # 初始化参数
        self.weights = np.zeros(num_features)
        self.bias = 0

        # 梯度下降优化
        for _ in range(self.num_iterations):
            for i, x_i in enumerate(X):
                condition = y[i] * (np.dot(x_i, self.weights) - self.bias) >= 1

                if condition:
                    self.weights -= self.learning_rate * (2 * self.C * self.weights)
                else:
                    self.weights -= self.learning_rate * (2 * self.C * self.weights - np.dot(x_i, y[i]))
                    self.bias -= self.learning_rate * y[i]

    def predict(self, X):
        linear_output = np.dot(X, self.weights) - self.bias
        return np.sign(linear_output)
  • 决策边界
def plot_decision_boundary(model, X, y):
    # 创建网格来绘制决策边界
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02),
                           np.arange(x2_min, x2_max, 0.02))

    # 将网格点数据放入模型中进行预测
    Z = model.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)

    # 绘制等高线
    plt.contourf(xx1, xx2, Z, alpha=0.3)

    # 绘制样本点
    plt.scatter(X[:, 0], X[:, 1], c=y, marker='o', edgecolors='k', label='Data Points')

    # 绘制支持向量
    plt.scatter(X[model.support_vectors_idx, 0], X[model.support_vectors_idx, 1], c='red', marker='x', label='Support Vectors')

    # 设置图标题和坐标轴标题
    plt.title('Decision Boundary')
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')
    plt.legend()

    plt.show()

最终完善代码

import numpy as np
import matplotlib.pyplot as plt

# 设置字体为宋体
plt.rcParams['font.family'] = ['serif']  # 设置字体为有衬线字体(宋体是有衬线字体之一)
plt.rcParams['font.serif'] = ['SimSun']  # 设置有衬线字体为宋体

# 生成数据集
def generate_data(samples):
    from sklearn.datasets import make_blobs
    X, y = make_blobs(n_samples=samples, centers=2, random_state=42)
    y = np.where(y == 0, -1, 1)
    return X, y

class SupportVectorMachine:
    def __init__(self, learning_rate=0.01, num_iterations=1000, C=1.0):
        self.learning_rate = learning_rate
        self.num_iterations = num_iterations
        self.C = C
        self.weights = None
        self.bias = None
        self.support_vectors_idx = None

    def fit(self, X, y):
        num_samples, num_features = X.shape

        # 初始化参数
        self.weights = np.zeros(num_features)
        self.bias = 0

        # 梯度下降优化
        for _ in range(self.num_iterations):
            for i, x_i in enumerate(X):
                condition = y[i] * (np.dot(x_i, self.weights) - self.bias) >= 1

                if condition:
                    self.weights -= self.learning_rate * (2 * self.C * self.weights)
                else:
                    self.weights -= self.learning_rate * (2 * self.C * self.weights - np.dot(x_i, y[i]))
                    self.bias -= self.learning_rate * y[i]

        # 记录支持向量的索引
        self.support_vectors_idx = np.where((y * (np.dot(X, self.weights) - self.bias)) < 1)[0]

    def predict(self, X):
        linear_output = np.dot(X, self.weights) - self.bias
        return np.sign(linear_output)

def plot_decision_boundary(model, X, y):
    # 创建网格来绘制决策边界
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02),
                           np.arange(x2_min, x2_max, 0.02))

    # 将网格点数据放入模型中进行预测
    Z = model.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)

    # 绘制等高线
    plt.contourf(xx1, xx2, Z, alpha=0.3)

    # 绘制样本点
    plt.scatter(X[:, 0], X[:, 1], c=y, marker='o', edgecolors='k', label='Data Points')

    # 绘制支持向量
    plt.scatter(X[model.support_vectors_idx, 0], X[model.support_vectors_idx, 1], c='red', marker='x', label='Support Vectors')

    # 设置图标题和坐标轴标题
    plt.title('Decision Boundary')
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')
    plt.legend()

    plt.show()

# 样本和数据集划分
samples = 50

# 构造数据集
X, y = generate_data(samples)

# 训练SVM模型
svm_model = SupportVectorMachine()
svm_model.fit(X, y)

# 绘制决策边界和支持向量
plot_decision_boundary(svm_model, X, y)

总结
支持向量机(Support Vector Machine,SVM)是一种强大的机器学习算法,适用于分类和回归任务。以下是关于支持向量机的主要要点总结:

  1. 优点

    • 在高维空间中表现良好,适用于复杂的数据集。
    • 对于小样本数据集具有较好的泛化能力。
    • 可以使用不同的核函数来处理线性和非线性问题。
  2. 缺点

    • 对于大规模数据集训练时间较长。
    • 对于高维稀疏数据集的效果可能不如其他算法。
  3. 应用

    • 图像分类
    • 文本分类
    • 生物信息学
    • 金融数据分析等多个领域。

综上所述,支持向量机是一种功能强大的算法,广泛应用于各种机器学习任务中,尤其适用于处理高维数据和复杂分类问题。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值