当前位置: 首页 > article >正文

记5(一元逻辑回归+线性分类器+多元逻辑回归

目录

  • 1、一元逻辑回归
  • 2、线性可分&线性不可分
  • 3、Iris数据集实现多元逻辑回归
  • 4、绘制分类图
  • 5、鸢尾花分类图
  • 6、多分类问题:(softmax回归)
    • 6.1、编码:自然顺序码、独热编码、独冷编码
    • 6.2、二/多分类问题:
    • 6.3、softmax回归:
    • 6.4、(非)互斥的多分类问题:

1、一元逻辑回归

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#x是商品房面积,y是对应的商品房类型
x=np.array([137.97,104.50,100.00,126.32,79.20,99.00,124.00,114.00,
            106.69,140.05,53.75,46.91,68.00,63.02,81.26,86.21])
y=np.array([1,1,0,1,0,1,1,0,0,1,0,0,0,0,0,0])
#plt.scatter(x,y)  #可以看到横坐标面积都是大于40的正数
x_train=x-np.mean(x)        #因为sigmoid函数是以0点为中心的,所以需要中心化
y_train=y
#plt.scatter(x,y)

learn_rate=0.005        #超参数
iter=5
display_step=1          #显示间隔

np.random.seed(612)
w=tf.Variable(np.random.randn())
b=tf.Variable(np.random.randn())
cross_train=[]           #存放训练集的交叉熵损失
acc_train=[]             #存放训练集的分类准确率

plt.scatter(x_train,y_train)
x_=range(-80,80)
y_=1/(1+tf.exp(-(w*x_+b)))
plt.plot(x_,y_,color="red",linewidth=3) #绘制使用初始的w、b值时的sigmoid函数曲线,此时w<0,b<0

for i in range(0,iter+1):
    with tf.GradientTape() as tape:
        #Sigmoid函数
        pred_train=1/(1+tf.exp(-(w*x_train+b)))
        #交叉熵损失函数
        Loss_train=-tf.reduce_mean(y_train*tf.math.log(pred_train)+(1-y_train)*tf.math.log(1-pred_train))
        #准确率
        Accuracy_train=tf.reduce_mean(tf.cast(tf.equal(tf.where(pred_train<0.5,0,1),y_train),tf.float32))
        
    cross_train.append(Loss_train)
    acc_train.append(Accuracy_train)
    
    dL_dw,dL_db=tape.gradient(Loss_train, [w,b])
    w.assign_sub(learn_rate*dL_dw)
    b.assign_sub(learn_rate*dL_db)
    
    if i%display_step==0:
        print("i:%i,Train Loss:%f, Accuracy:%f" %(i,Loss_train,Accuracy_train))
        y_=1/(1+tf.exp(-(w*x_+b)))
        plt.plot(x_,y_)     #绘制每次间隔后,当前权值的sigmoid曲线

在这里插入图片描述
训练测试数据(不是测试集,因为是数据无标签)及其可视化:

x_test=[128.15,45.00,141.43,106.27,99.00,53.84,85.36,70.00,162.00,114.60]
pred_test=1/(1+tf.exp(-(w*(x_test-np.mean(x))+b)))
y_test=tf.where(pred_test<0.5,0,1)
for i in range(len(x_test)):
    print(x_test[i],"\t",pred_test[i].numpy(),"\t",y_test[i].numpy(),"\t")
#测试集数据的可视化
plt.scatter(x_test,y_test)
y_=1/(1+tf.exp(-(w*x_+b)))
plt.plot(x_+np.mean(x),y_)
plt.show()
#输出:
128.15 	 0.8610252 	 1 	
45.0 	 0.0029561974 	 0 	
141.43 	 0.9545566 	 1 	
106.27 	 0.45318928 	 0 	
99.0 	 0.2981362 	 0 	
53.84 	 0.00663888 	 0 	
85.36 	 0.108105935 	 0 	
70.0 	 0.028681064 	 0 	
162.0 	 0.9928677 	 1 	
114.6 	 0.6406205 	 1 

在这里插入图片描述

2、线性可分&线性不可分

  • 线性可分:通过一条直线分开
    与或非都是线性可分,异或线性不可分:
    在这里插入图片描述
  • 线性分类器
    在这里插入图片描述
  • 线性不可分:无法通过一条直线分开(但可以是2条直线或1条曲线)

3、Iris数据集实现多元逻辑回归

属性选取花萼长度、宽度;标签选山鸢尾(Setosa)、变色鸢尾(Virginica),

线性分类器:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
plt.rcParams["font.family"] = "SimHei"
plt.rcParams['axes.unicode_minus']=False    #用来正常显示负号
#读取文件,详见Python笔记10
train_path=tf.keras.utils.get_file("iris.csv", origin=None)   #获取文件的绝对路径
df_iris=pd.read_csv(train_path,header=0)        #结果是panda的二维数据表
iris=np.array(df_iris)        #将二维数据表类型转化为二维数组类型,shape=(150,6),与视频中不一样,索引号为0的是序号
x=iris[:,1:3]         #索引号1、2列属性:花瓣长度和宽度,x.shape=(150, 2)
y=iris[:,5]          #train_y.shape=(150,)

x_sv=np.concatenate((np.stack(x[y=='setosa']),  #选取2种花,共100条数据,以及其前2种属性
                     np.stack(x[y=='versicolor'])),axis=0)
y_sv=np.concatenate((np.zeros(np.where(y=='setosa')[0].size),   #元组只有一个元素(数组)
                     np.ones(np.where(y=='versicolor')[0].size)),axis=0)

np.random.seed(612)
iris_rand=np.concatenate((x_sv,np.expand_dims(y_sv,axis=1)),axis=1)
np.random.shuffle(iris_rand)        #打乱数组,并选前面78条数据为训练集,后面22条做测试集
x_train=iris_rand[:78,0:2]
y_train=iris_rand[:78,2]
x_test=iris_rand[78:,0:2]
y_test=iris_rand[78:,2]

#训练前的可视化
cm_pt=mpl.colors.ListedColormap(["blue","red"])     #自定义颜色集合(蓝色,红色)
#plt.scatter(x_train[:,0],x_train[:,1],c=y_train,cmap=cm_pt) 
#plt.show()  #横坐标花萼长度,纵坐标花萼宽度,蓝色'setosa',红色'versicolor',尺度相同不用归一化

x_train=x_train-np.mean(x_train,axis=0)     #中心化
x_test=x_test-np.mean(x_test,axis=0)        #中心化
# plt.scatter(x_train[:,0],x_train[:,1],c=y_train,cmap=cm_pt) 
# plt.show()

x0_train=np.ones(len(x_train)).reshape(-1,1)    #见机器学习笔记4——多元线性回归,一样的
X_train=tf.cast(tf.concat([x0_train,x_train],axis=1),tf.float32)  #X.shape=TensorShape([78, 3])
Y_train=tf.constant(y_train.reshape(-1,1),tf.float32)             #Y.shape=TensorShape([78, 1])

x0_test=np.ones(len(x_test)).reshape(-1,1)    #见上面训练集,一样的
X_test=tf.cast(tf.concat([x0_test,x_test],axis=1),tf.float32)  #X.shape=TensorShape([22, 3])
Y_test=tf.constant(y_test.reshape(-1,1),tf.float32)             #Y.shape=TensorShape([22, 1])

learn_rate=0.2                                  #超参数——学习率
iter=120                                         #迭代次数
display_step=30                                 #设置每迭代10次输出结果,方便查看
np.random.seed(615)
W=tf.Variable(np.random.randn(3,1),dtype=tf.float32)    #W列向量,3行1列
ce_train=[]       #保存交叉熵损失
ce_test=[]
acc_train=[]      #保存准确率
acc_test=[]
#训练模型
for i in range(0,iter+1):
    with tf.GradientTape() as tape:
        #Sigmoid函数,PRED是列向量,是每个样品的预测概率
        PRED_train=1/(1+tf.exp(-tf.matmul(X_train,W)))
        PRED_test=1/(1+tf.exp(-tf.matmul(X_test,W)))
        #交叉熵损失函数
        Loss_train=-tf.reduce_mean(Y_train*tf.math.log(PRED_train)+(1-Y_train)*tf.math.log(1-PRED_train))
        Loss_test=-tf.reduce_mean(Y_test*tf.math.log(PRED_test)+(1-Y_test)*tf.math.log(1-PRED_test))
    
    #准确率,训练集:将预测值PRED_train二值化,并与真实值Y_train比较
    Accuracy_train=tf.reduce_mean(tf.cast(tf.equal(tf.where(PRED_train.numpy()<0.5,0.,1.),Y_train),tf.float32))
    Accuracy_test=tf.reduce_mean(tf.cast(tf.equal(tf.where(PRED_test.numpy()<0.5,0.,1.),Y_test),tf.float32))    
    ce_train.append(Loss_train)
    ce_test.append(Loss_test)
    acc_train.append(Accuracy_train)
    acc_test.append(Accuracy_test)
    #只使用训练集来更新参数
    dL_dW=tape.gradient(Loss_train, W)
    W.assign_sub(learn_rate*dL_dW)
    
    if i%display_step==0:
        print("i:%i,\tTrainAcc:%f,TrainLoss:%f\tTestAcc:%f,TestLoss:%f" 
              %(i,Accuracy_train,Loss_train,Accuracy_test,Loss_test))

#可视化,
plt.figure(figsize=(8,8))
#绘制损失和准确率的变化曲线
plt.subplot(221)
plt.plot(ce_train,color="blue",label="Train Loss")
plt.plot(acc_train,color="red",label="Train Acc")
plt.legend()
plt.subplot(223)
plt.plot(ce_test,color="blue",label="Test Loss")
plt.plot(acc_test,color="red",label="Test Acc")
plt.legend()
#绘制散点图、决策边界
plt.subplot(222)
plt.scatter(x_train[:,0],x_train[:,1],c=y_train,cmap=cm_pt)
x_=[-1.5,1.5]
y_=-(W[1]*x_+W[0])/W[2]
plt.plot(x_,y_,color='g')
plt.subplot(224)
plt.scatter(x_test[:,0],x_test[:,1],c=y_test,cmap=cm_pt)
plt.plot(x_,y_,color='g')
plt.suptitle("训练集(上)&测试集(下)")
plt.show()

输出:

i:0,	TrainAcc:0.474359,TrainLoss:0.887229	TestAcc:0.409091,TestLoss:0.854671
i:30,	TrainAcc:0.846154,TrainLoss:0.464031	TestAcc:0.818182,TestLoss:0.448182
i:60,	TrainAcc:0.961538,TrainLoss:0.317919	TestAcc:0.909091,TestLoss:0.318348
i:90,	TrainAcc:0.987179,TrainLoss:0.244545	TestAcc:0.909091,TestLoss:0.256466
i:120,	TrainAcc:1.000000,TrainLoss:0.200362	TestAcc:0.909091,TestLoss:0.220343

在这里插入图片描述

4、绘制分类图

生成网格坐标矩阵:np.meshgrid()
填充网格:plt.pcolomesh()

import numpy as np
import matplotlib.pyplot as plt
n=10
x=np.linspace(-10,10,n)    #生成等差数列
y=np.linspace(-10,10,n)
X,Y=np.meshgrid(x,y)
Z=X+Y
plt.pcolormesh(X,Y,Z,cmap="rainbow")    #X是横坐标,Y是纵坐标,Z来控制颜色,cmap颜色方案
plt.show()

在这里插入图片描述
也可以自定义颜色序列

  • 绘制轮廓线:plt.contour()、plt.contourf()
  • 自定义颜色方案:cm=mpl.colors.ListedColormap([“#FFA0A0”,“red”])
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
n=200
x=np.linspace(-10,10,n)         #生成等差数列
y=np.linspace(-10,10,n)
X,Y=np.meshgrid(x,y)
Z=X+Y
#Z=tf.where(Z<0,0,1)   #也可以用这个函数来设置阈值划分颜色
plt.figure(figsize=(6,6))
#2种颜色
plt.subplot(221)
cm_bg1=mpl.colors.ListedColormap(["#FFA0A0","#A0FFA2"])#注意有中括号[]
plt.pcolormesh(X,Y,Z,cmap=cm_bg1)    #用Z来控制颜色
#3种颜色
plt.subplot(222)
cm_bg2=mpl.colors.ListedColormap(["#FFA0A0","#A0FFA2","#AA5555"])
plt.pcolormesh(X,Y,Z,cmap=cm_bg2)    #用Z来控制颜色,均分为3种颜色
#绘制轮廓图
plt.subplot(223)
Z=X**2+Y**2
plt.contour(X,Y,Z,cmap="rainbow")    #用Z来控制颜色,每一条线上的取值相同,理解为等高线
#绘制轮廓并填充
plt.subplot(224)
plt.contourf(X,Y,Z,cmap="rainbow")
plt.show()

在这里插入图片描述

5、鸢尾花分类图

x_train的数值见上面“Iris数据集实现多元逻辑回归”代码

#绘制分类图
M=300
x1_min,x2_min=x_train.min(axis=0)   #算出训练集中花萼长度x1、花萼宽度x2的最大值最小值
x1_max,x2_max=x_train.max(axis=0)
m1,m2=np.meshgrid(np.linspace(x1_min,x1_max,M),     #绘制网格,x1横坐标,x2纵坐标
                  np.linspace(x2_min,x2_max,M))     #linspace创建等差数列M是元素个数
X_mesh=tf.cast(np.stack((np.ones(M*M),m1.reshape(-1),m2.reshape(-1)),axis=1),
               dtype=tf.float32)   #生成多元线性回归需要的矩阵,shape=(90000, 3),并转化为浮点数类型
Y_mesh=tf.cast(1/(1+tf.exp(-tf.matmul(X_mesh,W))),dtype=tf.float32)
Y_mesh=tf.where(Y_mesh<0.5,0,1)     #0,1作为背景颜色填充的依据
n=tf.reshape(Y_mesh,m1.shape)       #维度变换,使Y_mesh与m1有相同形状
cm_pt=mpl.colors.ListedColormap(["blue","red"])     #散点图颜色方案
cm_bg=mpl.colors.ListedColormap(["#FFA022","#A0F111"])#背景颜色方案
plt.pcolormesh(m1,m2,n,cmap=cm_bg)
plt.scatter(x_train[:,0],x_train[:,1],c=y_train,cmap=cm_pt)

在这里插入图片描述

6、多分类问题:(softmax回归)

6.1、编码:自然顺序码、独热编码、独冷编码

  • 自然顺序码转化为独热编码:tf.one_hot(indices,depth) indices是一个整数,depth是深度
  • 依次是用一个数字、一个向量(独热是1,独冷是0)表示一个类别
    在这里插入图片描述

6.2、二/多分类问题:

  • 二分类问题:输入的x1、x2是样品的2个特征,令x0=1,因此,可以看成是输入3个特征,w0表示偏置项,通过sigmoid函数转化为一个0~1之间的概率值,逻辑回归
  • 多分类问题:样品的标记常常表示为独热编码的形式,如下图(0 0 1)^T,其中红色框里面的向量是对应标记的概率,softmax回归
    在这里插入图片描述
  • 交叉熵损失函数:
    二分类问题:二元交叉熵损失函数(BCE);多分类问题:多元交叉熵损失函数(CCE):
    在这里插入图片描述
    如下模型中A、B的准确率一样,但是A中那个预测错的比较离谱,计算知道A交叉熵损失较大:

在这里插入图片描述

6.3、softmax回归:

  • tf.nn.softmax()
  • 如下图,使得输入序列中较大的数在输出中的概率更大。这也是广义线性回归的一种,用来完成分类任务
    在这里插入图片描述
  • 例如鸢尾花数据集有4个属性,加上偏置项x0,输出有3个标签,so,模型参数矩阵W是5行3列
    在这里插入图片描述

6.4、(非)互斥的多分类问题:

  • 互斥的多分类问题:手写数字识别、鸢尾花识别、…
  • 非互斥的多分类问题:包含人物的图片与包含汽车的图片识别、…

http://www.kler.cn/a/529050.html

相关文章:

  • CSS 图像、媒体和表单元素的样式化指南
  • C# 环境:深入探讨与优化
  • Spring JDBC:简化数据库操作的利器
  • 电气相关知识
  • Android车机DIY开发之学习篇(六)编译讯为3568开发板安卓
  • C++,STL 命名空间:理解 std 的作用、规范与陷阱
  • 计算机视觉和图像处理
  • FPGA|安装USB Blaster驱动
  • 5 个开源且免费的提示词管理系统,按照 从优到劣 排序
  • OFDM系统仿真
  • 告别复杂,拥抱简洁:用plusDays(7)代替plus(7, ChronoUnit.DAYS)
  • 页表(Page Table)
  • 面向npm的实时仪表板Dashly
  • 红黑树介绍
  • 搜索旋转排序数组(二分查找)
  • cf集合***
  • NTU:多模态大模型的知识获取能力评估
  • Python 梯度下降法(七):Summary
  • 第一个Python程序
  • 深入了解 SSRF 漏洞:原理、条件、危害
  • 2021 年 12 月大学英语四级考试真题(第 1 套)——纯享题目版
  • 使用frp访问内网web、ssh和隧道搭建
  • 本地部署 DeepSeek-R1:简单易上手,AI 随时可用!
  • 85.[1] 攻防世界 WEB easyphp
  • Java小白入门教程:ArrayList
  • (超实用教程)利用MSF制作exe程序木马