学习内容:逻辑回归练习
学习时间:2020/9/29
教学视频、数据集等:
https://www.bilibili.com/video/BV1bt411p74v
代码实现:
https://github.com/boxes757/Machine-learning-exercises/blob/master/机器学习2——逻辑回归练习(线性可分)
https://github.com/boxes757/Machine-learning-exercises/blob/master/机器学习2——逻辑回归练习(线性不可分)
学习笔记:
练习题目
- 根据学生的两门成绩,预测该学生是否会被大学录取(线性可分)
- 根据芯片在两次测试中的测试结果,你要决定是否芯片要被接受或抛弃(线性不可分)
相关工具(包)
numpy(计算,处理多维数组)、pandas(数据分析)、matplotlib.pyplot(绘图框架)
参数
-
sigmoid函数
逻辑回归主要是进行分类功能,即选择一种决策方案把不同类别的东西进行分类,包括二分类以及多分类。二分类中又包括线性可分和线性不可分的类型。对于线性可分的情况来说,我们希望把结果(y值)分为0或者1。
观察下列样本:
假设样本拥有两个特征x1,x2。我们依然可以用 θ 0 + θ 1 x 1 + θ 2 x 2 \theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2} θ0+θ1x1+θ2x2来拟合出直线。但对于逻辑回归来说,我们需要的是分类的结果,而不是通过表达式计算出的具体的数值。在逻辑回归中,我们需要获得的结果不是一个具体数值,而是“是”或“不是”这个答案。为此我们引入sigmoid函数:
g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+e−z1
此外,我们定义
h
θ
(
x
)
=
g
(
θ
0
+
θ
1
x
1
+
θ
2
x
2
)
h_{\theta}(x)=g(\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2})
hθ(x)=g(θ0+θ1x1+θ2x2)。那么对于我们计算出的
h
θ
(
x
)
h_{\theta}(x)
hθ(x)来说,所得结果都在(0,1)这个区间内。
我们可以基于此对结果进行分类:
- 当 h θ ( x ) > = 0.5 h_{\theta}(x)>=0.5 hθ(x)>=0.5,我们认为y=1
- 当 h θ ( x ) < 0.5 h_{\theta}(x)<0.5 hθ(x)<0.5,我们认为y=0
此外,我们将 h θ ( x ) h_{\theta}(x) hθ(x)输出的结果理解为对于特征集x来说,y=1的概率。比如 h θ ( x ) = 0.7 h_{\theta}(x)=0.7 hθ(x)=0.7,我们理解为 y = 1 y=1 y=1的概率为0.7。
- 损失函数
这样定义损失函数的原因:
当y=1时:
-
如果我们预测出来的 h θ ( x ) h_{\theta}(x) hθ(x)也是1,则损失为-log(1)=0
-
如果我们预测出来的 h θ ( x ) h_{\theta}(x) hθ(x)是0(即和实际结果y差别很大),则损失为-log(0+)=+∞
y=0时类似。
将损失函数进行化简:
与线性回归一样,我们将 θ 0 + θ 1 x 1 + θ 2 x 2 \theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2} θ0+θ1x1+θ2x2写成 X ⋅ θ X\cdot\theta X⋅θ,其中
那么我们将 J ( θ ) J(\theta) J(θ) 继续化简,得到
J ( θ ) = − 1 m [ y ∗ l o g ( y ′ ) + ( 1 − y ) ∗ l o g ( 1 − y ′ ) ] J(\theta)=-\frac{1}{m}[y*log(y')+(1-y)*log(1-y')] J(θ)=−m1[y∗log(y′)+(1−y)∗log(1−y′)]注:
-
y ′ = g ( X ⋅ θ ) y'=g(X \cdot \theta) y′=g(X⋅θ)为(m×1)的矩阵,其中 g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+e−z1
-
l o g ( y ′ ) log(y') log(y′)也为(m×1)的矩阵,y也为(m×1)的矩阵, y ∗ l o g ( y ′ ) y*log(y') y∗log(y′)的意思是矩阵的点乘,即将相同维数的两个矩阵的各项互相进行相乘,这点需要和矩阵乘法进行区分
-
在实际操作中,上述 J ( θ ) J(\theta) J(θ) 算出来也是矩阵形式,我们需要用np.sum来达到求和目的
-
梯度下降函数
对于损失函数:
我们对该函数求 θ \theta θ 的偏导数,得到:
基于此,我们对 θ \theta θ 矩阵的更新应该是:
θ = θ − α m ⋅ X T ⋅ ( g ( X ⋅ θ ) − y ) \theta = \theta - \frac{\alpha}{m}\cdot X^T\cdot(g(X\cdot \theta)-y) θ=θ−mα⋅XT⋅(g(X⋅θ)−y)其中 α \alpha α 为学习率。
读取数据
与线性回归中的操作类似,此处不再赘述
可参考https://blog.csdn.net/HZH_box/article/details/108785386
数据准备
与线性回归中的操作类似,即进行下列操作:
- 插入值为1的一列
- 切片处理
- 转换dataFrame格式为矩阵格式
损失函数和梯度下降函数
按照上述公式进行书写。注意矩阵乘法用 @ @ @ 表示,矩阵点乘用 ∗ * ∗ 表示。
代入预测函数
- 通过不断迭代梯度下降函数,我们可以得到最终的 θ \theta θ
- 将最终的 θ \theta θ 代入下列公式, h θ ( x ) = g ( θ 0 + θ 1 x 1 + θ 2 x 2 ) h_{\theta}(x)=g(\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}) hθ(x)=g(θ0+θ1x1+θ2x2)
- 当 h θ ( x ) h_{\theta}(x) hθ(x) >=0.5,分类为1;当 h θ ( x ) h_{\theta}(x) hθ(x) <0.5,分类为0
预测准确值计算
// 预测函数以及准确值计算
def predict(X,theta):
A = sigmoid(X@theta)
return [1 if x>=0.5 else 0 for x in A]
y_= np.array(predict(X,theta_final))
y_=y_.reshape(len(y_),1)
acc = np.mean(y_ == y)
print(acc)
- 按照预测函数,predict函数输出了由0和1组成的列表,我们将其进行转置
- 对于(x == y)来说,如果两边对应位置的数是相等的,那么返回True(=1),否则返回False(=0)
- 那么观察预测出来的结果与实际值一致(即判断为True=1)的个数,求平均值,即可知道我们预测的准确性
绘制图像
对于
h
θ
(
x
)
=
g
(
θ
0
+
θ
1
x
1
+
θ
2
x
2
)
h_{\theta}(x)=g(\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2})
hθ(x)=g(θ0+θ1x1+θ2x2) 来说,当
θ
0
+
θ
1
x
1
+
θ
2
x
2
>
0
\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}>0
θ0+θ1x1+θ2x2>0 时,我们得到的
h
θ
(
x
)
>
=
0.5
h_{\theta}(x)>=0.5
hθ(x)>=0.5,分类为1,反之分类为0。
所以我们仅需要绘制直线
θ
0
+
θ
1
x
1
+
θ
2
x
2
=
0
\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2} = 0
θ0+θ1x1+θ2x2=0
对直线进行变换,得到
x
2
=
−
θ
0
θ
2
−
θ
1
θ
2
x
1
x_{2}=-\frac{\theta_{0}}{\theta_{2}}-\frac{\theta_{1}}{\theta_{2}}x1
x2=−θ2θ0−θ2θ1x1
结果展示
线性不可分时的逻辑回归
-
特征映射
-
代价函数(多了一项,注意求和从1开始)
-
梯度下降函数( θ = θ − ∂ J ( θ ) ∂ θ j \theta = \theta - \frac{\partial J(\theta)}{\partial \theta_{j}} θ=θ−∂θj∂J(θ),注意 j = 0 j = 0 j=0 时与之前的梯度下降函数一致)