首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我不能得到用sklearn和coefficients_sgd方法得到的结果呢?

为什么我不能得到用sklearn和coefficients_sgd方法得到的结果呢?
EN

Stack Overflow用户
提问于 2022-02-27 09:47:23
回答 1查看 184关注 0票数 6
代码语言:javascript
复制
from math import exp
import numpy as np
from sklearn.linear_model import LogisticRegression

我使用了如何从零开始在Python中实现Logistic回归下面的代码

代码语言:javascript
复制
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]

代码语言:javascript
复制
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?

EN

回答 1

Stack Overflow用户

发布于 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))),使用一些数据统计(例如,每个系数wdot(y, w)/(dot(w, w) ),或者使用预先训练过的模型参数。相反,没有关于学习速度或时代数的黄金法则。通常情况下,我们设置了大量的时间和其他的停止准则(例如,当前系数和先前系数之间的范数是否小于一些小的tol),一个中等的学习速率,每次迭代我们都会按照一定的规则(见SGDClassifier用户指南learning_rate参数)降低学习率,并检查停止准则。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71283701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档