from math import exp
import numpy as np
from sklearn.linear_model import LogisticRegression我使用了如何从零开始在Python中实现Logistic回归下面的代码
def predict(row, coefficients):
yhat = coefficients[0]
for i in range(len(row)-1):
yhat += coefficients[i + 1] * row[i]
return 1.0 / (1.0 + exp(-yhat))
def coefficients_sgd(train, l_rate, n_epoch):
coef = [0.0 for i in range(len(train[0]))]
for epoch in range(n_epoch):
sum_error = 0
for row in train:
yhat = predict(row, coef)
error = row[-1] - yhat
sum_error += error**2
coef[0] = coef[0] + l_rate * error * yhat * (1.0 - yhat)
for i in range(len(row)-1):
coef[i + 1] = coef[i + 1] + l_rate * error * yhat * (1.0 - yhat) * row[i]
return coef
dataset = [[2.7810836,2.550537003,0],
[1.465489372,2.362125076,0],
[3.396561688,4.400293529,0],
[1.38807019,1.850220317,0],
[3.06407232,3.005305973,0],
[7.627531214,2.759262235,1],
[5.332441248,2.088626775,1],
[6.922596716,1.77106367,1],
[8.675418651,-0.242068655,1],
[7.673756466,3.508563011,1]]
l_rate = 0.3
n_epoch = 100
coef = coefficients_sgd(dataset, l_rate, n_epoch)
print(coef)[-0.39233141593823756, 1.4791536027917747, -2.316697087065274]
x = np.array(dataset)[:,:2]
y = np.array(dataset)[:,2]
model = LogisticRegression(penalty="none")
model.fit(x,y)
print(model.intercept_.tolist() + model.coef_.ravel().tolist())[-3.233238244349982, 6.374828107647225, -9.631487530388092]
为了得到相同或更近的系数,我应该改变什么?如何建立初始系数,学习率,n_epoch?
发布于 2022-03-01 18:55:08
嗯,这里有很多细微之处
首先,回顾一下,用各种优化方法(包括你实现的SGD )可以估计带有(负)对数似然的logistic回归系数,但没有精确的封闭形式的解。因此,即使您实现了scikit的LogisticRegression的精确副本,您也需要设置相同的超参数(历元数、学习速率等)。和随机状态来获得相同的系数。
其次,LogisticRegression提供了五种不同的优化方法(solver参数)。您使用默认参数运行LogisticRegression(penalty="none"),而solver的默认参数是'lbfgs',而不是SGD;因此,根据您的数据和超参数,您可能会得到显著不同的结果。
为了得到相同或更近的系数,我应该改变什么?
我建议先将您的实现与SGDClassifier(loss='log')进行比较,因为LogisticRegression不提供SGD解决程序。尽管要记住,scikit-learn的实现更加复杂,特别是具有更多的超参数,用于像tol这样的早期停止。
如何建立初始系数,学习率,n_epoch?
通常,SGD的系数是随机初始化的(例如,uniform(-1/(2n), 1/(2n))),使用一些数据统计(例如,每个系数w的dot(y, w)/(dot(w, w) ),或者使用预先训练过的模型参数。相反,没有关于学习速度或时代数的黄金法则。通常情况下,我们设置了大量的时间和其他的停止准则(例如,当前系数和先前系数之间的范数是否小于一些小的tol),一个中等的学习速率,每次迭代我们都会按照一定的规则(见SGDClassifier或用户指南的learning_rate参数)降低学习率,并检查停止准则。
https://stackoverflow.com/questions/71283701
复制相似问题