我在尝试从头开始实现逻辑回归时遇到了困惑。最初,我们为权重随机生成一个单一的值。然而,随着过程的进行,我发现训练的最终结果给出了多个权重(与训练集中数据点的数量相匹配)。尽管预测效果正常,但我认为对于单个特征拥有多个权重是没有意义的。我也在下面的代码中提到了我的问题。
np.random.seed(100)class LogisticRegression:def sigmoid(self, z): return 1 / (1 + np.e**(-z))def cost_function(self, X, y, weights): z = X*weights predict_1 = y * np.log(self.sigmoid(z)) predict_0 = (1 - y) * np.log(1 - self.sigmoid(z)) #print(-sum(predict_1 + predict_0) / len(X)) return -sum(predict_1 + predict_0) / len(X)def fit(self, X, y, epochs=250, lr=0.05): loss = [] weights = np.rand() # 最初权重这里是一个单一的数字... N = len(X) for _ in range(epochs): # 梯度下降 y_hat = self.sigmoid(X*weights) weights -= lr * X*(y_hat - y) / N # ...但随后权重的数量 # 变成了与数据点数量相等 # 在这一行... # 保存进度 loss.append(self.cost_function(X, y, weights)) self.weights = weights self.loss = loss print('weights:', weights) # ...这导致我们为每个数据点得到不同的 # 权重。 # 如果我得到多个最终权重,如何绘制最终的逻辑曲线? #print(loss)def predict(self, X): # 使用sigmoid函数进行预测 z = X*self.weights # 返回二进制结果 return [1 if i > 0.5 else 0 for i in self.sigmoid(z)] #print(self.sigmoid(z))
clf = LogisticRegression()clf.fit(X,y)clf.predict(X)
回答:
权重的更新应该包括对数据点的总和。请查看这个页面,了解更多关于反向传播推导的详细信息。
因此,权重应该以如下方式更新:
weights -= lr * sum(X*(y_hat - y)) / N
而不是:
weights -= lr * X*(y_hat - y) / N
这样,你就只会得到一个预期的权重。