逻辑回归(Logistic Regression)详解,公式推导及代码实现
逻辑回归(Logistic Regression)
什么是逻辑回归:
逻辑回归(Logistic Regression)是一种基于概率的模式识别算法,虽然名字中带"回归",但实际上是一种分类方法,在实际应用中,逻辑回归可以说是应用最广泛的机器学习算法之一
回归问题怎么解决分类问题?
将样本的特征和样本发生的概率联系起来,而概率是一个数.换句话说,我预测的是这个样本发生的概率是多少,所以可以管它叫做回归问题
在许多机器学习算法中,我们都是在追求这样的一个函数
例如我们希望预测一个学生的成绩y,将现有数据x输入模型 f(x) 中,便可以得到一个预测成绩y
但是在逻辑回归中,我们得到的y的值本质是一个概率值p
在得到概率值p之后根据概率值来进行分类
当然了这个1和0在不同情况下可能有不同的含义,比如0可能代表恶性肿瘤患者,1代表良性肿瘤患者
逻辑回归既可以看做是回归算法,也可以看做是分类算法,通常作为分类算法用,只可以解决二分类问题,不过我们可以使用一些其他的技巧(OvO,OvR),使其支持解决多分类问题
下面我们来看一下逻辑回归使用什么样的方法来得到一个事件发生的概率的值
在线性回归中,我们使用
来计算,要注意,因为Θ0的存在,所以x用小的Xb来表示,就是每来一个样本,前面还还要再加一个1,这个1和Θ0相乘得到的是截距,但是不管怎样,这种情况下,y的值域是(-infinity, +infinity)
而对于概率来讲,它有一个限定,其值域为[0,1]
所以我们如果直接使用线性回归的方式,去看能不能找到一组Θ来与特征x相乘之后得到的y值就来表达这个事件发生的概率呢?
其实单单从应用的角度来说,可以这么做,但是这么做不够好,就是因为概率有值域的限制,而使用线性回归得到的结果则没有这个限制
为此,我们有一个很简单的解决方案:
我们将线性回归得到的结果再作为一个特征值传入一个新的函数,经过转换,将其转换成一个值域在[0,1]之间的值
Sigmoid函数:
将函数绘制出来:
其最左端趋近于0,最右端趋近于1,其值域在(0,1),这正是我们所需要的性质
当传入的参数 t > 0 时, p > 0.5, t < 0 时, p < 0.5,分界点是 t = 0
使用Sigmoid函数后:
现在的问题就是,给定了一组样本数据集X和它对应的分类结果y,我们如何找到参数Θ,使得用这样的方式可以最大程度的获得这个样本数据集X对应的分类输出y
这就是我们在训练的过程中要做的主要任务,也就是拟合我们的训练样本,而拟合过程,就会涉及到逻辑回归的损失函数
逻辑回归的损失函数:
我们定义了一个这样的损失函数:
画出图像:
将两个式子整合:
下面我们要做的事情,就是找到一组Θ,使得J(Θ)最小
对于这个式子,我们很难像线性回归那样推得一个正规方程解,实际上这个式子是没有数学解的,也就是无法把X和直接套进公式获得Θ
不过,我们可以使用梯度下降法求得它的解,而且,这个损失函数是一个凸函数,不用担心局部最优解的,只存在全局最优解
现在,我们的任务就是求出J(Θ)的梯度,使用梯度下降法来进行计算
首先,求J(Θ)的梯度的公式:
首先,我们对Sigmoid函数求导:
得到其导数,再对logσ(t)求导,求导步骤:
由此可知, 前半部分的导数:
其中y(i)是常数
再求后半部分:
这其中
将结果代入,化简得:
就得到后半部分的求导结果:
将前后部分相加:
即:
就可以得到:
此时我们回忆一下线性回归的向量化过程
参考这个,可以得到:
这就是我们要求的梯度,再使用梯度下降法,就可以求得结果
决策边界:
这里引入一个概念,叫做判定边界,可以理解为是用以对不同类别的数据分割的边界,边界的两旁应该是不同类别的数据
从二维直角坐标系中,举几个例子,大概是如下这个样子:
使用OvR和OvO方法解决多分类:
原本的逻辑回归只能解决双分类问题,但我们可以通过一些方法,让它支持多分类问题,比如OvR和OvO方法
OvR:
n 种类型的样本进行分类时,分别取一种样本作为一类,将剩余的所有类型的样本看做另一类,这样就形成了 n 个二分类问题,使用逻辑回归算法对 n 个数据集训练出 n 个模型,将待预测的样本传入这 n 个模型中,所得概率最高的那个模型对应的样本类型即认为是该预测样本的类型
n个类别就进行n次分类,选择分类得分最高的
OvO:
n 类样本中,每次挑出 2 种类型,两两结合,一共有 Cn2 种二分类情况,使用 Cn2 种模型预测样本类型,有 Cn2 个预测结果,种类最多的那种样本类型,就认为是该样本最终的预测类型
这两种方法中,OvO的分类结果更加精确,因为每一次二分类时都用真实的类型进行比较,没有混淆其它的类别,但时间复杂度较高
代码实现 :
import numpy as np
from .metrics import accuracy_score class LogisticRegression: def __init__(self):
"""初始化Linear Regression模型"""
self.coef_ = None
self.intercept_ = None
self._theta = None def _sigmoid(self, t):
return 1. / (1. + np.exp(-t)) def fit(self, X_train, y_train, eta=0.01, n_iters=1e4):
"""根据训练数据集X_train, y_train, 使用梯度下降法训练Logistic Regression模型"""
assert X_train.shape[0] == y_train.shape[0], \
"the size of X_train must be equal to the size of y_train" def J(theta, X_b, y):
y_hat = self._sigmoid(X_b.dot(theta))
try:
return - np.sum(y*np.log(y_hat) + (1-y)*np.log(1-y_hat)) / len(y)
except:
return float('inf') def dJ(theta, X_b, y):
return X_b.T.dot(self._sigmoid(X_b.dot(theta)) - y) / len(X_b) def gradient_descent(X_b, y, initial_theta, eta, n_iters=1e4, epsilon=1e-8): theta = initial_theta
cur_iter = 0 while cur_iter < n_iters:
gradient = dJ(theta, X_b, y)
last_theta = theta
theta = theta - eta * gradient
if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
break cur_iter += 1 return theta X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
initial_theta = np.zeros(X_b.shape[1])
self._theta = gradient_descent(X_b, y_train, initial_theta, eta, n_iters) self.intercept_ = self._theta[0]
self.coef_ = self._theta[1:] return self def predict_proba(self, X_predict):
"""给定待预测数据集X_predict,返回表示X_predict的结果概率向量"""
assert self.intercept_ is not None and self.coef_ is not None, \
"must fit before predict!"
assert X_predict.shape[1] == len(self.coef_), \
"the feature number of X_predict must be equal to X_train" X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
return self._sigmoid(X_b.dot(self._theta)) def predict(self, X_predict):
"""给定待预测数据集X_predict,返回表示X_predict的结果向量"""
assert self.intercept_ is not None and self.coef_ is not None, \
"must fit before predict!"
assert X_predict.shape[1] == len(self.coef_), \
"the feature number of X_predict must be equal to X_train" proba = self.predict_proba(X_predict)
return np.array(proba >= 0.5, dtype='int') def score(self, X_test, y_test):
"""根据测试数据集 X_test 和 y_test 确定当前模型的准确度""" y_predict = self.predict(X_test)
return accuracy_score(y_test, y_predict) def __repr__(self):
return "LogisticRegression()"
逻辑回归(Logistic Regression)详解,公式推导及代码实现的更多相关文章
- Coursera公开课笔记: 斯坦福大学机器学习第六课“逻辑回归(Logistic Regression)” 清晰讲解logistic-good!!!!!!
原文:http://52opencourse.com/125/coursera%E5%85%AC%E5%BC%80%E8%AF%BE%E7%AC%94%E8%AE%B0-%E6%96%AF%E5%9D ...
- 机器学习方法(五):逻辑回归Logistic Regression,Softmax Regression
欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. 前面介绍过线性回归的基本知识, ...
- 机器学习总结之逻辑回归Logistic Regression
机器学习总结之逻辑回归Logistic Regression 逻辑回归logistic regression,虽然名字是回归,但是实际上它是处理分类问题的算法.简单的说回归问题和分类问题如下: 回归问 ...
- 机器学习(四)--------逻辑回归(Logistic Regression)
逻辑回归(Logistic Regression) 线性回归用来预测,逻辑回归用来分类. 线性回归是拟合函数,逻辑回归是预测函数 逻辑回归就是分类. 分类问题用线性方程是不行的 线性方程拟合的是连 ...
- 机器学习入门11 - 逻辑回归 (Logistic Regression)
原文链接:https://developers.google.com/machine-learning/crash-course/logistic-regression/ 逻辑回归会生成一个介于 0 ...
- 机器学习 (三) 逻辑回归 Logistic Regression
文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang 的个人 ...
- ML 逻辑回归 Logistic Regression
逻辑回归 Logistic Regression 1 分类 Classification 首先我们来看看使用线性回归来解决分类会出现的问题.下图中,我们加入了一个训练集,产生的新的假设函数使得我们进行 ...
- 逻辑回归 Logistic Regression
逻辑回归(Logistic Regression)是广义线性回归的一种.逻辑回归是用来做分类任务的常用算法.分类任务的目标是找一个函数,把观测值匹配到相关的类和标签上.比如一个人有没有病,又因为噪声的 ...
- 【机器学习】Octave 实现逻辑回归 Logistic Regression
ex2data1.txt ex2data2.txt 本次算法的背景是,假如你是一个大学的管理者,你需要根据学生之前的成绩(两门科目)来预测该学生是否能进入该大学. 根据题意,我们不难分辨出这是一种二分 ...
随机推荐
- 【题解】旅行-C++
Description 某趟列车的最大载客容量为V人,沿途共有n个停靠站,其中始发站为第1站,终点站为第n站.在第1站至第n-1站之 间,共有m个团队申请购票搭乘,若规定:(1)对于某个团队的购票申请 ...
- Mysql 时间相关
-- 当前时间SELECT NOW(), SYSDATE(), CURRENT_TIMESTAMP(), LOCALTIME(), LOCALTIMESTAMP();SELECT CURDATE(), ...
- Android调用系统分享功能总结
Android分享-调用系统自带的分享功能 实现分享功能的几个办法 1.调用系统的分享功能 2.通过第三方SDK,如ShareSDK,友盟等 3.自行使用各自平台的SDK,比如QQ,微信,微博各自的S ...
- c语言进阶10-算法
一. 数据结构和算法关系 为什么要学数据结构和算法? 通常,计算机解决问题的步骤如下: 在数学模型中,计算机处理的对象之间通常存在着一种最简单的线性关系,这类数学模型就是线性的数据结构.著名计算机科 ...
- MongoDB 启动时关于 NUMA 警告 的分析----(To avoid performance problems)
1. 需求描述 观察MongoDB的启动Log,会看到一个关于 NUMA 的警告 和 优化建议 --17T17:: I CONTROL [initandlisten] ** WARNING: You ...
- 利用gcc编译链接时出现 ‘undefined reference to `std::ios_base::Init::Init()’ 解决
一般编译链接c++程序最好使用g++,若有如上的报错信息,需要在gcc后加上 -lstdc++ eg: gcc test.c -lstdc++ gcc和g++都是GNU的一个编译器. g++:后缀.c ...
- 2019杭电多校第二场hdu6601 Keen On Everything But Triangle
Keen On Everything But Triangle 题目传送门 解题思路 利用主席树求区间第k小,先求区间内最大的值,再求第二大,第三大--直到找到连续的三个数可以构成一个三角形.因为对于 ...
- TensorFlow(1)-基础知识点总结
1. tensorflow简介 Tensorflow 是 google 开源的机器学习工具,在2015年11月其实现正式开源,开源协议Apache 2.0. Tensorflow采用数据流图(data ...
- 【JDK】JDK源码分析-HashMap(1)
概述 HashMap 是 Java 开发中最常用的容器类之一,也是面试的常客.它其实就是前文「数据结构与算法笔记(二)」中「散列表」的实现,处理散列冲突用的是“链表法”,并且在 JDK 1.8 做了优 ...
- linux文本编辑vim命令
1.Vim Vim 是一个功能强大的全屏幕文本编辑器,是 Linux/UNIX 上最常用的文本编辑器,它的作用是建立.编辑.显示文本文件. Vim 没有菜单,只有命令 2.Vim 工作模式 3.插入 ...