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之dict()的操作方法
Sep 24 Python
Python内置数据结构与操作符的练习题集锦
Jul 01 Python
python字典多键值及重复键值的使用方法(详解)
Oct 31 Python
python验证码识别的示例代码
Sep 21 Python
Python图形绘制操作之正弦曲线实现方法分析
Dec 25 Python
python实现文本界面网络聊天室
Dec 12 Python
python字符串循环左移
Mar 08 Python
在django模板中实现超链接配置
Aug 21 Python
TensorFlow自定义损失函数来预测商品销售量
Feb 05 Python
Mac中PyCharm配置Anaconda环境的方法
Mar 04 Python
python将dict中的unicode打印成中文实例
May 11 Python
简单了解Python变量作用域正确使用方法
Jun 12 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程序
2006/10/09 PHP
php的字符串用法小结
2010/06/08 PHP
php使用Cookie控制访问授权的方法
2015/01/21 PHP
PHP中SESSION过期设置
2021/03/09 PHP
JQuery实现表格动态增加行并对新行添加事件
2014/07/30 Javascript
HTML Table 空白单元格补全的简单实现
2016/10/13 Javascript
浅谈JavaScript的计时器对象
2016/12/26 Javascript
Vue系列:通过vue-router如何传递参数示例
2017/01/16 Javascript
Angular2库初探
2017/03/01 Javascript
yarn的使用与升级Node.js的方法详解
2017/06/04 Javascript
使用vue构建一个上传图片表单
2017/07/04 Javascript
Vue框架下引入ActiveX控件的问题解决
2019/03/25 Javascript
解决LayUI数据表格复选框不居中显示的问题
2019/09/25 Javascript
taro 实现购物车逻辑的实例代码
2020/06/05 Javascript
python读取Android permission文件
2013/11/01 Python
python微元法计算函数曲线长度的方法
2018/11/08 Python
Django单元测试中Fixtures用法详解
2020/02/25 Python
浅析python标准库中的glob
2020/03/13 Python
Django Auth用户认证组件实现代码
2020/10/13 Python
CSS3的Border-radius轻松制作圆角
2012/12/24 HTML / CSS
CSS3 绘制BMW logo实的现代码
2013/04/25 HTML / CSS
html5教程调用绘图api画简单的圆形代码分享
2013/12/04 HTML / CSS
德国鞋子网上商店:Omoda.de
2017/03/31 全球购物
大四自我鉴定范文
2013/10/06 职场文书
同事打架检讨书
2014/02/04 职场文书
新教师工作感言
2014/02/16 职场文书
《望庐山瀑布》教学反思
2014/04/22 职场文书
环境保护标语
2014/06/20 职场文书
企业挂职心得体会
2014/09/10 职场文书
门市房租房协议书
2014/12/04 职场文书
承诺书范本
2015/01/21 职场文书
离职信范本
2015/06/23 职场文书
2016春季校长开学典礼致辞
2015/11/26 职场文书
Python趣味实战之手把手教你实现举牌小人生成器
2021/06/07 Python
浅析Redis Sentinel 与 Redis Cluster
2021/06/24 Redis
一小时迅速入门Mybatis之bind与多数据源支持 Java API
2021/09/15 Javascript