分类问题
在分类问题中,预测一个离散变量的值(0或1),可以使用一种逻辑回归的算法,预测变量属于哪一类。
二元类
我们将因变量(dependent variable)可能属于的两个类分别称为负向类(negative class)和正向类(positive class),则因变量y ∈ ( 0 , 1 ) \in(0,1) ∈(0,1),其中 0 表示负向类,1 表示正向类。
值得注意的是二分类分类函数的取值 0 < h θ ( x ) < 1 0 < h_{\theta}(x) < 1 0<hθ(x)<1,而样本的数值通过算法的到的值可能远大于1或远小于0,因此,逻辑回归算法的性质就是使得输出值永远在0到1之间(Sigmoid function)。
Sigmoid function
g ( z ) = 1 1 + e − z g(z) = \frac{1}{1+e^{-z}} g(z)=1+e−z1
g
(
z
)
g(z)
g(z)函数中
e
−
z
e^{-z}
e−z是一个大于0的函数,因此分母恒大于0,
0
<
g
(
z
)
<
1
0 <g(z)< 1
0<g(z)<1,该函数图像为
函数取不到
0
0
0或者
1
1
1,且注意当取值为0.5时,可将0.5归为0或者1。如:
if
h
θ
(
x
)
⩾
0.5
h_\theta(x) \geqslant 0.5
hθ(x)⩾0.5 predict “y=1”
if
h
θ
(
x
)
<
0.5
h_\theta(x) < 0.5
hθ(x)<0.5 predict “y=0”
现在我们假设一个样本集,具有三个特征
θ
0
θ
1
θ
2
\theta_0 \theta_1 \theta_2
θ0θ1θ2
设
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+θ1x1+θ2x2).假设特征向量
θ
\theta
θ为[-3 1 1],那么
θ
T
x
>
0
\theta^Tx > 0
θTx>0 相当于
−
3
+
x
1
+
x
2
>
0
-3+x_1+x_2 > 0
−3+x1+x2>0 ==>
x
1
+
x
2
>
3
x_1+x_2>3
x1+x2>3 那么模型如下:
若数据不能通过线性区分开,那该怎么做呢?如下图:
对于上图的模型我们则需要曲线才能分隔出二元分类
(
01
)
(0 1)
(01)区域,我们可以通过二次方程特征:
h
θ
(
x
)
=
θ
0
+
θ
1
x
1
+
θ
2
x
2
+
θ
3
x
3
2
+
θ
4
x
4
2
h_\theta(x) = \theta_0 + \theta_1x_1 +\theta_2x_2 + \theta_3x_3^2 +\theta_4x_4^2
hθ(x)=θ0+θ1x1+θ2x2+θ3x32+θ4x42 可以发现若
θ
1
θ
2
\theta_1 \theta_2
θ1θ2为0,则判定的边界恰好是个圆,如下图:
在这里提个问题是否通过特征值的阶数升高,那么拟合模型就更好?之后讨论。
代价函数
假设存在一个训练集{ ( x ( 1 ) , y ( 1 ) ) ( x ( 2 ) , y ( 2 ) ) ( x ( 3 ) , y ( 3 ) ) ( x ( 4 ) , y ( 4 ) ) . . . . . . . ( x ( n ) , y ( n ) ) (x^{(1)},y^{(1)})(x^{(2)},y^{(2)})(x^{(3)},y^{(3)})(x^{(4)},y^{(4)}).......(x^{(n)},y^{(n)}) (x(1),y(1))(x(2),y(2))(x(3),y(3))(x(4),y(4)).......(x(n),y(n))}
x
∈
[
x
0
x
1
x
2
.
.
.
.
x
n
]
x \in \begin{bmatrix}x_0\\x_1\\x_2\\....\\x_n \end{bmatrix}
x∈⎣⎢⎢⎢⎢⎡x0x1x2....xn⎦⎥⎥⎥⎥⎤
x
0
=
1
,
y
∈
{
0
1
}
x_0 = 1 , \qquad y\in\{0\quad1\}
x0=1,y∈{01}
h
θ
(
x
)
=
1
1
+
e
−
θ
T
x
h_\theta(x) = \frac{1}{1+e^{-\theta^Tx}}
hθ(x)=1+e−θTx1
之前线性模型确定特征向量
θ
\theta
θ的代价函数是所有模型误差的平方和(最小二乘法)。但如果我们将
h
θ
(
x
)
=
1
1
+
e
−
θ
T
x
h_\theta(x) = \frac{1}{1+e^{-\theta^Tx}}
hθ(x)=1+e−θTx1带入到这样的代价函数中,得到的代价函数不是一个凸函数:
这样的代价函数存在多个局部最小值,这将影响梯度下降函数算法找到全局最小值。因此我们重新定义逻辑回归代价函数:
J
(
θ
)
=
1
m
∑
i
=
1
m
C
o
s
t
(
h
θ
(
x
(
i
)
)
,
y
(
i
)
)
J(\theta) = \frac{1}{m}\sum_{i=1}^{m} Cost(h_\theta(x^{(i)}),y^{(i)})
J(θ)=m1i=1∑mCost(hθ(x(i)),y(i))其中
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) = -y \times log(h_\theta(x)) - (1-y) \times log (1 - h_\theta(x))
Cost(hθ(x),y)=−y×log(hθ(x))−(1−y)×log(1−hθ(x))
将代入代价函数得到:
J
(
θ
)
=
1
m
∑
i
=
1
m
[
−
y
(
i
)
l
o
g
(
h
θ
(
x
(
i
)
)
)
−
(
1
−
y
(
i
)
)
l
o
g
(
1
−
h
θ
(
x
)
)
]
J(\theta) = \frac{1}{m}\sum_{i=1}^{m}[-y^{(i)}log(h_\theta(x^{(i)})) - (1 - y^{(i)})log(1 - h\theta(x))]
J(θ)=m1i=1∑m[−y(i)log(hθ(x(i)))−(1−y(i))log(1−hθ(x))]
即:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
[
−
y
(
i
)
l
o
g
(
h
θ
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
l
o
g
(
1
−
h
θ
(
x
)
)
]
J(\theta) = -\frac{1}{m}\sum_{i=1}^{m}[-y^{(i)}log(h_\theta(x^{(i)})) + (1 - y^{(i)})log(1 - h\theta(x))]
J(θ)=−m1i=1∑m[−y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x))]
代码实现:
import numpy as np
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X* theta.T)))
second = np.multiply((1-y), np.log(1 - sigmoid(X* theta.T)))
return np.sum(first - second) / (len(X))
既然知道了代价函数,那么接下来的工作就是使用梯度下降算法来求得能使代价函数最小的参数。与线性回归一样,算法为:
θ
j
:
=
θ
j
−
α
∂
J
(
θ
)
∂
θ
j
\theta_j: = \theta_j - \alpha\frac{\partial J(\theta)}{\partial\theta_j}
θj:=θj−α∂θj∂J(θ)
接下来我们推导一下 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(θ)=−m1i=1∑m[y(i)log(hθ(xi))+(1−yi)log(1−hθ(xi))]
其中:
h
θ
(
x
(
i
)
)
=
1
1
+
e
−
θ
T
x
(
i
)
h_\theta(x^{(i)}) = \frac{1}{1+e^{-\theta^Tx^{(i)}}}
hθ(x(i))=1+e−θTx(i)1
代入
J
(
θ
)
J(\theta)
J(θ)得:
J
(
θ
)
=
−
y
(
i
)
l
o
g
(
1
+
e
−
θ
T
x
(
i
)
)
−
(
1
−
y
(
i
)
)
l
o
g
(
1
+
e
θ
T
x
(
i
)
)
J(\theta)\quad=\quad-y^{(i)}log(1 +e^{-\theta^Tx^{(i)}}) \quad- (1 - y^{(i)})log(1 +e^{\theta^Tx^{(i)}})
J(θ)=−y(i)log(1+e−θTx(i))−(1−y(i))log(1+eθTx(i))
接下来对
θ
\theta
θ求偏导:
∂
J
(
θ
)
∂
θ
j
=
∂
∂
θ
j
[
−
1
m
∑
i
=
1
m
[
−
y
(
i
)
l
o
g
(
1
+
e
−
θ
T
x
(
i
)
)
−
(
1
−
y
(
i
)
)
l
o
g
(
1
+
e
−
θ
T
x
(
i
)
)
]
]
\frac{\partial J(\theta)}{\partial \theta_j} = \frac{\partial}{\partial \theta_j}[-\frac{1}{m}\sum_{i=1}^m[-y^{(i)}log(1 +e^{-\theta^Tx^{(i)}})-(1- y^{(i)})log(1 +e^{-\theta^Tx^{(i)}})]]
∂θj∂J(θ)=∂θj∂[−m1i=1∑m[−y(i)log(1+e−θTx(i))−(1−y(i))log(1+e−θTx(i))]]
= − 1 m ∑ i = 1 m y ( i ) x j ( i ) 1 + e θ T x ( i ) − ( 1 − y ( i ) ) x j ( i ) e θ T x ( i ) 1 + e θ T x ( i ) \quad -\frac{1}{m}\sum_{i=1}^my^{(i)}\frac{x_j^{(i)}}{1 +e^{\theta^Tx^(i)}} -(1 - y^{(i)})\frac{x_j^{(i)}e^{\theta^Tx^(i)}}{1 +e^{\theta^Tx^{(i)}}} −m1i=1∑my(i)1+eθTx(i)xj(i)−(1−y(i))1+eθTx(i)xj(i)eθTx(i)
= − 1 m ∑ i = 1 m y ( i ) x j ( i ) − x j ( i ) e θ T x ( i ) + y ( i ) x j ( i ) e θ T x ( i ) 1 + e θ T x ( i ) -\frac{1}{m}\sum_{i=1}^m\frac{y^{(i)}x_j^{(i)}- x_j^{(i)}e^{\theta^Tx^{(i)}}+y^{(i)}x_j \\^{(i)}e^{\theta^Tx^{(i)}}}{1+ e^{\theta^Tx^{(i)}}} −m1i=1∑m1+eθTx(i)y(i)xj(i)−xj(i)eθTx(i)+y(i)xj(i)eθTx(i)
提取公因式:
−
1
m
∑
i
=
1
m
y
(
i
)
(
1
+
e
θ
T
x
(
i
)
)
−
e
θ
T
x
(
i
)
1
+
e
θ
T
x
(
i
)
x
j
(
i
)
-\frac{1}{m}\sum_{i=1}^m\frac{y^{(i)}(1+e^{\theta^Tx^{(i)}})-e^{\theta^Tx^{(i)}}}{1 +e^{\theta^Tx^{(i)}}}x_j^{(i)}
−m1i=1∑m1+eθTx(i)y(i)(1+eθTx(i))−eθTx(i)xj(i)
列项:
−
1
m
∑
i
=
1
m
(
y
(
i
)
−
e
θ
T
x
(
i
)
1
+
e
θ
T
x
(
i
)
)
x
j
(
i
)
-\frac{1}{m}\sum_{i=1}^m(y^{(i)} - \frac{e^{\theta^Tx^{(i)}}}{1 +e^{\theta^Tx^{(i)}}})x_j^{(i)}
−m1i=1∑m(y(i)−1+eθTx(i)eθTx(i))xj(i)
上下同处
e
θ
T
x
(
i
)
e^{\theta^Tx^{(i)}}
eθTx(i):
−
1
m
∑
i
=
1
m
(
y
(
i
)
−
1
1
+
e
−
θ
T
x
(
i
)
)
)
x
j
(
i
)
-\frac{1}{m}\sum_{i=1}^m(y^{(i)}-\frac{1}{1+e^{-\theta^Tx^{(i)}}}))x_j^{(i)}
−m1i=1∑m(y(i)−1+e−θTx(i)1))xj(i)
因为
h
θ
(
x
)
=
1
1
+
e
−
θ
T
x
h_\theta(x) = \frac{1}{1+e^{-\theta^Tx}}
hθ(x)=1+e−θTx1,所以上式等于:
−
1
m
∑
i
=
1
m
[
y
(
i
)
−
h
θ
(
x
(
i
)
)
]
x
j
(
i
)
-\frac{1}{m}\sum_{i=1}^m[y^{(i)} - h_\theta(x^{(i)})]x_j^{(i)}
−m1i=1∑m[y(i)−hθ(x(i))]xj(i)
=
1
m
∑
i
=
1
m
[
h
θ
(
x
(
i
)
)
−
y
(
i
)
]
x
j
(
i
)
\frac{1}{m}\sum_{i=1}^m[h_\theta(x^{(i)})-y^{(i)} ]x_j^{(i)}
m1i=1∑m[hθ(x(i))−y(i)]xj(i)
示例
接下来我们通过一个示例来加深下理解
这个例子是预测一个学生是否被录取,在训练的初始阶段,我们将要构建一个逻辑回归模型来预测,某个学生是否被大学录取。设想你是大学相关部分的管理者,想通过申请学生两次测试的评分,来决定他们是否被录取。现在你拥有之前申请学生的可以用于训练逻辑回归的训练样本集。对于每一个训练样本,你有他们两次测试的评分和最后是被录取的结果。为了完成这个预测任务,我们准备构建一个可以基于两次测试评分来评估录取可能性的分类模型。
首先我们读取一组数据,并查看他的分布
0为未录取,1为被录取。
接下来我们定义逻辑回归的sigmoid函数:
Sigmoid function
g ( z ) = 1 1 + e − z g(z) = \frac{1}{1+e^{-z}} g(z)=1+e−z1
h θ ( x ) = 1 1 + e − θ T x h_\theta(x) = \frac{1}{1+e^{-\theta^Tx}} hθ(x)=1+e−θTx1
def sigmoid(z):
return 1 / (1 + np.exp(-z))
我们可以用plot看下sigmoid函数的样子
我们写下代价函数:
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(θ)=−m1i=1∑m[y(i)log(hθ(xi))+(1−yi)log(1−hθ(xi))]
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X * theta.T)))
second = np.multiply((1-y), np.log(1 - sigmoid(X * theta.T)))
return np.sum(first - second) / (len(X))
接下来就是将数据处理下:
#插入一列 若已经插入则注释
#data.insert(0,'Ones', 1)
cols = data.shape[1]
X = data.iloc[:,0:cols -1]
y = data.iloc[:,cols-1:cols]
X = np.array(X.values)
y = np.array(y.values)
theta = np.zeros(3)
#print(theta)
结果:
梯度下降函数:
J
(
θ
)
=
1
m
∑
i
=
1
m
[
h
θ
(
x
(
i
)
)
−
y
(
i
)
]
x
j
(
i
)
J(\theta)=\frac{1}{m}\sum_{i=1}^m[h_\theta(x^{(i)})-y^{(i)} ]x_j^{(i)}
J(θ)=m1i=1∑m[hθ(x(i))−y(i)]xj(i)
def gradient(theta, X, y):
# '''just 1 batch gradient'''
return (1 / len(X)) * X.T @ (sigmoid(X @ theta) - y)
结果:
现在我们有了代价函数与梯度下降函数,那么我们可以用这两个函数去拟合参数了
这里我们使用的是scipy.optimize 寻找最小的值
res = opt.minimize(fun = cost, x0 = theta, args=(X, y), method='Newton-CG', jac=gradient)
我们可以看下拟合的结果:
现在我们用最终的
θ
\theta
θ预测下,先定义个预测函数:
def predict(x, theta):
prob = sigmoid(x @ theta)
return (prob >= 0.5 ).astype(int)
结果:
SVM与决策边界
支持向量机(SVM)分类的idea:
- 找到一条线将样本分开,这条线尽可能的“粗”
如图,三条线都将样本分开,但想象一下这三条线变粗的同时还能将样本分开的,明显第二条线是可以变最粗的。 - 找到一个垂直于决策边界的法向量,任意一个样本可作为一个向量,该向量在法向量上的投影距离若未超过决策边界,则为负类,反之为正类。
决策边界:在特征空间内,根据不同特征对样本进行分类,不同类型间的分界就是模型针对该数据集的决策边界。决策边界,用于分类问题中,通过决策边界可以更好的可视化分类结果。
我们将之前例子的决策边界画出来
coef = -(res.x / res.x[2])
#print(coef)
x = np.arange(130, step = 0.1)
y = coef[0] + coef[1]*x
sns.set(context="notebook", style="ticks", font_scale=1.5)
sns.lmplot('exam1', 'exam2', hue='admitted', data=data,
size=6,
fit_reg=False,
scatter_kws={"s": 25}
)
plt.plot(x, y, 'grey')
plt.xlim(0, 130)
plt.ylim(0, 130)
plt.title('Decision Boundary')
plt.show()