从机器学习到逻辑回归


今天,我们只关注机器学习到线性回归这条线上的概念。别的以后再说。为了让大家听懂,我这次也不查维基百科了,直接按照自己的理解用大白话说,可能不是很严谨。

机器学习就是机器可以自己学习,而机器学习的方法就是利用现有的数据和算法,解出算法的参数。从而得到可以用的模型。

监督学习就是利用已有的数据(我们叫X,或者特征),和数据的标注(我们叫Y),找到x和y之间的对应关系,或者说是函数f。

回归分析是一种因变量为连续值得监督学习。而分类是一种应变量为非连续值的监督学习。

这里顺便提一句非连续值和连续值的英文有很多表述。

连续值可以是continuous, numerical, quantitative等。

非连续值可以是categorical, nominal, qualitative等。

逻辑回归虽然名字里面有回归两个字,但是它是分类分析,不是回归分析。逻辑回归,它之所以叫这个名字,是因为它和线性回归实在是太像了。

问题

这里,我们使用sklearn自带的癌症数据集。首先读入数据并放入pandas里面。

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
from sklearn.datasets import load_breast_cancer
#from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_splitdataset = load_breast_cancer()
data = pd.DataFrame(data=dataset.data, columns=dataset.feature_names)
data['cancer'] = [dataset.target_names[t] for t in dataset.target]

输出两个分类。

print(dataset.target_names)

[‘malignant’ ‘benign’]
翻译成中文是[‘恶性’ ‘良性’]。

输出

data[18:28]
no mean radius mean texture mean perimeter mean area mean smoothness mean compactness mean concavity mean concave points mean symmetry mean fractal dimension worst texture worst perimeter worst area worst smoothness worst compactness worst concavity worst concave points worst symmetry worst fractal dimension cancer
18 19.810 22.15 130.00 1260.0 0.09831 0.10270 0.14790 0.09498 0.1582 0.05395 30.88 186.80 2398.0 0.1512 0.3150 0.53720 0.23880 0.2768 0.07615 malignant
19 13.540 14.36 87.46 566.3 0.09779 0.08129 0.06664 0.04781 0.1885 0.05766 19.26 99.70 711.2 0.1440 0.1773 0.23900 0.12880 0.2977 0.07259 benign
20 13.080 15.71 85.63 520.0 0.10750 0.12700 0.04568 0.03110 0.1967 0.06811 20.49 96.09 630.5 0.1312 0.2776 0.18900 0.07283 0.3184 0.08183 benign
21 9.504 12.44 60.34 273.9 0.10240 0.06492 0.02956 0.02076 0.1815 0.06905 15.66 65.13 314.9 0.1324 0.1148 0.08867 0.06227 0.2450 0.07773 benign
22 15.340 14.26 102.50 704.4 0.10730 0.21350 0.20770 0.09756 0.2521 0.07032 19.08 125.10 980.9 0.1390 0.5954 0.63050 0.23930 0.4667 0.09946 malignant
23 21.160 23.04 137.20 1404.0 0.09428 0.10220 0.10970 0.08632 0.1769 0.05278 35.59 188.00 2615.0 0.1401 0.2600 0.31550 0.20090 0.2822 0.07526 malignant
24 16.650 21.38 110.00 904.6 0.11210 0.14570 0.15250 0.09170 0.1995 0.06330 31.56 177.00 2215.0 0.1805 0.3578 0.46950 0.20950 0.3613 0.09564 malignant
25 17.140 16.40 116.00 912.7 0.11860 0.22760 0.22290 0.14010 0.3040 0.07413 21.40 152.40 1461.0 0.1545 0.3949 0.38530 0.25500 0.4066 0.10590 malignant
26 14.580 21.53 97.41 644.8 0.10540 0.18680 0.14250 0.08783 0.2252 0.06924 33.21 122.40 896.9 0.1525 0.6643 0.55390 0.27010 0.4264 0.12750 malignant
27 18.610 20.25 122.10 1094.0 0.09440 0.10660 0.14900 0.07731 0.1697 0.05699 27.26 139.90 1403.0 0.1338 0.2117 0.34460 0.14900 0.2341 0.07421 malignant

这里一共有30个属性。

手写算法

无论是线性回归,逻辑回归,以及我以后会写文章的神经网络,他们的基本思路都是一样的。首先,构建一个函数模型,用这个函数表示从x到y的映射关系。

然后构建一个损失函数loss function。它描述了模型函数f(x)f(x)f(x)和真实值yyy之间的差距。当然,这个差距越小越好。

