我假设你问的问题是:为什么逻辑回归的损失函数J的导数中,对X_b要进行转置,即下面的代码中,为什么使用X_b.T:
def dJ(theta, X_b, y):
return X_b.T.dot(self._sigmoid(X_b.dot(theta)) - y) / len(y)
实际上,这样的用法,我们在讲线性回归的时候,已经使用了:)在这一章的第三小节,我还将逻辑回归的向量化结果和线性回归的向量化结果进行了比较。可以从上一小节(9-3小节)14:00开始,再回顾一下:)
看一下下面的式子,是线性回归损失函数的梯度向量化的结果:
仔细观察左边的展开式,每一项最后乘以X(i)1,X(i)2,X(i)3,...,在sigma符号中,是在遍历i,换句话说,每一项后面所乘以的,是X的第1列,第2列,第3列....
规约到整个矩阵的乘法运算中,我们将X_b放到前面,就要将其转置,让列变成行:)
对于这个过程,还可以再回顾一下6-5小节,有更加详细的推导过程:)
回到逻辑回归损失函数的梯度,是这样表示的:
其实,这个表示方法和线性回归的损失函数的梯度求法,是出奇的一致的。对于线性回归的损失函数梯度,x*theta部分也是yhat!只不过在不同的模型假设下,yhat的求法不一样而已:)依然是,对于此的解释,建议再回顾一下9-3小节,14:00开始:)
最后,在6-5小节介绍过。矩阵运算的过程如果思考不明白,一个简单的方法是看矩阵的维度,看一下各个计算是否合法。比如设想你的X有100个数据,10个维度,然后带进式子里验证一下:)
当然,如果你能做一个简单的具体测试数据验证一下就更好了,比如只有5个样本,1个维度,具体用这个例子,带进上面的抽象式子中的X和y中,看看上面的式子会得到怎样的结果,印象会更深刻:)
加油!