支持向量机SVM

支持向量机SVM

一、支持向量机算法

支持向量机(Support Vector Machine,SVM)是一种用于分类和回归分析的机器学习算法。

  • 分类场景举例(更容易理解)

假设现在有一个二维平面上散落着一些点,这些点分为两类,一类是红色的圆形点,另一类是蓝色的方形点。我们的任务就是找到一条直线,能够把这两类点尽可能准确地分开。支持向量机算法做的事情就和这个类似。

  • 算法核心思想

它不是随便找一条能分开两类数据的直线(在高维空间可能是超平面),而是要找到一条特殊的直线。这条直线需要满足离它两边最近的那些点(这些点就叫做支持向量)的距离尽可能远。打个比方,这条直线就像一个 “缓冲带” 的中线,离两边支持向量越远,这个 “缓冲带” 就越宽,这样做的好处是能更好地对数据进行分类,即使有一些新的、之前没看过的数据点出现,也能有较高的分类准确率。

  • 高维空间情况

不过现实中的数据往往不是这么简单地分布在二维或三维空间里,很多都是在高维空间中。这时候支持向量机就会利用一些数学技巧,把低维的数据映射到高维空间,在高维空间里找到那个能很好分隔数据的超平面。这就好比我们把一个很难用直线在二维平面上分开的东西,通过一些方式 “升维” 到三维空间,在三维空间里找到一个平面(超平面在三维空间就是平面,在更高维空间就更难直观理解了)来把它们分开。

二、生活中的应用场景

  1. 垃圾邮件分类

    • 当你收到一封邮件时,邮件系统需要判断它是正常的邮件还是垃圾邮件。支持向量机算法可以对邮件的内容进行分析。
    • 例如,它会把邮件中的词汇、发件人信息等特征提取出来。如果邮件中出现大量的 “中奖”“免费赠送” 等词汇,就很可能被标记为垃圾邮件。通过训练支持向量机模型,把包含这些特征的垃圾邮件和正常邮件的数据作为训练样本,模型就能学会分辨新收到的邮件是垃圾邮件还是正常邮件。
  2. 手写体识别

    • 在银行处理支票等业务时,需要对支票上的手写数字进行识别。支持向量机可以对手写数字的图像进行处理。
    • 它把每个手写数字图像的像素值等信息作为特征,通过对大量手写数字样本(已经标注好是哪个数字)进行学习。当遇到一个新的手写数字图像时,就能根据模型判断它到底是 0 - 9 中的哪一个数字。
  3. 情感分析

    • 比如在一个社交网络平台上,商家想要了解用户对自己产品的评价是正面的、负面的还是中性的。支持向量机可以分析用户发布的关于产品的评论文本。
    • 它会关注文本中的词汇和语句结构等特征,像 “很棒”“很喜欢” 通常代表正面情感,“很差”“很失望” 则代表负面情感。通过训练模型,就能对新的评论进行情感分类。
  4. 生物信息学中的蛋白质分类

    • 科学家在研究蛋白质功能时,需要对蛋白质进行分类。支持向量机可以根据蛋白质的氨基酸序列等特征来分类。
    • 例如,区分一种蛋白质是参与代谢过程的还是参与信号传导的,对新发现的蛋白质序列进行快速准确的分类,有助于进一步的生物学研究。

三、代码案例

水果分类系统

这个代码示例模拟了一个水果分类系统,使用支持向量机(SVM)根据水果的重量和甜度来区分苹果和橙子。关键部分解释:

  1. 数据生成:通过高斯分布模拟苹果(轻且甜)和橙子(重且不太甜)的特征
  2. 模型训练:使用径向基函数(RBF)核的SVM分类器
  3. 可视化:绘制了决策边界和支持向量,帮助理解SVM的工作原理
  4. 预测功能:可以对新水果样本进行分类预测,并显示分类置信度

这个示例展示了SVM在二分类问题中的应用,通过调整特征和参数可以应用于更复杂的场景。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


# 模拟生成水果数据集
def generate_fruit_data(n_samples=100, random_state=42):
  """
  生成水果分类数据集,特征为重量(克)和甜度(0-10)

  参数:
  n_samples: 样本数量
  random_state: 随机种子,保证结果可重现

  返回:
  X: 特征矩阵 (重量, 甜度)
  y: 标签 (0=苹果, 1=橙子)
  """
  np.random.seed(random_state)

  # 生成苹果数据 (重量轻,甜度高)
  apples_weight = np.random.normal(loc=150, scale=20, size=n_samples // 2)
  apples_sweetness = np.random.normal(loc=8, scale=1, size=n_samples // 2)

  # 生成橙子数据 (重量重,甜度中等)
  oranges_weight = np.random.normal(loc=200, scale=25, size=n_samples // 2)
  oranges_sweetness = np.random.normal(loc=6, scale=1.5, size=n_samples // 2)

  # 合并数据
  X_apples = np.column_stack((apples_weight, apples_sweetness))
  X_oranges = np.column_stack((oranges_weight, oranges_sweetness))
  X = np.vstack((X_apples, X_oranges))

  # 创建标签 (0=苹果, 1=橙子)
  y = np.hstack((np.zeros(n_samples // 2), np.ones(n_samples // 2)))

  return X, y


# 生成数据集
X, y = generate_fruit_data(n_samples=100)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建SVM分类器
# 使用径向基函数(RBF)作为核函数
# C参数控制正则化强度,值越大对误分类的惩罚越大
clf = svm.SVC(kernel='rbf', C=1.0, gamma='scale')

# 训练模型
clf.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = clf.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率: {
     
     accuracy:.2f}")


# 可视化决策边界和数据点
def plot_decision_boundary(X, y, clf, title):
  """
  绘制SVM的决策边界和数据点

  参数:
  X: 特征矩阵
  y: 标签
  clf: 训练好的SVM分类器
  title: 图表标题
  """
  # 设置中文字体支持
  plt.rcParams['font.sans-serif'] = ['SimHei']
  plt.rcParams['axes.unicode_minus'] = False

  plt.figure(figsize=(10, 6))

  # 绘制数据点
  plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], c='red', marker='o', label='苹果', s=50)
  plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], c='orange', marker='^', label='橙子', s=50)

  # 创建网格来绘制决策边界
  h = 0.2  # 网格步长
  x_min, x_max = X[:, 0].min() - 10, X[:, 0].max() + 10
  y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
  xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

  # 预测网格点的类别
  Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
  Z = Z.reshape(xx.shape)

  # 绘制决策边界和间隔边界
  plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
  plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors='k')

  # 标记支持向量
  plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
              linewidth=1, facecolors='none', edgecolors='k', label='支持向量')

  plt.xlabel('重量(克)')
  plt.ylabel('甜度(0-10)')
  plt.title(title)
  plt.legend(loc='upper left')
  plt.grid(True)
  plt.show()


# 可视化训练集上的决策边界
plot_decision_boundary

你可能感兴趣的:(sklearn,人工智能,机器学习,支持向量机,算法,机器学习,sklearn,人工智能,数据挖掘)