Torleck 2024-03-02 23:28 采纳率: 0%
浏览 15

TWSVM如何修改维数问题(语言-python)

import numpy as np
import scipy.optimize as optimize
import cvxopt
class tw_svm():
    def __init__(self, X_train, y_train, X_test, c1=1, c2=1, kernel_type='rbf', b=1, c=1, d=2, sigma=3):
        self.X_train = X_train
        self.y_train = y_train
        self.X_test = X_test
        # Kernel 设置
        self.kernel_type = kernel_type
        self.b = b  # 双曲正切的常数乘子
        self.c = c  # 多项式,切线和线性样条的常数和
        self.d = d  # 多项式的权重
        self.sigma = sigma  # RBF 和 ERBF 的 sigma
        # Twin SVM settings
        self.c1 = c1  # TW-SVM 软间隔 1
        self.c2 = c2  # TW-SVM 软间隔 2
        # SVM settings
        self.C = 10                 # soft margin
        self.solver = 'optimize'   # Quadratic problem solver. 'cvxopt' or 'optimize'
        # #
        # self.alpha = None           # 拉格朗如乘子 (SVM and LSSVM)
        # self.SV = None              # 支持向量
        # self.bias = 1               # 偏置
    # 计算核函数 k(x1, x2)
    def kernel(self, x1, x2):

        if x1.ndim == 1:
            x1 = np.array([x1]).T

        if x2.ndim == 1:
            x2 = np.array([x2]).T

        m1 = x1.shape[0]
        m2 = x2.shape[0]
        k = np.zeros((m1, m2))

        t = self.kernel_type  # 选择使用的核函数
        b = self.b
        c = self.c
        d = self.d
        sigma = self.sigma
        for i in range(m1):
            for j in range(m2):
                # 线性核函数
                if t == 'linear':
                    k[i, j] = x1[i] @ x2[j]
                # 多项式核函数
                elif t == 'poly':
                    k[i, j] = (x1[i] @ x2[j] + c) ** d
                # 高斯核函数
                elif t == 'rbf':
                    k[i, j] = np.exp(-(x1[i] - x2[j]) @ (x1[i] - x2[j]) / (2 * sigma ** 2))
                # 指数径向基函数
                elif t == 'erbf':
                    k[i, j] = np.exp(-np.abs(x1[i] - x2[j]) / (2 * sigma ** 2))
                # H双曲正切核函数
                elif t == 'tanh':
                    k[i, j] = np.tanh(b * (x1[i] @ x2[j]) + c)
                # 线性样条核函数
                elif t == 'lspline':
                    k[i, j] = c + x1[i] * x2[j] + x1[i] * x2[j] * min(x1[i], x2[j]) + 1 / 2 * (x1[i] + x2[j]) * min(
                        x1[i], x2[j]) ** d
        return k


    # TWSVM: Solve quadratic problem
    def solveQP(p, q, x0, C=None):
        # "Quadratic Programming with Python and CVXOPT"
        # Solve SVM QP optimization problem:
        # min(x) 1/2 * x.T P x + q.T x
        # s.t. Gx<=h
        #      Ax=b
        # Input parameters of CVXOPT library
        N = q.shape[0]
        # construct P, q, G, h matrices for CVXOPT
        p = cvxopt.matrix(p, tc='d')
        q = cvxopt.matrix(q, tc='d')
        if C is None or C == 0:  # hard-margin SVM
            g = cvxopt.matrix(np.diag(np.ones(N) * -1), tc='d')
            h = cvxopt.matrix(np.zeros((N, 1)), tc='d')
        else:  # soft-margin SVM
            g = cvxopt.matrix(np.vstack((np.diag(np.ones(N) * -1), np.eye(N))), tc='d')
            h = cvxopt.matrix(np.hstack((np.zeros(N), np.ones(N) * C)), tc='d')
        # solve QP problem
        x = cvxopt.solvers.qp(p, q, g, h)

        return x

    # TWSVM: Solve quadratic problem using SciPy optimize
    def minimize(self, alpha, M):
        g = -np.sum(alpha) + 0.5 * alpha.T @ M @ alpha
        return g


    def train(self):
        X_train = self.X_train
        y_train = self.y_train
        if y_train.ndim == 1:
            y_train = np.array([y_train]).T
        A = X_train[y_train[:, 0] == 1]   # 取得正样本数据
        B = X_train[y_train[:, 0] == -1]  # 取得负样本数据
        self.Ct = np.vstack((A, B))       # 将样本拼接,用来计算核函数

        m1 = A.shape[0]
        m2 = B.shape[0]

        e1 = np.ones((m1, 1))
        e2 = np.ones((m2, 1))

        K_ACt = self.kernel(A, self.Ct)
        K_BCt = self.kernel(B, self.Ct)

        # TWSVM 1
        S = np.hstack((K_ACt, e1))
        R = np.hstack((K_BCt, e2))
        P1 = R @ np.linalg.pinv(S.T @ S) @ R.T

        # TWSVM 2
        L = np.hstack((K_ACt, e1))
        J = np.hstack((K_BCt, e2))
        P2 = L @ np.linalg.pinv(J.T @ J) @ L.T

        # 初始化 alpha 和 gamma
        alpha0 = np.zeros((np.size(R, 0), 1))
        gamma0 = np.zeros((np.size(L, 0), 1))

        # 拉格朗日乘数
        if self.solver == 'cvxopt':
            # CVXOPT algorithm:
            alpha = self.solveQP(P1, -e2, C=self.c1)
            gamma = self.solveQP(P2, -e1, C=self.c2)

            alpha = np.ravel(alpha['x'])
            gamma = np.ravel(gamma['x'])
        elif self.solver == 'optimize':
            # Scipy optimize
            b1 = optimize.Bounds(0, self.c1)
            b2 = optimize.Bounds(0, self.c2)
            alpha = optimize.minimize(self.minimize, x0=alpha0, args=P1, method='L-BFGS-B', bounds=b1).x
            gamma = optimize.minimize(self.minimize, x0=gamma0, args=P2, method='L-BFGS-B', bounds=b2).x

        if alpha.ndim == 1:
            alpha = np.array([alpha]).T

        if gamma.ndim == 1:
            gamma = np.array([gamma]).T

        # 解出参数
        epsilon = 1e-16
        I = np.eye(len(S.T @ S))
        self.z1 = -np.linalg.pinv(S.T @ S + epsilon * I) @ R.T @ alpha

        I = np.eye(len(J.T @ J))
        self.z2 = np.linalg.pinv(J.T @ J + epsilon * I) @ L.T @ gamma

        return

    def predict(self, X_test):
        # 输入参数:
        # z1, z2
        # Ct
        u1 = self.z1[:-1]   # TWSVM 1 的权重
        b1 = self.z1[-1:]   # TWSVM 1 的偏置
        u2 = self.z2[:-1]   # TWSVM 2 的权重
        b2 = self.z2[-1:]   # TWSVM 2 的偏置

        K_XCt = self.kernel(X_test, self.Ct)

        # 得到两个非平行的超平面
        surface1 = K_XCt @ u1 + b1
        surface2 = K_XCt @ u2 + b2

        # 计算点到两个超平面的距离
        dist1 = abs(surface1)  # class 1
        dist2 = abs(surface2)  # class -1

        # 根据数据点距离两个超平面的远近来判断所属的类别
        y_hat = np.argmax(np.hstack((dist1, dist2)), axis=1)
        if y_hat.ndim == 1:
            y_hat = np.array([y_hat]).T
        y_hat = np.where(y_hat == 0, -1, y_hat)
        return y_hat


