benym的知识笔记 benym的知识笔记
🦮首页
  • Java

    • Java-基础
    • Java-集合
    • Java-多线程与并发
    • Java-JVM
    • Java-IO
  • Python

    • Python-基础
    • Python-机器学习
  • Kafka
  • Redis
  • MySQL
  • 分布式事务
  • Spring

    • SpringIOC
    • SpringAOP
🦌设计模式
  • 剑指Offer
  • LeetCode
  • 排序算法
🐧实践
  • Rpamis

    • Utils
    • Exception
    • Security
  • 归档
  • 标签
  • 目录
🦉里程碑
🐷关于
GitHub (opens new window)

benym

惟其艰难,才更显勇毅🍂惟其笃行,才弥足珍贵
🦮首页
  • Java

    • Java-基础
    • Java-集合
    • Java-多线程与并发
    • Java-JVM
    • Java-IO
  • Python

    • Python-基础
    • Python-机器学习
  • Kafka
  • Redis
  • MySQL
  • 分布式事务
  • Spring

    • SpringIOC
    • SpringAOP
🦌设计模式
  • 剑指Offer
  • LeetCode
  • 排序算法
🐧实践
  • Rpamis

    • Utils
    • Exception
    • Security
  • 归档
  • 标签
  • 目录
🦉里程碑
🐷关于
GitHub (opens new window)
  • Python-基础

    • assert语句的运用
    • list(列表)、tuple(元组)、dict(字典)的回顾
    • Python中的Docstring
    • Python中的多态
    • Python中的集合
    • Python中的列表
    • Python中的序列以及切片的解释
    • Python中的引用和切片
    • Python中的元组
    • Python中对列表和元组的切片操作
    • Python中完整for循环的实际运用
    • Python中字典(key-value)
    • Python中字符串的一些方法回顾(拆分与合并)
    • Python中字符串的一些方法回顾(切片回顾)
    • Python中字符串的一些方法回顾(文本对齐、去除空白)
    • Python中字符串的一些方法回顾
    • Python中字符串的一些基本操作
    • 多种方法快速交换两个变量的值
    • 利用Python进行文件的自动备份
    • 利用Python进行文件的自动备份(第二版)
    • 利用Python进行文件的自动备份(第三版和第四版)
    • 列表推导
    • 在函数中接受元组与字典
    • 装饰器
    • finally异常处理
    • Python的__name__ = '__main__' 的作用
    • Python的pickle模块
    • Python对象的实例化
    • Python日志模块
    • Python中的__new__方法的重写
    • Python中的lambda函数
    • Python中的静态方法、实例方法、类方法的区别
    • Python中的正则表达式
    • Python中的正则表达式match和search
    • Python中面向对象比较简单的内部函数
    • with open异常处理
    • 单例设计模式
    • 继承的运用
    • 简单的异常处理
    • 类变量与对象变量
    • 输入输出——简单的回文判断
    • 输入输出——回文字串的判断(加强版)
    • 文件操作
    • 用户自己引发的异常处理
    • 正则表达式检索与替换
    • 正则表达式中的compile函数
    • 正则表达式中的compile函数(二)
  • Python-机器学习

    • Numpy库的首次使用
    • kNN(k-近邻算法)
    • kNN识别手写图像
    • LogisticRegression(逻辑回归)
      • 使用极大似然估计法
      • 梯度下降算法求J(θ)的最小值
      • 梯度下降的向量化(vectorization)
        • 代码实现
      • 运行结果
    • Ndarray对象
    • Numpy中的数组维度
    • Numpy中花式索引和shape用法
    • turtle绘图库
    • 第一个使用Tensorflow的程序
    • 将下载下来的MNIST手写数字数据集转化成为图片
    • Tensorflow交互式使用
    • 使用k-近邻算法改进约会网站的配对效果
    • Numpy数据类型和arange方法、astype方法的使用
    • 一些TensorFlow的基本操作
  • Python
  • Python-机器学习
benym
2018-10-21
目录

LogisticRegression(逻辑回归)

# LogisticRegression定义

logistic回归,是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域。例如,探讨引发疾病的危险因素,并根据危险因素预测疾病发生的概率等。以胃癌病情分析为例,选择两组人群,一组是胃癌组,一组是非胃癌组,两组人群必定具有不同的体征与生活方式等。一般来说逻辑回归用来做分类任务,本文列举的是以线性的2分类为例, 除此之外还可以拓展到多更多参数实现非线性分类,以及多分类问题等。在文章中主要写了其推导过程以及部分代码实现

# 构造函数h(x)

其中sigmoid函数形式为:

对应的函数图像是一个取值在0和1之间的曲线:

sigmoid函数图像

因为:

由上两式联立可得:

# 使用极大似然估计法

取似然函数(离散型):

对似然函数取ln,转换为:

极大似然估计就是要求得使l(θ)取最大值时的θ,所以如果是这样的话会对应这梯度上升算法,虽然和梯度下降效果一样但是为了便于理解,将J(θ)定义为如下式子,以变化为梯度下降算法求解。

因为乘以了一个负的系数,所以J(θ)取最小值时的θ是最优参数

# 梯度下降算法求J(θ)的最小值

根据梯度下降法可知,更新过程为:

式中α为学习率,求偏导数步骤:

偏导数

所以更新过程可以写成:

因为α是常量,所以1/m可以省略,最后更新过程变为:

# 梯度下降的向量化(vectorization)

约定训练数据的矩阵形式如下,x的每一行为一条训练样本,而每一列为不同的特称取值 :

约定待求的参数θ的矩阵形式为:

先求x*θ并记为A :

求hθ(x)-y并记为E:

