美文网首页
ML:自己动手实现逻辑回归算法(1)

ML:自己动手实现逻辑回归算法(1)

作者: ACphart | 来源:发表于2018-09-05 17:59 被阅读47次

介绍

  • 注意:这里的代码都是在Jupyter Notebook中运行,原始的.ipynb文件可以在我的GitHub主页上下载 https://github.com/acphart/Hand_on_ML_Algorithm 其中的LogisticRegression_linear_classifier.ipynb,直接在Jupyter Notebook中打开运行即可,里面还有其他的机器学习算法实现,喜欢可以顺便给个star哦 ~~~

描述

  • 这里实现两个特征变量的逻辑回归算法的线性分类器(二分类)
import numpy as np
import matplotlib.pyplot as plt
from IPython.core.interactiveshell import InteractiveShell

InteractiveShell.ast_node_interactivity = 'all'

生成模拟数据

  • 模拟数据的内在模式是
    y = \begin{cases} 1 \quad & x_1 + x_2 \ge 0 \\ 0 \quad & x_1 + x_2 \lt 0 \end{cases}

  • 可以通过sigmod()函数及四舍五入来实现: \normalsize sigm(z) = \frac{1}{1 + e^{-z}}

  • 此函数的图像如下:

z = np.linspace(-10, 10, 100)
sigm = 1./(1. + np.exp(-z))
_ = plt.plot(z, sigm)
_ = plt.ylim(0, 1)
  • 加入随机噪声就可以得到我们的模拟数据
np.random.seed(20180823)

m = 100   # 样本量
xlim = 4  # 数据采样范围

x0 = np.ones((m, 1))
x1 = np.random.rand(m, 1)*xlim*2 - xlim
x2 = np.random.rand(m, 1)*xlim*2 - xlim
ty = 1./(1. + np.exp(-(x1 + x2))) + np.random.randn(m, 1)*0.2
y = np.round(ty)
  • 可以把图作出来,直线代表数据的内在模式,也就是红绿两种点的分界线
  • 分界线的方程是:\theta_0 x_0 + \theta_1 x_1 + \theta_2 x_2 = 0
  • 其中:\theta_0 = 0 ,\; \theta_1 = 1 ,\; \theta_2 = 1, 我们之后的算法就是要得到这三个参数的值
_ = plt.scatter(x1, x2, c=y, cmap='PiYG')
_ = plt.plot(x1, -x1, 'r')
_ = plt.ylim(-4.5, 3.5)

假设函数

  • 我们的假设函数为:\normalsize h_\theta(x^{(i)}) = \frac{1}{1 + e^{-x^{(i)}\theta}}

损失函数和梯度

  • 损失函数为: \large J(\theta) = \frac{1}{m} \sum_{i=1}^{m} Cost \left(h_\theta(x^{(i)}),\; y^{(i)}\right)
  • 其中
    \large Cost(\; h_\theta(x^{(i)}),\; y^{(i)}\;) = \begin{cases} -log(h_\theta(x^{(i)})) \quad & y^{(i)} = 1 \\ -log(1 - h_\theta(x^{(i)})) \quad & y^{(i)} = 0 \end{cases}
  • 因为y^{(i)} 只能为1或者0,所以可以合并:
    \large J(\theta) = -\frac{1}{m} \sum_{i=1}^{m} \left [y^{(i)}log(h_\theta(x^{(i)})) + (1 - y^{(i)})log(1 - h_\theta(x^{(i)}))\right ]

梯度和梯度下降

  • 梯度:
    \large \frac {\partial}{\partial \theta_j}J(\theta) = \frac{1}{m} \sum_{i=1}^{m} \left [h_\theta(x^{(i)}) - y^{(i)}\right ] x_j^{(i)}
  • 梯度下降
    \begin{aligned} \mbox{Repeat : }&\mbox{j is from 0 to n}\\ \large & \theta_j := \theta_j - \alpha \frac {\partial}{\partial \theta_j}J(\theta) \end{aligned}