def loadDataSet(fileName):
    dataMat = []
    labelMat = []
    testarr = []
    testarr1 = []
    fr = open(fileName)
    for line in fr.readlines():  # 逐行读取,滤除空格等
        lineArr = line.strip().split('\t')
        dataMat.append([float(lineArr[0]), float(lineArr[1]), float(lineArr[2]), float(lineArr[3]), float(lineArr[4]), float(lineArr[5]), float(lineArr[6]), float(lineArr[7]), float(lineArr[8]), float(lineArr[9]), float(lineArr[10]), float(lineArr[11])])  # 添加数据
        labelMat.append(float(lineArr[12]))  # 添加标签
    X=np.array(dataMat)
    Y=np.array(labelMat)
    X_train = np.array(X[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199]])
    y_train = np.array(Y[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199]])
    X_test = np.array(X[[200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285]])
    y_test = np.array(Y[[200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285]])
    return X_train, y_train, X_test, y_test


if __name__ == '__main__':
    X_train, y_train, X_test, y_test = loadDataSet('新建 Microsoft Excel 工作表.txt')
    tw_svm = tw_svm(X_train, y_train, X_test)
    tw_svm.train()
    y_hat = tw_svm.predict(X_test)
    error = 0
    for i in range(len(y_test)):
        if y_test[i] != y_hat[i]:
            error += 1
    print(1-(error/len(y_test)))
