自定义数据集 使用scikit-learn中svm的包实现svm分类

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

points = np.array([[1.9, 1.2],
                   [1.5, 2.1],
                   [1.9, 0.5],
                   [1.5, 0.9],
                   [0.9, 1.2],
                   [1.1, 1.7],
                   [1.4, 1.1]])

points2 = np.array([[3.2, 3.2],
                    [3.7, 2.9],
                    [3.2, 2.6],
                    [1.7, 3.3],
                    [3.4, 2.6],
                    [4.1, 2.3],
                    [3.0, 2.9]])

# 合并为一个数据集
x1_data = np.concatenate((points[:, 0], points2[:, 0]))  # 所有的 x1 坐标
x2_data = np.concatenate((points[:, 1], points2[:, 1]))  # 所有的 x2 坐标

# 创建标签
y = np.concatenate((np.ones(points.shape[0]), -np.ones(points2.shape[0])))

# 初始化超平面的参数 w1, w2 和偏置 b
w1 = 0.1
w2 = 0.1
b = 0

# 学习率
learning_rate = 0.05

# 数据集的大小
l_data = x1_data.size

# 创建图形和子图
fig, (ax1, ax2) = plt.subplots(2, 1)

# 初始化存储每一步的损失值和迭代步数
step_list = np.array([])
loss_values = np.array([])

# 设定迭代次数,控制模型训练的周期
num_iterations = 1000
for n in range(1, num_iterations + 1):
    # 计算超平面预测值:z = w1 * x1 + w2 * x2 + b
    z = w1 * x1_data + w2 * x2_data + b

    # 计算每个点的损失:Hinge loss
    yz = y * z  # 预测值与真实标签的乘积
    loss = 1 - yz  # hinge loss 为 1 - yz,当 yz > 1 时,损失为 0
    loss[loss < 0] = 0  # 如果损失小于 0,置为 0
    hinge_loss = np.mean(loss)  # 计算平均损失(取所有数据点的损失均值)
    loss_values = np.append(loss_values, hinge_loss)  # 保存当前步的损失值
    step_list = np.append(step_list, n)  # 保存当前迭代步数

    # 初始化梯度
    gradient_w1 = 0
    gradient_w2 = 0
    gradient_b = 0

    # 梯度下降法计算梯度
    for i in range(len(y)):
        if loss[i] > 0:  # 仅考虑损失大于 0 的点
            gradient_w1 += -y[i] * x1_data[i]
            gradient_w2 += -y[i] * x2_data[i]
            gradient_b += -y[i]

    # 平均化梯度
    gradient_w1 /= len(y)
    gradient_w2 /= len(y)
    gradient_b /= len(y)

    # 更新超平面参数:w1, w2, b
    w1 -= learning_rate * gradient_w1
    w2 -= learning_rate * gradient_w2
    b -= learning_rate * gradient_b

    # 每 50 步或第一次迭代时,绘制一次更新图
    frequence_display = 50
    if n % frequence_display == 0 or n == 1:
        if np.abs(w2) < 1e-5:  # 避免 w2 太小导致无法计算
            continue

        # 计算超平面的直线方程,用于绘制超平面
        x1_min, x1_max = 0, 6  # x1 的范围
        x2_min, x2_max = -(w1 * x1_min + b) / w2, -(w1 * x1_max + b) / w2  # x2 的值,基于超平面方程计算

        # 清除上一轮绘制的图像,绘制新的图
        ax1.clear()
        ax1.scatter(x1_data[:len(points)], x2_data[:len(points)], c='red', label='Class 1')  # class1 红色
        ax1.scatter(x1_data[len(points):], x2_data[len(points):], c='blue', label='Class 2')  # class2 蓝色
        ax1.plot([x1_min, x1_max], [x2_min, x2_max], 'r-')  # 绘制超平面
        ax1.set_title(f"SVM: w1={round(w1.item(), 3)}, w2={round(w2.item(), 3)}, b={round(b.item(), 3)}")

        # 绘制损失函数的变化图
        ax2.clear()
        ax2.plot(step_list, loss_values, 'g-')  # 损失图
        ax2.set_xlabel("Step")
        ax2.set_ylabel("Loss")

        # 每次绘图后暂停 1 秒,展示图像
        plt.pause(1)

# 显示最终图形
plt.show()
相关推荐
程序员三藏35 分钟前
Selenium无法定位元素的几种解决方案
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
前端小趴菜~时倾36 分钟前
自我提升-python爬虫学习:day04
爬虫·python·学习
小罗和阿泽38 分钟前
接口测试系列 接口自动化测试 pytest框架(三)
开发语言·python·pytest
毕设源码-邱学长7 小时前
【开题答辩全过程】以 基于Java的学校住宿管理系统的设计与实现为例,包含答辩的问题和答案
java·开发语言
rookieﻬ°8 小时前
PHP框架漏洞
开发语言·php
猿界零零七8 小时前
pip install mxnet 报错解决方案
python·pip·mxnet
炸膛坦客9 小时前
单片机/C/C++八股:(二十)指针常量和常量指针
c语言·开发语言·c++
兑生9 小时前
【灵神题单·贪心】1481. 不同整数的最少数目 | 频率排序贪心 | Java
java·开发语言
炸膛坦客10 小时前
单片机/C/C++八股:(十九)栈和堆的区别?
c语言·开发语言·c++
零雲10 小时前
java面试:了解抽象类与接口么?讲一讲它们的区别
java·开发语言·面试