继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

支持向量机python实现(优化版)

慕标5832272
关注TA
已关注
手记 1071
粉丝 228
获赞 996
from numpy import *import numpy as npimport matplotlib.pyplot as pltdef load_set_data(file_name):
    data_mat = []
    label_mat = []
    n = 0

    fr = open(file_name)    for line in fr.readlines():
        line_arr = line.strip().split()
        data_mat.append([float(line_arr[0]), float(line_arr[1])])
        label_mat.append(float(line_arr[2]))
        n += 1

    return data_mat, label_mat, ndef select_j_rand(i, m):
    j = i    while (j == i):
        j = int(random.uniform(0, m))    return jdef clip_alpha(aj, H, L):
    if aj > H:
        aj = H    if aj < L:
        aj = L    return ajclass opt_struct:
    def __init__(self, data_matin, class_labels, C, toler):
        self.X = data_matin
        self.label_mat = class_labels
        self.C = C
        self.tol = toler
        self.m = shape(data_matin)[0]
        self.alphas = mat(zeros((self.m, 1)))
        self.b = 0
        self.e_cache = mat(zeros((self.m, 2)))    def calc_ek(os, k):

        fxk = float((multiply(os.alphas, os.label_mat).T) * (os.X * os.X[k, :].T)) + os.b
        ek = fxk - os.label_mat[k]        return fxk,ek    
    def select_j(os, i, ei):
        maxk = -1
        max_delta_e = 0
        ej = 0
        os.e_cache[i] = [1, ei]
        valid_e_cache_list = nonzero(os.e_cache[0].A)[0]        if(len(valid_e_cache_list)) > 1:            for k in valid_e_cache_list:                if (k == 1):                    continue
                fxk,ek = os.calc_ek(k)
                delta_e = abs(ei - ek)                if(delta_e > max_delta_e):
                    maxk = k
                    max_delta_e = delta_e
                    ej = ek                return maxk, ej        else:
            j = select_j_rand(i, os.m)
            fj,ej = os.calc_ek(j)            return j, ej    def update_ek(os, k):
        fxk,ek = os.calc_ek(k)
        os.e_cache[k] = [1, ek]def innert(os, i):
    fxi,ei = os.calc_ek(i)    if(((os.label_mat[i] * ei < -os.tol) and (os.alphas[i] < os.C)) or\
        ((os.label_mat[i] * ei > os.tol) and (os.alphas[i] > 0))):    #if((os.label_mat[i] * (fxi - 2 * os.b) <= 1 and os.alphas[i] < os.C)\
    #            or (os.label_mat[i] * (fxi - 2 * os.b) >= 1 and os.alphas[i] > 0)\
    #            or (os.label_mat[i] * (fxi - 2 * os.b) == 1 and (os.alphas[i] == 0 or os.alphas[i] == os.C))):
        j,ej = os.select_j(i, ei)
        alpha_i_old = os.alphas[i].copy()
        alpha_j_old = os.alphas[j].copy()        if(os.label_mat[i] != os.label_mat[j]):
            L = max(0, os.alphas[j] - os.alphas[i])
            H = min(os.C, os.C + os.alphas[j] - os.alphas[i])        else:
            L = max(0, os.alphas[j] + os.alphas[i] - os.C)
            H = min(os.C, os.alphas[j] + os.alphas[i])        if(L == H):
            print("L == H")            return 0
        eta = 2 * os.X[i, :] * os.X[j, :].T - os.X[i, :] * os.X[i, :].T - os.X[j, :] * os.X[j, :].T        if(eta >= 0):
            print("eta >= 0")            return 0
        os.alphas[j] = alpha_j_old - (os.label_mat[j] * (ei - ej)) * 1.0 / eta
        os.alphas[j] = clip_alpha(os.alphas[j], H, L)
        os.update_ek(j)        if(abs(os.alphas[j] - alpha_j_old) < 0.00001):
            print("j not move")            return 0
        os.alphas[i] = alpha_i_old + os.label_mat[i] * os.label_mat[j] * (alpha_j_old - os.alphas[j])
        os.update_ek(i)
        b1 = os.b - ei - os.label_mat[i] * (os.alphas[i] - alpha_i_old) * (os.alphas[i, :] * os.alphas[i, :].T) -\
            os.label_mat[j] * (os.alphas[j] - alpha_j_old) * (os.alphas[i, :] * os.alphas[j, :].T)
        b2 = os.b - ej - os.label_mat[j] * (os.alphas[i] - alpha_i_old) * (os.alphas[i, :] * os.alphas[j, :].T) -\
            os.label_mat[j] * (os.alphas[j, :] - alpha_j_old) * (os.alphas[j, :] * os.alphas[j, :])        if(os.alphas[i] > 0 and os.alphas[i] < os.C):
            os.b = b1        elif(os.alphas[j] > 0 and os.alphas[j] < os.C):
            os.b = b2        else:
            os.b = (b1 + b2) * 1.0 / 2
        return 1
    else:        return 0def smop(data_mat_in, class_labels, C, toler, max_iter):
    os = opt_struct(mat(data_mat_in), mat(class_labels).transpose(), C, toler)
    iter = 0
    entire_set = True
    alpha_paris_changed = 0
    while((iter < max_iter) and (alpha_paris_changed > 0) or (entire_set)):
        alpha_paris_changed = 0
        if entire_set:            for i in range(os.m):
                alpha_paris_changed += innert(os, i)
            iter += 1
        else:
            non_bound_is = nonzero((os.alphas.A > 0) * (os.alphas.A < C))[0]            for i in non_bound_is:
                alpha_paris_changed += innert(os, i)
            iter += 1
        if entire_set:
            entire_set = False
        elif(alpha_paris_changed == 0):
            entire_set = True

    return os.b, os.alphasdef show_experiment_plot(alphas, data_list_in, label_list_in, b, n):
    data_arr_in = array(data_list_in)
    label_arr_in = array(label_list_in)
    alphas_arr = alphas.getA()
    data_mat = mat(data_list_in)
    label_mat = mat(label_list_in).transpose()

    i = 0
    weights = zeros((2, 1))    while(i < n):        if(label_arr_in[i] == -1):
            plt.plot(data_arr_in[i, 0], data_arr_in[i, 1], "ob")        elif(label_arr_in[i] == 1):
            plt.plot(data_arr_in[i, 0], data_arr_in[i, 1], "or")        if(alphas_arr[i] > 0):
            plt.plot(data_arr_in[i, 0], data_arr_in[i, 1], "oy")
            weights += multiply(alphas[i] * label_mat[i], data_mat[i, :].T)
        i += 1

    x = arange(-2, 12, 0.1)
    y = []    for k in x:
        y.append(float(-b - weights[0] * k) / weights[1])

    plt.plot(x, y, '-g')
    plt.xlabel("X")
    plt.ylabel("Y")
    plt.show()def main():
    data_list,label_list, n = load_set_data("test_set.txt")
    b,alphas = smop(data_list, label_list, 0.6, 0.001, 40)
    b_data = array(b)[0][0]
    show_experiment_plot(alphas, data_list, label_list, b_data, n)

