一个名为回归却用于解决分类问题的算法,吴恩达coursera第三周
逻辑回归(Logic Regression)
代码
数据处理
(1)常规读取数据的方法,值得注意的是X = data.iloc[:, :-1].values
中.values
作用是将DataFrame
转化为ndarray
。根据手册,更推荐使用.to_numpy()
。
1 | path = 'ex2data1.txt' |
数据可视化
1 | ''' |
假设函数
假设函数:
(1)公式:$h_{\theta}(x)=\frac{1}{1+e^{-\theta^{T}x}}$,又名Sigmoid function,函数图像如下图所示,从图中可以看出$h_{\theta}$的取值范围0~1
(2)$h_{\theta}$的含义是:特征x的情况下,y=1的概率
1 | def sigmoid(z): |
代价函数:
如果这时再使用线性回归的$J(\theta_{0},\theta_{1})=\frac{1}{2m}\sum_{i=1}^{m}(h_{\theta}(x_{i})-y_{i})^{2}$将会导致函数图像不光滑。这样使用最小值法时容易导致无法找到全局最优解。因此需要使用新的代价函数。
(1)公式:
具体解释如下:
1 | ''' |
高级优化法:
除了梯度下降法之外,还有其他几种优化方法,比起gradient descent,这些方法更适合处理大型数据且不需要你设置学习速率。
这些方法的具体原理非常复杂,但是,python的模块往往是非常强大的,因此往往只需要你计算一下到导数项即可
1 | def gradient(theta, X, y): |
再使用import scipy.optimize as opt
中的.fmin_tnc
来迭代,得到最终的$\theta$值。
1 | # 这里不使用梯度下降法,换成其他优化算法来迭代 |
检测准确率
1 | ''' |
将得到的预测标签同数据原有的标签进行比对,得到准确率
1 | predictions = predict(final_theta, X) |
也可以自定义一个样本预测一发
1 | # 输入一个数据进行预测 |
决策边界
$h_{\theta}=0.5$时的直线,由假设函数图像可以看出,当$h_{\theta}=0.5$时,$z=\theta^{T}x=0$,这里图中是以$x2$作为纵坐标。
1 | # 决策边界 |
画图函数
1 | plt.figure(figsize=(8, 5)) |
结果图为:
带正则化项的逻辑回归函数
读入数据:
1 | path = 'ex2data2.txt' |
可视化数据
1 | def plot_data(data): |
特征映射
由可视化数据可知,如果单独用两个特征,是无法表示出决策边界的(欠拟合underfit)。因此需要映射多个特征。
这里将$x1$和$x2$映射为6个特征值
1 | def map_feature(x1, x2): |
但这种映射可能导致过拟合(overfit),泛化能力差,因此还需要正则化(regularization)。
*正则化
(1)原理:
因为过拟合是由于特征项过多引起的,减少特征的数量固然可以,还有一种方法就是正则化:减小$\theta_{j}$的值。
由图中可以看出,线性回归算法中添加两个正则化项——也叫惩罚项,1000$\theta_{3}$和1000$\theta_{4}$。上图可以看出,在利用优化算法求解参数时,要想让代价函数值变小,会使得$\theta_{3}$和$\theta_{4}$变得非常小,也就导致了$\theta_{3}x^{3}$和$\theta_{4}x^{4}$非常小,那么图中右边的假设函数就近似与左边的函数了。
实际操作中,我们很多时候并不知道究竟应该惩罚哪一项,所以实际上除了$\theta_{0}$(全是1),所有项都会惩罚。
回到逻辑回归算法上也是一样的
(2)公式:
对于线性回归算法也类似:
代价函数:
1 | def cost_reg(theta,X, y, lmd): |
梯度函数
(1)公式:
(2)向量化:$\theta_{j}:=\theta-\alpha[\frac{1}{m} X^{T} (g(X^{T}\theta)-y)+\frac{\lambda}{m}\theta_{j}]$
代码只需要计算蓝色括号中的内容,然后用优化算法迭代:
1 | def gradient_reg(theta,X, y, lmd): |
优化算法:
用于迭代计算$\theta_{j}$值。
1 | result = opt.fmin_tnc( |
画出决策边界
不是代入假设函数来画!!在逻辑回归中假设函数时Sigmoid function,用于计算概率的!!
1 | def plot_decision_boundary(theta): |