1. python 原生实现

这里的原生实现异常粗糙(没有正则项,随机梯度上升),就是上一篇 原理篇 的代码实现,数据集直接来自sklearn iris(3分类问题),另外,手工提出了0,1两类,仅做了两类iris的分类。
对于 (h(X) = w_0 + w_1 x_1 + w_2 x_2 + ... + W_m x_m) = (W^T X)
其中 (W =[w_0,w_1,...w_m] , X = [1,x_1,x_2,...,X_m]) 我习惯于把截距(w_0) 也合到向量中去了。

import numpy as np
from sklearn.datasets import load_iris"""
加载数据
"""
def load_dataSet():X, Y = load_iris(return_X_y=True)X_data, Y_data = X[:100,:], Y[:100]   ## 只要 0,1 两类,做两分类Z = np.concatenate((X_data, Y_data.reshape(X_data.shape[0], 1)), axis=1)np.random.shuffle(Z)#分割数据为训练集和测试集X_train, Y_train = Z[:75,0:-1], Z[:75,-1:]X_test, Y_test = Z[75:, :-1], Z[75:, -1:]return X_train,Y_train,X_test,Y_test"""
模型训练
"""def sigmoid(W,X):return 1.0 / (np.exp( - np.dot(W.T,X)) + 1)def LRModel(W,X,Y,epoch,alpha):for i in range(0,epoch):Yhat = sigmoid(W, X)J = np.dot(Y, np.log(Yhat.T + 0.001)) + np.dot((1 - Y), np.log(1 - Yhat.T +0.001)) ## 这里我手工加了一个0.001,防止处理log0的情况W = W + (alpha * (np.dot((Y - Yhat),X.T)).T)return W"""
模型预测,计算各个指标
"""
def predict(X_test,Y_test,Wf):Ypre = sigmoid(Wf, X_test)print(Ypre)Ypre = np.where(Ypre > 0.5, 1., 0.)print(Ypre)print(Y_test)acc = Ypre - Y_testprint(acc)if __name__ == "__main__":# 初始化WW0 = np.random.randn(5,1) # 列向量print(W0)X_train,Y_train,X_test,Y_test = load_dataSet()X_train = np.concatenate((np.ones((X_train.shape[0], 1)), X_train),axis=1)X_test = np.concatenate((np.ones((X_test.shape[0], 1)), X_test), axis=1)Wf = LRModel(W0,X_train.T,Y_train.T,1000,0.05)print("最终学习的参数为:")print(Wf)predict(X_test.T,Y_test.T,Wf)
  • 结果
[[-0.32794377][-0.16341301][-0.46871745][-0.58777365][ 0.72274566]]
最终学习的参数为:
[[-0.92044644][-0.86818604][-3.75098037][ 5.22856039][ 3.17813294]]
[[9.99919845e-01 9.99939370e-01 9.99912569e-01 9.99983816e-019.97146748e-01 6.61803146e-05 3.19672831e-06 9.99976409e-019.99999553e-01 9.99837974e-01 9.99827795e-01 4.69817201e-041.65549104e-05 9.99878991e-01 9.99982895e-01 1.66078700e-049.88524297e-01 1.12949239e-05 9.99600934e-01 6.22679950e-059.99989180e-01 1.44838053e-04 4.05583288e-05 3.13544364e-049.99987482e-01]]
[[1. 1. 1. 1. 1. 0. 0. 1. 1. 1. 1. 0. 0. 1. 1. 0. 1. 0. 1. 0. 1. 0. 0. 0.1.]]
[[1. 1. 1. 1. 1. 0. 0. 1. 1. 1. 1. 0. 0. 1. 1. 0. 1. 0. 1. 0. 1. 0. 0. 0.1.]]
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.0.]]   ## acc,可以看到在测试集上完全预测正确

2. scikit-learn代码实现

scikit-learn中LR的损失函数函数和我们想象的不一样,一方面,他加入了正则项,另一方面,scikit-learn中(y_i)取 1 或者 -1,故他构造的损失函数形式与我们常规的构造不同,(其实,不管是机器学习,还是深度学习中,在得出目标函数后,我们都要想办法把(y_i)加入目标函数中,得到了损失函数,所以可以灵活构造哈

[hat{y_i} = P(y_i| x_i;W) = frac{1}{e^{-x_i^T W + c} + 1} (1) ]

其中(hat{y_i})为预测值,W为列向量,c为标量

[(hat{y_i} = 1) = P(y_i = 1| x_i;W) = frac{1}{e^{y_i(-x_i^TW + c)} + 1} = frac{1}{e^{-x_i^T W + c} + 1} (2) ]

[(hat{y_i} = -1) = P(y_i = -1| x_i;W) = 1 - P(y_i = 1| x_i;W) = 1 - frac{1}{e^{-x_i^T W + c} + 1} = frac{1}{e^{x_i^TW + c} + 1} = frac{1}{e^{y_i(-x_i^T W + c)} + 1} (3) ]

综上(0)(1)(2),sklearn LR的损失函数可定义为:

[J(W,c) = mathop{argmax}_{W,c} prod_i^m frac{1}{e^{y_i(-x_i^T W + c)} + 1} ]

即为等价于:

[J(W,c) = mathop{argmax}_{W,c}( - sum_{i}^{m} log(e^{y_i(-x_i^T W + c)} + 1) ) ]

即为:

[J(W,c) = mathop{argmin}_{W,c} sum_{i}^{m} log(exp(-y_i(x_i^T W + c)) + 1) ]

引入(L_2)正则化:

[J(W,c) = mathop{argmin}_{W,c} sum_{i}^{m} log(exp(-y_i(x_i^T W + c)) + 1) + frac{1}{2} lambda W^T W (4) ]

其中 (lambda)是超参且必须为正浮点数,需要手工调参
(4)式求出来的参数W,c的值和下式无异

[J(W,c) = mathop{argmin}_{W,c} lambda sum_{i}^{m} log(exp(-y_i(x_i^T W + c)) + 1) + frac{1}{2} W^T W (5) ]

对于无异的解释:

另外除了L2正则化外,还有L1,Elastic-Net 正则化

  • L1正则化:

[min_{W,c} |w|_1 + C sum_{i=1}^n log(exp(- y_i (X_i^T w + c)) + 1) ]

  • Elastic-Net正则化:

[min_{w, c} frac{1 - ho}{2}w^T w + ho |w|_1 + C sum_{i=1}^n log(exp(- y_i (X_i^T w + c)) + 1) ]

简单来讲,L1正则化偏向于起到特征选择作用,L2正则化偏向于起到防止过拟合的作用,Elastic-Net综合了L1,L2两种正则化的作用
另外说一句,由于水平有限,鄙人仅关注于sklearn的API的使用,各个参数的含义,不管追究sklearn中算法的具体实现,原因参考如下:怎样开始阅读scikit-learn的源码?是否值得读? - 知乎 [Glenn Qian的回答]

sklearn API

  • sklearn.linear_model.LogisticRegression 参数介绍
class sklearn.linear_model.LogisticRegression(penalty='l2', *, dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1,
class_weight=None, random_state=None, solver='lbfgs', max_iter=100, multi_class='auto',
verbose=0, warm_start=False, n_jobs=None, l1_ratio=None)
  • penalty{‘l1’, ‘l2’, ‘elasticnet’, ‘none’}, default=’l2’
    penalty表示选择的正则化,可选L1,L2,elasticnet, none,默认是l2

  • dual: bool, default=False
    当使用solver='liblinear',l2正则化时,才有dual = true

  • tol: float, default=1e-4
    停止训练的条件,当迭代前后的函数差值小于等于tol时就停止

  • C: float, default=1.0
    正则化强度的倒数,必须为正浮点数。越小的值表示越强的正则化

  • fit_intercept: bool, default=True
    指定是否应将常量(也称为偏差或截距)添加到决策函数

  • intercept_scaling: float, default=1
    仅在使用solver = 'liblinear' 且fit_intercept = True时有用。
    *intercept_scaling: float, default=1

  • class_weight: dict or ‘balanced’, default=None
    以字典或者'balanced'形式给出模型的参数。如果没有给出,所有类的权重都应该是1。“balanced” 模式使用y的值自动调整权值与输入数据中的类频率成反比,如n_samples / (n_classes * np.bincount(y))。
    注意,如果指定了sample_weight,那么这些权重将与sample_weight相乘(通过fit方法传递)。
    0.17版本新增:class_weight= 'balanced'

  • random_state: int, RandomState instance, default=None
    在solver= 'sag','saga'或 'liblinear' 才需要有random_state设置。

  • solver: {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’}, default=’lbfgs’
    求解器solver可以使用 'newton-cg','lbfgs','liblinear','sag','sage'算法来更新参数,其中sage 表示 Stochastic Average Gradient descent。选择solver的一般原则如下:

  1. 对于小型数据集,选择'liblinear',大型数据集,可选择‘sag’,'saga';
  2. ‘newton-cg’, ‘lbfgs’, ‘sag’ and ‘saga’ 应用在L2正则化或没有正则化的地方;
  3. ‘liblinear’ 和‘saga’ 也可以应用在L1正则化出现的地方;
  4. ‘saga’支持‘elasticnet’正则化;
  5. ‘liblinear’不支持penalty='none';
  6. 对于多分类问题,只有“newton-cg”, “sag”, “saga”和“lbfgs”直接处理多分类问题。而"liblinear"多分类问题转化成多个二分类问题(one-versus-rest,又称ovr)
  • max_iter: int, default=100
    使求解器solver收敛所需的最大迭代次数
  • multi_class: {‘auto’, ‘ovr’, ‘multinomial’}, default=’auto’
  • multi_class: {‘auto’, ‘ovr’, ‘multinomial’}, default=’auto’
    如果选择的选项是'ovr',那么将多分类转化成多个二分类问题。对于“multinomial”损失最小化是多项式损失适合整个概率分布,即使当数据是二进制。当求解器= ' liblinear '时,'多项'不可用。auto选择' ovr '如果数据是二进制的,或者如果solver= ' liblinear ',否则选择'多项'。
  • verbose: int, default=0
    记录训练的日志,int类型。默认为0。就是不输出训练过程,1的时候偶尔输出结果
  • warm_start: bool, default=False
    热启动参数,bool类型。默认为False。如果为True,则下一次训练是以重新上一次的调用作为初始化
  • n_jobs : int, default: 1
    用cpu的几个核来跑程序,-1表示使用所有处理器。
  • l1_ratio: float, default=None
    当 0 <= l1_ratio <= 1 且 penalty = 'Elasticnet'时, 使用的才是'elasticnet'正则化。设置l1_ratio=0 相当于使用penalty='l2',而设置l1_ratio=1 相当于使用penalty='l1'。

机器学习之LR算法理论和实战(实战篇)相关推荐

  1. 【机器学习算法笔记系列】逻辑回归(LR)算法详解和实战

    逻辑回归(LR)算法概述 逻辑回归(Logistic Regression)是用于处理因变量为分类变量的回归问题,常见的是二分类或二项分布问题,也可以处理多分类问题,它实际上是属于一种分类方法. 逻辑 ...

  2. 数据产品必备技术知识:机器学习及常见算法,看这一篇就够了

    大家都知道,产品经理需要懂技术,很多面试官都偏好有技术背景的同学,毕竟产品经理经常要和开发同学相爱相杀.当然也不是一定要求能够精通,但是至少不要让这块成为沟通的障碍,懂点技术,实际工作中也能少被开发同 ...

  3. Python机器学习---2.聚类算法理论部分

    文章目录 1.聚类分析 1.1 无监督学习与聚类算法 1.1.1.旨在理解数据自然结构的聚类 1.1.2 用于数据处理的聚类 1.2 核心概念 1.2.1 聚类分析 1.2.2 簇 1.3 基于原型的 ...

  4. 支持向量机python代码_Python机器学习SVM支持向量机算法理论 | kTWO-个人博客

    PS:这篇文章讲的是SVM的算法的基础理论知识,因为博主也是刚学习没多久,对SVM的数学思想了解的不是很深,所以这篇文章就简单介绍一下什么是SVM以及SVM是怎么工作的. 1.什么是支持向量机(SVM ...

  5. 【白话机器学习】算法理论+实战之Xgboost算法

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支 ...

  6. 【白话机器学习】算法理论+实战之LightGBM算法

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支 ...

  7. 【白话机器学习】算法理论+实战之PageRank算法

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Ad ...

  8. 【白话机器学习】算法理论+实战之关联规则

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Ad ...

  9. 【白话机器学习】算法理论+实战之EM聚类

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Ad ...

最新文章

  1. python源码精要(10)-python源代码阅读概要(1)
  2. Egret入门学习日记 --- 第二篇
  3. C 桥接模式 - 开关和电器
  4. 计算机房英语单词,主机房是什么意思
  5. 301、404、200、304、500HTTP状态
  6. 流程图中的虚线含义_还在为画流程图烦恼,焦躁?介绍一款画图神器,让你爱上画图!...
  7. 初学Java6:Java OOP基础语法总结
  8. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 9丨有趣的电影【难度简单】
  9. 用牛顿法求方程的根的c语言编程,用牛顿迭代法和二分法求方程的根【C语言】...
  10. JavaScript笔记 - 对象继承的几种方式
  11. 零基础学python好学吗-想要0基础学python要怎么做?python好学吗?
  12. windows平台下在Cygwin中运行Nutch1。2的抓取命令提示JAVA_HOME not set解决方案
  13. win10 桌面设置为远程桌面
  14. 人脸识别数据集-WebFace260M
  15. 爬取贝壳网深圳二手房实战
  16. 【转】家庭影院的音频线改如何布置
  17. linux gz的如何解压缩,linux gz 解压缩
  18. HbuilderX 配置eslint规范 问题
  19. 【PyTorch】下载的预训练模型的保存位置(Windows)
  20. 【CV】图像标准化与归一化

热门文章

  1. 怎样简单的创建一个vector类?(干货 ! ! !详细 ! ! ! ! !)
  2. ios-通知:闹钟之关于设置闹钟后,点击app图标进入程序不播放音乐的问题(已解决)
  3. Python使用openCV获得图片的h,w,c
  4. 图像通道转换[n c h w] 转 [n h w c]
  5. 编程金融小白学 股票期权 lv.3 PCP 平价
  6. 泛微E9 sql缓存注意事项
  7. 视角来分析 腾讯 微信访客系统的一些问题 (一)
  8. vivo 短视频推荐去重服务的设计实践
  9. Certutil工具(Windows命令行下载常用)
  10. 检测单词拼写语法:是否符合大小写语法