最后是优化方法。优化方法首先计算损失函数对参数的导数。既,损失函数随参数是变大还是变小的。如果损失函数随着参数的变大而变小,则说明参数应该变大。如果损失函数随着参数的变小而变小,则说明参数应该变小。优化方法里面的α\alphaα是学习率,一个小于1的数值,可以是0.01,0.001, 甚至更小。

模型函数

这里,我们的y值,并非连续的。要么y=0y=0y=0,要么y=1y=1y=1。所以,和线性回归相比,我们要把yyy控制在0和1之间。这时,前人引进了sigmoid函数。当x大于0时,y无限接近于1;当x小于0时,y无限接近于0;当x等于0时,y=0.5。

y^=11+e−z\hat{y}=\frac{1}{1 + e^{- z}}y^​=1+e−z1​ 其中 z=θxz=\theta xz=θx

def sigmoid(z):s = 1/(1+np.exp(-z))s = s.reshape(s.shape[0],1)return s

我们可以把这个函数画出来看看。

def draw_sigmoid():x = np.arange(-6, 6, .01)y = sigmoid(x)plt.plot(x, y, color='red', lw=2)plt.show()draw_sigmoid()


最终,我们的模型函数是:

def model(theta, X):z = np.sum(theta.T * X, axis=1)return sigmoid(z)

损失函数

这里,损失函数用的是cross entropy,的定义如下。

J=−y∗log(y^)−(1−y)∗log(1−y^)J= - y * log(\hat{y}) - (1-y) * log(1-\hat{y})J=−y∗log(y^​)−(1−y)∗log(1−y^​)

#cross_entropy
def cross_entropy(y, y_hat):n_samples = y.shape[0]return sum(-y*np.log(y_hat)-(1-y)*np.log(1-y_hat))/n_samplesdef cost_function(theta, X, y):y_hat = model(theta, X)return cross_entropy(y, y_hat)

优化函数

这里先要解决∂J∂θ\frac{\partial J}{\partial \theta}∂θ∂J​

因为有

J=−y∗log(y^)−(1−y)∗log(1−y^)J= - y * log(\hat{y}) - (1-y) * log(1-\hat{y})J=−y∗log(y^​)−(1−y)∗log(1−y^​)

所以

∂J∂θ=−∂(y∗log(y^)+(1−y)∗log(1−y^))∂θ\frac{\partial J}{\partial \theta} = - \frac{\partial (y * log(\hat{y}) + (1-y) * log(1-\hat{y}))}{\partial \theta}∂θ∂J​=−∂θ∂(y∗log(y^​)+(1−y)∗log(1−y^​))​

=−∂(y∗log(y^))∂θ−∂((1−y)∗log(1−y^))∂θ= - \frac{\partial (y * log(\hat{y}))}{\partial \theta} - \frac{\partial ((1-y) * log(1-\hat{y}))}{\partial \theta}=−∂θ∂(y∗log(y^​))​−∂θ∂((1−y)∗log(1−y^​))​

=−y∗∂log(y^)∂θ−(1−y)∗log(1−y^)∂θ= - y * \frac{\partial log(\hat{y})}{\partial \theta} - (1-y) * \frac{log(1-\hat{y})}{\partial \theta}=−y∗∂θ∂log(y^​)​−(1−y)∗∂θlog(1−y^​)​

=−yy^∗∂y^∂θ−1−y1−y^∗∂(1−y^)∂θ= - \frac{y}{\hat{y}} *\frac{\partial \hat{y}}{\partial \theta} - \frac{1-y}{1-\hat{y}} *\frac{\partial (1-\hat{y})}{\partial \theta}=−y^​y​∗∂θ∂y^​​−1−y^​1−y​∗∂θ∂(1−y^​)​

=−yy^∗∂y^∂θ+1−y1−y^∗∂y^∂θ= - \frac{y}{\hat{y}} *\frac{\partial \hat{y}}{\partial \theta} + \frac{1-y}{1-\hat{y}} *\frac{\partial \hat{y}}{\partial \theta}=−y^​y​∗∂θ∂y^​​+1−y^​1−y​∗∂θ∂y^​​