main()

在opt_struct类中的成员函数select_j,选择误差值最大的点进行更新拉格朗日系数是由式子:


webp

3.PNG


决定的,同时也说明了由决策函数计算得到的值与实际值偏差太大,则更加需要调整决策函数的权值,分类决策函数基本模型如下:


webp

4.PNG


权值与拉格朗日系数与权值的关系:

webp

5.PNG


由权值与拉格朗日系数的关系可以得出,如果权值需要更新则拉格朗日的系数也需要更新。
实验数据:

3.542485    1.977398    -13.018896    2.556416    -17.551510    -1.580030   1
2.114999    -0.004466   -18.127113    1.274372    1
7.108772    -0.986906   1
8.610639    2.046708    1
2.326297    0.265213    -13.634009    1.730537    -10.341367    -0.894998   -13.125951    0.293251    -12.123252    -0.783563   -10.887835    -2.797792   -17.139979    -2.329896   1
1.696414    -1.212496   -18.117032    0.623493    1
8.497162    -0.266649   1
4.658191    3.507396    -18.197181    1.545132    1
1.208047    0.213100    -11.928486    -0.321870   -12.175808    -0.014527   -17.886608    0.461755    1
3.223038    -0.552392   -13.628502    2.190585    -17.407860    -0.121961   1
7.286357    0.251077    1
2.301095    -0.533988   -1-0.232542   -0.547690   -13.457096    -0.082216   -13.023938    -0.057392   -18.015003    0.885325    1
8.991748    0.923154    1
7.916831    -1.781735   1
7.616862    -0.217958   1
2.450939    0.744967    -17.270337    -2.507834   1
1.749721    -0.961902   -11.803111    -0.176349   -18.804461    3.044301    1
1.231257    -0.568573   -12.074915    1.410550    -1-0.743036   -1.736103   -13.536555    3.964960    -18.410143    0.025606    1
7.382988    -0.478764   1
6.960661    -0.245353   1
8.234460    0.701868    1
8.168618    -0.903835   1
1.534187    -0.622492   -19.229518    2.066088    1
7.886242    0.191813    1
2.893743    -1.643468   -11.870457    -1.040420   -15.286862    -2.358286   1
6.080573    0.418886    1
2.544314    1.714165    -16.016004    -3.753712   1
0.926310    -0.564359   -10.870296    -0.109952   -12.369345    1.375695    -11.363782    -0.254082   -17.279460    -0.189572   1
1.896005    0.515080    -18.102154    -0.603875   1
2.529893    0.662657    -11.963874    -0.365233   -18.132048    0.785914    1
8.245938    0.372366    1
6.543888    0.433164    1-0.236713   -5.766721   -18.112593    0.295839    1
9.803425    1.495167    1
1.497407    -0.552916   -11.336267    -1.632889   -19.205805    -0.586480   1
1.966279    -1.840439   -18.398012    1.584918    1
7.239953    -1.764292   1
7.556201    0.241185    1
9.015509    0.345019    1
8.266085    -0.230977   1
8.545620    2.788799    1
9.295969    1.346332    1
2.404234    0.570278    -12.037772    0.021919    -11.727631    -0.453143   -11.979395    -0.050773   -18.092288    -1.372433   1
1.667645    0.239204    -19.854303    1.365116    1
7.921057    -1.327587   1
8.500757    1.492372    1
1.339746    -0.291183   -13.107511    0.758367    -12.609525    0.902979    -13.263585    1.367898    -12.912122    -0.202359   -11.731786    0.589096    -12.387003    1.573131    -1

实验结果如下:


webp

1.PNG


可以看出优化版的与简化版的稍有不同,但是速度明显提高了许多,支持向量的点也多一些。

             




作者:幸福洋溢的季节
链接:https://www.jianshu.com/p/a2ee7524b75d


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP