机器学习 jupyter Python 监督学习 分类 Logistic回归分类器

1 主要思想

Logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的“回归”一词源于最佳拟合,表示要找到最佳拟合参数集。

2 sigmoid函数

我们定义逻辑回归的预测函数为
在这里插入图片描述
其中𝑔(𝑥)函数是sigmoid函数。

其中𝜃^𝑇𝑥可以看作回归方程
在这里插入图片描述
所以,
在这里插入图片描述
sigmoid 函数的图像如下:
在这里插入图片描述
定义域:R
值域:(0,1)
单调性:
当𝑥→+∞时,𝑦→1
当𝑥→−∞时,𝑦→0

比如现在我找到这个分类边界的曲线,即𝑦=𝜃^𝑇 𝑋,其中𝜃=(𝜃_1,𝜃_2,……𝜃_𝑛)已经确定
0.5作为分类的边界。
令y=𝜃^𝑇 𝑋(其中𝑋代表特征的取值)。
当y≥0的时候g(y)≥0.5,即𝜃^ 𝑇 𝑋≥0 的时候g(𝜃^𝑇 𝑋)≥0.5,我们把它归为1类别。
当𝑍≤0的时候g(Z)≤0.5,即𝜃^ 𝑇 𝑋≤0的时候g(𝜃^𝑇 𝑋)≤0.5, 我们把它归为0类别。

3 决策边界

决策边界(decision boundary),所谓决策边界就是能够把样本正确分类的一条边界,主要有线性决策边界(linear decision boundaries)和非线性决策边界(non-linear decision boundaries)。

3.1 线性决策边界

在这里插入图片描述
ℎ_𝜃 (𝑥)=𝑔(𝜃^𝑇 𝑋)=𝑔(𝜃_0+𝜃_1 𝑥_1+𝜃_2 𝑥_2 )=𝑔(−3+𝑥_1+𝑥_2)(其中𝜃_0为-3, 𝜃_1为1, 𝜃_2为1)
图中的决策边界:
在这里插入图片描述

3.2 非线性决策边界

在这里插入图片描述

在这里插入图片描述
其中,在决策边界上的点
在这里插入图片描述

4 梯度下降法

在这里插入图片描述

4.1 梯度和梯度下降法的含义

4.1.1 梯度

梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。
梯度有两点非常重要。一是,矢量。二是,沿着梯度的方向,目标函数增加最快。
方向导数
顾名思义,方向导数就是某个方向上的导数
比如下面的图示,在某一点处的方向导数其实是由很多(方向导数即该点处切线)
在这里插入图片描述

梯度:是一个矢量,其方向上的方向导数最大,其大小正好是此最大方向导数 。

我们采用的梯度下降法因为求的是目标函数的最小值,所以方向是该点梯度的反方向。

4.1.2 梯度下降法

梯度下降法是一个最优化算法,它是沿梯度下降的方向求解极小值。

4.2 形象理解

以”下山问题”进行类比,更直观的感受梯度下降法。比如现在我的代价函数只和两个参数有关𝜃_0,𝜃_1,我画如下的图形:
在这里插入图片描述

假设你站在山的某一处,你现在想以最快速度下山,那你肯定是找一条最陡峭的路走。你环顾四周,找到了一条路线,这个方向是最陡的(梯度方向)。于是你就出发了,走了一会发现,这个方向不是最陡的路了。你就停下来,换了个最陡的方向,继续往下走。重复这个步骤,你最终到达了山脚下。
那么,你从山顶到山脚的整个下山的过程,就是梯度下降。

4.3 如何求解梯度

在这里插入图片描述

4.4 梯度下降法算法步骤

在这里插入图片描述

4.5 求解梯度

在这里插入图片描述
在这里插入图片描述
注:在这里插入图片描述
详细求解点击这里

4.6 常见疑问

4.6.1 为什么沿着梯度的反方向代价函数一定会减小?

在这里插入图片描述

4.6.2 为什么更新𝜃 的值可以用?

在这里插入图片描述
在这里插入图片描述

5 Logistic回归的代价函数

5.1 函数展示

分段函数形式:
在这里插入图片描述

在这里插入图片描述
当𝑦=1, ℎ_𝜃 (𝑥)=1时,𝐶𝑜𝑠𝑡=0 。
当𝑦=1, ℎ_𝜃 (𝑥)=0时,𝐶𝑜𝑠𝑡=∞ 。
在这里插入图片描述
当𝑦=0, ℎ_𝜃 (𝑥)=0时,𝐶𝑜𝑠𝑡=0 。
当𝑦=0, ℎ_𝜃 (𝑥)=1时,𝐶𝑜𝑠𝑡=∞。

我们发现当真实值和预测值越接近的时候(也就是模型越好),代价函数越少。所以,我们找到最好的模型就等价于找到最小的代价函数。

