千家信息网

python模拟支持向量机举例分析

发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,本篇内容介绍了"python模拟支持向量机举例分析"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!思想
千家信息网最后更新 2024年11月18日python模拟支持向量机举例分析

本篇内容介绍了"python模拟支持向量机举例分析"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

思想简述

  • 1、线性可分支持向量机,或硬间隔支持向量机。构建它的条件是训练数据线性可分。其学习策略是最大间隔法。可以表示为凸二次规划问题

  • 2、现实中训练数据是线性可分的情形较少,训练数据往往是近似线性可分的,这时使用线性支持向量机,或软间隔支持向量机。线性支持向量机是最基本的支持向量机。对于噪声或例外,通过引入松弛变量,使其"可分",

  • 3、对于输入空间中的非线性分类问题,可以通过非线性变换将它转化为某个高维特征空间中的线性分类问题,在高维特征空间中学习线性支持向量机。由于在线性支持向量机学习的对偶问题里,目标函数和分类决策函数都只涉及实例与实例之间的内积,所以不需要显式地指定非线性变换,而是用核函数来替换当中的内积。核函数表示,通过一个非线性转换后的两个实例间的内积。

  • 4、SMO算法。SMO算法是支持向量机学习的一种快速算法,其特点是不断地将原二次规划问题分解为只有两个变量的二次规划子问题,并对子问题进行解析求解,直到所有变量满足KKT条件为止。这样通过启发式的方法得到原二次规划问题的最优解。因为子问题有解析解,所以每次计算子问题都很快,虽然计算子问题次数很多,但在总体上还是高效的。

程序

sklearn中已有相关包文件,直接调用

import numpy as npimport pandas as pdfrom sklearn.datasets import load_irisfrom sklearn.model_selection import  train_test_splitimport matplotlib.pyplot as pltfrom sklearn.svm import SVCdef create_data():    iris = load_iris()    df = pd.DataFrame(iris.data, columns=iris.feature_names)    df['label'] = iris.target    df.columns = [        'sepal length', 'sepal width', 'petal length', 'petal width', 'label'    ]    data = np.array(df.iloc[:100, [0, 1, -1]])    for i in range(len(data)):        if data[i, -1] == 0:            data[i, -1] = -1    # print(data)    return data[:, :2], data[:, -1]X, y = create_data()X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)clf = SVC()# 下边的参数设置了线性模拟,设置之后才可以画出模拟函数的图# clf = SVC(kernel='linear')clf.fit(X_train, y_train)print("训练集评分:{}".format(str(clf.score(X_test, y_test)*100)+"%"))# 上边设置线性之后,下边的注释代码才能使用# x_points = np.arange(4, 8)# y_ = -(clf.coef_[0][0]*x_points + clf.intercept_)/clf.coef_[0][1]# plt.plot(x_points, y_)plt.scatter(X[:50, 0], X[:50, 1], label='-1')plt.scatter(X[50:, 0], X[50:, 1], label='1')plt.legend()plt.show()

结果:

数据点:

线性模拟结果图:

训练集评分:100.0%

自己编写SVM类

