python 实现逻辑回归


Posted in Python onDecember 30, 2020

逻辑回归

适用类型:解决二分类问题

逻辑回归的出现:线性回归可以预测连续值,但是不能解决分类问题,我们需要根据预测的结果判定其属于正类还是负类。所以逻辑回归就是将线性回归的结果,通过Sigmoid函数映射到(0,1)之间

线性回归的决策函数:数据与θ的乘法,数据的矩阵格式(样本数×列数),θ的矩阵格式(列数×1)

python 实现逻辑回归

将其通过Sigmoid函数,获得逻辑回归的决策函数

python 实现逻辑回归

使用Sigmoid函数的原因:

可以对(-∞, +∞)的结果,映射到(0, 1)之间作为概率

可以将1/2作为决策边界

python 实现逻辑回归

数学特性好,求导容易

python 实现逻辑回归

逻辑回归的损失函数

线性回归的损失函数维平方损失函数,如果将其用于逻辑回归的损失函数,则其数学特性不好,有很多局部极小值,难以用梯度下降法求解最优

这里使用对数损失函数

python 实现逻辑回归

解释:如果一个样本为正样本,那么我们希望将其预测为正样本的概率p越大越好,也就是决策函数的值越大越好,则logp越大越好,逻辑回归的决策函数值就是样本为正的概率;如果一个样本为负样本,那么我们希望将其预测为负样本的概率越大越好,也就是(1-p)越大越好,即log(1-p)越大越好

为什么使用对数函数:样本集中有很多样本,要求其概率连乘,概率为0-1之间的数,连乘越来越小,利用log变换将其变为连加,不会溢出,不会超出计算精度

损失函数:: y(1->m)表示Sigmoid值(样本数×1),hθx(1->m)表示决策函数值(样本数×1),所以中括号的值(1×1)

python 实现逻辑回归

二分类逻辑回归直线编码实现

import numpy as np
from matplotlib import pyplot as plt
​
from scipy.optimize import minimize
from sklearn.preprocessing import PolynomialFeatures
​
​
class MyLogisticRegression:
  def __init__(self):
    plt.rcParams["font.sans-serif"] = ["SimHei"]
    # 包含数据和标签的数据集
    self.data = np.loadtxt("./data2.txt", delimiter=",")
    self.data_mat = self.data[:, 0:2]
    self.label_mat = self.data[:, 2]
    self.thetas = np.zeros((self.data_mat.shape[1]))
​
    # 生成多项式特征,最高6次项
    self.poly = PolynomialFeatures(6)
    self.p_data_mat = self.poly.fit_transform(self.data_mat)
​
  def cost_func_reg(self, theta, reg):
    """
    损失函数具体实现
    :param theta: 逻辑回归系数
    :param data_mat: 带有截距项的数据集
    :param label_mat: 标签数据集
    :param reg:
    :return:
    """
    m = self.label_mat.size
    label_mat = self.label_mat.reshape(-1, 1)
    h = self.sigmoid(self.p_data_mat.dot(theta))
​
    J = -1 * (1/m)*(np.log(h).T.dot(label_mat) + np.log(1-h).T.dot(1-label_mat))\
      + (reg / (2*m)) * np.sum(np.square(theta[1:]))
    if np.isnan(J[0]):
      return np.inf
    return J[0]
​
  def gradient_reg(self, theta, reg):
    m = self.label_mat.size
    h = self.sigmoid(self.p_data_mat.dot(theta.reshape(-1, 1)))
    label_mat = self.label_mat.reshape(-1, 1)
​
    grad = (1 / m)*self.p_data_mat.T.dot(h-label_mat) + (reg/m)*np.r_[[[0]], theta[1:].reshape(-1, 1)]
    return grad
​
  def gradient_descent_reg(self, alpha=0.01, reg=0, iterations=200):
    """
    逻辑回归梯度下降收敛函数
    :param alpha: 学习率
    :param reg:
    :param iterations: 最大迭代次数
    :return: 逻辑回归系数组
    """
    m, n = self.p_data_mat.shape
    theta = np.zeros((n, 1))
    theta_set = []
​
    for i in range(iterations):
      grad = self.gradient_reg(theta, reg)
      theta = theta - alpha*grad.reshape(-1, 1)
      theta_set.append(theta)
    return theta, theta_set
​
  def plot_data_reg(self, x_label=None, y_label=None, neg_text="negative", pos_text="positive", thetas=None):
    neg = self.label_mat == 0
    pos = self.label_mat == 1
    fig1 = plt.figure(figsize=(12, 8))
    ax1 = fig1.add_subplot(111)
    ax1.scatter(self.p_data_mat[neg][:, 1], self.p_data_mat[neg][:, 2], marker="o", s=100, label=neg_text)
    ax1.scatter(self.p_data_mat[pos][:, 1], self.p_data_mat[pos][:, 2], marker="+", s=100, label=pos_text)
    ax1.set_xlabel(x_label, fontsize=14)