5.2 线性回归的代价函数和Logistic回归代价函数不同的原因

线性回归代价函数的实际意义就是平方误差。而逻辑回归却不是,它的预测函数ℎ_𝜃 (𝑥)是非线性的。如果类比地使用线性回归的代价函数于逻辑回归,那𝐽(𝜃)很有可能就是非凸函数,即存在很多局部最优解,但不一定是全局最优解。我们希望构造一个凸函数,也就是一个碗型函数做为逻辑回归的代价函数。
在这里插入图片描述

6 小结

6.1 Logistic回归

虽然逻辑回归能够用于分类,不过其本质还是线性回归。它仅在线性回归的基础上,在特征到结果的映射中加入了一层sigmoid函数(非线性)映射,即先把特征线性求和(线性回归),然后使用sigmoid函数来预测。

6.2 多元线性回归表达式

在这里插入图片描述

6.3 易错点

易错点1:
这里𝜃_0表示截距项, 𝑥_0 等于1(不是来源于样本的特征数据),是我们给截距的一个系数,称为偏执项。
易错点2:
在这里插入图片描述

7 具体案列

在这里插入图片描述
用Logistic回归分类器,画出决策边界。
在这里插入图片描述
部分数据集如上图。

7.1 步骤

7.1.1 画出散点图

import numpy as np
import matplotlib.pyplot as plt
np.set_printoptions(suppress=True)#显示的数字不是以科学记数法显示
data=np.genfromtxt('testSet.txt')
print(data)
x_data=data[:,:-1]#特征的数据,列的切片,所有的列但是不包括最后一列
# print(x_data)
# print(x_data[1,0])
y_data=data[:,-1]#标签数据
#print(y_data)
def plot():
    x0=[]#存放0类别所有样本点的横坐标
    x1=[]#存放1类别所有样本点的横坐标
    y0=[]#存放0类别所有样本点的纵坐标
    y1=[]#存放1类别所有样本点的纵坐标
    for i in range(len(x_data)):
        if y_data[i]==0:#如果标签为0类别
            x0.append(x_data[i,0])#将x_data每个样本点的x轴坐标添加到x0中
            y0.append(x_data[i,1])#将x_data每个样本点的y轴坐标添加到y0中
        else:
            x1.append(x_data[i,0])
            y1.append(x_data[i,1])
    
#画图
    plt.scatter(x0,y0,marker='o',color='b',label='label0',s=40)
    plt.scatter(x1,y1,marker='*',c='r',label='label1',s=60)
    #scatter画散点图,marker标识散点图样式,color标识颜色,label表示图例的解释
    plt.legend()#显示图例
plot()
plt.show()

小结:
1.genfromtxt函数读取文件
2.特征数据的切片
3.先分0.1类别,再找横纵坐标
4.用 matplotlib.pyplot包里面的scatter函数画散点图。具体参数如下:marker标识散点图样式,color标识颜色,label表示图例的解释。此外,lenged函数显示图例,show函数展示散点图。

7.1.2 添加偏置项

import numpy as np
np.set_printoptions(suppress=True)#显示的数字不是以科学记数法显示
data=np.genfromtxt('testSet.txt')
x_data=data[:,:-1]#特征数据
y_data=data[:,-1]
m=len(x_data)
#print(m)
#1.为求解最佳的θ,对特征数据进行预处理,添加偏置项
a=np.ones((m,1))
X_data=np.concatenate((a,x_data),axis=1)
#concatenate实现数组拼接,axis=1左右拼接,axis=0上下拼接
#print(X_data)

知识点:
1.数据拼接
数据拼接这里有两种方法:
(1)numpy.append(arr, values, axis=None)函数。
对于参数规定,要么一个数组和一个数值;要么两个数组,不能三个及以上数组直接append拼接。
(2)numpy提供了numpy.concatenate((a1,a2,…), axis=0)函数。能够一次完成多个数组的拼接。
其中a1,a2,…是数组类型的,其中默认是沿纵向拼接,即axis=0,如果要求沿横向拼接,axis=1。
1表示横轴,方向从左到右;0表示纵轴,方向从上到下。
当axis=1时,数组的变化是横向的,体现出列的增加或者减少。
反之,当axis=0时,数组的变化是纵向的,体现出行的增加或减少。

7.1.3 利用梯度下降法求解最优的回归参数

def sigmold(x):
    return 1/(1+np.exp(-x))
#2.使用梯度下降法求最佳θ
def gradAscent(xArr,yArr):
    #1.定义迭代次数
    epochs=30000
    #2.给出学习率
    lr=0.001
    #3.将数组转换为矩阵
    xMat=np.mat(xArr)
    yMat=np.mat(yArr)
    m,n=xMat.shape
        #4.给定θ的初始值,开始迭代
    a=np.ones((n,1))
    theta=np.mat(a)
    #print(theta)
    for i in range(epochs):
        #预测值
        h=sigmold(xMat*theta)
        #print(h)
        theta_grad=xMat.T*(h-yMat.T)/m
        theta=theta-lr*theta_grad
    return theta
