逻辑回归的原理和python实现

输入

  鸢尾花卉数据集,数据集包含150个数据样本,分为3类,每类50个数据,每个数据包含4个属性。

输出

  根据手动实现的逻辑回归模型对鸢尾花卉数据集分类的预测结果。

原理

  逻辑回归处理的是分类问题,线性回归处理的是回归问题,这是两者最本质的区别。逻辑回归算法是一种分类算法,适用于标签取值离散的情况。

  逻辑回归的模型为:

               

  其中,代表特征向量,代表逻辑函数,一个常用的逻辑函数公式为:

                

  该函数的图像为:

  

  通过公式和图像,我们可以总结下的作用:对于给定的输入变量,根据选择的参数计算输出变量等于1的概率,即,比如给定的变量,通过给定的参数计算得到 = 0.7,则表示有70%的几率输出变量为正向类,30%的几率为负向类。

  在逻辑回归中,当时,预测y=1,当时,预测y=0。而这两种情况分别对应,在几何上意味着是真正意义上的分界边界函数,常见的比如:(线性分界函数)、(二次分界函数)。在实际的业务场景中,可以选择复杂的分界函数来处理数据。

当分解函数选定之后,有一个非常重要的操作是确定逻辑回归模型的参数,按照机器学习的思路,我们要定义代价函数,通过梯度下降法更新参数,最小化代价函数来得到参数

在线性回归模型中,采用的代价函数为所有样本误差的平方和,那是因为此时的代价函数是凸函数,一定会得到一个最小值。如果逻辑回归模型采用所有样本误差的平方和作为代价函数,那么得到的代价函数是非凸的,非凸函数有很多的极小值点,影响梯度下降法寻找全局最小值。

根据逻辑回归处理的分类问题本质上只有正、负样本的特性,我们定义逻辑回归的代价函数为:

            

其中,,其实这么定义也比较容易理解,比如对于一个y=1的正样本,由于是一个在作用域(0,1]上从正无穷大递减至0的函数,如果sigmoid函数模型预测的概率比较小,接近于0,预测为负样本,那么代价函数值就比较大,如果sigmoid函数模型预测的概率比较大,接近于1,预测为正样本,那么代价就比较小,如果概率为1的话,代价函数值就为0了,这不就刚好是我们想要的吗?同理可理解对于y=0时采用的代价函数。

我们将代价函数整理如下:

针对每个求偏导得到:

  有了偏导之后,就可以更新参数:

      

在训练的过程中,有可能遇到到过拟合的问题,我们可以使用正则化的技术来较少过拟合的影响,我们对参数做适当的惩罚,优化代价函数为:

  

这里注意到,我们一般不对做惩罚。

  同时,由于偏导有了改变,更新参数也需要对应改变:

            

这样我们就可以通过最小化代价函数,一步步更新参数,拟合出想要的参数了,得到一个逻辑回归分类器,但是如果我们处理的是多分类问题该怎么办呢?

  假如我们处理的是一个三分类问题,有三个类别0,1,2。我们可以构造3个分类器:

那么如何构造这些分类器呢?我们以为例,在构造这个分类器时,标签类别为0的样本为正样本对应的y修改为1,其余的标签类别非0的样本为负样本对应的y修改为0,这样处理之后进行训练就可以得到一个可以分类0类别与非0类别的分类器了,同理另外两个分类器也可得到。

得到3个分类器后,对于一个样本而言,如何生成最终的类别呢?我们可以让三个分类器分别作用于该样本,值最大的分类器为最终的分类结果。

