文章目录
- 逻辑回归简述
- 代码
- sklearn逻辑回归 - 手写数字识别
- 代码
- 逻辑回归算法详解
- 似然与概率的区别
- 逻辑回归算法的代码实现
- 代码
- 逻辑回归案例 - 癌细胞精准识别
- 代码
逻辑回归简述
什么是逻辑回归
当一看到“回归”这两个字,可能会认为逻辑回归是一种解决回归问题的算法,然而逻辑回归是通过回归的思想来解决二分类问题的算法。
那么问题来了,回归的算法怎样解决分类问题呢?其实很简单,逻辑回归是将样本特征和样本所属类别的概率联系在一起,假设现在已经训练好了一个逻辑回归的模型为 f(x) ,模型的输出是样本 x 的标签是 1 的概率,则该模型可以表示,p =f(x) 。若得到了样本 x 属于标签 1 的概率后,很自然的就能想到当p>0.5 时 x 属于标签 1 ,否则属于标签 0 。所以就有
由于概率是 0 到 1 的实数,所以逻辑回归若只需要计算出样本所属标签的概率就是一种回归算法,若需要计算出样本所属标签,则就是一种二分类算法。
sigmoid 函数
sigmoid函数的公式为:
函数图像如下图所示:
从sigmoid函数的图像可以看出当 t 趋近于 −∞ 时函数值趋近于 0 ,当 t 趋近于 +∞ 时函数值趋近于 1 。可见sigmoid函数的值域是 (0,1) ,满足我们要将 (−∞,+∞) 的实数转换成 (0,1) 的概率值的需求。因此逻辑回归在预测时可以看成
代码
#encoding=utf8
import numpy as np
def sigmoid(t):
'''
完成sigmoid函数计算
:param t: 负无穷到正无穷的实数
:return: 转换后的概率值
:可以考虑使用np.exp()函数
'''
#********** Begin **********#
#np.exp()函数可以实现 e 的幂运算
p = 1/(1+np.exp(-t))
return p
#********** End **********#
sklearn逻辑回归 - 手写数字识别
数据简介
本关使用的是手写数字数据集,该数据集有 1797 个样本,每个样本包括 8*8 像素(实际上是一条样本有 64 个特征,每个像素看成是一个特征,每个特征都是float类型的数值)的图像和一个 [0, 9] 整数的标签。比如下图的标签是 2 :
sklearn为该数据集提供了接口,若想使用该数据集,代码如下:
from sklearn import datasets
import matplotlib.pyplot as plt
#加载数据集
digits = datasets.load_digits()
#X表示图像数据,y表示标签
X = digits.data
y = digits.target
#将第233张手写数字可视化
plt.imshow(digits.images[232])
LogisticRegression
LogisticRegression中默认实现了 OVR ,因此LogisticRegression可以实现多分类。LogisticRegression的构造函数中有三个常用的参数可以设置:
solver:{‘newton-cg’ , ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’}, 分别为几种优化算法。默认为liblinear;
C:正则化系数的倒数,默认为 1.0 ,越小代表正则化越强;
max_iter:最大训练轮数,默认为 100 。
和sklearn中其他分类器一样,LogisticRegression类中的fit函数用于训练模型,fit函数有两个向量输入:
X:大小为 [样本数量,特征数量] 的ndarray,存放训练样本;
Y:值为整型,大小为 [样本数量] 的ndarray,存放训练样本的分类标签。
LogisticRegression类中的predict函数用于预测,返回预测标签,predict函数有一个向量输入:
X:大小为[样本数量,特征数量]的ndarray,存放预测样本。
LogisticRegression的使用代码如下:
logreg = LogisticRegression(solver=‘lbfgs’,max_iter =10,C=10)
logreg.fit(X_train, Y_train)
result = logreg.predict(X_test)
代码
from sklearn.linear_model import LogisticRegression
def digit_predict(train_image, train_label, test_image):
'''
实现功能:训练模型并输出预测结果
:param train_sample: 包含多条训练样本的样本集,类型为ndarray,shape为[-1, 8, 8]
:param train_label: 包含多条训练样本标签的标签集,类型为ndarray
:param test_sample: 包含多条测试样本的测试集,类型为ndarry
:return: test_sample对应的预测标签
'''
#************* Begin ************#
flat_train_image = train_image.reshape((-1,64))
train_min = flat_train_image.min()
train_max = flat_train_image.max()
flat_train_image = (flat_train_image-train_min)/(train_max-train_min)
#测试集变形
flat_test_image = test_image.reshape((-1,64))
test_min = flat_test_image.min()
test_max = flat_test_image.max()
flat_test_image = (flat_test_image - test_min) / (test_max - test_min)
logreg = LogisticRegression(C=4.0)
logreg.fit(flat_train_image,train_label)
result = logreg.predict(flat_test_image)
return result
#************* End **************#
逻辑回归算法详解
逻辑回归的基本概念
线性回归模型通常是处理因变量是连续变量的问题,建立的模型描述是因变量的期望与自变量之间的线性关系。而在采用回归模型分析实际问题中,所研究的变量往往不全是区间变量而是顺序变量或属性变量,比如二项分布问题。通过分析年龄、性别、体质指数、平均血压、疾病指数等指标,判断一个人是否换糖尿病,Y=0表示未患病,Y=1表示患病,这里的响应变量是一个两点(0-1)分布变量,它就不能用h函数连续的值来预测因变量Y(只能取0或1)。此时就要用Logistic regression(逻辑回归)模型解决。逻辑回归可以用来回归,也可以用来分类,主要是二分类。
逻辑回归模型的求解即:给出一组m个样本数据,每个样本数据有n个特征,并且带有标记0或者1,代表属于哪一类,为了把输入的参数代入到预测函数后始终是一个0到1之间的数,这样我们可以把0,1看做两个类别。逻辑回归中引入sigmod函数这个函数的函数值始终是在0到1之间。
逻辑回归算法
逻辑回归(Logistic Regression)虽然是名词是回归,但是实际上它是一种分类模型。假设输入值函数如下:
s(z)函数的定义域范围为( − ∞ , + ∞ ) ,sigmoid函数是一个(0,1)上的函数,从而可以将连续数据进行分类,这可能就是“回归”二字的含义吧。此外,我们也可以将s(z)函数看成概率p,假设p=0.8,此时概率值离1很近,可以将数据类别判别为1;假设p=0.2,概率值离0很近,可以将数据类别判别为0。
因此,假设我们已经训练好了一组权值W ,只要把我们需要预测的数据X代入到方程,输出的y值就是这个标签为0/1的概率,进而判断输入数据是属于哪个类别。下面我们分析使用梯度下降法来分析权值W的求解过程。
似然与概率的区别
似然 (likehood) 与概率 (probability) 在英语语境中是可以互换的。但是在统计学中,二者有截然不同的用法。
概率描述了已知参数时的随机变量的输出结果;似然则用来描述已知随机变量输出结果时,未知参数的可能取值。
例如,对于“一枚正反对称的硬币上抛十次”这种事件,我们可以问硬币落地时十次都是正面向上的“概率”是多少;而对于“一枚硬币上抛十次”,我们则可以问,这枚硬币正反面对称的“似然”程度是多少。
区别似然和概率的直接方法为,"谁谁谁的概率"中谁谁谁只能是事件,也就是,事件(发生)的概率是多少;而"谁谁谁的似然"中的谁谁谁只能是参数,比如说,参数等于某个值时的似然是多少。
似然概率正好与这个过程相反,我们关注的量不再是事件的发生概率,而是我们希望知道参数取了某个值时,有多接近实际。
逻辑回归算法的代码实现
从上述可知,逻辑回归可用于分类任务,下面我们将使用该算法完成一个基本的逻辑回归问题,我们将使用sklearn实现该算法与应用过程。sklearn是机器学习中一个常用的python第三方模块,函数sklearn.linear_model.LogisticRegression封装了逻辑回归类,可用于逻辑回归任务实现,其过程包括:
库函数导入
数据导入和划分
模型调用
模型训练
数据预测
下面给出关键过程:
from sklearn import datasets
from sklearn.datasets import load_iris
import numpy as np
import math
from sklearn.model_selection import train_test_split
from collections import Counter
from sklearn.linear_model import LogisticRegression #导入逻辑回归模型
# 数据导入
iris = datasets.load_iris()
X= iris['data']
y = iris['target']
X = X[y!=2] # 筛选数据,只选择标签为0和1
y=y[y!=2]
# 数据划分,使用默认参数
# 模型调用
logr = LogisticRegression()
# 进行训练
# 行预测
X_test_pred = logr.predict(X_test)
# 准确度计算
acc = logr.score(X_test,y_test)
代码
from sklearn import datasets
from sklearn.datasets import load_iris
import numpy as np
import math
from sklearn.model_selection import train_test_split
from collections import Counter
from sklearn.linear_model import LogisticRegression #导入逻辑回归模型
#########Begin########
# 导入数据
iris = datasets.load_iris()
X= iris['data']
y = iris['target']
X = X[y!=2] # 筛选数据,只选择标签为0和1
y=y[y!=2]
# 数据划分
X_train,X_test,y_train,y_test = train_test_split(X,y)
# 模型调用
logr = LogisticRegression()
# 模型训练
logr.fit(X_train,y_train)
# 数据预测
X_test_pred = logr.predict(X_test)
print("准确度:",logr.score(X_test,y_test))
# 结果打印
########End#########
逻辑回归案例 - 癌细胞精准识别
数据集介绍
乳腺癌数据集,其实例数量是 569 ,实例中包括诊断类和属性,帮助预测的属性一共 30 个,各属性包括为 radius 半径(从中心到边缘上点的距离的平均值), texture 纹理(灰度值的标准偏差)等等,类包括: WDBC-Malignant 恶性和 WDBC-Benign 良性。用数据集的 80% 作为训练集,数据集的 20% 作为测试集,训练集和测试集中都包括特征和类别。其中特征和类别均为数值类型,类别中 0 代表良性, 1 代表恶性。
构建逻辑回归模型
由数据集可以知道,每一个样本有 30 个特征和 1 个标签,而我们要做的事就是通过这 30 个特征来分析细胞是良性还是恶性(其中标签 y=0 表示是良性, y=1 表示是恶性)。逻辑回归算法正好是一个二分类模型,我们可以构建一个逻辑回归模型,来对癌细胞进行识别。模型如下:
我们将一个样本输入模型,如果预测值大于等于 0.5 则判定为 1 类别,如果小于 0.5 则判定为 0 类别。
训练逻辑回归模型
我们已经知道如何构建一个逻辑回归模型,但是如何得到一个能正确对癌细胞进行识别的模型呢?通常,我们先将数据输入到模型,从而得到一个预测值,再将预测值与真实值结合,得到一个损失函数,最后用梯度下降的方法来优化损失函数,从而不断的更新模型的参数 θ ,最后得到一个能够正确对良性细胞和癌细胞进行分类的模型。
使用梯度下降算法首先要知道损失函数对参数的梯度,即损失函数对每个参数的偏导,求解步骤如下:
代码
# -*- coding: utf-8 -*-
import numpy as np
import warnings
warnings.filterwarnings("ignore")
def sigmoid(x):
'''
sigmoid函数
:param x: 转换前的输入
:return: 转换后的概率
'''
return 1/(1+np.exp(-x))
def fit(x,y,eta=1e-3,n_iters=10000):
'''
训练逻辑回归模型
:param x: 训练集特征数据,类型为ndarray
:param y: 训练集标签,类型为ndarray
:param eta: 学习率,类型为float
:param n_iters: 训练轮数,类型为int
:return: 模型参数,类型为ndarray
'''
# 请在此添加实现代码 #
#********** Begin *********#
theta=np.zeros(x.shape[1])
i_iter=0
while i_iter < n_iters:
gradient = (sigmoid(x.dot(theta))-y).dot(x)
theta = theta-eta*gradient
i_iter = i_iter+1
return theta
#********** End **********#