scipy 固定参数回归的最小平方误差

pgx2nnw8  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(107)

目前,我正在比较几种传统的方法来选择一系列点的指数趋势。在我所在的行业中,选择趋势时通常不考虑拟合度,这意味着常用的方法是简单地测量年/年变化,并在一段时间内对这些结果取平均值。这会产生一个因子,但不会产生拟合。所以很难将它与指数回归或其他方法进行比较。所以我的问题是:
如果我为指数曲线预先选择了一个固定的趋势因子,是否有一个简单的方法可以优化“截距”值,使一组数据的总体拟合的平方误差最小?请考虑以下问题:

import numpy as np
from sklearn.metrics import r2_score
from scipy.optimize import curve_fit

# Define exponential function

def ex(x,a,b):
    return a*b**x

# Seed data with normally distributed error

x=np.linspace(1,20,20)
np.random.seed(100)
y=ex(x,100,1.01)+3*np.random.randn(20)

# Exponential regression for trend value, fitted values, and r_sq measure

popt, pcov = curve_fit(ex, x, y)
trend,fit,r_sq=(popt[1])-1, ex(x,*popt), r2_score(y,ex(x,*popt))

# Mean Yr/Yr change as an alternative measure of trend

trend_yryr=np.mean(np.diff(y)/y[1:])

print(trend)
print(trend_yryr)

平均年/年变化为数据生成了一个不同的趋势值,我想将其与指数回归的选定趋势进行比较。我的目标是找到截距,使数据上的替代趋势值的平方误差最小,并测量该平方误差以进行比较。感谢您的帮助。

mspsb9vt

mspsb9vt1#

在使用curve_fit时,修复参数的一种方法是传递一个lambda函数,该函数对您要修复的参数进行硬编码。


# ... all your preamble, but importing matplotlib

new_b = trend_yryr + 1
popt2, pcov2 = curve_fit(lambda x, a: ex(x, a, new_b), x, y)
fit2, r_sq2 = ex(x, *popt2, new_b), r2_score(y, ex(x, *popt2, new_b))

poptarray([100.24989416, 1.00975864]),而popt2array([99.09513612])。将结果绘制为:

您可以使用lmfit来完成此操作,这可能会更优雅一点,但这基本上取决于您自己。

from lmfit import Parameters, minimize

def residual(params, x, y):
    a = params['a']
    b = params['b']
    model = ex(x, a, b)
    return model - y

p1 = Parameters()
p1.add('a', value=1, vary=True)
p1.add('b', value=1, vary=True)

p2 = Parameters()
p2.add('a', value=1, vary=True)
p2.add('b', value=np.mean(np.diff(y)/y[1:]) + 1, vary=False) # important

out1 = minimize(residual, p1, args=(x, y))
out2 = minimize(residual, p2, args=(x, y))

这两种方法的输出基本上是相同的,因此我不再重复

相关问题