改善曲线拟合R中的数据

时间:2018-01-22 20:47:35

标签: r curve-fitting

无法为此数据拟合适当的曲线。

x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 31, 41, 51, 61, 71, 
81, 91, 110, 210, 310, 410, 510, 610, 710, 810, 910, 1100, 2100, 
3100, 4100, 5100, 6100, 7100, 8100, 9100)

y <- c(75, 84, 85, 89, 88, 91, 92, 92, 93, 92, 94, 95, 95, 96, 95, 
95, 94, 97, 97, 97, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 
99, 99, 99, 99, 99, 99)

到目前为止尝试过:

fit1 <- lm(y~log(x)+I(1/x))
fit2 <- lm(y~log(x)+I(1/x)+x)

plot(x,y, log="x")
lines(0.01:10000, predict(fit1, newdata = data.frame(x=0.01:10000)))
lines(0.01:10000, predict(fit2, newdata = data.frame(x=0.01:10000)), col='red')

enter image description here

这种情况很合适,但完全凭经验得出,还有改进的余地。我不适合黄土或花键更好。

  

具体目标是增加拟合的R ^ 2并改进回归诊断(例如残差的Q-Q图)。

编辑预期模型:这是抽样数据,其中更多样本(x)提高了估算的准确性(y);它会以100%饱和。

3 个答案:

答案 0 :(得分:3)

这将是我的函数猜测,并根据python

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize as so


def f( x, a, b , s, p ):
    return a + b * s * ( x - 1 ) / (  1 + ( s * ( x - 1 ) )**( abs( 1 / p ) ) )**abs( p )


def g( x, a , s, p ):
    return a * s * x / (  1 + ( s * x )**( abs( 1 / p ) ) )**abs( p )


def h( x, s, p ):
    return 100 * s * x / (  1 + ( s * x )**( abs( 1 / p ) ) )**abs( p )


xData = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 21, 31, 41, 51, 61, 71, 
        81, 91, 110, 210, 310, 410, 510, 610, 710, 810, 910, 1100, 2100, 
        3100, 4100, 5100, 6100, 7100, 8100, 9100 ]

yData = [ 75, 84, 85, 89, 88, 91, 92, 92, 93, 92, 94, 95, 95, 96, 95, 
        95, 94, 97, 97, 97, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 
        99, 99, 99, 99, 99, 99 ]

xList = np.logspace( 0, 5, 100 )

bestFitF, err = so.curve_fit( f , xData, yData, p0=[ 75, 25, 1, 1])
bestFitG, err = so.curve_fit( g , xData, yData)
bestFitH, err = so.curve_fit( h , xData, yData)

fList = np.fromiter( ( f(x, *bestFitF ) for x in xList ), np.float)
gList = np.fromiter( ( g(x, *bestFitG ) for x in xList ), np.float)
hList = np.fromiter( ( h(x, *bestFitH ) for x in xList ), np.float)

fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )

ax.plot( xData, yData, marker='o', linestyle='')
ax.plot( xList, fList, linestyle='-.', label='f')
ax.plot( xList, gList, linestyle='-.', label='g')
ax.plot( xList, hList, linestyle='-.', label='h')

ax.set_xscale( 'log' )
ax.legend( loc=0 )
plt.show()

Three options

功能f需要起始值,gh不需要。应该可以编写一些代码来猜测参数,基本上第一个是yData[0],第二个是yData[-1] - yData[0],其他的无关紧要,只是设置为1,但是我在这里手动完成了。

gh都具有通过( 0, 0 )的属性。 此外,h会在100饱和。

注意:确定参数越多,拟合越好,但如果是,例如,CDF你可能想要一个固定的饱和度值,也可能需要通过( 0, 0 )

答案 1 :(得分:3)

这可能是Gunary等式的可接受拟合,R平方值为0.976:

y = x /(a + bx + cx ^ 0.5)

Fitting target of lowest sum of squared absolute error = 2.4509677507601545E+01

a =  1.2327255760994933E-03
b =  1.0083740273268828E-02
c =  1.9179200839782879E-03

答案 2 :(得分:1)

R package drc有很多选择。

这是一个5参数对数逻辑模型,它产生的残差低于问题中的拟合。

奖励:它具有自启动功能,因此您可以避免找到非线性回归的初始值的挑战。

library(drc)
dosefit <- drm(y ~ x, fct = LL2.5())

enter image description here