import numpy as npimport pandas as pdfrom sklearn.datasets import load_irisfrom sklearn.model_selection import  train_test_splitimport matplotlib.pyplot as pltdef create_data():    iris = load_iris()    df = pd.DataFrame(iris.data, columns=iris.feature_names)    df['label'] = iris.target    df.columns = [        'sepal length', 'sepal width', 'petal length', 'petal width', 'label'    ]    data = np.array(df.iloc[:100, [0, 1, -1]])    for i in range(len(data)):        if data[i, -1] == 0:            data[i, -1] = -1    # print(data)    return data[:, :2], data[:, -1]X, y = create_data()X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)plt.scatter(X[:50, 0], X[:50, 1], label='-1')plt.scatter(X[50:, 0], X[50:, 1], label='1')plt.legend()plt.show()class SVM:    def __init__(self, max_iter=100, kernel='linear'):        self.max_iter = max_iter        self._kernel = kernel    def init_args(self, features, labels):        self.m, self.n = features.shape        self.X = features        self.Y = labels        self.b = 0.0        # 将Ei保存在一个列表里        self.alpha = np.ones(self.m)        self.E = [self._E(i) for i in range(self.m)]        # 松弛变量        self.C = 1.0    def _KKT(self, i):        y_g = self._g(i) * self.Y[i]        if self.alpha[i] == 0:            return y_g >= 1        elif 0 < self.alpha[i] < self.C:            return y_g == 1        else:            return y_g <= 1    # g(x)预测值,输入xi(X[i])    def _g(self, i):        r = self.b        for j in range(self.m):            r += self.alpha[j] * self.Y[j] * self.kernel(self.X[i], self.X[j])        return r    # 核函数    def kernel(self, x1, x2):        if self._kernel == 'linear':            return sum([x1[k] * x2[k] for k in range(self.n)])        elif self._kernel == 'poly':            return (sum([x1[k] * x2[k] for k in range(self.n)]) + 1)**2        return 0    # E(x)为g(x)对输入x的预测值和y的差    def _E(self, i):        return self._g(i) - self.Y[i]    def _init_alpha(self):        # 外层循环首先遍历所有满足0= 0:                j = min(range(self.m), key=lambda x: self.E[x])            else:                j = max(range(self.m), key=lambda x: self.E[x])            return i, j    def _compare(self, _alpha, L, H):        if _alpha > H:            return H        elif _alpha < L:            return L        else:            return _alpha    def fit(self, features, labels):        self.init_args(features, labels)        for t in range(self.max_iter):            # train            i1, i2 = self._init_alpha()            # 边界            if self.Y[i1] == self.Y[i2]:                L = max(0, self.alpha[i1] + self.alpha[i2] - self.C)                H = min(self.C, self.alpha[i1] + self.alpha[i2])            else:                L = max(0, self.alpha[i2] - self.alpha[i1])                H = min(self.C, self.C + self.alpha[i2] - self.alpha[i1])            E1 = self.E[i1]            E2 = self.E[i2]            # eta=K11+K22-2K12            eta = self.kernel(self.X[i1], self.X[i1]) + self.kernel(                self.X[i2],                self.X[i2]) - 2 * self.kernel(self.X[i1], self.X[i2])            if eta <= 0:                # print('eta <= 0')                continue            alpha2_new_unc = self.alpha[i2] + self.Y[i2] * (                E1 - E2) / eta  #此处有修改,根据书上应该是E1 - E2,书上130-131页            alpha2_new = self._compare(alpha2_new_unc, L, H)            alpha1_new = self.alpha[i1] + self.Y[i1] * self.Y[i2] * (                self.alpha[i2] - alpha2_new)            b1_new = -E1 - self.Y[i1] * self.kernel(self.X[i1], self.X[i1]) * (                alpha1_new - self.alpha[i1]) - self.Y[i2] * self.kernel(                    self.X[i2],                    self.X[i1]) * (alpha2_new - self.alpha[i2]) + self.b            b2_new = -E2 - self.Y[i1] * self.kernel(self.X[i1], self.X[i2]) * (                alpha1_new - self.alpha[i1]) - self.Y[i2] * self.kernel(                    self.X[i2],                    self.X[i2]) * (alpha2_new - self.alpha[i2]) + self.b            if 0 < alpha1_new < self.C:                b_new = b1_new            elif 0 < alpha2_new < self.C:                b_new = b2_new            else:                # 选择中点                b_new = (b1_new + b2_new) / 2            # 更新参数            self.alpha[i1] = alpha1_new            self.alpha[i2] = alpha2_new            self.b = b_new            self.E[i1] = self._E(i1)            self.E[i2] = self._E(i2)        return 'train done!'    def predict(self, data):        r = self.b        for i in range(self.m):            r += self.alpha[i] * self.Y[i] * self.kernel(data, self.X[i])        return 1 if r > 0 else -1    def score(self, X_test, y_test):        right_count = 0        for i in range(len(X_test)):            result = self.predict(X_test[i])            if result == y_test[i]:                right_count += 1        return right_count / len(X_test)    def _weight(self):        # linear model        yx = self.Y.reshape(-1, 1) * self.X        self.w = np.dot(yx.T, self.alpha)        return self.wsvm = SVM(max_iter=200)svm.fit(X_train, y_train)print("评分:{}".format(svm.score(X_test, y_test)))

"python模拟支持向量机举例分析"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0