​
    # 描绘逻辑回归直线(曲线)
    if isinstance(thetas, type(np.array([]))):
      x1_min, x1_max = self.p_data_mat[:, 1].min(), self.p_data_mat[:, 1].max()
      x2_min, x2_max = self.p_data_mat[:, 2].min(), self.p_data_mat[:, 2].max()
      xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))
      h = self.sigmoid(self.poly.fit_transform(np.c_[xx1.ravel(), xx2.ravel()]).dot(thetas))
      h = h.reshape(xx1.shape)
      ax1.contour(xx1, xx2, h, [0.5], linewidths=3)
    ax1.legend(fontsize=14)
    plt.show()
​
  @staticmethod
  def sigmoid(z):
    return 1.0 / (1 + np.exp(-z))
​
​
if __name__ == '__main__':
  my_logistic_regression = MyLogisticRegression()
  # my_logistic_regression.plot_data(x_label="线性不可分数据集")
​
  thetas, theta_set = my_logistic_regression.gradient_descent_reg(alpha=0.5, reg=0, iterations=500)
  my_logistic_regression.plot_data_reg(thetas=thetas, x_label="$\\lambda$ = {}".format(0))
​
  thetas = np.zeros((my_logistic_regression.p_data_mat.shape[1], 1))
  # 未知错误,有大佬解决可留言
  result = minimize(my_logistic_regression.cost_func_reg, thetas,
           args=(0, ),
           method=None,
           jac=my_logistic_regression.gradient_reg)
  my_logistic_regression.plot_data_reg(thetas=result.x, x_label="$\\lambda$ = {}".format(0))

二分类问题逻辑回归曲线编码实现

import numpy as np
from matplotlib import pyplot as plt
​
from scipy.optimize import minimize
from sklearn.preprocessing import PolynomialFeatures
​
​
class MyLogisticRegression:
  def __init__(self):
    plt.rcParams["font.sans-serif"] = ["SimHei"]
    # 包含数据和标签的数据集
    self.data = np.loadtxt("./data2.txt", delimiter=",")
    self.data_mat = self.data[:, 0:2]
    self.label_mat = self.data[:, 2]
    self.thetas = np.zeros((self.data_mat.shape[1]))
​
    # 生成多项式特征,最高6次项
    self.poly = PolynomialFeatures(6)
    self.p_data_mat = self.poly.fit_transform(self.data_mat)
​
  def cost_func_reg(self, theta, reg):
    """
    损失函数具体实现
    :param theta: 逻辑回归系数
    :param data_mat: 带有截距项的数据集
    :param label_mat: 标签数据集
    :param reg:
    :return:
    """
    m = self.label_mat.size
    label_mat = self.label_mat.reshape(-1, 1)
    h = self.sigmoid(self.p_data_mat.dot(theta))
​
    J = -1 * (1/m)*(np.log(h).T.dot(label_mat) + np.log(1-h).T.dot(1-label_mat))\
      + (reg / (2*m)) * np.sum(np.square(theta[1:]))
    if np.isnan(J[0]):
      return np.inf
    return J[0]
​
  def gradient_reg(self, theta, reg):
    m = self.label_mat.size
    h = self.sigmoid(self.p_data_mat.dot(theta.reshape(-1, 1)))
    label_mat = self.label_mat.reshape(-1, 1)
​
    grad = (1 / m)*self.p_data_mat.T.dot(h-label_mat) + (reg/m)*np.r_[[[0]], theta[1:].reshape(-1, 1)]
    return grad
​
  def gradient_descent_reg(self, alpha=0.01, reg=0, iterations=200):
    """
    逻辑回归梯度下降收敛函数
    :param alpha: 学习率
    :param reg:
    :param iterations: 最大迭代次数
    :return: 逻辑回归系数组
    """
    m, n = self.p_data_mat.shape
    theta = np.zeros((n, 1))
    theta_set = []
​
    for i in range(iterations):
      grad = self.gradient_reg(theta, reg)
      theta = theta - alpha*grad.reshape(-1, 1)
      theta_set.append(theta)
    return theta, theta_set
​
  def plot_data_reg(self, x_label=None, y_label=None, neg_text="negative", pos_text="positive", thetas=None):
    neg = self.label_mat == 0
    pos = self.label_mat == 1
    fig1 = plt.figure(figsize=(12, 8))
    ax1 = fig1.add_subplot(111)
    ax1.scatter(self.p_data_mat[neg][:, 1], self.p_data_mat[neg][:, 2], marker="o", s=100, label=neg_text)
    ax1.scatter(self.p_data_mat[pos][:, 1], self.p_data_mat[pos][:, 2], marker="+", s=100, label=pos_text)
    ax1.set_xlabel(x_label, fontsize=14)
​
    # 描绘逻辑回归直线(曲线)
    if isinstance(thetas, type(np.array([]))):
      x1_min, x1_max = self.p_data_mat[:, 1].min(), self.p_data_mat[:, 1].max()
      x2_min, x2_max = self.p_data_mat[:, 2].min(), self.p_data_mat[:, 2].max()
      xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))
      h = self.sigmoid(self.poly.fit_transform(np.c_[xx1.ravel(), xx2.ravel()]).dot(thetas))
      h = h.reshape(xx1.shape)
      ax1.contour(xx1, xx2, h, [0.5], linewidths=3)
    ax1.legend(fontsize=14)
    plt.show()