theta=gradAscent(X_data,y_data)

知识点:
1.矩阵和数组是不同的。矩阵的转置和矩阵的乘积是需要借助mat函数。数组的相乘就是对应位子相乘。
例如:
在这里插入图片描述
numpy中数组和矩阵的区别:matrix是array的分支,matrix和array在很多时候都是通用的,你用哪一个都一样。但这时候,官方建议大家如果两个可以通用,那就选择array,因为array更灵活,速度更快,很多人把二维的array也翻译成矩阵。但是matrix的优势就是相对简单的运算符号,比如两个矩阵相乘,就是用符号*,但是array相乘不能这么用,得用方法.dot()array的优势就是不仅仅表示二维,还能表示3、4、5…维,而且在大部分Python程序里,array也是更常用的。

利用梯度下降法求解最优的回归参数数学基本原理:
在这里插入图片描述

7.1.4 迭代求得最优参数

代码在上一步骤里面。
知识点:
在这里插入图片描述

在这里插入图片描述

7.1.5 画出决策边界

#画出决策边界
#plot()
x_test=[[-4],[3]]
y_test=(-theta[0]-x_test*theta[1])/theta[2]
print(y_test)
plt.plot(x_test,y_test,'y')

运行结果:
在这里插入图片描述
知识点:
在这里插入图片描述

8 案列2 使用sklearn 的 Logistic回归

8.1 第一题题目

根据老师女性乳腺癌患者数据集(医学指标)构建逻辑回归分类类型模型进行良性或恶性乳腺癌肿瘤预测

8.1.2 代码

from sklearn.datasets import load_breast_cancer#加载乳腺癌数据集
from sklearn.model_selection import train_test_split#数据集划分
from sklearn import linear_model#导入sklearn里面的线性回归模块!
import numpy as np
np.set_printoptions(suppress=True)#显示的数据不是科学记数法
cancer=load_breast_cancer()
x=cancer.data#特征数据
y=cancer.target#特征数据标签
print(cancer.target_names)#0代表恶性,1代表良性
# print(x)
# print(y)
X_train,X_test,Y_train,Y_test=train_test_split(cancer.data,cancer.target,test_size=0.2)
#定义模型
logistic=linear_model.LogisticRegression(solver='liblinear')
logistic.fit(X_train,Y_train)
print(logistic.score(X_train,Y_train))#训练集的精度
print(logistic.score(X_test,Y_test))#测试集的精度

8.1.3 步骤总结

1 导入包
2 找到特征数据和特征数据标签
3 划分训练集和测试集
4 定义模型
5 求精度
注:
记得导入sklearn里面的线性回归模块

from sklearn import linear_model

8.2 第二题

使用sklearn模块划分下出下图的决策边界。
在这里插入图片描述

8.2.1 画出散点图

#载入数据
data=np.genfromtxt('testSet.txt')
x_data=data[:,:-1]
y_data=data[:,-1]
#print('data:',data)
#print('x_data',x_data)
#print('y_data',y_data)
def plot():
    x0=[]
    x1=[]
    y0=[]
    y1=[]
    for i in range(len(x_data)):
        if y_data[i]==0:
            x0.append(x_data[i,0])
            y0.append(x_data[i,1])
        else:
            x1.append(x_data[i,0])
            y1.append(x_data[i,1])
#画图
    plt.scatter(x0,y0,marker='o',c='b',label='label0',s=40)
    plt.scatter(x1,y1,marker='*',c='y',label='label1',s=60)
    plt.legend()#显示图例
plot()
plt.show()

运行结果:
在这里插入图片描述

8.2.2 建立模型、训练模型

logistic=linear_model.LogisticRegression()
#传入的数据不需要在添加偏置项,sklearn里面的logistic回归可以自行处理
logistic.fit(x_data,y_data)
print('截距:',logistic.intercept_)#logistic.intercept_代表截距
print('系数:',logistic.coef_)#coef特征数前面的系数
print(logistic.coef_[0])
print(logistic.coef_[0][0])

运行结果:
在这里插入图片描述

8.2.3 画出决策边界

plot()
x_test=np.array([[-4],[3]])
y_test=(-logistic.intercept_-x_test*logistic.coef_[0][0])/logistic.coef_[0][1]
plt.plot(x_test,y_test,'r')
plt.show()

运行结果:
在这里插入图片描述

9.随机梯度下降法

9.1 与标准梯度下降法的区别

9.2 具体案列

10 逻辑回归解决多分类问题

11 决策边界可视化

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值