支持向量机的数学推导与代码实现

数学推导

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码实现

class SVMClassifier:
    def __init__(self, C=1., kernel=rbf_kernel, power=4, gamma=None, coef=4):
        """
        :param C: 惩罚参数
        :param kernel: 核函数
        :param power: 多项式核函数最高次项
        :param gamma: 核函数参数
        :param coef: 多项式核函数参数
        """
        self.C = C
        self.kernel = kernel
        self.power = power
        self.gamma = gamma
        self.coef = coef
        self.lagr_multipliers = None
        self.support_vectors = None
        self.support_vectors_labels = None
        self.intercept = None

    def fit(self, X, y):
        """
        :param X: 连续数据
        :param y: 二分类 传入只有1和0的
        :return:
        """
        y[y == 0] = -1
        m, n = np.shape(X)
        if not self.gamma:
            self.gamma = 1 / n  # 若为空,设默认值
        self.kernel = self.kernel(  # 初始化核函数
            power=self.power,
            gamma=self.gamma,
            coef=self.coef
        )
        kernel_matrix = np.zeros((m, m))  # 计算样本点之间结果,结果存在矩阵中
        for i in range(m):
            for j in range(m):
                kernel_matrix[i, j] = self.kernel(X[i], X[j])
        # 处理凸优化问题
        P = cvxopt.matrix(np.outer(y, y) * kernel_matrix, tc='d')
        q = cvxopt.matrix(np.ones(m) * -1)
        A = cvxopt.matrix(y, (1, m), tc='d')
        b = cvxopt.matrix(0, tc='d')

        if not self.C:
            G = cvxopt.matrix(np.identity(m) * -1)
            h = cvxopt.matrix(np.zeros(m))
        else:
            G_max = np.identity(m) * -1
            G_min = np.identity(m)
            G = cvxopt.matrix(np.vstack((G_max, G_min)))
            h_max = cvxopt.matrix(np.zeros(m))
            h_min = cvxopt.matrix(np.ones(m) * self.C)
            h = cvxopt.matrix(np.vstack((h_max, h_min)))
        # 使用cvxopt库解决凸优化问题
        minimization = cvxopt.solvers.qp(P, q, G, h, A, b)
        lagr_mult = np.ravel(minimization['x'])  # 拉格朗日乘子
        idx = lagr_mult > 1e-7  # 获取非0拉格朗日乘子的索引
        self.lagr_multipliers = lagr_mult[idx]  # 获取符合的拉格朗日乘子
        self.support_vectors = X[idx]  # 获取支持向量
        self.support_vectors_labels = y[idx]  # 获取对应标签
        self.intercept = self.support_vectors_labels[0]  # 计算wx+b中的b
        for i in range(len(self.lagr_multipliers)):
            self.intercept -= self.lagr_multipliers[i] * self.support_vectors_labels[i] *\
                              self.kernel(self.support_vectors[i], self.support_vectors[0])
        y[y == -1] = 0

    def predict(self, X_text):
        y_predict = []
        for sample in X_text:
            prediction = 0
            for i in range(len(self.lagr_multipliers)):
                prediction += self.lagr_multipliers[i] * self.support_vectors_labels[i] * \
                              self.kernel(self.support_vectors[i], sample)
            prediction += self.intercept
            y_predict.append(np.sign(prediction))  # 大于0返回1,小于0返回-1
        y_predict = np.array(y_predict, dtype=np.int8)
        y_predict[y_predict == -1] = 0
        return y_predict
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值