Python代码实现

  1 import pandas as pd
  2 import numpy as np
  3 from sklearn.model_selection import train_test_split
  4
  5 # 鸢尾花卉数据集,数据集包含150个数据样本,分为3类,每类50个数据,每个数据包含4个属性。
  6 # 可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。
  7 iris_path = ‘./iris.csv‘
  8 iris_data = pd.read_csv(iris_path)
  9
 10 # 将字符串标签映射为int
 11 def iris_str_to_int(str):
 12     label = {‘setosa‘:0, ‘versicolor‘:1, ‘virginica‘:2}
 13     return label[str]
 14 new_iris_data = pd.io.parsers.read_csv(iris_path, converters={4:iris_str_to_int})
 15 data = np.array(new_iris_data)
 16
 17 # 对数据进行归一化
 18 for col in range(0, len(data[0]) - 1):
 19     mean = np.mean(data[:, col])
 20     std = np.std(data[:, col])
 21     data[:, col] = data[:, col] - mean
 22     data[:, col] = data[:, col] / std
 23
 24 # 划分数据集,30%测试集、70%训练集,使用sklearn的train_test_split方法
 25 x, y = np.split(data, (4,), axis=1)
 26 x_train, x_test, y_train, y_test = train_test_split(x,y,test_size = 0.3)
 27
 28 # sigmoid方法
 29 def sigmoid(x):
 30     return 1.0/(1+np.exp(-x))
 31
 32 # 修改目标y值时使用的方法,因为是多分类,在训练时需要保证只有正类、负类两类
 33 def func(value,lb):
 34     if any(value == lb):
 35         value = 1
 36     else:
 37         value = 0
 38     return value
 39
 40 # 选择线性模型(theta_0 + theta_1 * x1 + theta_2 * x2 + ...)来做逻辑回归
 41 # 因为有三类,所以要构造3个分类器,即为h0, h1, h2
 42 # 根据入参的标签值,来对y进行修改,
 43 # 比方说,如果label = 0,说明这是h0分类器,那么y == 0为正样本(y值应从0修改为1),其他非0的修改为负样本(y值应修改为0)
 44 # 如果label = 1,说明这是h1分类器,那么y == 1为正样本(y值应从1修改为1),其他非1的修改为负样本(y值应修改为0)
 45 # 如果label = 2,说明这是h2分类器,那么y中2为正样本(y值应从2修改为1),其他非2的修改为负样本(y值应修改为0)
 46 alpha = np.random.random() #学习率
 47 lamda = np.random.random() #正则化系数
 48 theta = np.random.rand(5) # theta参数初始值
 49 print(‘init alpha:{}, lamda:{}, theta:{}‘.format(alpha, lamda, theta))
 50 def cost_line_reg(theta, x, y, label):
 51     theta = np.mat(theta)
 52
 53     # x特征向量加一个元素x0,x0 == 1
 54     x_one = np.ones(x.shape[0])
 55     x = np.insert(x, 0, values= x_one, axis=1)
 56     x = np.mat(x)
 57
 58     # 根据label参数指定的分类器种类,对应修改y值
 59     y = np.apply_along_axis(func, axis=1, arr=y, lb=label)
 60     y = np.mat(y)
 61
 62     # 计算损失值和更新theta
 63     for step in range(0,100):
 64         first = np.multiply((-y).T, np.log(sigmoid(np.dot(x, theta.T))))
 65         second = np.multiply((1-y).T, np.log(1 - sigmoid(np.dot(x, theta.T))))
 66         reg = (lamda/(2*len(x)) * np.sum(np.power(theta[:, 1:theta.shape[1]], 2)))
 67         cost = np.sum(first - second) / (len(x)) + reg
 68
 69         # 更新theta
 70         for theta_index in range(0, len(theta.T)):
 71             h_theta = sigmoid(np.dot(x, theta.T))
 72             sum = np.dot((h_theta.T - y), x[:, theta_index : theta_index + 1])
 73             sum = np.sum(sum)/len(x)
 74
 75             # theta0 与 其他的theta元素更新方式有点差异
 76             if theta_index == 0:
 77                 theta[0,theta_index] = theta[0,theta_index] - alpha * sum
 78             else:
 79                 theta[0, theta_index] = theta[0, theta_index] - alpha * (sum + lamda/len(x) * theta[0, theta_index])
 80
 81     return np.array(theta)
 82
 83 theta_result_h0 = cost_line_reg(theta, x_train, y_train, 0) # h0 分类器
 84 theta_result_h1 = cost_line_reg(theta, x_train, y_train, 1) # h1 分类器
 85 theta_result_h2 = cost_line_reg(theta, x_train, y_train, 2) # h2 分类器
 86
 87 print(‘theta_result_h0:{}‘.format(theta_result_h0))
 88 print(‘theta_result_h1:{}‘.format(theta_result_h1))
 89 print(‘theta_result_h2:{}‘.format(theta_result_h2))
 90
 91 # h0,h1,h2三个分类器确定好之后,把生成结果最大的分类器作为最终分类
 92 # 输入是特征向量,返回的是分类结果
 93 def h_theta(x_arr):
 94
 95     # 这里默认三个分类器的分界函数都是线性的
 96     h0_result = sigmoid(np.dot(x_arr , theta_result_h0.T))
 97     h1_result = sigmoid(np.dot(x_arr, theta_result_h1.T))
 98     h2_result = sigmoid(np.dot(x_arr , theta_result_h2.T))
 99     # 结果最大的分类器作为最终分类
