1、介绍

前言
  为了更好的理解本章内容,请参考下面的网址,自主学习一些矩阵求导运算。

https://zhuanlan.zhihu.com/p/158182135机器学习约定规则:
向量对标量求导,默认使用分子布局(本博客采用了这一条)
矩阵对标量求导,默认使用分子布局
标量对向量求导,默认使用分母布局
向量对向量求导,常使用分母布局

1、概述
  逻辑回归(Logistic Regression)虽然是名词是回归,但是实际上它是一种分类模型。假设输入值函数(单值x1x_1x1​)如下:
z=WTx1=w0+w1x11+w2x12+⋯+wpx1pW∈Rp+1,x1∈Rp+1z=W^Tx_1=w^0+w^1x_{11}+w^2x_{12}+\cdots+w^px_{1p} \\ W \in R^{p+1} , x_1 \in R^{p+1} z=WTx1​=w0+w1x11​+w2x12​+⋯+wpx1p​W∈Rp+1,x1​∈Rp+1
  逻辑回归模型通过sigmoid函数将输入值映射到[0,1]区间范围。其中,逻辑回归函数形式如下:
p=s(z)=11+e−zp=s(z)=\frac{1}{1+e^{-z}} p=s(z)=1+e−z1​
  逻辑回归函数图像如下:

  s(z)函数的定义域范围为(−∞,+∞)(-\infty,+\infty)(−∞,+∞),sigmoid函数是一个(0,1)上的函数,从而可以将连续数据进行分类,这可能就是“回归”二字的含义吧。此外,我们也可以将s(z)函数看成概率p,假设p=0.8,此时概率值离1很近,可以将数据类别判别为1;假设p=0.2,概率值离0很近,可以将数据类别判别为0。
  因此,假设我们已经训练好了一组权值W ,只要把我们需要预测的数据X代入到方程,输出的y值就是这个标签为0/1的概率,进而判断输入数据是属于哪个类别。下面我们分析使用梯度下降法来分析权值W的求解过程。
2、梯度下降法求解权值W
(1)损失函数的求解过程
  假设二分类问题的输出值是一个包含2个离散值函数,即y∈{0,1}y \in \{0,1\}y∈{0,1},令p等于y=1y=1y=1发生的概率,将每个样本看成一个事件,每个事件发生的概率如下:
