1. 人工分类
主要靠 plt.pcolormesh 来实现
尝试使用线性回归和岭回归来耍耍,但效果不咋地
特别是正则项c的取法,奇怪的一批
import numpy as np
import matplotlib.pyplot as plt
x = np.array([
[3, 1],
[2, 5],
[1, 8],
[6, 4],
[5, 2],
[3, 5],
[5, 7],
[4, -1]])
y = np.array([0, 1, 1, 0, 0, 1, 1, 0])
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
n = 500
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
grid_z = np.piecewise(grid_x, [grid_x>grid_y, grid_x<grid_y], [1, 0])
plt.figure('Simple Classification', facecolor='lightgray')
plt.title('Simple Classification', fontsize=20)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x, grid_y, grid_z, cmap='gray')
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80)
#下面尝试用线性回归的方法来试试
#没啥就是觉得好玩
#我再确认一下这个y要么0要么1是干什么用的
#只是一个代表,表示x1>x2->0,x1<x2->1
#y=kx+b, distance=|kx0+b-y0|/(k**2+1)**1/2
#loss=(kx0+b-y0)**2/(k**2+1)
#原始的好像不大行,要不考虑下加入c*y来判定,类似岭回归?
#玩不了,这个不知道怎么把y=-1或+1加进去
lr=0.001
times=1000
w=2
b=2
x1=x[:,0]
x2=x[:,1]
c=-5
z=y
y=x2
x=x1
size=int(len(x))
# w=argmin(J(w)=(x.T+c*i).(-1)*x.T*y
#J=(y-w*x)**2+c*w*w
for i in range(times):
loss=0
loss=((y-w*x)**2+c*w*w).sum()
d_k=((-2)*x*(y-w*x)+2*c*w).sum()
d_b=(2*(y-w*x+b)).sum()
w=w-d_k*lr
b=b-d_b*lr
print(loss)
print(w,b)
x1=x
x2=y
x1_max=x1.max()
x1_min=x1.min()
test_x=np.linspace(x1_min,x1_max,100)
x1=test_x
pred_test_y=w*test_x+b
plt.title('try')
plt.plot(test_x, pred_test_y, '--', c='limegreen', label='Regression', linewidth=1)
plt.legend()
plt.show()
2.逻辑分类
通过输入的样本数据,基于多元线型回归模型求出线性预测方程。
y = w0+w1x1+w2x2
但通过线型回归方程返回的是连续值,不可以直接用于分类业务模型,所以急需一种方式使得把连续的预测值->离散的预测值。 [-inf, +inf]->{0, 1}
逻
辑
函
数
(
s
i
g
m
o
i
d
f
u
n
c
t
i
o
n
)
:
y
=
1
1
+
e
−
x
逻辑函数(sigmoid function):y = \frac{1}{1+e^{-x}}
逻辑函数(sigmoidfunction):y=1+e−x1
该逻辑函数当x>0,y>0.5----->0;
当x<0, y<0.5------->1
按这边上面的y0 = w0+w1x1+w2x2,可以将y0当作x带入到sigmoid function,然后得到0或1,完成分类任务
API
原理:找到一组最适合的权重,构造
y0 = w0+w1x1+w2x2
接着下测试的时候把y0带入sigmoid函数中完成分类
import sklearn.linear_model as lm
# 构建逻辑回归器
# solver:逻辑函数中指数的函数关系(liblinear为线型函数关系)
# C:参数代表正则强度,为了防止过拟合。正则越大拟合效果越小。
model = lm.LogisticRegression(solver='liblinear', C=正则强度)
model.fit(训练输入集,训练输出集)
result = model.predict(带预测输入集)
#相较于人工分类感觉也没改多少,但是也不难发掘上面的np.piecewise()有点主观臆测的意思,不大好
import numpy as np
import matplotlib.pyplot as plt
import sklearn.linear_model as lm
x = np.array([
[3, 1],
[2, 5],
[1, 8],
[6, 4],
[5, 2],
[3, 5],
[5, 7],
[4, -1]])
y = np.array([0, 1, 1, 0, 0, 1, 1, 0])
model=lm.LogisticRegression(solver='liblinear')
model.fit(x,y)
#x1,x2
#作图
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
n = 500
#grid_x: 50*50
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
sameples= np.column_stack((grid_x.ravel(),grid_y.ravel()))
grid_z=model.predict(sameples)
grid_z = grid_z.reshape(grid_x.shape)
plt.figure('Simple Classification', facecolor='lightgray')
plt.title('Simple Classification', fontsize=20)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x, grid_y, grid_z,shading='auto', cmap='gray')
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80)
plt.show()
3.多元分类
以窥一斑而知全豹,后面的可能也是用这种方法
它的想法是这样的,知道一个sigmoid可以得到一个概率值(0和1是在师傅大于0.5的基础上再弄的),比如说下面那个图,要分成3类,准备三个分类器,对一个对象三个都跑一轮并几率下属于A,B,C的概率值,取最大者为类属
方法:
import numpy as np
import sklearn.linear_model as lm
import matplotlib.pyplot as mp
x = np.array([
[4, 7],
[3.5, 8],
[3.1, 6.2],
[0.5, 1],
[1, 2],
[1.2, 1.9],
[6, 2],
[5.7, 1.5],
[5.4, 2.2]])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])
# 逻辑分类器
model = lm.LogisticRegression(solver='liblinear', C=1000)
model.fit(x, y)
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
n = 500
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
samples = np.column_stack((grid_x.ravel(), grid_y.ravel()))
grid_z = model.predict(samples)
print(grid_z)
grid_z = grid_z.reshape(grid_x.shape)
mp.figure('Logistic Classification', facecolor='lightgray')
mp.title('Logistic Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x, grid_y, grid_z, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80)
mp.show()
4.手写版
解释一下参数
这里认为最后的拟合结果是y=w0+w1x1+w2x2
认为损失函数是这个
loss_fuc:用来求损失值
e_y : exp.((-1)(w0+w1x1+w2*x2))
times1/2: loss function的乘法用项
model_lr:用来训练的
d_w_0/1/2:偏导结果
lr:学习率
times:训练轮数
num:分类结果数目、分类器数目
size_x: 样本长度
jug:这个本来是用来进行多分类的函数,它的想法是创造一个大小为size_x * num的矩阵,然后对于每一个样本,分别带入num个model中(此时的model应该是sigmoid(y)),返回一个概率,然后取num个概率中的最大值对应的选项为分类结果
至于为什么不用.sum(),说真的不大会操作,因为式子太长怕出问题
t=[[]]:这个是解决size不对用的
import numpy as np
import math
import matplotlib.pyplot as plt
def loss_func(w0,w1,w2,x,y):
x1 = x[:, 0]
x2 = x[:, 1]
# print('hello!!!!!!')
# print('x1',x1)
# print('x2',x2)
# print('y',y)
size_x=int(len(x))
# print('size_x',size_x)
fina=0
e_y=0
#sum
for i in range(size_x):
e_y=0
p_y_1=0
# print('i', i)
# print('w0',w0,'w1',w1,'w2',w2)
# print('x1[i]', x1[i])
e_y = w0 + w1 * x1[i] + w2 * x2[i]
e_y=(-1)*e_y
e_y=math.exp(e_y)
#print('e_y:',e_y)
p_y_1 = 1 / (1 + e_y)
# print('p_y_1',p_y_1)
# print('YYYYY'*50)
times_1=math.log(p_y_1)
temp=1-p_y_1
# print('times1', times_1)
# print('temp',temp)
# print('temp',temp)
times_2=math.log(temp)
# print('times1',times_1)
# print('times2',times_2)
fina = y[i] * times_1 + (1 - y[i]) * times_2+fina
# print('fina',fina)
# print('_' * 50)
# print('*'*50)
return fina
#y=w0+w1*x1+w2*x2
def model_lr(x,y,times,lr=0.001,w0=1,w1=1,w2=1):
size_x=int(len(x))
#p(xi)表示什么
x1=x[:,0]
x2=x[:,1]
loss_last=0
loss_now=0
for i in range(times):
# print('round##########'*50)
# print('round',i)
loss_pre = loss_func(w0=w0,w1=w1,w2=w2,x=x,y=y)
# print('loss_ready&&&&&&'*10)
loss_last = (-1) * loss_pre / size_x
# p_x表示x对应的y=1的概率
d_w_0 = 0
d_w_1 = 0
d_w_2 = 0
#sum
base_one=0
for j in range(size_x):
base_one=(y[j] -1)
d_w_0 = d_w_0+base_one
d_w_1 = d_w_1+base_one * x1[j]
d_w_2 = d_w_2+base_one* x2[j]
w0=w0-lr*d_w_0
w1=w1-lr*d_w_1
w2=w2-lr*d_w_2
loss_now=loss_func(w0,w1,w2,x,y)
loss_gap=abs(loss_now-loss_last)
#print('loss_now',loss_now)
#print('times:{:} size:{:} loss_gap'.format(i,j),loss_gap)
return w0,w1,w2
def model_pred(w0,w1,w2,x):
x1=x[:,0]
x2=x[:,1]
e_x = (w0 + w1 * x1 + w2 * x2).sum()
e_x = (-1) * e_x
e_x = math.exp(e_x)
sigmoid_result=1/(1+e_x)
return sigmoid_result
#return z
def jug(samples,size_x, num,model_w_list,y_list):
jug_array=np.array(np.arange(size_x*num),dtype=np.float32).reshape(size_x,num)
print(model_w_list)
for j in range(size_x):
for i in range(num):
#model = model_list[i]
l = np.array(model_w_list, dtype=np.float32)
w0,w1,w2=l[i][0],l[i][1],l[i][2]
t=[[]]
t[0]=samples[j]
sample_in=np.array(t)
jug_array[j][i]=np.array(model_pred(w0=w0,w1=w1,w2=w2,x=sample_in),dtype=np.float32)
fin_array=np.arange(size_x*1).reshape(size_x,1)
#y_list中的顺序以及确切数字
z_pre=[]
z=[]
for k in range(size_x):
a=jug_array[k,:]
#print(a)
a_f=a.argsort()[::-1]
#顺序数字
z_pre.append(a_f[0])
#得到对应数字
print(z_pre)
for i in range(int(len(z_pre))):
pos=z_pre[i]
z.append(y_list[pos])
return z
x = np.array([
[3, 1],
[2, 5],
[1, 8],
[6, 4],
[5, 2],
[3, 5],
[4, 7],
[4, -1]])
y = np.array([0, 1, 1, 0, 0, 1, 1, 0])
#print(y)
y_list=list(set(y))
#print(y_list)
num=int(len(set(y)))
#print(num)
size_x=int(len(x))
#print(size_x)
model_list=[]
# 逻辑分类器
# 每一个分类器都得到训练
#train
#w0 w1 w2
model_w_list=np.arange(num*3).reshape(num,3)
model_w_list=np.array(model_w_list,dtype=np.float32)
print(model_w_list)
print(num)
for i in range(num):
# print('round',i)
#exec(f'model_{i} = lm.LogisticRegression(solver=\'liblinear\')')
chara = y_list[i]
#print('y',y)
y_new = np.where(y ==chara,1,0)
# y_new=np.array(y_new).ravel()
#print('y_new',y_new)
l=np.array(model_lr(x,y_new,100),dtype=np.float32)
model_w_list[i][0],model_w_list[i][1],model_w_list[i][2]=l[0],l[1],l[2]
#print('/'*50)
#print(len(set(list)))
#y=w0+w1*x1+w2*x2
#分类器的话,是不是相符的给1,不相符的给0这样
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
n = 100
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
samples = np.column_stack((grid_x.ravel(), grid_y.ravel()))
#samples = x
size_x=int(len(samples))
grid_z=jug(samples,size_x,num,model_w_list=model_w_list,y_list=y_list)
grid_z =np.array(grid_z).reshape(grid_x.shape)
plt.pcolormesh(grid_x, grid_y, grid_z, cmap='gray')
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80,zorder=3)
plt.show()
分类效果不如人意