导语
如我们在第二章中提到的,有监督学习主要分为 回归问题和 分类问题。之前的章节我们已经介绍过一元线性回归问题,多元线性回归问题,从本章开始我们将进入另一个方向—— 分类问题 (Classification)。
1. 什么是分类问题?
分类问题主要针对”是不是”和”有没有”的问题,大致分为:
- 二分类问题:比如猫狗识别,判断一张图片中是猫还是狗(是不是)
- 多分类问题:比如阿拉伯数字识别,判断一张图片中的数字是几(是不是)
- 多标签二分类问题:比如一个包含多个物品的图片,判断是否存在物品A,B,C,…(有没有)
- 多标签多分类问题:图片降噪,每个像素都有0~255,总共256个类别,因此为多标签256分类问题
2. 是否可以用线性回归来解决?
举个例子,垃圾邮件过滤。假如我们用一些手段获得了一系列邮件样本X (其中包含若干个特征)以及真实标签Y(表示每个样本是否是垃圾邮件),然后设置了一个线性模型h(x),通过样本X和真实标签Y进行学习,优化参数,那我们就会得到一个拟合X的模型。在这个过程中,真实标签Y其实只有两种离散的结果:0表示非垃圾邮件,1表示垃圾邮件。为我们的线性模型h(x)输出的是连续值,所以我们需要设定一个 阈值(threshold) 来判断h(x)的输出应该对应0还是1,一般的,我们习惯在h(x)
但是,假如我们再加一个x很大的,y=1的点,会发生什么呢?答:阈值会向右移,导致误判。
因此,使用线性回归来处理分类问题是不合适的。从另一个角度讲,我们的标签只有0和1,但h(x)的值域却可以是负无穷到正无穷,二者并不统一。
; 3. 二分类
3.1 假设函数
在上面的例子中,我们使用h θ ( x ) = θ T x h_\theta(x)=\theta^T x h θ(x )=θT x作为模型,但效果不好。这时我们进行转换,设h θ ( x ) = g ( θ T x ) h_\theta(x)=g(\theta^Tx)h θ(x )=g (θT x ),z = θ T x z = \theta^Tx z =θT x,而g ( z ) = 1 1 + e − z g(z) = \frac{1}{1+e^{-z}}g (z )=1 +e −z 1 ,则:
h θ ( x ) = 1 1 + e − θ T x h_\theta(x) = \frac{1}{1+e^{-\theta^Tx}}h θ(x )=1 +e −θT x 1
这就是 sigmoid函数(也称逻辑函数,Logistic Function, 逻辑回归问题也因此得名,虽然叫回归,但其实是分类问题)
sigmoid函数的图形(例如,theta=4时)如下:
sigmoid函数有几个特性:
- 它的输出是0~1,满足我们对预测标签范围的要求
- 它可以表示待测样本是正样本的概率,即h ( x ) = P ( y = 1 ∣ x ; θ ) h(x) = P(y=1|x;\theta)h (x )=P (y =1 ∣x ;θ),h(x,θ)=0.7意味着特征为x,参数为θ的情况下,y=1的可能性是70%,而y=0的可能是就是30%,二者相加一定等于100%
- 它关于x=0,y=0.5中心对称,可以用y=0.5做为分水岭
至于为什么要用sigmoid函数,涉及到最大熵,在此不做展开
; 3.2 决定边界
我们使用sigmoid函数,并规定h θ ( x ) ≥ 0.5 h_\theta(x)\ge0.5 h θ(x )≥0 .5时,我们预测结果为1;h θ ( x ) < 0.5 h_\theta(x)< 0.5 h θ(x )<0 .5时,我们预测结果为0。
通过观察sigmoid函数的图像,我们发现当z ≥ 0 z\ge0 z ≥0时,h θ ( x ) ≥ 0.5 h_\theta(x)\ge0.5 h θ(x )≥0 .5,而z < 0 z时,h θ ( x ) < 0.5 h_\theta(x)< 0.5 h θ(x )<0 .5。
又因为z = θ T x z = \theta^Tx z =θT x,所以上面的观察又可以替换成:当θ T x ≥ 0 \theta^Tx\ge0 θT x ≥0时,h θ ( x ) ≥ 0.5 h_\theta(x)\ge0.5 h θ(x )≥0 .5;当θ T x < 0 \theta^Tx时,h θ ( x ) < 0.5 h_\theta(x),
那么,θ T x ≥ 0 \theta^Tx\ge0 θT x ≥0 和 θ T x < 0 \theta^Tx又意味着什么呢?
假设我们的模型函数是:h θ ( x ) = g ( θ 0 + θ 1 x 1 + θ 2 x 2 ) h_\theta(x)=g(\theta_0+\theta_1x_1+\theta_2x_2)h θ(x )=g (θ0 +θ1 x 1 +θ2 x 2 ),那么为了使h θ ( x ) ≥ 0.5 h_\theta(x)\ge0.5 h θ(x )≥0 .5,应该有 θ 0 + θ 1 x 1 + θ 2 x 2 ≥ 0 x 2 ≥ − θ 1 x 1 − θ 0 θ 2 x 2 ≥ − θ 1 θ 2 x 1 − θ 0 θ 2 \theta_0+\theta_1x_1+\theta_2x_2\ge0\x_2\ge\frac{-\theta_1x_1-\theta_0}{\theta_2}\x_2\ge-\frac{\theta_1}{\theta_2}x_1-\frac{\theta_0}{\theta_2}θ0 +θ1 x 1 +θ2 x 2 ≥0 x 2 ≥θ2 −θ1 x 1 −θ0 x 2 ≥−θ2 θ1 x 1 −θ2 θ0
我们将x 2 x_2 x 2 视为一个关于x 1 x_1 x 1 的因变量的话,就可以画出一条直线(形如:y=kx+b),例如下面这种情况,圆点表示负样本(y=0),×点表示正样本(y=1),红色虚线就是 决定边界(Decision Boundary)。决定边界就是y=0和y=1的分界线,下图中边界以下的点我们会预测为0,边界以上的点我们会预测为1
而决定边界不一定是一条直线,还可能是圆,椭圆,三角,曲线,各种线,图形。比如:如果有两个特征x1和x2,满足决定边界关系为x 1 2 + x 2 2 ≥ 1 x_1^2+x_2^2\ge1 x 1 2 +x 2 2 ≥1,那么决定边界将是一个半径为1,以(0,0)为中心的圆,圆内的样本我们会预测为0,圆外的样本我们会预测为1,随着特征的量和指数的增加,决定边界可以变成各种各种的形状。
3.3 代价函数
线性回归的代价函数,我们使用平方误差函数,J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2 J (θ)=2 m 1 ∑i =1 m (h θ(x (i ))−y (i ))2,但如果我们直接沿用这个函数,会得到一个非凸函数(代价会上下波动),导致我们无法通过求导和梯度下降法最优化参数。
为了解决这个问题,分类问题我们采用另一种代价函数:
J ( θ ) = 1 m ∑ i = 1 m C o s t ( h θ ( x ( i ) , y ( i ) ) C o s t ( h θ ( x ) , y ) = − l o g ( h θ ( x ) ) i f y = 1 C o s t ( h θ ( x ) , y ) = − l o g ( 1 − h θ ( x ) ) i f y = 0 J(\theta)=\frac{1}{m}\sum_{i=1}^{m}Cost(h_\theta(x^{(i)},y^{(i)})\Cost(h_\theta(x),y)=-log(h_\theta(x)) \;\;\;if \;\;\;y=1 \Cost(h_\theta(x),y)=-log(1-h_\theta(x)) \;\;\;if \;\;\;y=0 J (θ)=m 1 i =1 ∑m C o s t (h θ(x (i ),y (i ))C o s t (h θ(x ),y )=−l o g (h θ(x ))i f y =1 C o s t (h θ(x ),y )=−l o g (1 −h θ(x ))i f y =0
这个代价函数的图像如下(蓝色为y=1的代价函数,红色为y=0的代价函数):
横坐标为h θ ( x ) h_\theta(x)h θ(x ),范围总是0~1,纵坐标为代价J ( θ ) J(\theta)J (θ),当y=1时,h θ ( x ) h_\theta(x)h θ(x )越接近1,代价越小,当二者相等时,代价为0,而h θ ( x ) h_\theta(x)h θ(x )越接近0,代价越大,当h θ ( x ) = 0 h_\theta(x)=0 h θ(x )=0时,代价为+ ∞ +\infty +∞。类似地,当y=0时,h θ ( x ) h_\theta(x)h θ(x )越接近0,代价越小,越靠近1,代价越大。
可是,分段函数还是不太方便,介于我们是针对二分类问题,我们可以将cost函数合并成1个:
C o s t ( h θ ( x ) , y ) = − y l o g ( h θ ( x ) ) − ( 1 − y ) l o g ( 1 − h θ ( x ) ) Cost(h_\theta(x),y) = -ylog(h_\theta(x))-(1-y)log(1-h_\theta(x))C o s t (h θ(x ),y )=−y l o g (h θ(x ))−(1 −y )l o g (1 −h θ(x ))
这个函数和上面的分段函数其实是等价的,因为当y=1时,1-y=0,后一项会变成0;当y=0时,前一项会变成0,但如此操作之后,我们可以更加方便的进行计算和代码实现了。将C o s t Cost C o s t函数代入代价函数J ( θ ) J(\theta)J (θ),得到:
J ( θ ) = − 1 m ∑ i = 1 m [ − y ( i ) l o g ( h θ ( x ( i ) ) ) − ( 1 − y ( i ) ) l o g ( 1 − h θ ( x ( i ) ) ) ] J(\theta) = -\frac{1}{m}\sum_{i=1}^{m}[-y^{(i)}log(h_\theta(x^{(i)}))-(1-y^{(i)})log(1-h_\theta(x^{(i)}))]J (θ)=−m 1 i =1 ∑m [−y (i )l o g (h θ(x (i )))−(1 −y (i ))l o g (1 −h θ(x (i )))]
如果我们用矩阵表示的话,代价函数可以化简为:
J ( θ ) = 1 m ⋅ ( − y T l o g ( h ) − ( 1 − y ) T l o g ( 1 − h ) ) , h = g ( X θ ) J(\theta) = \frac{1}{m}\cdot(-y^Tlog(h)-(1-y)^Tlog(1-h)), h=g(X\theta)J (θ)=m 1 ⋅(−y T l o g (h )−(1 −y )T l o g (1 −h )),h =g (X θ)
; 3.4 梯度下降法
现在我们知道了模型,知道了代价函数,接下来该最优化参数了。我们同样使用梯度下降法,则每一次迭代得到的新参数为(实际求导和化简的过程省略):
θ j : = θ j − α m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j-\frac{\alpha}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)}θj :=θj −m αi =1 ∑m (h θ(x (i ))−y (i ))x j (i )
看上去和我们在线性回归中得到的学习算法一致,但线性回归中的模型h ( x ) = θ T x h(x)=\theta^Tx h (x )=θT x,而这里的模型为h θ ( x ) = 1 1 + e − θ T x h_\theta(x) = \frac{1}{1+e^{-\theta^Tx}}h θ(x )=1 +e −θT x 1 ,所以其实是不一样的。
如果用矩阵表示的话,上面的学习算法可以化简为:
θ : = θ − α m X T ( g ( X θ ) − y ⃗ ) ) \theta := \theta – \frac{\alpha}{m} X^T(g(X\theta)-\vec{y}))θ:=θ−m αX T (g (X θ)−y ))
3.5 代码实现
import numpy as np
from matplotlib import pyplot as plt
import csv
from sklearn.linear_model import LogisticRegression
def legend_without_duplicate_labels(ax):
handles, labels = ax.get_legend_handles_labels()
unique = [(h, l) for i, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:i]]
ax.legend(*zip(*unique))
def plotData(X, y, m):
pos = np.argwhere(y==1)
neg = np.argwhere(y==0)
fig, ax = plt.subplots(facecolor="w")
ax.plot(X[pos, 0], X[pos, 1], '+', color='g', label="Admitted")
ax.plot(X[neg, 0], X[neg, 1], 'o',color='r', label="Not Admitted")
plt.xlabel('Exam 1 Score')
plt.ylabel('Exam 2 Score')
legend_without_duplicate_labels(ax)
def gradientDescent(X,y,theta,alpha,iterations):
m = len(y)
J_history = []
for iter in range(1,iterations+1):
J,grad = computeCost(X,y,theta)
theta = theta-grad*alpha
J_history.append([iter,J])
return theta,J_history
def featureNormalize(X)->[]:
mu = np.mean(X,axis=0)
sigma = np.std(X,axis=0)
X = (X-mu)/sigma
return [X,mu,sigma]
def computeCost(X,y,theta):
m = len(y)
J = sum(np.log(sigmoid(X.dot(theta))).T.dot(-1 * y) - np.log(1 - sigmoid(X.dot(theta))).T.dot(1 - y)) / m
grad = X.T.dot(sigmoid(X.dot(theta))-y)/m
return J,grad
def sigmoid(z):
g = 1 / (1+np.exp(-z))
return g
def predict_norm(X,mu,sigma,theta):
X = (X - mu) / sigma
m, n = X.shape
X = np.hstack((np.ones((m, 1)), X))
return (sigmoid(X.dot(theta))>=0.5)
def predict(X,theta):
m = len(X)
X = np.hstack((np.ones((m, 1)), X))
return (sigmoid(X.dot(theta))>=0.5)
def main():
data = []
with open('data1.txt') as f:
csv_reader = csv.reader(f,delimiter=',')
for row in csv_reader:
data.append(row)
f.close()
data = np.mat(data,dtype='float32')
m,n = data.shape
X = data[:,0:n-1]
y = np.mat(data[:,n-1],dtype='int32')
plotData(X,y,m)
test_X = X
X,mu,sigma = featureNormalize(X)
print(sigmoid(0))
X = np.hstack((np.ones((m, 1)), X))
theta = np.zeros((n, 1))
test_theta = np.mat([[-25.1613],[0.2062],[0.2015]])
alpha = 0.3
iterations = 10000
theta,history = gradientDescent(X,y,theta,alpha,iterations)
print(theta)
print(predict_norm(np.mat([45, 85]), mu, sigma, theta))
print(predict_norm(np.mat([55, 75]), mu, sigma, theta))
p = predict_norm(test_X,mu,sigma,theta)
ans = p-y
correct = np.argwhere(ans==0)
print(len(correct)/m*100)
p2 = predict(test_X,test_theta)
ans2 = p2 - y
correct2 = np.argwhere(ans2 == 0)
print(len(correct2) / m * 100)
clf = LogisticRegression()
clf.fit(test_X,y)
print(clf.score(test_X,y))
print(computeCost_Reg(X,y,theta,0.1))
if __name__ == '__main__':
main()
4. 多元分类
上面我们提到了二分类问题,那么对于多分类问题(比如,阿拉伯数字识别),我们可以将其拆分成多个二分类问题。
假设我们有三种类,下面是我们的样本,绿色表示I I I类,红色表示I I II I I类,黑色表示I I I III I I I类。那么我们可以建立3套二分类模型,分别识别”是否是I I I类”,”是否是I I II I I类”,以及”是否是I I I III I I I类”三个问题。
对于I I I类,我们设模型为h θ ( 1 ) ( x ) h_\theta^{(1)}(x)h θ(1 )(x ),这个模型输出的结果为:在特征x和参数θ \theta θ下,y=1的概率,剩下两类都会被认为是y=0,我们只关心是否是I I I类。因此,从I I I类的视角来看,上面的样本图应该如下所示,青色代表无关样本,绿色代表:I I I类样本,红色虚线表示决定边界。
对于I I II I I类,我们设模型为h θ ( 2 ) ( x ) h_\theta^{(2)}(x)h θ(2 )(x ),这个模型输出的结果为:在特征x和参数θ \theta θ下,y=1的概率,剩下两类都会被认为是y=0,我们只关心是否是I I II I I类。因此,从I I II I I类的视角来看,上面的样本图应该如下所示,青色代表无关样本,红色代表:I I II I I类样本,红色虚线表示决定边界。
对于I I I III I I I类,我们设模型为h θ ( 3 ) ( x ) h_\theta^{(3)}(x)h θ(3 )(x ),这个模型输出的结果为:在特征x和参数θ \theta θ下,y=1的概率,剩下两类都会被认为是y=0,我们只关心是否是I I I III I I I类。因此,从I I I III I I I类的视角来看,上面的样本图应该如下所示,青色代表负样本,黑色代表:I I I III I I I类样本,红色虚线表示决定边界。
在分别最优化模型参数之后,对于一个待测样本x,我们分别用三个模型去计算,得到的就是x是I I I类,I I II I I类,I I I III I I I类的概率,然后去概率最大的,就是我们的预测结果。
Original: https://blog.csdn.net/cyoushika_Nara/article/details/122675644
Author: cyoushika_Nara
Title: 【从零开始的机器学习】-07 分类问题与逻辑回归
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/666958/
转载文章受原作者版权保护。转载请注明原作者出处!