支持向量机SVM

支持向量机SVM

一、支持向量机算法

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

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

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

  • 算法核心思想

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

  • 高维空间情况

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

二、生活中的应用场景

  1. 垃圾邮件分类

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

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

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

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

三、代码案例

水果分类系统

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

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

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

python 复制代码
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(X_train, y_train, clf, 'SVM水果分类决策边界 (训练集)')


# 预测新样本
def predict_fruit(weight, sweetness, model):
  """预测给定重量和甜度的水果类别"""
  fruit_type = model.predict([[weight, sweetness]])[0]
  fruit_name = "苹果" if fruit_type == 0 else "橙子"
  confidence = model.decision_function([[weight, sweetness]])[0]
  print(f"预测结果: 重量为{weight}克,甜度为{sweetness}的水果是{fruit_name}")
  print(f"决策函数值: {confidence:.2f},值越大表示越确信是橙子,值越小表示越确信是苹果")


# 测试几个新样本
predict_fruit(160, 8.5, clf)  # 可能是苹果
predict_fruit(210, 6.2, clf)  # 可能是橙子
predict_fruit(180, 7.0, clf)  # 接近边界的样本
复制代码
模型准确率: 0.87
复制代码
预测结果: 重量为160克,甜度为8.5的水果是苹果
决策函数值: -0.46,值越大表示越确信是橙子,值越小表示越确信是苹果
预测结果: 重量为210克,甜度为6.2的水果是橙子
决策函数值: 1.38,值越大表示越确信是橙子,值越小表示越确信是苹果
预测结果: 重量为180克,甜度为7.0的水果是橙子
决策函数值: 0.33,值越大表示越确信是橙子,值越小表示越确信是苹果

垃圾邮件检测(基于邮件内容和发件人特征)

基于邮件长度、特殊字符比例和发件人可疑度等特征判断邮件是否为垃圾邮件。

python 复制代码
import numpy as np
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report


