SVM支持向量机

Support Vector Machine

学习模型
有监督学习:需要事先对数据打上分类标签,这样机器就知道数据属于哪一类。

无监督学习:数据没有打上分类标签,有可能因为不具备先验知识,或打标签的成本很高,需要机器代替我们部分完成改工作,比如将数据进行聚类,方便后人工对每个类进行分析。

SVM 是有监督的学习模型:可以进行模式识别、分类以及回归分析。

SVM工作原理
示例: 桌面上有两种颜色混乱的小球,我们将这两种小球来区分开,我们猛拍桌子小球会腾起,在腾空的那一刹那,会出现一个水平切面,将两种颜色的球分开来。

原因: 二维平面无法找出一条直线来区分小球颜色,但是在三位空间。我们可以找到一个平面来区分小球颜色,该平面我们叫做超平面。

SVM计算过程: 就是帮我们找到一个超平面的过程,该超平面就是 SVM分类器。

分类间隔
我们在示例中,会找到一个决策面来将小球颜色分离,在保证决策面C不变,且分类不产生错误的情况下,我们可以移动决策面,来产生两个极限位置:决策面A和决策面B,分界线C就是最优决策面,极限位置到最优决策面的距离就是 分类间隔 。

我们可以转动最优决策面,会发现存在多个最优决策面,它们都能把数据集正确分开,这些最优决策面的分类间隔可能是不同的,拥有最大间隔的决策面就是 SVM 需要的最优解。

点到超平面距离公式
决策面在一维空间就是一个点、二维空间就是一条直线、三维空间就是一个平面,当空间维度更多,这个线性函数名称叫做 “超平面”:g(x)=wTx+b g(x) = w^Tx + bg(x)=w
T
x+b,其中w,x∈Rn w,x\in R^nw,x∈R
n

w、x是n维空间里的向量,其中x是函数变量,w是法向量。法向量指的是垂直于平面直线所表示的向量,决定超平面的方向。

SVM就是帮我们找到一个超平面 ,这个超平面能将不同样本划分,使得样本集中的点到这个分类超平面的最小距离(分类间隔)最大化,在这个过程中 支持向量 就是离 分类超平面 最近的样本点,如果确定了支持向量也就确定了这个超平面,所以支持向量决定了分类间隔是多少,在最大间隔以外的样本点,对分类都没有意义。

硬间隔、软间隔和非线性SVM
数据线性可分:模型称为硬间隔支持向量机
硬间隔:完全分类准确,不存在分类错误的情况
软间隔:允许一定量的样本分类错误
非线性数据:模型称为非线性支持向量机
非线性数据集合: 两种颜色的小球,呈现大小圆环的形状。

非线性数据集合,不论多高级的分类器,只要映射函数是线性的,就没办法处理,SVM也处理不了。

核函数: 可以将样本从原始空间映射到一个更高的特质空间中,使得样本在新空间中线性可分,我们就以可以使用原来的推到进行计算,所有推到都是在新空间,而不是在原来的空间中进行。

在非线性SVM中,核函数的选择就是影响SVM最大的变量,下面是常用的核函数

线性核
多项式核
高斯核
拉普拉斯核
sigmoid核
这些函数的区别在于映射方式的不同,通过核函数就能把样本空间投射到新的高维空间中。

结果: 软间隔和核函数的提出,都是为了方便对超平面公式中的w和b进行求解,得到最大分类间隔的超平面
SVM

SVM_introduction:

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 'sepal length', 'sepal width', 'petal length', 'petal width'
iris_feature = u'花萼长度', u'花萼宽度', u'花瓣长度', u'花瓣宽度'

if __name__ == "__main__":
    path = 'iris.data'  # 数据文件路径
    data = pd.read_csv(path, header=None)
    x, y = data[range(4)], data[4]
    y = pd.Categorical(y).codes
    x = x[[0, 1]]
    x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1, train_size=0.6)

    # 分类器
    clf = svm.SVC(C=0.1, kernel='linear', decision_function_shape='ovr')
    # clf = svm.SVC(C=0.8, kernel='rbf', gamma=20, decision_function_shape='ovr')
    clf.fit(x_train, y_train.ravel())

    # 准确率
    print(clf.score(x_train, y_train))  # 精度
    print('训练集准确率:', accuracy_score(y_train, clf.predict(x_train)))
    print(clf.score(x_test, y_test))
    print('测试集准确率:', accuracy_score(y_test, clf.predict(x_test)))

    # decision_function
    print('decision_function:\n', clf.decision_function(x_train))
    print('\npredict:\n', clf.predict(x_train))

    # 画图
    x1_min, x2_min = x.min()
    x1_max, x2_max = x.max()
    x1, x2 = np.mgrid[x1_min:x1_max:500j, x2_min:x2_max:500j]  # 生成网格采样点
    grid_test = np.stack((x1.flat, x2.flat), axis=1)  # 测试点
    # print 'grid_test = \n', grid_test
    # Z = clf.decision_function(grid_test)    # 样本到决策面的距离
    # print Z
    grid_hat = clf.predict(grid_test)  # 预测分类值
    grid_hat = grid_hat.reshape(x1.shape)  # 使之与输入的形状相同
    mpl.rcParams['font.sans-serif'] = [u'SimHei']
    mpl.rcParams['axes.unicode_minus'] = False

    cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
    cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
    plt.figure(facecolor='w')
    plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light)
    plt.scatter(x[0], x[1], c=y, edgecolors='k', s=50, cmap=cm_dark)  # 样本
    plt.scatter(x_test[0], x_test[1], s=120, facecolors='none', zorder=10)  # 圈中测试集样本
    plt.xlabel(iris_feature[0], fontsize=13)
    plt.ylabel(iris_feature[1], fontsize=13)
    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.title(u'鸢尾花SVM二特征分类', fontsize=16)
    plt.grid(b=True, ls=':')
    plt.tight_layout(pad=1.5)
    plt.show()

