[Quant 1.1] 尝试只用Numpy实现逻辑回归
之前关注了一个up主,看了两个视频之后感觉他讲的非常好。因为当时还没放假,所以就没有仔细看,就想着放假之后一定好好修炼修炼技术。祝自己能坚持下去,同时非常感谢大神的视频。

从我的水平看,up调取了pytorch的包,把numpy array转化成张量然后带入到自己写的逻辑回归函数中循环。因为我感觉短期可能没法把pytorch学的那么扎实,所以就想只用numpy试试能不能把逻辑回归写出来(我也不想做调包侠)。然后这个仅作为我看完原up视频之后的一点小练习和记录,所以我不会说的非常的细致。如果读到这篇的朋友需要我在哪个地方详细说明的话我会更新这篇。我会尽快附上代码链接。感兴趣的朋友可以私我一些意见/把我拉进金工金数量化或者CFA2级备考的群,菜鸟不胜感激!
1. 模型
在开始讲代码之前,我们先整理一下逻辑,也相当于复习一下逻辑回归的框架了。
逻辑回归模型是基于sigmoid激活函数的,也就是
模型是
左边的条件概率相当于一个关于x的函数。x是一个样本的attributes向量,例如对你来说,你有一个x向量,是你的身高,
是你的体重...。同样,对你来说,你还有一个性别y(不好意思我这里暂时不考虑trans),y=1说明你是女性,y=0说明你是男性。w是针对所有的人来说每一个attribute对判断你性别的影响,例如w1就是一个人的身高在判断这个人是男是女的时候的重要性。
在线性回归里面,我们用的损失函数是MSE。而在逻辑回归里面我们要用的损失函数是cross entropy。
y是你真实的性别,是之前预测的你的性别
这是因为在逻辑回归模型下,损失函数MSE非凸,所以不能使用梯度下降法来求最小的loss。如果你在逻辑回归中用了MSE,那么你要最小化的损失函数很可能长这个样子。

但是如果你使用了cross entropy,损失函数基本就长这样子。

Plot by Wolfram
多说一句,即使cross entropy损失函数是凸的,我们也没办法用first order condition来求解他的全局最小值,因为他没有。我是愚蠢的用手推了很久才发现的。
所以之后要做的事情就是:我们先猜想一组 和
,然后我们把attributes向量一个一个的代入到这个逻辑回归模型里面。我们就会获得1个预测值,然后用1个预测值和1个真实值来计算出1个对应的loss。然后计算这个loss对各个attribute的偏导数,就可以更新我们的
和
了。
这里因为在计算 的时候要用到
和
,所以g也是关于
和
的函数。
而实际上,我们可以选择多个attributes向量一起代入,得到多个loss的平均值,然后求这个平均loss的对 和
的偏导数,在用上面同样的式子来更新参数。在这种情况下,向量乘法会变成矩阵乘法,大神在视频2中有详细讲解。
2. 代码
除了numpy之外,sklearn主要是导入和up同样的数据库来检验我自己建立的逻辑回归模型的表现。matplotlib拿来画图。
然后是定义sigmoid函数和cross entropy函数,数学表达式就是上面写到的激活函数和损失函数。
下一个函数是计算损失,大致就是先用 (把前面提到的
纵向堆叠到一起),
和
来求出
,再对应实际的
计算出的多个样本对应损失的平均值。样本个数就是矩阵
的行数。
下面是用来求梯度的函数,因为numpy本身的diff函数是计算离散数列邻项的差的,因此不能用来求偏导。因此我来定义一个函数,用来求解loss函数在 各个方向的梯度。
提取数据,划分训练集和测试集(和原up的代码相同),把 和
都初始化为0向量。
下面是主函数。
我的代码用了5000次迭代,最后的loss是0.20495,下面是最后得到的 和
的结果。
这个和原up的回归结果有一些出入,但是还好。。

最后计算一下预测的准确率
计算出来是92.647%