本来想先把tensorflow架构下的线性回归研究一下的,发现不懂的还是太多,先放一放。等之后用的多了再回头理解理解。
前置知识:
逻辑回归的基本模型:(比线性回归稍微复杂一点,一句话说不清,慢慢顺,但主要还是用假设函数在优化代价函数的过程中拟合数据集以适应通用的情况)
逻辑回归(logistic_regression)主要用于分类数据集,其输出值域是一个离散型的结构。这里先研究二元分类(01分类)
假设函数:![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/63549f9f7c9a65d4fdad79f0267e0d85.png#pic_center)
其中用到这样一个sigmoid 函数来作为假设函数的结构,其原因是:
对于分类算法数据集中的数据,其特征值可能很夸张,如果用线性回归的方法去做,这些很夸张的特征值可能会直接影响假设函数的参数,但对于一个分类算法,这些夸张特征没有特别的意义,它再怎么夸张,真正影响假设函数的是其分类的是0还是1。用图感性理解一下:
图中红圈圈中的两个数据结点,尽管相差很远,但他们对最终拟合的曲线的形态的影响是很接近的。换句话说,这个sigmoid的函数让原来的数据集变成了下面这样。
如果不是上面那个最终结果的边界曲线的话,下面的没有成功拟合的边界曲线可想而知代价是很大的。(当然这些都是感性的理解,从式子角度才是精确的)
代价函数:
逻辑回归中代价函数需要改一改,使用了log()对数算子,具体解释看
https://www.bilibili.com/video/BV164411b7dx?p=35
同样感性理解一下,在将定义域限制在(0,1)间(通过sigmoid函数),log(1)=0,log(0)=∞,
那么对于上图那个欠拟合的状态,那些直线左侧的绿点和右侧的蓝点产生的代价会巨大,在梯度下降的作用下就能改变参数使之能够拟合。
同时鉴于sigmoid函数的特性,不会真的产生无穷大的数,而且对于”同一类“的那些数据点,无论他们到分类的边界曲线距离多么远,对于用来拟合的曲线他们没有区别(因为都很接近0或1,log都很大或很小)
当然最重要的log引入是为了让梯度下降可以求出全局极值,这一点我解释不了,因为我只是一只小菜鸡。
代码逐行分析:
前几行主要读入数据到data中,并绘制了数据集的图像。它和线性回归中的数据不一样的地方是它有两个轴,exam1和exam2,值域是两元01(admitted)。
数据分类,get_X分出特征(exam1 exam2)get_Y分出对应的值(admitted),最后是便于梯度下降的数据标准化。
定义sigmoid函数,并且给了个直观的曲线呈现。(参数值矩阵theta转置和特征值矩阵乘积后,不管离0多远,在g作用后都划归到(0,1)之间,不用别的曲线如经过(0,0.5)的直线的原因可以思考一下,即使出于经验也是出于道理,可以参照刚刚解释代价函数中的log算子理解这句话)
一个求梯度的函数接口
这里没有像上一节那样写一个循环epoch了,而是借用了一个外部库,具体可以百度下
用来自动帮忙算出cost这个函数的最小值(当然应该是局部最小)
参数列表分别为:
指定需要最小化的函数为cost函数、
函数自变量的初始值(初始猜测值)、
函数本身需要的参数列表(cost(theta, X, y),theta已经是要用来最小化函数的自变量了,其它作为常数量从这里导入即可)、
最小化方法指定牛顿CG(我也不知道这是啥)、
jac用来指定目标函数梯度运算的函数
调用一下,最后要求的theta向量就在res.x里面了
用这些theta带入假设函数
就能得到训练结果。带入特征值就能算的最后值域取1的可能性
上面是假设函数都为1次的情况,最后的边界曲线是一条直线。
如果是这种情况,显然结果是椭圆一类的曲线,显然不能用直线取拟合了。
这时要用到下面的方法
原来的特征值只有2个维度 x1、x2,
将他俩进行有限次的次方组合就得到了高次的特征值。
这样得到的对应的theta也是相应高次的拟合值
就可以进行曲折的曲线的拟合了。
结束
后面还有一些正则化的代码,容我同线性回归的正则一起研究一波