P(yi∣xi)={p,y=11−p,y=0P(y_i|x_i)= \begin{cases} p,y=1 \\ 1-p,y=0 \end{cases} P(yi​∣xi​)={p,y=11−p,y=0​
  上面的表达式等价于下面的形式:
P(yi∣xi)=pyi(1−p)1−yiP(y_i|x_i)=p^{y_i}(1-p)^{1-y_i} P(yi​∣xi​)=pyi​(1−p)1−yi​
  假设采集到服从独立同分布的样本N个数据,其联合概率就是每个样本的概率的乘积,此时似然函数有:
L(W)=∏i=1Npyi(1−p)1−yiL(W)=\prod_{i=1}^N{p^{y_i}(1-p)^{1-y_i}} L(W)=i=1∏N​pyi​(1−p)1−yi​
  为了计算简便,对上面的似然函数求对数:
F(W)=ln(L(W))=∑i=1N(yiln(p)+(1−yi)ln(1−p))F(W)=ln(L(W))=\sum_{i=1}^N({{y_i}ln(p)+({1-y_i})ln(1-p)}) F(W)=ln(L(W))=i=1∑N​(yi​ln(p)+(1−yi​)ln(1−p))
  上面的表达式求出最大值,对应的似然函数的求解,最大化似然函数对应最小化代价函数,因此可以在前面加上负号,从而将上面的表达式看成我们的损失函数。
(2)对损失函数求梯度
  假设输入值的特征向量有n个,可以对输入值特征向量进行下面的扩展,此时输出值是一个n维的向量,其中向量的每一个元素表示一个输入值的特征向量对应的输出。
[x1T,1x2T,1⋯xnT,1]\left[ \begin{array}{c} x_1^T,1 \\ x_2^T ,1\\ \cdots \\ x_n^T,1 \end{array} \right] ⎣⎢⎢⎡​x1T​,1x2T​,1⋯xnT​,1​⎦⎥⎥⎤​
  假设逻辑回归函数形式使用下面的形式:
p′=s(z)′=11+e−XWp′∈Rnp^{'}=s(z)^{'}=\frac{1}{1+e^{-XW}} \\ p^{'} \in R^{n} p′=s(z)′=1+e−XW1​p′∈Rn
  p′p^{'}p′进行wiw_iwi​求导:
(p′)′=(11+e−XW)′=−(11+e−XW)−2.(1+e−XW)′=−(11+e−XW)−2.e−XW.(−XW)′=(11+e−XW)−2.e−XW.Xi=p′(1−p′)Xi(p^{'})^{'}=(\frac{1}{1+e^{-XW}})^{'} \\ =-(\frac{1}{1+e^{-XW}})^{-2}.(1+e^{-XW})^{'} \\ =-(\frac{1}{1+e^{-XW}})^{-2}.e^{-XW}.(-XW)^{'} \\ =(\frac{1}{1+e^{-XW}})^{-2}.e^{-XW}.X_i \\ =p^{'}(1-p^{'})X_i (p′)′=(1+e−XW1​)′=−(1+e−XW1​)−2.(1+e−XW)′=−(1+e−XW1​)−2.e−XW.(−XW)′=(1+e−XW1​)−2.e−XW.Xi​=p′(1−p′)Xi​
  当我们采用整个矩阵进行求导的时候,我发现上面得出的矩阵结果维度好像不多,但是有一点就是通过下面的代码可以看出(−XW)′(-XW)^{'}(−XW)′对wiw_iwi​求导确实只剩下XiX_iXi​,此时向量对于变量进行求导,采用分子布局方式。
[1x11x12⋯x1p1x21x22⋯x2p⋯1xn1xn2⋯xnp]∗[w0w1⋯wi⋯wp]=[y0y1⋯yi⋯yn]\left[ \begin{array}{c} 1 & x_{11} & x_{12} & \cdots & x_{1p} \\ 1 & x_{21} & x_{22} & \cdots & x_{2p}\\ \cdots \\ 1 & x_{n1} & x_{n2} & \cdots & x_{np} \end{array} \right] * \left[ \begin{array}{c} w_0 \\ w_1 \\ \cdots \\ w_i \\ \cdots \\ w_p \end{array} \right] = \left[ \begin{array}{c} y_0 \\ y_1 \\ \cdots \\ y_i \\ \cdots \\ y_n \end{array} \right] ⎣⎢⎢⎡​11⋯1​x11​x21​xn1​​x12​x22​xn2​​⋯⋯⋯​x1p​x2p​xnp​​⎦⎥⎥⎤​∗⎣⎢⎢⎢⎢⎢⎢⎡​w0​w1​⋯wi​⋯wp​​⎦⎥⎥⎥⎥⎥⎥⎤​=⎣⎢⎢⎢⎢⎢⎢⎡​y0​y1​⋯yi​⋯yn​​⎦⎥⎥⎥⎥⎥⎥⎤​
  因此,我们不对整个输入值矩阵进行求导,我们只针对单个输入值进行求导,我们采用下面的求导方式,然后观察出规律即可。假设输入值为x(i)x^{(i)}x(i),逻辑回归函数对wiw_iwi​进行求导

(p)′=(11+e−WTx(i))′=−(11+e−WTx(i))−2.(1+e−WTx(i))′=−(11+e−WTx(i))−2.e−WTx(i).(−WTx(i))′=(11+e−WTx(i))−2.e−WTx(i).xi(i)=p(1−p)xi(i)(p)^{'}=(\frac{1}{1+e^{-W^Tx^{(i)}}})^{'} \\ =-(\frac{1}{1+e^{-W^Tx^{(i)}}})^{-2}.(1+e^{-W^Tx^{(i)}})^{'} \\ =-(\frac{1}{1+e^{-W^Tx^{(i)}}})^{-2}.e^{-W^Tx^{(i)}}.(-W^Tx^{(i)})^{'} \\ =(\frac{1}{1+e^{-W^Tx^{(i)}}})^{-2}.e^{-W^Tx^{(i)}}.x^{(i)}_i \\ =p(1-p)x^{(i)}_i (p)′=(1+e−WTx(i)1​)′=−(1+e−WTx(i)1​)−2.(1+e−WTx(i))′=−(1+e−WTx(i)1​)−2.e−WTx(i).(−WTx(i))′=(1+e−WTx(i)1​)−2.e−WTx(i).xi(i)​=p(1−p)xi(i)​

  损失函数F(W)对W进行求导:
F(W)′=(∑i=1N(yiln(p)+(1−yi)ln(1−p)))′=∑i=1N(yiln(p)′+(1−yi)ln(1−p)′)=∑i=1N(yi(1pp′)+(1−yi)ln(1−p)′)=∑i=1N(yi(1pp′)+(1−yi)(11−p(1−p)′))=∑i=1N(yi−p)xi(i){F(W)}^{'}=(\sum_{i=1}^N({{y_i}ln(p)+({1-y_i})ln(1-p)}))^{'} \\ =\sum_{i=1}^N({{y_i}ln(p)^{'}+({1-y_i})ln(1-p)^{'}}) \\ =\sum_{i=1}^N({{y_i}(\frac{1}{p}p^{'})+({1-y_i})ln(1-p)^{'}}) \\ =\sum_{i=1}^N({{y_i}(\frac{1}{p}p^{'})+({1-y_i}) (\frac{1}{1- p}{(1-p)^{'}})}) \\ =\sum_{i=1}^N(y_i - p)x^{(i)}_i F(W)′=(i=1∑N​(yi​ln(p)+(1−yi​)ln(1−p)))′=i=1∑N​(yi​ln(p)′+(1−yi​)ln(1−p)′)=i=1∑N​(yi​(p1​p′)+(1−yi​)ln(1−p)′)=i=1∑N​(yi​(p1​p′)+(1−yi​)(1−p1​(1−p)′))=i=1∑N​(yi​−p)xi(i)​
  最后采用下面的公式,在代码中更新权重即可:
wik+1=wik+α∗∂F(w)∂wiw^{k+1}_i = w^{k}_i + \alpha*\frac{\partial {F(w)}}{\partial {w_i}} wik+1​=wik​+α∗∂wi​∂F(w)​

2、代码

1、算法描述
  本博客采用逻辑回归算法实现鸢尾花数据集的二分类。
2、数据csv准备
(1)数据格式

sepallength  sepalwidth  petallength petalwidth  class
5.1 3.5 1.4 0.2 Iris-setosa
4.9 3   1.4 0.2 Iris-setosa
4.7 3.2 1.3 0.2 Iris-setosa
4.6 3.1 1.5 0.2 Iris-setosa
5   3.6 1.4 0.2 Iris-setosa
5.4 3.9 1.7 0.4 Iris-setosa
4.6 3.4 1.4 0.3 Iris-setosa
5   3.4 1.5 0.2 Iris-setosa
4.4 2.9 1.4 0.2 Iris-setosa
...

  为了大家能够更好的学习KNN算法,我将这个csv文件放到我博客的资源中,通过下面的链接即可下载:

https://download.csdn.net/download/weixin_43334389/13130463

3、代码

# @Time : 2020/11/22 20:45
# @Description : 使用鸢尾花数据集采用逻辑回归算法实现二分类
import numpy as np
import pandas as pddata = pd.read_csv(r"dataset/iris.arff.csv", header=0)
data.drop_duplicates(inplace=True)
# 名称映射为数字
data["class"] = data["class"].map({"Iris-setosa": 0, "Iris-versicolor": 1, "Iris-virginica": 2})
# 筛选数据,只选择0和1
data = data[data["class"] != 2]class LogisticRegression:"""@desc:逻辑回归算法实现"""def __init__(self, learning_rate, times):"""@desc:初始化算法@param learning_rate: 学习率@param times: 迭代次数"""self.learning_rate = learning_rateself.times = timesdef sigmoid(self, z):"""@desc:sigmoid函数实现@param z: 自变量: z=w.T*x@return: float, 属于[0,1]区间。s>=0.5(z>0)时,类别为1,否则为0"""return 1.0 / (1.0 + np.exp(-z))def fit(self, X, y):"""@desc:训练模型@param X:训练集特征矩阵,shape[0]为样本数量(即特征矩阵),shape[1]为特征数量@param y:标签数组"""X = np.asarray(X)print(X.shape)print(type(X))y = np.asarray(y)# 创建权重向量,初始化为0.多出来的1是截距self.w_ = np.zeros(1 + X.shape[1])  # shape[0]为样本数量,shape[1]为特征数量# 创建损失列表,保存每次迭代后的损失值self.loss_ = []for i in range(self.times):z = np.dot(X, self.w_[1:]) + self.w_[0]# 计算概率值(判定为1的概率值)p = self.sigmoid(z)# 根据逻辑回归的代价函数(目标函数或叫损失函数)计算损失值# 通过计算逻辑回归函数的最大似然函数得到下面的公式,np.log()函数以e为底# J(W) = - sum(yi * log(s(zi))+(1-yi)log(1-s(zi)))cost = - np.sum(y * np.log(p) + (1 - y) * np.log(1 - p))self.loss_.append(cost)# 调整权重值,上面的损失函数对w求导得到# 公式 权重(j行) = 权重(j行) + 学习率 * sum( y - s(z)) * X(j列)self.w_[0] += self.learning_rate * np.sum(y - p) * 1self.w_[1:] += self.learning_rate * np.dot(X.T, y - p)def predict_proba(self, X):"""@desc: 根据参数传递的样本,对样本数据进行预测属于某一个类别的概率@param X:测试集特征矩阵@return:预测(概率值)"""X = np.asarray(X)z = np.dot(X, self.w_[1:]) + self.w_[0]p = self.sigmoid(z)# 将预测结果转换为二维数组,方便后续拼接p = p.reshape(-1, 1)# 将两个数组拼接,方向是横向拼接test1 = np.concatenate([1 - p, p], axis=1)print("--------test1----------")# (18, 2)print(test1.shape)# <class 'numpy.ndarray'>print(type(test1))# [[0.99066619 0.00933381]#  [0.99297624 0.00702376]#  [0.97928108 0.02071892]print(test1)return np.concatenate([1 - p, p], axis=1)  # 横向拼接为为1def predict(self, X):"""@desc:根据参数预测样本属于哪个类别@param X:测试集特征矩阵@return: 返回测试数据属于那个类别标签对应的较大值的索引axis=1 表示每一行的最大索引,当下面函数输出为0的时候,表示第一列数据大,刚好对应分类为0的标签。"""return np.argmax(self.predict_proba(X), axis=1)t1 = data[data["class"] == 0]
t2 = data[data["class"] == 1]
t1 = t1.sample(len(t1), random_state=0)
t2 = t2.sample(len(t2), random_state=0)
train_X = pd.concat([t1.iloc[:40, :-1], t2.iloc[:40, :-1]], axis=0)
train_y = pd.concat([t1.iloc[:40, -1], t2.iloc[:40, -1]], axis=0)
test_X = pd.concat([t1.iloc[40:, :-1], t2.iloc[40:, :-1]], axis=0)
test_y = pd.concat([t1.iloc[40:, -1], t2.iloc[40:, -1]], axis=0)# 鸢尾花的特征列都在同一个数量级,我们可以不用标准化处理
lr = LogisticRegression(learning_rate=0.01, times=20)
lr.fit(train_X, train_y)
# 预测的概率值
# lr.predict_proba(test_X)
# lr.predict(test_X)预测的类别
result = lr.predict(test_X)
# 计算准确性
accuracy = np.sum(result == test_y) / len(test_y)
# 1.0
print(accuracy)import matplotlib as mpl
import matplotlib.pyplot as pltmpl.rcParams['font.family'] = 'SimHei'
mpl.rcParams['axes.unicode_minus'] = False# 绘制预测值
plt.plot(result, 'ro', ms=15, label="预测值")  # ms指定圆圈大小
plt.plot(test_y.values, 'go', label="真实值")  # pandas读取时serise类型,我们需要转为ndarray
plt.title('逻辑回归预测')
plt.xlabel('样本序号')
plt.ylabel('预测值')
plt.legend()
plt.show()# 绘制目标函数随着迭代次数的损失值图像
plt.plot(range(1, lr.times + 1), lr.loss_, 'go-')
plt.xlabel('迭代次数')
plt.ylabel('损失值loss')
plt.show()

4、结果展示
(1)预测值和真实值之间的拟合

(2)损失函数图像

3、分析

1、argmax函数
  

 def predict(self, X):#索引值和分类类别相对应return np.argmax(self.predict_proba(X), axis=1)# 举例
matrix2_2 = np.array([[1, 2], [3, 4]])
# [1 1] 即第一行的2和第二行的4比较大,作为索引返回。
# axis=1表示返回每1行的最大索引(0/1).
# 参数axis,默认是0.
print(np.argmax(matrix2_2, axis=1))

2、数组拼接函数concatenate

#拼接之后成为一个n*2的数组矩阵,其索引值(0/1)和分类类别相对应
return np.concatenate([1 - p, p], axis=1)  # 横向拼接为1# 举例 按轴axis连接array组成一个新的array
# 一维情况进行连接 axis=1
# 我们对其进行转换尺寸
a1 = a.reshape(-1, 1)
b1 = b.reshape(-1, 1)
ab1 = np.concatenate((a1, b1), axis=1)
# [[ 1 11]
#  [ 2 22]
#  [ 3 33]]
print(ab1)
(3, 2)
print((ab1).shape)# 二维情况进行连接 axis=0
c = np.array([[1, 2], [3, 4]])
d = np.array([[5, 6]])
cd = np.concatenate((c, d), axis=0)
# [[1 2]
#  [3 4]
#  [5 6]]
print(cd)# 二维情况进行连接 axis=0
cd2 = np.concatenate((c, d.T), axis=1)
# [[1 2 5]
#  [3 4 6]]
print(cd2)

逻辑回归算法实现鸢尾花数据集的二分类相关推荐

  1. 【基础机器学习算法原理与实现】使用感知器算法LDA、最小二乘法LSM、Fisher线性判别分析与KNN算法实现鸢尾花数据集的二分类问题

    本文设计并实现了PerceptronLA.PseudoIA.LeastSM.LinearDA.KNN等五个算法类,以及DataProcessor的数据处理类.对感知器算法LDA.最小二乘法LSM的伪逆 ...

  2. 基于逻辑回归模型对鸢尾花数据集进行分类

    基于逻辑回归模型对鸢尾花数据集进行分类 理论知识 不做过多赘述,相关知识有:指数分布族.GLM建模(分布函数+连接函数,对于本例来说是二项分布+sigmoid函数).最大似然函数.交叉熵函数(评估逻辑 ...

  3. ML之xgboost:利用xgboost算法对breast_cancer数据集实现二分类预测并进行graphviz二叉树节点图可视化

    ML之xgboost:利用xgboost算法对breast_cancer数据集实现二分类预测并进行graphviz二叉树节点图可视化 目录 实现结果 实现代码 实现结果

  4. 基于Isotonic回归(保序回归算法)的鸢尾花数据集回归问题

    基于Isotonic回归的鸢尾花数据集回归问题 1. 作者介绍 2.保序回归算法 2.1 算法原理 2.2 保序回归算法举例 3. 鸢尾花数据集介绍 3.1 数据集获取 4.代码实现 4.1 导入需要 ...

  5. RDkit&mol2vec :基于逻辑回归的靶标抑制剂活性二分类对比

    逻辑回归(logistics regression) 逻辑回归又称logistic回归分析,是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域.逻辑回归从本质来说属于二分类问题 ...

  6. Python+sklearn使用逻辑回归算法预测期末考试能否及格

    封面图片:<Python程序设计实验指导书>,董付国编著,清华大学出版社 ================= 虽然名字中带有"回归"二字,但实际上逻辑回归是一个用于分类 ...

  7. Python使用逻辑回归算法根据三围数据判断用户性别

    逻辑回归算法是一种经典的分类算法,使用时应注意: 1)样本需要足够多. 2)样本的多个特征之间尽量不要存在线性相关性. 问题描述: 根据三围数据判断用户性别.假设男性和女性的三围和身高的计算公式如下: ...

  8. 深度学习原理-----逻辑回归算法

    系列文章目录 深度学习原理-----线性回归+梯度下降法 深度学习原理-----逻辑回归算法 深度学习原理-----全连接神经网络 深度学习原理-----卷积神经网络 深度学习原理-----循环神经网 ...

  9. 【统计学习方法】线性可分支持向量机对鸢尾花(iris)数据集进行二分类

    本文摘要 · 理论来源:[统计学习方法]第七章 SVM · 技术支持:pandas(读csv).numpy.sklearn.svm.svm思想.matplotlib.pyplot(绘图) · 代码目的 ...

最新文章

  1. 教你轻松将springboot打包成exe程序
  2. 谷歌人为干预搜索结果被曝光:增加大公司曝光,主动营造岁月静好
  3. 跨域请求的一种解决方案
  4. 2.7 RMSprop-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  5. 漫说单例模式--宝宝成长记 你真的了解了吗?
  6. UIbutton系统按键(System)和图片按键(Custom)对比
  7. 数据库内部存储结构探索
  8. [iOS]应用内支付(内购)的个人开发过程及坑!
  9. 前端学习(1340):mongoose验证规则
  10. LeetCode--32. 最长有效括号(栈)
  11. 【报告分享】企鹅智家智慧社区解决方案2019.pdf(附下载链接)
  12. Linux系统上利用nmcli命令创建网络组
  13. process id linux,userdel:user* is currently used by process id
  14. mysql concat函数进行模糊查询
  15. 惠普服务器如何修改ip地址,HP网络打印机如何设置IP地址
  16. CSS基础知识10-两种CSS布局
  17. linux怎么取消光盘,怎样取消ubuntu官方光盘
  18. win7计算机不显示摄像头图标不见了,win7系统摄像头图标不显示的解决方法
  19. 如何使用vue开发公众号网页
  20. webpack中处理css文件

热门文章

  1. C++麻将游戏算法深入解析
  2. access数据库剔除重复项_access排重工具-Access数据库重复记录删除器下载V1.04免费注册版-西西软件下载...
  3. 物联网前景可期 将会是下一个万亿级的通信业务
  4. 微信发的图片服务器也清除,怎么清空自己在微信朋友圈里发的图片?
  5. 关于pdf文件直接在chrome浏览器中直接打开而不是下载的问题
  6. 求解填字游戏问题(回溯)
  7. Jetpack Compose 深入探索系列四: Compose UI
  8. 辽宁大学计算机专业专硕分数线,辽宁大学社会工作硕士历年复试分数线_社会工作考研分数线_复试线 - 希赛网...
  9. 【业务数据分析】——Excel公式与函数(三)
  10. 【机器学习】11、贝叶斯网络