##报错的内容如下:
Traceback (most recent call last):
  File "D:\python pro\web_crawler\novel\TWSVM.py", line 208, in <module>
    tw_svm.train()
  File "D:\python pro\web_crawler\novel\TWSVM.py", line 140, in train
    alpha = optimize.minimize(self.minimize, x0=alpha0, args=P1, method='L-BFGS-B', bounds=b1).x
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\python pro\web_crawler\.venv\Lib\site-packages\scipy\optimize\_minimize.py", line 535, in minimize
    raise ValueError("'x0' must only have one dimension.")
ValueError: 'x0' must only have one dimension.

这个是什么问题呀?具体该怎么改呢?

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-02 23:29
    关注

    引自免费微信小程序:皆我百晓生

    在您提供的代码中,错误发生在使用 scipy.optimize.minimize 函数时。该函数要求输入的初始点(x0)是一个一维数组或列表,表示优化变量的初值。但在您的代码中,当调用 minimize 时,传入的 alpha0 是一个二维数组,这与 minimize 的要求不符。

    为了解决这个问题,您需要确保在初始化 alpha0gamma0 时将其设置为一维数组:

    # 初始化 alpha 和 gamma
    alpha0 = np.zeros(np.size(R, 0))  # 将其修改为一维数组
    gamma0 = np.zeros(np.size(L, 0))   # 同样修改为一维数组
    

    修正后的完整训练方法如下:

    def train(self):
        X_train = self.X_train
        y_train = self.y_train
        if y_train.ndim == 1:
            y_train = np.array([y_train]).T
        A = X_train[y_train[:, 0] == 1]
        B = X_train[y_train[:, 0] == -1]
        self.Ct = np.vstack((A, B))
    
        m1 = A.shape[0]
        m2 = B.shape[0]
    
        e1 = np.ones((m1, 1))
        e2 = np.ones((m2, 1))
    
        K_ACt = self.kernel(A, self.Ct)
        K_BCt = self.kernel(B, self.Ct)
    
        # TWSVM 1
        S = np.hstack((K_ACt, e1))
        R = np.hstack((K_BCt, e2))
        P1 = R @ np.linalg.pinv(S.T @ S) @ R.T
    
        # TWSVM 2
        L = np.hstack((K_ACt, e1))
        J = np.hstack((K_BCt, e2))
        P2 = L @ np.linalg.pinv(J.T @ J) @ L.T
    
        # 初始化 alpha 和 gamma 为一维数组
        alpha0 = np.zeros(np.size(R, 0))
        gamma0 = np.zeros(np.size(L, 0))
    
        # 拉格朗日乘数
        if self.solver == 'cvxopt':
            # CVXOPT algorithm:
            alpha = self.solveQP(P1, -e2, C=self.c1)
            gamma = self.solveQP(P2, -e1, C=self.c2)
    
            alpha = np.ravel(alpha['x'])
            gamma = np.ravel(gamma['x'])
        elif self.solver == 'optimize':
            # Scipy optimize
            b1 = optimize.Bounds(0, self.c1)
            b2 = optimize.Bounds(0, self.c2)
            
            # 确保 x0 是一维数组
            alpha = optimize.minimize(self.minimize, x0=alpha0.flatten(), args=P1, method='L-BFGS-B', bounds=b1).x
            gamma = optimize.minimize(self.minimize, x0=gamma0.flatten(), args=P2, method='L-BFGS-B', bounds=b2).x
    
            # 如果返回的是标量,转换为列向量
            if alpha.ndim == 0:
                alpha = np.array([alpha])
            if gamma.ndim == 0:
                gamma = np.array([gamma])
    
        # 解出参数...
        # ...其余部分保持不变
    

    请注意,在调用 minimize 函数时,为了安全起见,我将 alpha0.flatten()gamma0.flatten() 作为输入,以确保它们是一维数组。同时检查了返回结果,如果优化后得到的是标量,也转换为列向量形式,以符合后续计算的要求。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月2日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见