挖个坑先
参考书籍为机器学习实践,之后会做详细解释
?
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
import torch
import time
iris =datasets.load_iris()
def get_data():
fig = plt.figure()
x, y1 =datasets.make_circles(n_samples=100, factor=0.1, noise=0.1)
plt.scatter(x[:, 0], x[:, 1], marker='o', c=y1)
plt.pause(2)
return x,y1
def process(_x):
'''
映射到高维核空间
:param data_point:
:param data_noise:
:return:
'''
Z = np.zeros([100, 3])
# 二项式映射
# X[:,0] = _x[:,0]**2
# X[:, 1] = math.sqrt(2)*_x[:,0]*_x[:,1]
# X[:,2] = _x[:,1]**2
# 高斯核映射
Z[:, 0] = np.exp(-(_x[:, 0] ** 2)) * np.exp(-(_x[:, 1] ** 2))
Z[:, 1] = 2 * _x[:, 0] * _x[:, 1] * np.exp(-(_x[:, 0] ** 2)) * np.exp(-(_x[:, 1] ** 2))
Z[:, 2] = 2 * _x[:, 0] ** 2 * _x[:, 1] ** 2 * np.exp(-(_x[:, 0] ** 2)) * np.exp(-(_x[:, 1] ** 2))
return Z
def selectJ(i,samples_num):
j=i
while j==i:
j=int(np.random.uniform(0,samples_num))
return j
def clipAlpha(L,H,alpha):
if alpha>H:
alpha= H
if alpha<L:
alpha=L
return alpha
#C是软间隔的惩罚参数,越大对错误分类惩罚越大
def smo(dataIn,classLabel,C,toler,maxIter):
dataMat = np.mat(dataIn)
labelMat = np.mat(classLabel).T
b = 0
m, n = np.shape(dataMat) # 样本数量为m
alpha = np.mat(np.zeros((m, 1)))
itera = 0
while itera < maxIter:
alphaPairChange = 0
for i in range(m):
if i == 1:
time.sleep(0.01)
gx_i = float(np.multiply(alpha, labelMat).T * (dataMat * dataMat[i, :].T)) + b
Ei = gx_i - float(labelMat[i])
if (labelMat[i] * Ei < -toler and alpha[i] < C) or (
labelMat[i] * Ei > toler and alpha[i] > 0): # 和书上kkt不一样为什么?
j = selectJ(i, m)
gx_j = float(np.multiply(alpha, labelMat).T * (dataMat * dataMat[j, :].T)) + b
Ej = gx_j - float(labelMat[j])
alpha_i_old = alpha[i].copy()
alpha_j_old = alpha[j].copy()
print(i, itera, gx_i, gx_j,b,np.sum(alpha))
time.sleep(0.01)
if labelMat[i] != labelMat[j]:
L = max(0, alpha[j] - alpha[i])
H = min(C, C + alpha[j] - alpha[i])
else:
L = max(0, alpha[j] + alpha[i] - C)
H = min(C, alpha[j] + alpha[i])
if L==H:
print('L==H')
continue
eta=2.0*dataMat[i,:]*dataMat[j,:].T-dataMat[i,:]*dataMat[i,:].T-dataMat[j,:]*dataMat[j,:].T#什么东西这是?epsilon
print(eta)
if eta>=0:
print('eta>=0')#why????????????
continue
alpha[j] -= labelMat[j] * (Ei - Ej) / eta # +or->>>>
alpha[j] = clipAlpha(L, H, alpha[j])
if abs(alpha[j] - alpha_j_old) < 0.00001:
print('j not moving enough')
continue
alpha[i] += labelMat[j] * labelMat[i] * (alpha_j_old - alpha[j])
b1 = b - Ei - labelMat[i] * (alpha[i] - alpha_i_old) * dataMat[i, :] * dataMat[i, :].T - labelMat[
j] * (alpha[j] - alpha_j_old) * dataMat[i, :] * dataMat[j, :].T
b2 = b - Ej - labelMat[i] * (alpha[i] - alpha_i_old) * dataMat[i, :] * dataMat[j, :].T - labelMat[
j] * (alpha[j] - alpha_j_old) * dataMat[j, :] * dataMat[j, :].T
if alpha[i] > 0 and alpha[i] < C:
b = b1
elif alpha[j] > 0 and alpha[j] < C:
b=b2
else:
b=(b1+b2)/2.0
alphaPairChange+=1
print(("iter{},i:{},pairchange{}".format(itera,i,alphaPairChange)))
if (alphaPairChange==0):
itera+=1
else:
itera=0
print('iteration{},m{}'.format(itera,i))
return b,alpha
#
# x0,y0=get_data()
# x=process(x0)
# print(x)
##线性可分
np.random.seed(0)
x=np.random.random((100,2))
x[:50,:]+=0.8
x[50:,:]-=0.8
print
y=np.array([0]*100)
y[:50]+=1
y[50:]-=1
print('y{}'.format(y))
plt.scatter(x[:50,0],x[:50,1],c='r')
plt.scatter(x[50:,0],x[50:,1],c='g')
# plt.pause(3)
b,alpha=smo(dataIn=x,classLabel=y,C=0.6,toler=0.001,maxIter=40)
print(b,alpha)
# w=alpha*y*x.T
#画出分割面
for i in range(100):
if alpha[i]>0.0:
print(x[i],y[i])
plt.scatter(x[i,0], x[i, 1], c='y')
plt.pause(10)
?
|