import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.linear_model import Perceptron
import warnings
warnings.filterwarnings('ignore')
def loadDataset():
dataset = datasets.load_breast_cancer()
x = dataset.data
y = dataset.target
feats = dataset.feature_names
labels = dataset.target_names
return x,y,feats,labels
x,y,feats,labels = loadDataset()
def normalizationData(x,y):
nx = x.copy()
dim = x.shape[1]
for i in range(dim):
nx[:,i] = (x[:,i]-x[:,i].min())/(x[:,i].max()-x[:,i].min())
ny = y.copy()
ny[ny==0] = -1
return nx,ny
nx,ny = normalizationData(x,y)
def divideDataset(nx,y,rate):
samples = y.shape[0]
trainnum = round(samples*rate)
index = np.random.permutation(range(samples))
x_train,x_test = nx[index[0:trainnum],:],x[index[trainnum:],:]
y_train,y_test = y[index[0:trainnum]],y[index[trainnum:]]
return x_train,x_test,y_train,y_test
x_train,x_test,y_train,y_test = divideDataset(nx,ny,rate=0.8)
def trainModel(x_train,y_train,maxgen,lr):
dim = x_train.shape[1]
w = np.zeros(dim)
b = 0
for L in range(maxgen):
S = (np.dot(x_train,w)+b)*y_train
Mx = np.where(S<=0)[0]
if len(Mx):
index = np.random.choice(Mx)
w = w + lr*y_train[index]*(x_train[index,:]).T
b = b + lr*y_train[index]
else:
break
return w,b
w,b = trainModel(x_train,y_train,maxgen=200,lr=0.01)
def predictModel(x,y,w,b):
predict = np.sign(np.dot(x,w)+b)
acc = len(y[predict==y])/len(y)
return predict,round(acc,4)
print('======结果比对======\n')
predict_train,train_acc = predictModel(x_train,y_train,w,b)
predict_test,test_acc = predictModel(x_test,y_test,w,b)
print('self-written (origin)==> Train acc = ',train_acc,' Test acc = ',test_acc)
def gramMat(x):
num = x.shape[0]
gram = []
for i in range(num):
for j in range(num):
gram.append(np.dot(x[i,:],x[j,:].T))
gram = np.array(gram).reshape(num,num)
return gram
def dualTrainModel(x_train,y_train,maxgen,lr):
alpha = np.zeros(y_train.shape[0])
b = 0
gram = gramMat(x_train)
for L in range(maxgen):
S = y_train*(np.dot(gram.T,alpha*y_train)+b)
Mx = np.where(S<=0)[0]
if len(Mx):
index = np.random.choice(Mx)
alpha[index] = alpha[index] + lr
b = b + lr*y_train[index]
else:
break
return alpha,b
alpha,b = dualTrainModel(x_train,y_train,maxgen=200,lr=0.01)
def dualPredictModel(x,y,alpha,b):
predict = np.zeros(y.shape[0])
for i in range(x.shape[0]):
v = np.sum(alpha*y_train*np.dot(x_train,x[i].T))+b
predict[i] = v
predict = np.sign(predict)
acc = len(y[predict==y])/len(y)
return predict,round(acc,4)
predict_train,train_acc = predictModel(x_train,y_train,w,b)
predict_test,test_acc = predictModel(x_test,y_test,w,b)
print('self-written(dual) ==> Train acc = ',train_acc,' Test acc = ',test_acc)
model = Perceptron(alpha=0.01)
model.fit(x_train,y_train)
train_acc = model.score(x_train,y_train)
test_acc = model.score(x_test,y_test)
print('sklearn ==> Train acc = ',round(train_acc,4),' Test acc = ',round(test_acc,4))