# 模拟垃圾邮件检测数据
def generate_spam_data(n_samples=200, random_state=42):
  """
  生成垃圾邮件检测数据集

  参数:
  n_samples: 样本数量
  random_state: 随机种子

  返回:
  X: 特征矩阵 (邮件长度, 特殊字符比例, 发件人可疑度)
  y: 标签 (0=正常邮件, 1=垃圾邮件)
  """
  np.random.seed(random_state)

  # 正常邮件特征 (较短, 特殊字符少, 发件人可疑度低)
  normal_length = np.random.normal(loc=200, scale=100, size=n_samples // 2)
  normal_special_chars = np.random.normal(loc=0.05, scale=0.03, size=n_samples // 2)
  normal_sender = np.random.normal(loc=0.1, scale=0.05, size=n_samples // 2)

  # 垃圾邮件特征 (较长, 特殊字符多, 发件人可疑度高)
  spam_length = np.random.normal(loc=500, scale=200, size=n_samples // 2)
  spam_special_chars = np.random.normal(loc=0.2, scale=0.05, size=n_samples // 2)
  spam_sender = np.random.normal(loc=0.8, scale=0.1, size=n_samples // 2)

  # 合并数据
  X_normal = np.column_stack((normal_length, normal_special_chars, normal_sender))
  X_spam = np.column_stack((spam_length, spam_special_chars, spam_sender))
  X = np.vstack((X_normal, X_spam))

  # 创建标签 (0=正常邮件, 1=垃圾邮件)
  y = np.hstack((np.zeros(n_samples // 2), np.ones(n_samples // 2)))

  return X, y


# 生成数据集
X, y = generate_spam_data(n_samples=200)

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

# 创建SVM分类器
clf = svm.SVC(kernel='rbf', C=10, gamma='scale')

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

# 预测并评估
y_pred = clf.predict(X_test)
print("垃圾邮件检测模型评估:")
print(classification_report(y_test, y_pred, target_names=['正常邮件', '垃圾邮件']))


# 预测新邮件
def predict_spam(email_length, special_char_ratio, sender_suspicion, model):
  """预测邮件是否为垃圾邮件"""
  is_spam = model.predict([[email_length, special_char_ratio, sender_suspicion]])[0]
  result = "垃圾邮件" if is_spam else "正常邮件"
  confidence = model.decision_function([[email_length, special_char_ratio, sender_suspicion]])[0]
  print(f"预测结果: 该邮件是{result}")
  print(f"置信度得分: {confidence:.2f} (正值表示垃圾邮件,负值表示正常邮件)")


# 测试预测功能
predict_spam(300, 0.08, 0.2, clf)  # 可能是正常邮件
predict_spam(600, 0.18, 0.7, clf)  # 可能是垃圾邮件
复制代码
垃圾邮件检测模型评估:
              precision    recall  f1-score   support

        正常邮件       0.90      0.90      0.90        31
        垃圾邮件       0.90      0.90      0.90        29

    accuracy                           0.90        60
   macro avg       0.90      0.90      0.90        60
weighted avg       0.90      0.90      0.90        60

预测结果: 该邮件是正常邮件
置信度得分: -0.33 (正值表示垃圾邮件,负值表示正常邮件)
预测结果: 该邮件是垃圾邮件
置信度得分: 3.42 (正值表示垃圾邮件,负值表示正常邮件)

疾病诊断(基于症状和检查指标)

通过体温、血压、心率和白细胞计数等生理指标来判断患者是否患病。

python 复制代码
import numpy as np
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report


# 模拟疾病诊断数据
def generate_disease_data(n_samples=150, random_state=42):
  """
  生成疾病诊断数据集

  参数:
  n_samples: 样本数量
  random_state: 随机种子

  返回:
  X: 特征矩阵 (体温, 血压, 心率, 白细胞计数)
  y: 标签 (0=健康, 1=患病)
  """
  np.random.seed(random_state)

  # 健康人群特征
  healthy_temp = np.random.normal(loc=36.5, scale=0.5, size=n_samples // 2)
  healthy_bp = np.random.normal(loc=120, scale=10, size=n_samples // 2)
  healthy_hr = np.random.normal(loc=70, scale=10, size=n_samples // 2)
  healthy_wbc = np.random.normal(loc=7.5, scale=1.5, size=n_samples // 2)

  # 患病人群特征
  sick_temp = np.random.normal(loc=38.5, scale=1.0, size=n_samples // 2)
  sick_bp = np.random.normal(loc=140, scale=15, size=n_samples // 2)
  sick_hr = np.random.normal(loc=90, scale=15, size=n_samples // 2)
  sick_wbc = np.random.normal(loc=12.5, scale=3.0, size=n_samples // 2)

  # 合并数据
  X_healthy = np.column_stack((healthy_temp, healthy_bp, healthy_hr, healthy_wbc))
  X_sick = np.column_stack((sick_temp, sick_bp, sick_hr, sick_wbc))
  X = np.vstack((X_healthy, X_sick))

  # 创建标签 (0=健康, 1=患病)
  y = np.hstack((np.zeros(n_samples // 2), np.ones(n_samples // 2)))

  return X, y


# 生成数据集
X, y = generate_disease_data(n_samples=150)

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

# 创建SVM分类器
clf = svm.SVC(kernel='rbf', C=5, gamma='scale')

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

# 预测并评估
y_pred = clf.predict(X_test)
print("疾病诊断模型评估:")
print(classification_report(y_test, y_pred, target_names=['健康', '患病']))


# 预测新病例
def predict_disease(temperature, blood_pressure, heart_rate, wbc_count, model):
  """预测患者是否患病"""
  is_sick = model.predict([[temperature, blood_pressure, heart_rate, wbc_count]])[0]
  result = "患病" if is_sick else "健康"
  confidence = model.decision_function([[temperature, blood_pressure, heart_rate, wbc_count]])[0]
  print(f"预测结果: 该患者{result}")
  print(f"置信度得分: {confidence:.2f} (正值表示患病,负值表示健康)")


# 测试预测功能
predict_disease(37.0, 125, 72, 8.0, clf)  # 可能健康
predict_disease(39.2, 145, 95, 14.2, clf)  # 可能患病
复制代码
疾病诊断模型评估:
              precision    recall  f1-score   support

          健康       0.90      1.00      0.95        27
          患病       1.00      0.83      0.91        18

    accuracy                           0.93        45
   macro avg       0.95      0.92      0.93        45
weighted avg       0.94      0.93      0.93        45

预测结果: 该患者健康
置信度得分: -0.67 (正值表示患病,负值表示健康)
预测结果: 该患者患病
置信度得分: 2.18 (正值表示患病,负值表示健康)

手写数字识别(区分0-9的数字)

使用 scikit-learn 自带的手写数字数据集,训练 SVM 模型识别 0-9 的数字。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets, svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载手写数字数据集
digits = datasets.load_digits()

# 探索数据
print(f"数据集大小: {len(digits.data)}个样本")
print(f"每个样本特征数: {digits.data.shape[1]} (8x8像素图像)")

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 可视化一些样本
plt.figure(figsize=(10, 5))
for i in range(10):
  plt.subplot(2, 5, i + 1)
  plt.imshow(digits.images[i], cmap=plt.cm.gray_r)
  plt.title(f"数字: {digits.target[i]}")
  plt.axis('off')
plt.tight_layout()
plt.show()

# 准备数据
X = digits.data  # 特征矩阵 (1797x64)
y = digits.target  # 标签 (0-9)

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

# 创建SVM分类器
clf = svm.SVC(gamma=0.001, C=100)

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

# 预测并评估
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"手写数字识别准确率: {accuracy:.4f}")

# 可视化预测结果
plt.figure(figsize=(12, 6))
for i in range(12):
  plt.subplot(3, 4, i + 1)
  plt.imshow(X_test[i].reshape(8, 8), cmap=plt.cm.gray_r)
  plt.title(f"预测: {y_pred[i]}, 实际: {y_test[i]}")
  plt.axis('off')
plt.tight_layout()
plt.show()


# 测试单个样本预测
def predict_digit(sample_index, model):
  """预测单个手写数字"""
  sample = X_test[sample_index].reshape(1, -1)
  prediction = model.predict(sample)[0]
  confidence = np.max(model.decision_function(sample))
  print(f"预测结果: 数字 {prediction}")
  print(f"置信度: {confidence:.2f}")

  # 可视化预测的样本
  plt.figure(figsize=(4, 4))
  plt.imshow(X_test[sample_index].reshape(8, 8), cmap=plt.cm.gray_r)
  plt.title(f"预测: {prediction}, 实际: {y_test[sample_index]}")
  plt.axis('off')
  plt.show()


# 测试预测功能
predict_digit(0, clf)  # 预测测试集中第一个样本
复制代码
数据集大小: 1797个样本
每个样本特征数: 64 (8x8像素图像)
复制代码
手写数字识别准确率: 0.9907
复制代码
预测结果: 数字 6
置信度: 9.30
python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets, svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import cv2

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 加载手写数字数据集
digits = datasets.load_digits()

# 探索数据
print(f"数据集大小: {len(digits.data)}个样本")
print(f"每个样本特征数: {digits.data.shape[1]} (8x8像素图像)")

# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 可视化一些样本
plt.figure(figsize=(10, 5))
for i in range(10):
  plt.subplot(2, 5, i + 1)
  plt.imshow(digits.images[i], cmap=plt.cm.gray_r)
  plt.title(f"数字: {digits.target[i]}")
  plt.axis('off')
plt.tight_layout()
plt.show()

# 准备数据
X = digits.data  # 特征矩阵 (1797x64)
y = digits.target  # 标签 (0-9)

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

# 创建SVM分类器
clf = svm.SVC(gamma=0.001, C=100, probability=True)

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

# 预测并评估
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"手写数字识别准确率: {accuracy:.4f}")

# 可视化预测结果
plt.figure(figsize=(12, 6))
for i in range(12):
  plt.subplot(3, 4, i + 1)
  plt.imshow(X_test[i].reshape(8, 8), cmap=plt.cm.gray_r)
  plt.title(f"预测: {y_pred[i]}, 实际: {y_test[i]}")
  plt.axis('off')
plt.tight_layout()
plt.show()


# 测试单个样本预测
def predict_digit(sample_index, model):
  """预测单个手写数字"""
  sample = X_test[sample_index].reshape(1, -1)
  prediction = model.predict(sample)[0]
  confidence = np.max(model.predict_proba(sample))
  print(f"预测结果: 数字 {prediction}")
  print(f"置信度: {confidence:.2%}")

  # 可视化预测的样本
  plt.figure(figsize=(4, 4))
  plt.imshow(X_test[sample_index].reshape(8, 8), cmap=plt.cm.gray_r)
  plt.title(f"预测: {prediction}, 实际: {y_test[sample_index]}")
  plt.axis('off')
  plt.show()


# 摄像头拍照预测功能
def predict_from_camera(model):
  """从摄像头捕获图像并进行数字预测"""
  # 打开摄像头
  cap = cv2.VideoCapture(3)

  if not cap.isOpened():
    print("无法打开摄像头")
    return

  print("按 's' 键拍照并预测,按 'q' 键退出")

  while True:
    # 读取一帧图像
    ret, frame = cap.read()

    if not ret:
      print("无法获取图像")
      break

    # 显示当前帧
    cv2.imshow('摄像头', frame)

    # 等待按键事件
    key = cv2.waitKey(1)

    # 按 's' 键拍照并预测
    if key == ord('s'):
      # 转换为灰度图
      gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

      # 调整图像大小为8x8
      resized = cv2.resize(gray, (8, 8), interpolation=cv2.INTER_AREA)

      # 反转颜色(因为MNIST数据集是白底黑字)
      inverted = cv2.bitwise_not(resized)

      # 归一化到0-16范围(与MNIST数据集匹配)
      normalized = inverted.astype(np.float32) / 16.0

      # 展平为一维数组
      flattened = normalized.flatten().reshape(1, -1)

      # 预测
      prediction = model.predict(flattened)[0]
      confidence = np.max(model.predict_proba(flattened))

      # 显示预测结果
      print(f"\n===== 预测结果 =====")
      print(f"预测数字: {prediction}")
      print(f"置信度: {confidence:.2%}")

      # 可视化预测结果
      plt.figure(figsize=(10, 4))

      plt.subplot(1, 2, 1)
      plt.imshow(frame)
      plt.title('原始摄像头图像')
      plt.axis('off')

      plt.subplot(1, 2, 2)
      plt.imshow(normalized, cmap=plt.cm.gray_r)
      plt.title(f'处理后的图像 - 预测: {prediction}')
      plt.axis('off')

      plt.tight_layout()
      plt.show()

    # 按 'q' 键退出
    elif key == ord('q'):
      break

  # 释放摄像头并关闭窗口
  cap.release()
  cv2.destroyAllWindows()


# 测试预测功能
predict_digit(0, clf)  # 预测测试集中第一个样本

# 启动摄像头预测功能
predict_from_camera(clf)
复制代码
数据集大小: 1797个样本
每个样本特征数: 64 (8x8像素图像)
复制代码
手写数字识别准确率: 0.9907
复制代码
预测结果: 数字 6
置信度: 97.54%
复制代码
按 's' 键拍照并预测,按 'q' 键退出

===== 预测结果 =====
预测数字: 9
置信度: 17.40%

金融风险评估(区分高风险和低风险客户)

根据客户收入、负债比率、信用历史长度和违约次数等特征评估客户的风险等级。

python 复制代码
import numpy as np
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report


# 模拟金融风险评估数据
def generate_risk_data(n_samples=300, random_state=42):
  """
  生成金融风险评估数据集

  参数:
  n_samples: 样本数量
  random_state: 随机种子

  返回:
  X: 特征矩阵 (收入, 负债比率, 信用历史长度, 违约次数)
  y: 标签 (0=低风险, 1=高风险)
  """
  np.random.seed(random_state)

  # 低风险客户特征
  low_income = np.random.normal(loc=8000, scale=2000, size=n_samples // 2)
  low_debt_ratio = np.random.normal(loc=0.3, scale=0.1, size=n_samples // 2)
  low_credit_history = np.random.normal(loc=120, scale=30, size=n_samples // 2)
  low_defaults = np.random.poisson(lam=0.2, size=n_samples // 2)

  # 高风险客户特征
  high_income = np.random.normal(loc=5000, scale=1500, size=n_samples // 2)
  high_debt_ratio = np.random.normal(loc=0.7, scale=0.15, size=n_samples // 2)
  high_credit_history = np.random.normal(loc=60, scale=25, size=n_samples // 2)
  high_defaults = np.random.poisson(lam=1.5, size=n_samples // 2)

  # 合并数据
  X_low_risk = np.column_stack((low_income, low_debt_ratio, low_credit_history, low_defaults))
  X_high_risk = np.column_stack((high_income, high_debt_ratio, high_credit_history, high_defaults))
  X = np.vstack((X_low_risk, X_high_risk))

  # 创建标签 (0=低风险, 1=高风险)
  y = np.hstack((np.zeros(n_samples // 2), np.ones(n_samples // 2)))

  return X, y


# 生成数据集
X, y = generate_risk_data(n_samples=300)

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

# 创建SVM分类器
clf = svm.SVC(kernel='rbf', C=10, gamma='scale')

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

# 预测并评估
y_pred = clf.predict(X_test)
print("金融风险评估模型评估:")
print(classification_report(y_test, y_pred, target_names=['低风险', '高风险']))


# 预测新客户风险
def predict_risk(income, debt_ratio, credit_history, defaults, model):
  """预测客户的风险等级"""
  risk_level = model.predict([[income, debt_ratio, credit_history, defaults]])[0]
  result = "高风险" if risk_level else "低风险"
  confidence = model.decision_function([[income, debt_ratio, credit_history, defaults]])[0]
  print(f"预测结果: 该客户是{result}客户")
  print(f"置信度得分: {confidence:.2f} (正值表示高风险,负值表示低风险)")


# 测试预测功能
predict_risk(7500, 0.25, 100, 0, clf)  # 可能是低风险
predict_risk(4000, 0.8, 40, 2, clf)  # 可能是高风险
复制代码
金融风险评估模型评估:
              precision    recall  f1-score   support

         低风险       0.90      0.79      0.84        48
         高风险       0.79      0.90      0.84        42

    accuracy                           0.84        90
   macro avg       0.85      0.85      0.84        90
weighted avg       0.85      0.84      0.84        90

预测结果: 该客户是低风险客户
置信度得分: -0.52 (正值表示高风险,负值表示低风险)
预测结果: 该客户是高风险客户
置信度得分: 1.21 (正值表示高风险,负值表示低风险)
相关推荐
盼小辉丶1 小时前
图机器学习(11)——链接预测
人工智能·机器学习·图机器学习
CareyWYR2 小时前
每周AI论文速递(250714-250718)
人工智能
想要成为计算机高手2 小时前
9. isaacsim4.2教程-ROS加相机/CLOCK
人工智能·机器人·ros·仿真·具身智能·isaacsim
Elastic 中国社区官方博客3 小时前
AI 驱动的仪表板:从愿景到 Kibana
大数据·数据库·人工智能·elasticsearch·搜索引擎·全文检索·kibana
西柚小萌新3 小时前
【大模型:知识图谱】--6.Neo4j DeskTop安装+使用
人工智能·知识图谱
曾几何时`3 小时前
分别使用Cypher与python构建neo4j图谱
开发语言·python·机器学习
杨小扩3 小时前
开发者进化论:驾驭AI,开启软件工程新纪元
人工智能·软件工程
请站在我身后3 小时前
无声视频自动配音效,开源模型thinksound 和mmaudio复现
人工智能·深度学习·算法·计算机视觉·aigc
咖啡星人k3 小时前
PandaWiki与GitBook深度对比:AI时代的知识管理工具,选谁好?
人工智能·深度学习·神经网络
往日情怀酿做酒 V17639296383 小时前
深度学习和神经网络的介绍
人工智能·深度学习·神经网络