21.8.29 逻辑分类

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+ex1
该逻辑函数当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()

分类效果不如人意
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值