​
  @staticmethod
  def sigmoid(z):
    return 1.0 / (1 + np.exp(-z))
​
​
if __name__ == '__main__':
  my_logistic_regression = MyLogisticRegression()
  # my_logistic_regression.plot_data(x_label="线性不可分数据集")
​
  thetas, theta_set = my_logistic_regression.gradient_descent_reg(alpha=0.5, reg=0, iterations=500)
  my_logistic_regression.plot_data_reg(thetas=thetas, x_label="$\\lambda$ = {}".format(0))
​
  thetas = np.zeros((my_logistic_regression.p_data_mat.shape[1], 1))
  # 未知错误,有大佬解决可留言
  result = minimize(my_logistic_regression.cost_func_reg, thetas,
           args=(0, ),
           method=None,
           jac=my_logistic_regression.gradient_reg)
  my_logistic_regression.plot_data_reg(thetas=result.x, x_label="$\\lambda$ = {}".format(0))

以上就是python 实现逻辑回归的详细内容,更多关于python 实现逻辑回归的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
使用Python编写简单网络爬虫抓取视频下载资源
Nov 04 Python
Python常用模块介绍
Nov 21 Python
Python的SQLAlchemy框架使用入门
Apr 29 Python
在Python中合并字典模块ChainMap的隐藏坑【推荐】
Jun 27 Python
Python Django 添加首页尾页上一页下一页代码实例
Aug 21 Python
详解Python图像处理库Pillow常用使用方法
Sep 02 Python
Python倒排索引之查找包含某主题或单词的文件
Nov 13 Python
python 统计文件中的字符串数目示例
Dec 24 Python
浅谈pymysql查询语句中带有in时传递参数的问题
Jun 05 Python
Python 使用 PyQt5 开发的关机小工具分享
Jul 16 Python
PyQt5中QSpinBox计数器的实现
Jan 18 Python
Python中使用Selenium环境安装的方法步骤
Feb 22 Python
Python 随机按键模拟2小时
Dec 30 #Python
Python的scikit-image模块实例讲解
Dec 30 #Python
用Python实现职工信息管理系统
Dec 30 #Python
python实现双人五子棋(终端版)
Dec 30 #Python
pandas 数据类型转换的实现
Dec 29 #Python
python中xlutils库用法浅析
Dec 29 #Python
Python操作PostgreSql数据库的方法(基本的增删改查)
Dec 29 #Python
You might like
PHP 万年历实现代码
2012/10/18 PHP
在Mac OS上搭建Nginx+PHP+MySQL开发环境的教程
2015/12/21 PHP
PHP封装的简单连接MongoDB类示例
2019/02/13 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
js 操作select相关方法函数
2009/12/06 Javascript
Jquery.addClass始终无效原因分析
2013/09/08 Javascript
给超链接添加特效鼠标移动展示提示信息且随鼠标移动
2013/10/17 Javascript
浅谈javascript中return语句
2015/07/15 Javascript
如何利用Promises编写更优雅的JavaScript代码
2016/05/17 Javascript
AngularJS在IE下取数据总是缓存问题的解决方法
2016/08/05 Javascript
JavaScript之Vue.js【入门基础】
2016/12/06 Javascript
JavaScript获取短信验证码(周期性)
2016/12/29 Javascript
微信小程序自动客服功能
2017/11/02 Javascript
vue实现element-ui对话框可拖拽功能
2018/08/17 Javascript
基于jquery实现的tab选项卡功能示例【附源码下载】
2019/06/10 jQuery
React实现类似淘宝tab居中切换效果的示例代码
2020/06/02 Javascript
Ajax获取node服务器数据的完整步骤
2020/09/20 Javascript
解决vue项目axios每次请求session不一致的问题
2020/10/24 Javascript
vue使用transition组件动画效果的实例代码
2021/01/28 Vue.js
Django中对数据查询结果进行排序的方法
2015/07/17 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
pymongo insert_many 批量插入的实例
2020/12/05 Python
PyTorch中的拷贝与就地操作详解
2020/12/09 Python
需要知道的CSS3动画技术
2010/01/01 HTML / CSS
英国汽车座椅和婴儿车购物网站:Uber Kids
2017/04/19 全球购物
.NET面试题:什么是值类型和引用类型
2016/01/12 面试题
医学专业本科毕业生自我鉴定
2013/12/28 职场文书
致200米运动员广播稿
2014/02/06 职场文书
《雷鸣电闪波尔卡》教学反思
2014/02/23 职场文书
暑期培训随笔感言
2014/03/10 职场文书
作风建设整改方案
2014/10/27 职场文书
群众路线党员个人整改措施
2014/10/27 职场文书
委托公证书格式
2015/01/26 职场文书
教师工作决心书
2015/02/04 职场文书
5.12护士节活动总结
2015/02/10 职场文书
Vue Element plus使用方法梳理
2022/12/24 Vue.js