g(A)的参数A为一列向量,所以实现g函数时要支持列向量作为参数,并返回列向量。由上式可知hθ(x)-y可以由g(A)-y一次计算求得。

更新过程可以转化为:

综合起来就是:

综上所述,vectorization后θ更新的步骤如下 :

  1. 求A=x*θ
  2. 求E=g(A)-y
  3. 求θ:=θ-α.x'.E,x'表示矩阵x的转置

最后,向量化的参数更新公式为:

# 代码实现

# @Time    : 2018/10/19 16:37
# @Author  : YuanMing
# @File    : Logistic_regression.py
# @Software: PyCharm
import numpy as np
import matplotlib.pyplot as plt


def loadDataSet():
    """
    取出数据和标签
    :return:
    """
    data = np.loadtxt('testSet.txt')
    # 取数据集的第一列到最后一列的前一列
    dataMat = data[:, 0:-1]
    # 取数据集的最后一列
    lableMat = data[:, -1]
    # 为dataMat添加一列1,代表所有theta0的参数,其中0代表第1列,1代表需要插入的数值,axis=1代表横轴(即列添加)
    dataMat = np.insert(dataMat, 0, 1, axis=1)
    return dataMat, lableMat


def sigmoid(Z):
    """
    构造sigmoid函数
    :param Z: thetaT*x
    :return: 分类精度
    """
    return 1.0 / (1 + np.exp(-Z))


def gradient_descent(dataMat, labelMat):
    """
    梯度下降算法
    :param dataMat: 特征数组
    :param labelMat: 标签数组
    :return: 最小化的theta
    """
    # 将特征数组转化为矩阵形式
    dataMatrix = np.mat(dataMat)
    # 将标签数据转化为矩阵并取矩阵的转置
    labelMatrix = np.mat(labelMat).transpose()
    # 得到特征矩阵的行数和列数
    m, n = np.shape(dataMatrix)
    # 学习率
    alpha = 0.001
    # 迭代次数
    iterations = 500
    # 生成n行1列的全1矩阵
    theta = np.ones((n, 1))
    # 执行梯度下降更新
    for k in range(iterations):
        # 求h(x)函数
        h = sigmoid(dataMatrix * theta)
        # 求误差
        error = h - labelMatrix
        # 按照推导的迭代公式求得新的theta
        theta = theta - alpha * dataMatrix.transpose() * error
    return theta


def plotBestFIt(theta):
    # 导入数据
    dataMat, lableMat = loadDataSet()
    # 获取数据行数
    n = np.shape(dataMat)[0]
    # 初始化坐标列表
    xcord1 = []
    ycord1 = []
    xcord2 = []
    ycord2 = []
    for i in range(n):
        # 如果对应的类别标签对应数值1,就添加到xcord1,ycord1中
        if lableMat[i] == 1:
            xcord1.append(dataMat[i][1])
            ycord1.append(dataMat[i][2])
        # 如果对应的类别标签对应数值0,就添加到xcord2,ycord2中
        else:
            xcord2.append(dataMat[i][1])
            ycord2.append(dataMat[i][2])
    # 创建空图
    fig = plt.figure()
    # 将画布分割成1行1列,图像画在从左到右从上到下的第1块
    # 添加subplot,三种数据都画在一张图上
    ax = fig.add_subplot(111)
    # 1类用红色标识,形状为正方形,s为标记点大小
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    # 0类用蓝色标识
    ax.scatter(xcord2, ycord2, s=30, c='blue')
    # 生成一个ndarray数组范围从-3到3,步长为0.1
    x = np.arange(-3, 3, 0.1)
    '''
    这里设置了sigmoid函数的取值为1/2,也就是说取阈值为0.5来划分最后预测的结果
    根据e(−thetaTX)=1,即-thetaTX=0,可以推出x2 = (-theta0x0 - theta1x1)/theta2
    因为x1和x2是两个特征,没有一定的x和y关系,这里假设y是x2,x是x1,之前x0代表1
    '''
    y = (-theta[0, 0] - theta[1, 0] * x) / theta[2, 0]
    # 画出拟合直线
    ax.plot(x, y)
    # 规定X轴标签
    plt.xlabel('X1')
    # 规定Y轴标签
    plt.ylabel('X2')
    plt.show()


if __name__ == '__main__':
    dataMat, labelMat = loadDataSet()
    theta = gradient_descent(dataMat, labelMat)
    dataMat, labelMat = loadDataSet()
    length = len(dataMat)
    for i in range(length):
        print("分类精度:{}".format(round(float(sigmoid(dataMat[i]*theta))*100,2))+"%")
    plotBestFIt(theta)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

# 运行结果

D:\Anaconda3\python.exe E:/PythonProject/MachineLeaning/logistic_regression/Logistic_regression.py
分类精度:1.04%
分类精度:64.06%
分类精度:43.28%
分类精度:28.44%
分类精度:7.64%
分类精度:49.0%
分类精度:3.18%
分类精度:21.54%
分类精度:18.35%
分类精度:8.94%
分类精度:56.55%
分类精度:3.37%
分类精度:93.91%
分类精度:8.76%
分类精度:57.59%
分类精度:97.32%
.........
Process finished with exit code 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

编辑 (opens new window)
#逻辑回归#Python#机器学习
上次更新: 2022/12/31, 16:52:27
kNN识别手写图像
Ndarray对象

← kNN识别手写图像 Ndarray对象→

最近更新
01
SpringCache基本配置类
05-16
02
DSTransactional与Transactional事务混用死锁场景分析
03-04
03
Rpamis-security-原理解析
12-13
更多文章>
Theme by Vdoing | Copyright © 2018-2024 benym | MIT License
 |   |   | 
渝ICP备18012574号 | 渝公网安备50010902502537号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式