CH06中logistic_regression代码的问题
yxwangscu opened this issue · 9 comments
相关章节
CH06
相关主题
- 代码
问题描述
logistic_regression.py中第74行代码:rst_ = (1 / m) * np.dot(x_.T, y_ * sigmoid(np.dot(x_, w_))) (g函数);
如果使用梯度下降作为更新法则,应该是y_ - sigmoid(np.dot(x_, w_))才对吧?请问作者为什么这里给的是y_ * sigmoid(np.dot(x_, w_))呢?感谢。
之前review都没看代码,很久没看都忘了之前的想法。
通常遇到$y$的乘法一般都利用$y\in {0,1}$这样的性质,这里的$y$在前面做了one-hot,乘法之后,只有对应的为别的位置是sigmoid(np.dot(x_, w_))
通常f,g一个对应loss,一个对应导数,这里我回头再review下。
我觉得算法很有意思在于有时候错了依然能出结果,所以有结果不一定是对的。。。。
这块的数据我会补充个MWE的版本。
更新了下代码,y*那个是用了one-hot汇总这个类别的样本结果。
添加了trian.csv的数据,可以跑一下看看中间数据维度。
我还是没有太理解到。我能理解利用one-hot汇总这个类别的样本结果,但是对于某一个类的权重更新应该是需要用到所有样本,而不是只有这个类别的样本吧?(当然我这个说法是建立在权重更新代码是使用梯度下降算法的基础上)
我还是没有太理解到。我能理解利用one-hot汇总这个类别的样本结果,但是对于某一个类的权重更新应该是需要用到所有样本,而不是只有这个类别的样本吧?(当然我这个说法是建立在权重更新代码是使用梯度下降算法的基础上)
嗯,这个是个多分类,用OvR实现多分类,在GD那个函数把类别遍历了一边,每个类别训练一个是这个类别,不是这个类别的分类器,所以你看最后w的维度是10x784
在predict的时候都预测,然后选择最大可能性的类别,作为最后的结果。
不知道这样还有没有问题。
def gradient_descent(self, x_, y_, epsilon_=0.00001, n_iter=1500):
n = x_.shape[len(x_.shape)-1]
# f_his = []
# one-hot encoding
y_ = pd.get_dummies(y_)
w_ = np.array([])
print(n, y_.shape, y_.columns)
# OvR for multiclass N个分类器 ck vs rest
for ck in np.arange(y_.shape[1]):
wck_ = np.zeros(n)
# k = 0
for k in np.arange(n_iter):
# f_xk = self.f(x_, y_.values[:, ck], wck_)
g_k = self.g(x_, y_.values[:, ck], wck_)
if np.average(g_k*g_k) < epsilon_:
w_ = wck_ if w_.size == 0 else np.vstack([w_, wck_])
break
else:
p_k = -g_k
lambda_k = 0.0000001 # TODO: 更新算法
wck_ = wck_ + lambda_k*p_k
# f_his.append(f_xk)
if k == n_iter-1:
w_ = wck_ if w_.size == 0 else np.vstack([w_, wck_])
print("progress: %d done" % ck)
self.coef_ = w_
self.cols_ = y_.columns.tolist()
return self.coef_, self.cols_
首先感谢您如此耐心的回复,占用了您的时间实在抱歉。
我的理解如下:
g函数里使用rst_ = (1 / m) * np.dot(x_.T, y_ * sigmoid(np.dot(x_, w_)));
总数据X: m\*n, m为样本量, n为特征量;
总标签y: m\*cls, m为样本量, cls为类别 (one-hot);
对于类$c \in {1, 2, 3, ... , cls}$的权重$w_c$训练所需的数据为: {X, y[:,c]}, 此时模型为二项逻辑斯蒂回归模型。使用梯度下降法解决极大似然估计的最优化问题即可。
我的问题是:
针对二项逻辑斯蒂回归模型,在使用梯度下降法解决极大似然估计的最优化问题时(似然函数为书本p79顺数第3个公式),推导出的权重更新方式为:rst_ = (1 / m) * np.dot(x_.T, y_ - sigmoid(np.dot(x_, w_)))。
事实上我发现您使用的 y_ * sigmoid(np.dot(x_, w_)) 可以通过修改书上的似然函数得到:
书本的似然函数(p79第3个公式)为 $\prod_{i=1}^{N}{[\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i}}$
修改似然函数为 $\prod_{{i} \in {C}}{[\pi(x_i)]^{y_i}}, C为所有正类的下标 $即可得到 y_ * sigmoid(np.dot(x_, w_))
由于我的应用项目略少,所以比较好奇这样的用法是如何来的?非常感谢您能抽空回答我的问题。
首先感谢您如此耐心的回复,占用了您的时间实在抱歉。
我的理解如下:
g函数里使用rst_ = (1 / m) * np.dot(x_.T, y_ * sigmoid(np.dot(x_, w_)));
总数据X: m\*n, m为样本量, n为特征量;
总标签y: m\*cls, m为样本量, cls为类别 (one-hot);
对于类$c \in {1, 2, 3, ... , cls}$的权重$w_c$训练所需的数据为: {X, y[:,c]}, 此时模型为二项逻辑斯蒂回归模型。使用梯度下降法解决极大似然估计的最优化问题即可。
我的问题是:
针对二项逻辑斯蒂回归模型,在使用梯度下降法解决极大似然估计的最优化问题时(似然函数为书本p79顺数第3个公式),推导出的权重更新方式为:rst_ = (1 / m) * np.dot(x_.T, y_ - sigmoid(np.dot(x_, w_)))。
事实上我发现您使用的 y_ * sigmoid(np.dot(x_, w_)) 可以通过修改书上的似然函数得到:
书本的似然函数(p79第3个公式)为 $\prod_{i=1}^{N}{[\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i}}$
修改似然函数为 $\prod_{{i} \in {C}}{[\pi(x_i)]^{y_i}}, C为所有正类的下标 $即可得到 y_ * sigmoid(np.dot(x_, w_))
由于我的应用项目略少,所以比较好奇这样的用法是如何来的?非常感谢您能抽空回答我的问题。
感谢你详细解释了你的问题。但是,如果用MLE来找参数的话,我觉得这个地方可能是个bug。
我在新的代码中修正了这里。
另外你说的修改似然函数的问题,我没看懂。
似然样本集中,每个样本得到这个结果的概率的连乘。
二项可以考虑成这样的形式。
这里同样利用了$y\in{0,1}$
对于多项的情况,参考书中公式6.7
还可以写成
似然函数大概是这个形式
这部分内容可以参考NG的CS229中监督学习的第二部分。
首先感谢您如此耐心的回复,占用了您的时间实在抱歉。
我的理解如下:
g函数里使用rst_ = (1 / m) * np.dot(x_.T, y_ * sigmoid(np.dot(x_, w_)));
总数据X: m\*n, m为样本量, n为特征量;
总标签y: m\*cls, m为样本量, cls为类别 (one-hot);
对于类$c \in {1, 2, 3, ... , cls}$的权重$w_c$训练所需的数据为: {X, y[:,c]}, 此时模型为二项逻辑斯蒂回归模型。使用梯度下降法解决极大似然估计的最优化问题即可。
我的问题是:
针对二项逻辑斯蒂回归模型,在使用梯度下降法解决极大似然估计的最优化问题时(似然函数为书本p79顺数第3个公式),推导出的权重更新方式为:rst_ = (1 / m) * np.dot(x_.T, y_ - sigmoid(np.dot(x_, w_)))。
事实上我发现您使用的 y_ * sigmoid(np.dot(x_, w_)) 可以通过修改书上的似然函数得到:
书本的似然函数(p79第3个公式)为 $\prod_{i=1}^{N}{[\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i}}$
修改似然函数为 $\prod_{{i} \in {C}}{[\pi(x_i)]^{y_i}}, C为所有正类的下标 $即可得到 y_ * sigmoid(np.dot(x_, w_))
由于我的应用项目略少,所以比较好奇这样的用法是如何来的?非常感谢您能抽空回答我的问题。
感谢你的回复,同时抱歉我之前的修改似然函数部分对你产生了疑惑。我更正一下这里的修改似然函数,应该是:$\prod_{i=1}^{N}{[\pi(x_i)]^{y_i}} $ 这个似然函数,这里利用了$y\in{0,1}$,从而可以推导出你在代码里的权重更新方式:rst_ = (1 / m) * np.dot(x_.T, y_ * sigmoid(np.dot(x_, w_))) ;
你在上面的给出的二项形式 \cite{
感谢你的回复,同时抱歉我之前的修改似然函数部分对你产生了疑惑。我更正一下这里的修改似然函数,应该是:∏Ni=1[π(xi)]yi∏i=1N[π(xi)]yi 这个似然函数,这里利用了y∈0,1y∈0,1,从而可以推导出你在代码里的权重更新方式:rst_ = (1 / m) * np.dot(x_.T, y_ * sigmoid(np.dot(x_, w_))) ;
你在上面的给出的二项形式 \cite{ ∏i=1NP(yi|xi,W)=∏i=1N(exp(w⋅xi))yi1+exp(w⋅xi)∏i=1NP(yi|xi,W)=∏i=1N(exp(w⋅xi))yi1+exp(w⋅xi) },利用这个公式得到的权重更新方式仍然是:y_ - sigmoid(np.dot(x_, w_))。
哦,重新理了一下。
我觉得改过的这部分应该叫损失函数,而不是似然了,似然应该就是概率的连乘,最大似然是最大化出现这种样本组合的可能性。
这个损失是不是认为0样本肯定发生,都是必然。 我似乎理解了你之前说的只用了部分样本的意思。
感谢你的回复,同时抱歉我之前的修改似然函数部分对你产生了疑惑。我更正一下这里的修改似然函数,应该是:∏Ni=1[π(xi)]yi∏i=1N[π(xi)]yi 这个似然函数,这里利用了y∈0,1y∈0,1,从而可以推导出你在代码里的权重更新方式:rst_ = (1 / m) * np.dot(x_.T, y_ * sigmoid(np.dot(x_, w_))) ;
你在上面的给出的二项形式 \cite{ ∏i=1NP(yi|xi,W)=∏i=1N(exp(w⋅xi))yi1+exp(w⋅xi)∏i=1NP(yi|xi,W)=∏i=1N(exp(w⋅xi))yi1+exp(w⋅xi) },利用这个公式得到的权重更新方式仍然是:y_ - sigmoid(np.dot(x_, w_))。哦,重新理了一下。
我觉得改过的这部分应该叫损失函数,而不是似然了,似然应该就是概率的连乘,最大似然是最大化出现这种样本组合的可能性。
$\prod_{i=1}^{N}{[\pi(x_i)]^{y_i}} $
这个损失是不是认为0样本肯定发生,都是必然。 我似乎理解了你之前说的只用了部分样本的意思。
嗯,应该是叫损失函数了。我的疑惑已经被解答了,谢谢你的回复。