向量化

  • 生成特征矩阵XX_{m\times 3} = (x_0, x_1, x_2), \quad x_0 = ({1, 1, \dots 1})^T \quad x_0\mbox{ 's size is m}
  • 假设函数:\normalsize h_\theta(X) = \frac{1}{1 + e^{-X\theta}}
  • 损失函数:
    \large J(\theta) = -\frac{1}{m} \left [y^Tlog(h_\theta(X)) + (1 - y^T)log(1 - h_\theta(X))\right ]
  • 梯度:
    \large \nabla J(\theta) = \frac{1}{m} X^T [h_\theta(X) - y]
  • 梯度下降:
    \large \theta := \theta - \alpha \nabla J(\theta)

根据向量化之后的数学式构建我们的函数

# 假设函数
def h_theta(X, theta):
    return 1./(1. + np.exp(- np.dot(X, theta)))

# 损失函数
def loss_func(X, theta, y):
    y1 = np.log(h_theta(X, theta))
    y0 = np.log(1. - h_theta(X, theta))
    return -1./m * (np.dot(y.T, y1) + np.dot((1. - y.T), y0))
    
# 梯度函数
def grad_func(X, theta, y):
    return 1./m * np.dot(X.T, h_theta(X, theta) - y)

使用梯度下降算法进行训练

np.random.seed(20180823)
# 设置学习率和收敛开关
alpha = 0.1
stop = 1e-6

i = 1
index = 1
c = np.array([0.8, 0.8, 0.8])   # 设置颜色,颜色逐渐加深

theta = np.random.randn(3, 1)
X = np.hstack((x0, x1, x2))
grad = grad_func(X, theta, y)
while not np.all(abs(grad) <= stop):
    theta = theta - alpha*grad
    grad = grad_func(X, theta, y)
    
    # 作出学习过程
    i = i+1
    if i%index == 0:
        yline = -theta[0]/theta[2] - theta[1]/theta[2]*x1
        _ = plt.plot(x1, yline, color=c)
        c = c - 0.1
        index = index*4

_ = plt.scatter(x1, x2, c=y, cmap='PiYG')
_ = plt.plot(x1, -x1, 'r')
_ = plt.ylim(-4.5, 3.5)
  • 可以看到,随着训练迭代的加深,我们的直线(灰色—黑色)和数据的内在模式(红色)越来越接近,说明实现了逻辑分类的功能

测试预测性能

  • 和模拟数据一样的模式生成测试数据,注意修改随机种子的值,这样说明得到的数据和训练数据是同一个模式,但是是全新的数据
# 测试数据
np.random.seed(2018082302) #修改随机种子

test_x0 = np.ones((m, 1))
test_x1 = np.random.rand(m, 1)*xlim*2 - xlim
test_x2 = np.random.rand(m, 1)*xlim*2 - xlim
test_ty = 1./(1. + np.exp(-(test_x1 + test_x2))) + np.random.randn(m, 1)*0.2
test_y = np.round(test_ty)
  • 使用我们训练出来的参数向量theta进行预测
  • 并输出正确率,正确率达0.95,说明我们的性能还是可以的 ~~
test_X = np.hstack((test_x0, test_x1, test_x2))
y_ = h_theta(test_X, theta)
pre_y = np.round(y_)

acc = sum(int(a == b) for a, b in zip(pre_y, test_y))/m
acc
0.95

相关文章

  • ML:自己动手实现逻辑回归算法(1)

    介绍 注意:这里的代码都是在Jupyter Notebook中运行,原始的.ipynb文件可以在我的GitHub主...

  • ML:自己动手实现单变量线性回归算法

    介绍 注意:这里的代码都是在Jupyter Notebook中运行,原始的.ipynb文件可以在我的GitHub主...

  • 从0开始实现逻辑回归算法(LogicRegression)

    从0开始实现逻辑回归算法(LogicRegression) 逻辑回归(LR)算法是一个比较常见的二元分类算法,通常...

  • 2018-10-19

    Python与数据挖掘(二)——逻辑回归 逻辑回归一般用来实现分类 一、算法原理 1、预测函数 2、将预测函数的输...

  • 【原创】逻辑回归基本概念梳理

    逻辑回归 前言 1、逻辑回归是经典二分类方法、不是回归方法 2、机器算法中,先选简单算法、后复杂,逻辑回归特别简单...

  • ML03-逻辑回归(下部分)

    本文主题-逻辑回归(下部分):逻辑回归的应用背景逻辑回归的数学基础逻辑回归的模型与推导逻辑回归算法推导梯度下降算法...

  • ML02-逻辑回归(上部分)

    本文主题-逻辑回归(上部分):逻辑回归的应用背景逻辑回归的数学基础逻辑回归的模型与推导逻辑回归算法推导梯度下降算法...

  • 7 逻辑回归

    本章讲解一个在机器学习领域里,用到的最多的一个算法,逻辑回归 1 逻辑回归 逻辑回归是一个分类算法 回归问题怎么解...

  • 逻辑回归模型

    1.逻辑回归介绍2.机器学习中的逻辑回归3.逻辑回归面试总结4.逻辑回归算法原理推导5.逻辑回归(logistic...

  • MLIib基本统计

    MLIib全貌ML Algorithms (ML 算法): 常用的学习算法,如分类,回归,聚类和协同过滤Featu...

网友评论

      本文标题:ML:自己动手实现逻辑回归算法(1)

      本文链接:https://www.haomeiwen.com/subject/guqzwftx.html