基本知识
Sigmoid函数
逻辑回归用于二分类任务, 我们在将特征的实值转化为分类的二元离散值时, 想要的最理想的函数是单位跃迁函数
即:
利用这个函数就可以通过z的值建立一个到0,1的映射, 可以用于我们的二分类任务
但是, 由于这个函数不连续, 使用起来不方便
我们就用Sigmoid函数进行替代
即:
这个函数在0附近出现变化很剧烈, 称为逻辑函数
损失函数
利用之前我们在线性回归里面的知识, 我们可以用来作为z的值
再用来代替上述符号, 便于简化表达式
对于y=, 可以得到y代表正例的概论, 1-y代表反例的概率
进行对数似然估计, 单个样本我们有损失函数
定性地解释一下吧, 对于y=1, 当t接近 0 时, 损失函数会变得非常大, 所以如果模型估计一个正例概率接近于0, 那么损失函数将会很大, 同时如果模型估计一个负例的概率接近1,那么损失函数同样会很大. 对于y=0, 也是一样.
至于究竟为什么要用对数似然, 我们就得先讲讲极大似然估计了.
极大似然估计就是我们如果在一次实验中发现A事件发生了, 我们需要一个理由相信A发生的概论就是最大的, A发生概论最大对应于一个参数, 我们就是要去估计这个参数
使得我们相信就是A发生了. (比如我们在上面的二分类任务中需要一个参数
使得我们在算得y为1的时候能够相信的的确确这个z对应的分类就是1)
极大似然估计有很多应用价值, 比如在汤姆的情妇默特尔被盖茨比的车撞死之后, 我们没有切实的证据, 但是由于知道了盖茨比干的是贩卖私酒和其他见不得人的勾当, 我们更倾向于怀疑是盖茨比撞死的默特尔, 而不会很肯定地觉得是黛西干的.(这貌似是个反例, 无所谓反正就是这个意思)
但是新的问题来了, 我们如何去求得这个参数呢? 我们可以先列出似然函数
但是由于似然函数是用的迭乘, 不方便运算, 所以我们取对数
在对求导, 令导数=0, 解出
就可以了
极大似然估计说完了,我们就可以得到逻辑回归损失函数
对于求偏导可得
然后利用梯度下降算法进行迭代就可以对于Logistic回归模型
(本人刚上大二, 才疏学浅, 以上公式推导如有谬误欢迎指出)
代码实现
用numpy实现
先开个天窗, 等我看完梯度下降再写
sklearn实现&鸢尾花例子
鸢尾花数据的样子:
import numpy as np
from sklearn import datasets
iris=datasets.load_iris()
list(iris.keys())
['data', 'target', 'target_names', 'DESCR', 'feature_names']
print(iris['data'][:5])
print(iris['target'])
[[5.1 3.5 1.4 0.2] [4.9 3. 1.4 0.2] [4.7 3.2 1.3 0.2] [4.6 3.1 1.5 0.2] [5. 3.6 1.4 0.2]]
[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 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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
使用np.dtype()查看数据类型
np.astype()转换数据类型
iris['data']是样本, iris['target']是标签
X=iris['data'][:,3:]#花瓣宽度
print(X[:5])
y=(iris['target']==2).astype(np.int)#将0,1归为0,将2归为1,便于使用逻辑回归进行二分类
print(y)
[[0.2] [0.2] [0.2] [0.2] [0.2]]
[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 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 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 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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
from sklearn.linear_model import LogisticRegression
log_reg=LogisticRegression()
log_reg.fit(X,y)
import matplotlib.pyplot as plt
X_new=np.linspace(0,3,1000).reshape(-1,1)#取1000个在0到3之间均匀分布的数字
y_proba=log_reg.predict_proba(X_new)#逻辑回归预测
print(X_new[:5])
print(y_proba)#第0列为是Virginica的可能性,第1列为不是的可能性
plt.plot(X_new,y_proba[:,1],'g-',label='Iris-Virginica')
plt.plot(X_new,y_proba[:,0],'b--',label='Not Iris-Virginica')
plt.xlabel('petal width')
plt.ylabel('probability')
plt.legend()
[[0. ] [0.003003 ] [0.00600601] [0.00900901] [0.01201201]]
[[0.98552764 0.01447236] [0.98541511 0.01458489] [0.98530171 0.01469829] ... [0.02620686 0.97379314] [0.02600703 0.97399297] [0.02580868 0.97419132]]
简单测试:
log_reg.predict([[1.7],[1.5]])
array([1, 0])
将所有特征全部加入训练:
X_another=iris['data']#此次将花萼长度,花萼宽度,花瓣长度,花瓣宽度全部作为训练集进行训练
log_reg.fit(X_another,y)#重新预测
X_new_test=[[6,2.2,5,1.2]]
log_reg.predict(X_new_test)
array([1])
以上都是在google colab里面写的, 复制过来的数据可能有点变形
可以直接打开链接看: https://colab.research.google.com/drive/1w3qEl9qvOfbLPk3LkhrBnNvnXqEfRwsC
本篇博客参考:
《机器学习》(周志华)
《Hands on machine learning with sk-learn and tensorflow》