SVR:

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
from sklearn import svm
import matplotlib.pyplot as plt

if __name__ == "__main__":
    N = 50
    np.random.seed(0)
    x = np.sort(np.random.uniform(0, 6, N), axis=0)
    y = 2 * np.sin(x) + 0.1 * np.random.randn(N)
    x = x.reshape(-1, 1)
    print('x =\n', x)
    print('y =\n', y)

    print('SVR - RBF')
    svr_rbf = svm.SVR(kernel='rbf', gamma=0.2, C=100)
    svr_rbf.fit(x, y)
    print('SVR - Linear')
    svr_linear = svm.SVR(kernel='linear', C=100)
    svr_linear.fit(x, y)
    print('SVR - Polynomial')
    svr_poly = svm.SVR(kernel='poly', degree=3, C=100)
    svr_poly.fit(x, y)
    print('Fit OK.')

    # 思考:系数1.1改成1.5
    x_test = np.linspace(x.min(), 1.1 * x.max(), 100).reshape(-1, 1)
    y_rbf = svr_rbf.predict(x_test)
    y_linear = svr_linear.predict(x_test)
    y_poly = svr_poly.predict(x_test)

    plt.figure(figsize=(9, 8), facecolor='w')
    plt.plot(x_test, y_rbf, 'r-', linewidth=2, label='RBF Kernel')
    plt.plot(x_test, y_linear, 'g-', linewidth=2, label='Linear Kernel')
    plt.plot(x_test, y_poly, 'b-', linewidth=2, label='Polynomial Kernel')
    plt.plot(x, y, 'mo', markersize=6)
    plt.scatter(x[svr_rbf.support_], y[svr_rbf.support_], s=200, c='r', marker='*', label='RBF Support Vectors',
                zorder=10)
    plt.legend(loc='lower left')
    plt.title('SVR', fontsize=16)
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.grid(True)
    plt.tight_layout(2)
    plt.show()

sklearn.metrics评价指标
SVM评价指标

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score, recall_score, f1_score, fbeta_score
from sklearn.metrics import precision_recall_fscore_support, classification_report

if __name__ == "__main__":
    y_true = np.array([1, 1, 1, 1, 0, 0])
    y_hat = np.array([1, 0, 1, 1, 1, 1])
    print('Accuracy:\t', accuracy_score(y_true, y_hat))

    # The precision is the ratio 'tp / (tp + fp)' where 'tp' is the number of
    # true positives and 'fp' the number of false positives. The precision is
    # intuitively the ability of the classifier not to label as positive a sample
    # that is negative.
    # The best value is 1 and the worst value is 0.
    precision = precision_score(y_true, y_hat)
    print('Precision:\t', precision)

    # The recall is the ratio 'tp / (tp + fn)' where 'tp' is the number of
    # true positives and 'fn' the number of false negatives. The recall is
    # intuitively the ability of the classifier to find all the positive samples.
    # The best value is 1 and the worst value is 0.
    recall = recall_score(y_true, y_hat)
    print('Recall:  \t', recall)

    # F1 score, also known as balanced F-score or F-measure
    # The F1 score can be interpreted as a weighted average of the precision and
    # recall, where an F1 score reaches its best value at 1 and worst score at 0.
    # The relative contribution of precision and recall to the F1 score are
    # equal. The formula for the F1 score is:
    #     F1 = 2 * (precision * recall) / (precision + recall)
    print('f1 score: \t', f1_score(y_true, y_hat))
    print(2 * (precision * recall) / (precision + recall))

    # The F-beta score is the weighted harmonic mean of precision and recall,
    # reaching its optimal value at 1 and its worst value at 0.
    # The 'beta' parameter determines the weight of precision in the combined
    # score. 'beta < 1' lends more weight to precision, while 'beta > 1'
    # favors recall ('beta -> 0' considers only precision, 'beta -> inf' only recall).
    print('F-beta:')
    for beta in np.logspace(-3, 3, num=7, base=10):
        fbeta = fbeta_score(y_true, y_hat, beta=beta)
        print('\tbeta=%9.3f\tF-beta=%.5f' % (beta, fbeta))
        # print (1+beta**2)*precision*recall / (beta**2 * precision + recall)

    print(precision_recall_fscore_support(y_true, y_hat, beta=1))
    print(classification_report(y_true, y_hat))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值