=(−yy^+1−y1−y^)∗∂y^∂θ= (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * \frac{\partial \hat{y}}{\partial \theta}=(−y^​y​+1−y^​1−y​)∗∂θ∂y^​​

=(−yy^+1−y1−y^)∗∂(11+e−θx)∂a= (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * \frac{\partial (\frac{1}{1 + e^{- \theta x}})} {\partial a}=(−y^​y​+1−y^​1−y​)∗∂a∂(1+e−θx1​)​

=(−yy^+1−y1−y^)∗(−y^2)∗∂(1+e−θx)∂θ= (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * (- \hat{y} ^ 2) * \frac{\partial (1 + e^{- \theta x})} {\partial \theta}=(−y^​y​+1−y^​1−y​)∗(−y^​2)∗∂θ∂(1+e−θx)​

=(−yy^+1−y1−y^)∗(−y^2)∗∂(e−θx)∂θ= (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * (- \hat{y} ^ 2) * \frac{\partial (e^{- \theta x})} {\partial \theta}=(−y^​y​+1−y^​1−y​)∗(−y^​2)∗∂θ∂(e−θx)​

=(−yy^+1−y1−y^)∗(−y^2)∗e−θx∗∂(−θx)∂θ= (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * (- \hat{y} ^ 2) * e^{- \theta x} * \frac{\partial (- \theta x)} {\partial \theta}=(−y^​y​+1−y^​1−y​)∗(−y^​2)∗e−θx∗∂θ∂(−θx)​

=(−yy^+1−y1−y^)∗y^2∗e−θx∗x= (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * \hat{y} ^ 2 * e^{- \theta x} * x=(−y^​y​+1−y^​1−y​)∗y^​2∗e−θx∗x

∵ y^=11+e−θx\hat{y}=\frac{1}{1 + e^{- \theta x}}y^​=1+e−θx1​

∴ 1+e−θx=1y^1 + e^{- \theta x}=\frac{1}{\hat{y}}1+e−θx=y^​1​

∴ e−θx=1y^−1e^{- \theta x}=\frac{1}{\hat{y}} - 1e−θx=y^​1​−1

∴ e−θx=1−y^y^e^{- \theta x}=\frac{1-\hat{y}}{\hat{y}}e−θx=y^​1−y^​​

∂J∂θ=(−yy^+1−y1−y^)∗y^2∗1−y^y^∗x\frac{\partial J}{\partial \theta} = (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * \hat{y} ^ 2 * \frac{1-\hat{y}}{\hat{y}} * x∂θ∂J​=(−y^​y​+1−y^​1−y​)∗y^​2∗y^​1−y^​​∗x

∂J∂θ=(−yy^+1−y1−y^)∗y^∗(1−y^)∗x\frac{\partial J}{\partial \theta} = (- \frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}} ) * \hat{y} * (1-\hat{y}) * x∂θ∂J​=(−y^​y​+1−y^​1−y​)∗y^​∗(1−y^​)∗x

∂J∂θ=(−y∗(1−y^)+(1−y)∗y^)∗x\frac{\partial J}{\partial \theta} = (- y * (1-\hat{y}) + (1-y) * \hat{y} ) * x∂θ∂J​=(−y∗(1−y^​)+(1−y)∗y^​)∗x

∂J∂θ=(−y+y∗y^+y^−y∗y^)∗x\frac{\partial J}{\partial \theta} = (- y + y *\hat{y} + \hat{y}-y * \hat{y} ) * x∂θ∂J​=(−y+y∗y^​+y^​−y∗y^​)∗x

∂J∂θ=(y^−y)∗x\frac{\partial J}{\partial \theta} = (\hat{y}-y ) * x∂θ∂J​=(y^​−y)∗x

最后,得到优化函数:

θ=θ−α∗∂J∂θ\theta = \theta - \alpha * \frac{\partial J}{\partial \theta}θ=θ−α∗∂θ∂J​

θ=θ−α∗(y^−y)∗x\theta = \theta - \alpha * (\hat{y}-y ) * xθ=θ−α∗(y^​−y)∗x

python函数如下:

def optimize(theta,X,y):n = X.shape[0]alpha = 1e-1y_hat = model(theta,X)dtheta = (1.0/n) * ((y_hat-y)*X)dtheta = np.sum(dtheta, axis=0)dtheta=dtheta.reshape((31,1))theta = theta - alpha * dthetareturn theta

评估

分类问题的评估比较简单,一般用准确率就可以了。当然也可以用别的(召回率,Precision,ROC,F1 Score等等),其公式如下。

def predict_proba(theta, X):y_hat=model(theta, X)return y_hatdef predict(X, theta):y_hat=predict_proba(theta,X)y_hard=(y_hat > 0.5) * 1return y_harddef accuracy(theta, X, y):y_hard=predict(X, theta)count_right=sum(y_hard == y)return count_right*1.0/len(y)

循环函数

我们不断的调用优化函数来更新参数。

def iterate(theta,X,y,times):costs = []accs = []for i in range(times):theta = optimize(theta,X,y)costs.append(cost_function(theta, X, y))accs.append(accuracy(theta, X, y))return theta, costs, accs

使用算法

准备数据

加载数据

X = dataset.data
y = dataset.target
n_features = X.shape[1]

归一化

std=X.std(axis=0)
mean=X.mean(axis=0)
X_norm = (X - mean) / std

在x矩阵前面加上一列1,这样做的好处是,不需要单独处理截距(interception)。前面的优化方法的推导,已经很麻烦了。如果把截距和斜率(coefficient)分开处理,我又要推导一遍。并且这样程序变得很复杂,很难维护了。

def add_ones(X):ones=np.ones((X.shape[0],1))X_with_ones=np.hstack((ones, X))return X_with_ones
X_with_ones = add_ones(X_norm)

求参数

首先,初始化参数。我这里都为1。

theta = np.ones((n_features+1,1))

接着,就可以一直循环求参数了。

theta, costs, accs = iterate(theta, X_train, y_train, 1500)

随着不断的训练,loss不断下降。

(放大到1到100)

而准确率不断提升。

(放大到1到100)


我们最终的loss和准确率是

print(costs[-1], accs[-1])

[0.0489982] [0.99246231]

用测试数据评估为

accuracy(theta, X_test, y_test)

array([0.97660819])

用sklearn计算

from sklearn.linear_model import LogisticRegression
X = dataset.data
y = dataset.target
X_train, X_test, y_train, y_test = train_test_split(X_with_ones, y, test_size = 0.3, random_state=12345)
lr = LogisticRegression()
lr.fit(X_train, y_train)

训练数据集准确率

lr.score(X_train, y_train)

0.992462311557789

测试数据集准确率

lr.score(X_test, y_test)

0.9766081871345029

可以看到,这里的准确率和我们手写的逻辑回归是一样的。大功告成了!

模型参数解释

把函数

y^=11+e−θx\hat{y}=\frac{1}{1 + e^{- \theta x}}y^​=1+e−θx1​

分解得到

y^=11+e−θ0−θ1x1−θ2x2−θ3x3\hat{y}=\frac{1}{1 + e^{- \theta_0 - \theta_1 x_1 - \theta_2 x_2 - \theta_3 x_3}}y^​=1+e−θ0​−θ1​x1​−θ2​x2​−θ3​x3​1​

y^=11+e−θ0e−θ1x1e−θ2x2e−θ3x3\hat{y}=\frac{1}{1 + e^{- \theta_0} e^{- \theta_1 x_1} e^{ - \theta_2 x_2 } e^{- \theta_3 x_3}}y^​=1+e−θ0​e−θ1​x1​e−θ2​x2​e−θ3​x3​1​

当θ1\theta_1θ1​为0时,e−θ1x1=1e^{- \theta_1 x_1}=1e−θ1​x1​=1 ,x1x_1x1​的变化对结果没有影响。

当θ1\theta_1θ1​为大于0时,e−θ1x1e^{- \theta_1 x_1}e−θ1​x1​随x1x_1x1​的增大而变小 ,而分母变小则y^\hat{y}y^​变大。既,y^\hat{y}y^​随着x1x_1x1​的变大而变大。

反之,当θ1\theta_1θ1​为小于0时,y^\hat{y}y^​随着x1x_1x1​的变大而变小。

我们这里以mean radius为例,它的参数为-0.356072,所以,y^\hat{y}y^​随着mean radius的变大而变小。而0对应的是恶性,1对应的是良性。我们可以说,mean radius越大,越有可能是恶行肿瘤。

python机器学习手写算法系列

完整源代码:

https://github.com/juwikuang/machine_learning_step_by_step

欢迎阅读本系列其他文章:

《python机器学习手写算法系列——线性回归》

《python机器学习手写算法系列——逻辑回归》

《python机器学习手写算法系列——决策树》

《python机器学习手写算法系列——kmeans聚类》

python机器学习手写算法系列——逻辑回归相关推荐

  1. python机器学习手写算法系列——线性回归

    本系列另一篇文章<决策树> https://blog.csdn.net/juwikuang/article/details/89333344 本文源代码: https://github.c ...

  2. python机器学习手写算法系列——kmeans聚类

    从机器学习到kmeans 聚类是一种非监督学习,他和监督学习里的分类有相似之处,两者都是把样本分布到不同的组里去.区别在于,分类分析是有标签的,聚类是没有标签的.或者说,分类是有y的,聚类是没有y的, ...

  3. python机器学习手写算法系列——贝叶斯优化 Bayesian Optimization

    Bayesian Optimization 贝叶斯优化在无需求导的情况下,求一个黑盒函数的全局最优解的一系列设计策略.(Wikipedia) 最优解问题 最简单的,获得最优解的方法,就是网格搜索Gri ...

  4. 《Tensorflow 从基础到实战》01 安装与基础操作、手写数据集、逻辑回归

    书山有路勤为径,学海无涯苦作舟 凡我不能创造的,我就不能理解 1. 安装与简介 1.1 安装 在anaconda的promat pip install tensorflow 不能安装的话,外部安装网址 ...

  5. python机器学习库keras——线性回归、逻辑回归、一般逻辑回归

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 线性回归 import numpy as npfrom keras.models import Sequential from ker ...

  6. python机器学习基础05——sklearn之逻辑回归+分类评价指标

    文章目录 逻辑回归 逻辑回归的损失函数 逻辑回归API 分类模型的评价指标 混淆矩阵 准确率 召回率(较多被使用) 精确率 f1-score:精确率和召回率的调和平均数 AUC 逻辑回归 逻辑回归是经 ...

  7. python机器学习手写字体识别_Python 3 利用机器学习模型 进行手写体数字检测

    0.引言 介绍了如何生成手写体数字的数据,提取特征,借助 sklearn 机器学习模型建模,进行识别手写体数字 1-9 模型的建立和测试. 用到的几种模型: 1. LR,Logistic Regres ...

  8. 【机器学习与算法】python手写算法:Cart树

    [机器学习与算法]python手写算法:Cart树 背景 代码 输出示例 背景 Cart树算法原理即遍历每个变量的每个分裂节点,找到增益(gini或entropy)最大的分裂节点进行二叉分割. 这里只 ...

  9. sklearn分类算法(逻辑回归、朴素贝叶斯、K近邻、支持向量机 、决策树、随机森林 )的使用

    scikit-learn机器学习的分类算法包括逻辑回归.朴素贝叶斯.KNN.支持向量机.决策树和随机森林等.这些模块的调用形式基本一致,训练用fit方法,预测用predict方法.用joblib.du ...

最新文章

  1. 楼盘历史价格管理导入功能优化
  2. TextLink的空格使用
  3. etcd — 安装部署
  4. PHP密码生成管理源码,php密码生成类(附源码)
  5. Application,Session和Cookies的区别
  6. ffmpeg 命令过滤器裁剪
  7. 正则表达式(一) -- 元字符(转)
  8. 我国计算机系统安全保护等级的划分,信息安全技术题库:我国制定了强制性国家标准《计算机信息系统安全保护等级划分准则》,其中属于第二级的是()。...
  9. Bar函数--Matplotlib
  10. linux ps2鼠标驱动,a1657苹果鼠标驱动 最新版:VoodooPS2Controller v1.9
  11. 混合多云时代:大型主机z15的新使命
  12. 微信小程序阅读器功能
  13. excel 2010 删除重复行(按某一列重复)
  14. 量子BB84,B92协议简单介绍
  15. 计算机会计数据处理流程是怎样的,实现会计电算化后,会计数据的处理流程依旧和手工..._高级会计师_帮考网...
  16. Map.containsKey() 的一个使用场景.
  17. 【软件工程】UML序列图
  18. SHU1757 村村通工程(Floyd算法)
  19. 使用微软官方工具制作U盘系统重装盘
  20. Android 通过 NSD 服务 Netty(断线重连、心跳、黏包处理) 实现两个 Android 系统端的长连接通讯

热门文章

  1. 光影软件测试自学,使用set a light 3D STUDIO来学习如何布光②
  2. 小说规则捕捉器 V1.55——能支持绝大多数小说网站捕捉
  3. AT24C02的IIC通信
  4. 学python笔记本什么牌子好且实惠实用_想自学python,应该买什么牌子的笔记本?...
  5. canvas 圆角矩形填充_canvas制作圆角矩形(包括填充矩形的功能)
  6. MDK5.25 Jlink提示无器件解决方法
  7. 计算机二级培训 策划,计算机二级培训策划书.doc
  8. 【回放】5G小基站射频测试网络研讨会
  9. Ubuntu Linux入门到精通
  10. 阿里云iot haas Micropython连接esp32;esp32物联网设备上报信息及云端信息获取;远程控制设备自带led熄灭;网页界面交互远程控制