赞
踩
逻辑斯蒂回归虽然名字叫回归,但是其实分类, 而且这个分类很强大(以后工作是必须要用的(分类问题))。逻辑回归假设数据服从伯努利分布,通过极大化似然函数的方法,运用梯度下降来求解参数,来达到将数据二分类的目的。
利用Logistics回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的“回归” 一词源于最佳拟合,表示要找到最佳拟合参数集。训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化算法。接下来介绍这个二值型输出分类器的数学原理
Logistic Regression和Linear Regression的原理是相似的,可以简单的描述为这样的过程:
(1)找一个合适的预测函数,一般表示为h函数,该函数就是我们需要找的分类函数,它用来预测输入数据的判断结果。这个过程是非常关键的,需要对数据有一定的了解或分析,知道或者猜测预测函数的“大概”形式,比如是线性函数还是非线性函数。
(2)构造一个Cost函数(损失函数),该函数表示预测的输出(h)与训练数据类别(y)之间的偏差,可以是二者之间的差(h-y)或者是其他的形式。综合考虑所有训练数据的“损失”,将Cost求和或者求平均,记为J(θ)函数,表示所有训练数据预测值与实际类别的偏差。
(3)显然,J(θ)函数的值越小表示预测函数越准确(即h函数越准确),所以这一步需要做的是找到J(θ)函数的最小值。找函数的最小值有不同的方法,Logistic Regression实现时有梯度下降法(Gradient Descent)。
1 构造预测函数
logistic Regression虽然名字里带“回归”,但是它实际上是一种分类方法,用于两分类问题(即输出只有两种)。首先需要先找到一个预测函数(h),显然,该函数的输出必须是两类值(分别代表两个类别),所以利用了Logistic函数(或称为Sigmoid函数),函数形式为
2构造损失函数
Cost函数和J(θ)函数是基于最大似然估计推导得到的。
最大似然估计就是要求得使l(θ)取最大值时的θ,其实这里可以使用梯度上升法求解,求得的θ就是要求的最佳参数
3梯度下降法求J(θ)的最小值
求J(θ)的最小值可以使用梯度下降法,根据梯度下降法可得θ的更新过程:
形式简单,模型的可解释性非常好。从特征的权重可以看到不同的特征对最后结果的影响,某个特征的权重值比较高,那么这个特征最后对结果的影响会比较大;
模型效果不错。在工程上是可以接受的(作为baseline),如果特征工程做的好,效果不会太差,并且特征工程可以大家并行开发,大大加快开发的速度;
训练速度较快。分类的时候,计算量仅仅只和特征的数目相关。并且逻辑回归的分布式优化sgd发展比较成熟,训练的速度可以通过堆机器进一步提高,这样我们可以在短时间内迭代好几个版本的模型;
资源占用小,尤其是内存。因为只需要存储各个维度的特征值;
方便输出结果调整。逻辑回归可以很方便的得到最后的分类结果,因为输出的是每个样本的概率分数,我们可以很容易的对这些概率分数进行cutoff,也就是划分阈值(大于某个阈值的是一类,小于某个阈值的是一类)。
准确率并不是很高。因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布;
很难处理数据不平衡的问题。举个例子:如果我们对于一个正负样本非常不平衡的问题比如正负样本比 10000:1.我们把所有样本都预测为正也能使损失函数的值比较小。但是作为一个分类器,它对正负样本的区分能力不会很好;
处理非线性数据较麻烦。逻辑回归在不引入其他方法的情况下,只能处理线性可分的数据,或者进一步说,处理二分类的问题;
逻辑回归本身无法筛选特征。有时候,我们会用gbdt来筛选特征,然后再上逻辑回归。
(1)逻辑回归的损失函数为什么要使用极大似然函数作为损失函数?
损失函数一般有四种,平方损失函数,对数损失函数,HingeLoss0-1损失函数,绝对值损失函数。将极大似然函数取对数以后等同于对数损失函数。在逻辑回归这个模型下,对数损失函数的训练求解参数的速度是比较快的。
因为目标是要让预测为正的的概率最大,且预测为负的概率也最大,即每一个样本预测都要得到最大的概率,将所有的样本预测后的概率进行相乘都最大,这就能到似然函数了。
(2)逻辑回归在训练的过程当中,如果有很多的特征高度相关或者说有一个特征重复了100遍,会造成怎样的影响?
如果在损失函数最终收敛的情况下,其实就算有很多特征高度相关也不会影响分类器的效果。
(3)为什么我们还是会在训练的过程当中将高度相关的特征去掉?
去掉高度相关的特征会让模型的可解释性更好,可以大大提高训练的速度。如果模型当中有很多特征高度相关的话,就算损失函数本身收敛了,但实际上参数是没有收敛的,这样会拉低训练的速度。其次是特征多了,本身就会增大训练的时间。
(4)使用L1L2正则化,为什么可以降低模型的复杂度?
模型越复杂,越容易过拟合,这大家都知道,加上L1正则化给了模型的拉普拉斯先验,加上L2正则化给了模型的高斯先验。从参数的角度来看,L1得到稀疏解,去掉一部分特征降低模型复杂度。L2得到较小的参数,如果参数很大,样本稍微变动一点,值就有很大偏差,这当然不是我们想看到的,相当于降低每个特征的权重。
(5)为什么L1能得到稀疏解呢?
L1正则化是L1范数而来,投到坐标图里面,是棱型的,最优解在坐标轴上取到,所以某些部分的特征的系数就为0。
(6)L1正则化不可导,怎么求解?
坐标轴下降法(按照每个坐标轴一个个使其收敛),最小角回归(是一个逐步的过程,每一步都选择一个相关性很大的特征,总的运算步数只和特征的数目有关,和训练集的大小无关)
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=‘liblinear’, max_iter=100, multi_class=‘ovr’, verbose=0, warm_start=False, n_jobs=1)
solver参数的选择:
“liblinear”:小数量级的数据集 “lbfgs”,
“sag” or “newton-cg”:大数量级的数据集以及多分类问题
“sag”:极大的数据集
使用KNN与Logistic回归两种方法
# 导包
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
import sklearn.datasets as datasets
import matplotlib.pyplot as plt
%matplotlib inline
#导入数据load_digits() digits = datasets.load_digits() digits data = digits.data data.shape images = digits.images images.shape plt.imshow(images[0], cmap = "gray") data[0].shape plt.imshow(data[0].reshape(8,8), cmap = "gray") target = digits.target from sklearn.model_selection import train_test_split X_train, X_test,y_train,y_test = train_test_split(data, target, test_size = 0.02) #创建模型,训练和预测 knn = KNeighborsClassifier() knn.fit(X_train,y_train) knn.score(X_test,y_test) logic = LogisticRegression() logic.fit(X_train,y_train) logic.score(X_test,y_test)
导包使用datasets.make_blobs创建一系列点
#make_blobs是专门画三簇点的 data, target = datasets.make_blobs(n_samples=150) data.shape target plt.scatter(data[:,0],data[:,1], c = target) #创建机器学习模型,训练数据 logic = LogisticRegression() logic.fit(data, target) import numpy as np #预测数据 xmin, xmax = data[:,0].min(), data[:,0].max() ymin, ymax = data[:,1].min(), data[:,1].max() x = np.linspace(xmin, xmax, 500) y = np.linspace(ymin, ymax, 300) xx, yy = np.meshgrid(x,y) x_test = np.c_[xx.ravel(), yy.ravel()] x_test.shape #预测坐标点数据,并进行reshape() #对数据进行预测 y_= logic.predict(x_test) #绘制图形 xx.shape y_.shape plt.figure(figsize=(12,9)) #plt.scatter(xx, x_test[:,1], c = y_) #对坐标点进行着色 plt.pcolormesh(xx, yy,y_.reshape(xx.shape)) plt.scatter(data[:,0], data[:,1], c = target, cmap = "rainbow")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。