100     result_lable = 0
101     if h0_result > h1_result and h0_result > h2_result:
102         result_lable = 0
103     elif h1_result > h0_result and h1_result > h2_result:
104         result_lable = 1
105     elif h2_result > h0_result and h2_result > h1_result:
106         result_lable = 2
107     return result_lable
108
109 # 在数据集上进行测试
110 def verify(x, y):
111     x_one = np.ones(x.shape[0])
112     x = np.insert(x, 0, values= x_one, axis=1)
113     x = np.mat(x)
114
115     # 各个真实类别的统计个数
116     y_real_0_num = 0
117     y_real_1_num = 0
118     y_real_2_num = 0
119
120     # 各个真实类别等于预测类别的统计个数
121     y_real_0_prediction_0_num = 0
122     y_real_1_prediction_1_num = 0
123     y_real_2_prediction_2_num = 0
124
125     # 各类别的预测准确度
126     accuracy_rite_0 = 0.0
127     accuracy_rite_1 = 0.0
128     accuracy_rite_2 = 0.0
129     accuracy_rite_whole = 0.0
130
131     for row in range(0, len(x)):
132         x_arr = x[row,:]
133         y_real = y[row,0]
134         y_prediction = h_theta(x_arr)
135
136         # 统计各个真实类别的个数
137         if y_real == 0:
138             y_real_0_num = y_real_0_num + 1
139         elif y_real == 1:
140             y_real_1_num = y_real_1_num + 1
141         elif y_real == 2:
142             y_real_2_num = y_real_2_num + 1
143
144         # 统计各个真实类别等于预测类别的个数
145         if y_real == 0 and y_prediction == 0:
146             y_real_0_prediction_0_num = y_real_0_prediction_0_num + 1
147         elif y_real == 1 and y_prediction == 1:
148             y_real_1_prediction_1_num = y_real_1_prediction_1_num + 1
149         elif y_real == 2 and y_prediction == 2:
150             y_real_2_prediction_2_num = y_real_2_prediction_2_num + 1
151
152     print(‘y_real_0_prediction_0_num[{}],y_real_0_num[{}], y_real_1_prediction_1_num[{}], y_real_1_num[{}], y_real_2_prediction_2_num[{}], y_real_2_num[{}]‘
153                  .format(y_real_0_prediction_0_num, y_real_0_num, y_real_1_prediction_1_num, y_real_1_num, y_real_2_prediction_2_num, y_real_2_num))
154
155     accuracy_rite_0 = y_real_0_prediction_0_num / y_real_0_num
156     accuracy_rite_1 = y_real_1_prediction_1_num / y_real_1_num
157     accuracy_rite_2 = y_real_2_prediction_2_num / y_real_2_num
158     accuracy_rite_whole = (y_real_0_prediction_0_num + y_real_1_prediction_1_num + y_real_2_prediction_2_num) / (len(x))
159     print(‘accuracy_rite_0[{}], accuracy_rite_1[{}], accuracy_rite_2[{}], accuracy_rite_whole[{}]‘.format(accuracy_rite_0, accuracy_rite_1, accuracy_rite_2, accuracy_rite_whole))
160 print(‘############## train_verify begin ##########‘)
161 verify(x_train, y_train)
162 print(‘############## train_verify end ##########‘)
163 print(‘############## test_verify begin ##########‘)
164 verify(x_test, y_test)
165 print(‘############## test_verify end ##########‘)

代码运行结果

  本文档重点在于讨论逻辑回归的原理和实现,所以代码里面的一些参数是随机生成的,每次执行的结果会有少许差异,工业环境中要对参数进行调优,选择最优化的参数。

  执行程序,产生的测试结果如下:

 1 init alpha:0.9878106271950878, lamda:0.07590602610318298, theta:[0.09612366 0.49599455 0.38297285 0.9730732  0.54394658]
 2 theta_result_h0:[[-1.91985969 -1.42605078  1.81454853 -1.74542862 -1.84684359]]
 3 theta_result_h1:[[-0.93718773  0.49878395 -1.18385395  0.59397282 -0.81950924]]
 4 theta_result_h2:[[-3.40965892  0.07144545 -0.59527357  2.66257363  2.65466814]]
 5 ############## train_verify begin ##########
 6 y_real_0_prediction_0_num[39],y_real_0_num[39], y_real_1_prediction_1_num[29], y_real_1_num[33], y_real_2_prediction_2_num[30], y_real_2_num[33]
 7 accuracy_rite_0[1.0], accuracy_rite_1[0.8787878787878788], accuracy_rite_2[0.9090909090909091], accuracy_rite_whole[0.9333333333333333]
 8 ############## train_verify end ##########
 9 ############## test_verify begin ##########
10 y_real_0_prediction_0_num[11],y_real_0_num[11], y_real_1_prediction_1_num[16], y_real_1_num[17], y_real_2_prediction_2_num[17], y_real_2_num[17]
11 accuracy_rite_0[1.0], accuracy_rite_1[0.9411764705882353], accuracy_rite_2[1.0], accuracy_rite_whole[0.9777777777777777]
12 ############## test_verify end ##########

  

原文地址:https://www.cnblogs.com/wyb-mingtian/p/12315314.html

时间: 2024-07-30 17:23:32

逻辑回归的原理和python实现的相关文章

逻辑回归(LogisticRegression)--python实现

1.概述 Logistic regression(逻辑回归)是当前业界比较常用的机器学习方法,用于估计某种事物的可能性. 在经典之作<数学之美>中也看到了它用于广告预测,也就是根据某广告被用 户点击的可能性,把最可能被用户点击的广告摆在用户能看到的地方,然后叫他“你点我啊!”用户点了,你就有钱收了.这就是为什么我们的电脑现在广告泛滥的 原因.还有类似的某用户购买某商品的可能性,某病人患有某种疾病的可能性啊等等.这个世界是随机的(当然了,人为的确定性系统除外,但也有可能有噪声或产生错误的结果,只

机器学习之感知器算法原理和Python实现

(1)感知器模型 感知器模型包含多个输入节点:X0-Xn,权重矩阵W0-Wn(其中X0和W0代表的偏置因子,一般X0=1,图中X0处应该是Xn)一个输出节点O,激活函数是sign函数. (2)感知器学习规则 输入训练样本X和初始权重向量W,将其进行向量的点乘,然后将点乘求和的结果作用于激活函数sign(),得到预测输出O,根据预测输出值和目标值之间的差距error,来调整初始化权重向量W.如此反复,直到W调整到合适的结果为止. (3)算法的原始形式 (4)Python代码实现 1 import

机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

机器学习算法与Python实践这个系列主要是参考<机器学习实战>这本书.因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学习算法.恰好遇见这本同样定位的书籍,所以就参考这本书的过程来学习了. 这节学习的是逻辑回归(Logistic Regression),也算进入了比较正统的机器学习算法.啥叫正统呢?我概念里面机器学习算法一般是这样一个步骤: 1)对于一个问题,我们用数学语言来描述它,然后建立一个模型,例如回归模型或者分类模型等

21-城里人套路深之用python实现逻辑回归算法

如果和一个人交流时,他的思想像弹幕一样飘散在空中,将是怎样的一种景象?我想大概会毫不犹豫的点关闭的.生活为啥不能简单明了?因为太直白了令人乏味.保留一些不确定性反而扑朔迷离,引人入胜.我们学习了线性回归,对于损失函数及权重更新公式理解起来毫无压力,这是具体直白的好处.然而遇到抽象晦涩的逻辑回归,它的损失函数及权重更新公式就经历了从p(取值范围0~1)->p/(1-p)(取值范围0~+oo)->z=log(p/(1-p))(取值范围-oo~+oo)->p=1/1+e^(-z)->极大

用Python开始机器学习(7:逻辑回归分类) --好!!

from : http://blog.csdn.net/lsldd/article/details/41551797 在本系列文章中提到过用Python开始机器学习(3:数据拟合与广义线性回归)中提到过回归算法来进行数值预测.逻辑回归算法本质还是回归,只是其引入了逻辑函数来帮助其分类.实践发现,逻辑回归在文本分类领域表现的也很优秀.现在让我们来一探究竟. 1.逻辑函数 假设数据集有n个独立的特征,x1到xn为样本的n个特征.常规的回归算法的目标是拟合出一个多项式函数,使得预测值与真实值的误差最小

逻辑回归模型(Logistic Regression)及Python实现

逻辑回归模型(Logistic Regression)及Python实现 http://www.cnblogs.com/sumai 1.模型 在分类问题中,比如判断邮件是否为垃圾邮件,判断肿瘤是否为阳性,目标变量是离散的,只有两种取值,通常会编码为0和1.假设我们有一个特征X,画出散点图,结果如下所示.这时候如果我们用线性回归去拟合一条直线:hθ(X) = θ0+θ1X,若Y≥0.5则判断为1,否则为0.这样我们也可以构建出一个模型去进行分类,但是会存在很多的缺点,比如稳健性差.准确率低.而逻辑

《统计学习方法》-逻辑回归笔记和python源码

逻辑回归(Logistic regression) 逻辑回归是统计学习中的经典分类方法.其多用在二分类{0,1}问题上. 定义1: 设X是连续随机变量,X服从逻辑回归分布是指X具有下列分布函数与密度函数: 分布函数属于逻辑斯谛函数,其图形是一条S形曲线. 定义2: 二项逻辑斯谛回归模型是如下条件概率分布: 从上式可以看出,逻辑回归对线性回归经行了归一化操作,将输出范围规定在{0,1}. 现在来看,逻辑回归的的特点,几率,指一件事件发生的概率与不发生的概率的比值.对上式分别求对数,我们可得如下式子

Python数据挖掘—回归—逻辑回归

概念 针对因变量为分类变量而进行回归分析的一种统计方法,属于概率型非线性回归 优点:算法易于实现和部署,执行效率和准确度高 缺点:离散型的自变量数据需要通过生成虚拟变量的方式来使用 在线性回归中,因变量是连续性变量,那么线性回归能根据因变量和自变量存在的线性关系来构造回归方程,因变量变成分类变量后就不存在这种关系了,需通过对数变换来进行处理(Sigmoid函数) 步骤: 1.读取数据: import pandas from pandas import read_csv data=read_csv

python实现随机森林、逻辑回归和朴素贝叶斯的新闻文本分类

实现本文的文本数据可以在THUCTC下载也可以自己手动爬虫生成, 本文主要参考:https://blog.csdn.net/hao5335156/article/details/82716923 nb表示朴素贝叶斯 rf表示随机森林 lg表示逻辑回归 初学者(我)通过本程序的学习可以巩固python基础,学会python文本的处理,和分类器的调用.方便接下来的机器学习的学习. 各个参数直观的含义: # -*- coding: utf-8 -*- """ Created on