Python(线性不可分SVM)

线性不可分SVM(SMO算法)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import classification_report

import warnings
warnings.filterwarnings('ignore')

data = pd.read_csv('data.csv',encoding='utf8',header=None)
arr = data.values

encoder = preprocessing.LabelEncoder()
labels = encoder.fit_transform(arr[:,1])
for label,num in enumerate(encoder.classes_):
    print(label,'-->',num)
arr[:,1] = labels

x,y = arr[:,0:-1],arr[:,-1]
nx = preprocessing.StandardScaler().fit_transform(x)
x_train,x_test,y_train,y_test = train_test_split(nx.astype(float),y.astype(float),test_size=0.2,random_state=1)

(n,m) = x_train.shape

def func(x,y,choice):
    if choice == 'rbf':
        r = 0.5
        result = np.exp(-r*sum((x-y)**2))
    if choice == 'poly':
        p = 2
        result = (np.dot(x.T,y)+1)**p
    return result
    
gram = np.zeros((n,n))
for i in range(n):
    for j in range(n):
        gram[i,j] = func(x_train[i],x_train[j],'rbf')

a = np.zeros(n)
b = 0
C = 1
p = np.zeros(n)
maxgen = 100

def v1(a,y,gram):
    yg = np.dot((a*y).T,gram)
    e = (yg-1)**2
    e1,e2,e3 = e,e.copy(),e.copy()
    e1[(a>0)|(yg>=1)] = 0
    e2[(a==0)|(a==C)|(yg==1)] = 0
    e3[(a<C)|(yg<=1)] = 0
    s = e1+e2+e3
    index = np.argmax(s)
    return index

def v2(v1,n):
    index = np.random.randint(n)
    while v1 == index:
        index = np.random.randint(n)
    return index

for t in range(maxgen):
    i1 = v1(a,y_train,gram)
    i2 = v2(i1,n)
    
    old_a1,old_a2 = a[i1],a[i2]
    old_y1,old_y2 = y_train[i1],y_train[i2]
    if old_y1 == old_y2:
        L = max(0,old_a2+old_a1-C)
        H = min(C,old_a2+old_a1)
    else:
        L = max(0,old_a2-old_a1)
        H = min(C,old_a2-old_a1+C)
    E1 = np.dot((a*y_train).T,gram[:,i1])+b - y_train[i1]
    E2 = np.dot((a*y_train).T,gram[:,i2])+b - y_train[i2]
    g = gram[i1,i1]+gram[i2,i2]-2*gram[i1,i2]
    tmp_a2 = old_a2 + y_train[i2]*(E1-E2)/g
    
    if tmp_a2>H:
        a[i2] = H
    if tmp_a2 >=L and tmp_a2<=H:
        a[i2] = tmp_a2
    if tmp_a2<L:
        a[i2] = L
        
    deta_a2 = a[i2]-old_a2
    a[i1] = old_a1-old_y1*old_y2*deta_a2
    deta_a1 = a[i1]-old_a1
    dw = (y_train[i1]*deta_a1,y_train[i2]*deta_a2)
    b1 = -E1-y_train[i1]*gram[i1,i1]*deta_a1-y_train[i2]*gram[i1,i2]*deta_a2
    b2 = -E2-y_train[i1]*gram[i1,i2]*deta_a1-y_train[i2]*gram[i2,i2]*deta_a2
    db = (b1+b2)/2
    p = p+dw[0]*gram[i1].T+dw[1]*gram[i2].T+db

w = np.dot(x_train.T,(a*y_train))
index = np.where((a>0)&(a<C))[0][0]        
b = y_train[index]-np.dot((y_train*a).T,gram[:,index])

predict_train = np.sign(np.dot(x_train,w)+b)
train_acc = len(y_train[predict_train==y_train])/len(y_train)
print('Train acc = ',train_acc)
print(classification_report(y_train,predict_train))

predict_test = np.sign(np.dot(x_test,w)+b)
test_acc = len(y_test[predict_test==y_test])/len(y_test)
print('Test acc = ',test_acc)
print(classification_report(y_test,predict_test))

print('------sklearn-SVC------')
clf = SVC(C=1.0,kernel='rbf')
clf.fit(x_train,y_train.astype(int))
predict_train = clf.predict(x_train)
train_acc = len(y_train[predict_train==y_train])/len(y_train)
predict_test = clf.predict(x_test)
test_acc = len(y_test[predict_test==y_test])/len(y_test)
print('Train acc:',train_acc,'\n',classification_report(y_train.astype(int),predict_train))
print('Test acc:',test_acc,'\n',classification_report(y_test.astype(int),predict_test))

猜你喜欢

转载自blog.csdn.net/qinlan1994/article/details/82931868