逻辑回归——用来做分类的回归模型
1、回归模型做分类
线性回归的预测结果是一个连续值域上的任意值,而朴素贝叶斯分类模型的预测结果则是一个离散值,但LR却是用来做分类的,其模型函数:
在二维坐标中形成S形曲线:
图中,z是自变量(横轴),最终计算出的因变量y(纵轴),是一个[0,1]区间内的实数值。一般而言,时,z被归类为真(True)或阳性(Positive),否则当时,z被归类为假(False)或阴性(Negative)。
自问自答,如果大量输入得到的结果都在附近,或者所有输入数据得到的结果都在附近,会不会没有分类的意义呢?当然不是,此模型函数在附近非常敏感,自变量取值稍有不同,因变量取值就会有很大差异,所以不用担心出现大量因细微特征差异而被归错类的情况——这也是逻辑回归的神奇之处。
2、逻辑回归的目标函数
逻辑函数是我们要通过训练的出来的最终结果。在最开始的时候,参数未知,已知为若干的x和对应的y(训练集),而训练LR的过程,就是求的过程。
从公式本身的角度来看,实际上是x为阳性的分布概率,所以,才会在时将x归于阳性,也就是说,反之,样例是阴性的概率,当我们把测试数据带入其中的时候,和就都有了先决条件,它们为训练数据的x所限定。
当我们把测试数据带入其中的时候,和就都有了先决条件,它们为训练数据的x所限定,因此:
根据二项分布公式,可得出:
假设我们的训练集一共有m个数据,那么这m个数据的联合概率就是:
我们求取的结果,就是让这个达到最大,此处LR目标函数的构建过程也是依据极大似然估计。
就是LR的似然函数,我们要让它达到最大,也就上对其进行“极大估计”,因此,求解LR目标函数的过程,就是对LR模型函数进行极大似然估计的过程:
求对数似然函数:
其实可以作为LR的目标函数(要求是凸函数且具备最小值),设定
这样,求的最大值就成了求的最小值,又叫负对数似然函数,它就是LR的目标函数。
优化算法
梯度下降走起来:
- 通过对求导获得下降方向——
- 根据预设的步长,更新参数
- 重复以上两步直到逼近最优解,满足终止条件。
已知:
对求导:
因为有
同时,运用链式法则,有:
带入的表达式:
在x为多维的时候(n维),在对求导的时候,要对x的每一个维度求导。又因为和x维度相同,所以当x有n维的时候,同样有n维,则的求导也变成了对的每一个维度求导:
因此优化算法伪代码:
3、实例及代码实现
举个例子,某老师想用上个学期的考试成绩(Last Score)和本学期在学习上话费的时间(Hours Spent)来预期本学期的成绩,数据如下:
面对这个问题,如果用线性回归,那么取,然后代码:
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import LinearRegression
import pandas as pd
# Importing dataset
data = pd.read_csv('quiz.csv', delimiter=',')
used_features = ["Last Score", "Hours Spent"]
X = data[used_features].values
scores = data["Score"].values
X_train = X[:11]
X_test = X[11:]
# Linear Regression - Regression
y_train = scores[:11]
y_test = scores[11:]
regr = LinearRegression()
regr.fit(X_train, y_train)
y_predict = regr.predict(X_test)
print(y_predict)
训练集[0,10] 、测试集[11,13],训练之后,得到的预测结果为:[55.33375602 54.29040467 90.76185124]即id为12-14的同学预测分数分别为55,54和91。这就不科学了,12号同学明明是考及格了。。。原因呢?我们要的是原因,发现4号同学只用了20h就考了第一?????搞我呢?放弃线性回归,转LR:
LR就不是预测分数,而是预测这位同学是否能及格,且还需将数据稍作修改,具体分数改成合格(1)和不合格(0),code如下:
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import LinearRegression
import pandas as pd
# Importing dataset
data = pd.read_csv('quiz.csv', delimiter=',')
used_features = [ "Last Score", "Hours Spent"]
X = data[used_features].values
scores = data["Score"].values
X_train = X[:11]
X_test = X[11:]
# Logistic Regression – Binary Classification
passed = []
for i in range(len(scores)):
if(scores[i] >= 60):
passed.append(1)
else:
passed.append(0)
y_train = passed[:11]
y_test = passed[11:]
classifier = LogisticRegression(C=1e5)
classifier.fit(X_train, y_train)
y_predict = classifier.predict(X_test)
print(y_predict)
输出[1 0 1],12-14号同学判断正确了。Congratulation~
4、LR处理多分类问题
面对多分类问题,该如何用LR算法做呢?答案是把二分类问题分多次来做。
假设一共有n个类别,那么构造n个LR分类模型,第一个用来区分label_1和non_label_1,第二个用来区分label_2和non_label_2…第n个用来区分label_n和non_label_n。
到使用的时候,每一个输入数据都被这n个模型同时预测,哪个模型得到Positive结果,就判定为该类;若多个模型都是Positive,那么输出还需要加一个概率,这样对比概率选择概率最高的那一个作为类别。sklearn已经搞定这个问题。
举栗子:上面的例子,要区分学生是优秀(>=85)——2、及格——1、不及格——0,然后在做LR分类,附code:
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import LinearRegression
import pandas as pd
# Importing dataset
data = pd.read_csv('quiz.csv', delimiter=',')
used_features = [ "Last Score", "Hours Spent"]
X = data[used_features].values
scores = data["Score"].values
X_train = X[:11]
X_test = X[11:]
# Logistic Regression - Multiple Classification
level = []
for i in range(len(scores)):
if(scores[i] >= 85):
level.append(2)
elif(scores[i] >= 60):
level.append(1)
else:
level.append(0)
y_train = level[:11]
y_test = level[11:]
classifier = LogisticRegression(C=1e5)
classifier.fit(X_train, y_train)
y_predict = classifier.predict(X_test)
print(y_predict)
测试集的输出是:[1 0 2],对应12号(62分)、13号(52分)、14号(93分)还是没错的~
案例数据已上传:https://download.csdn.net/download/qq_41909317/11008167