假设我有一个简单的数据集。也许是字典形式,它看起来像这样:
{1:5, 2:10, 3:15, 4:20, 5:25}
(订单总是在提升)。
我想要做的是从逻辑上弄清楚下一个数据点最有可能是什么。例如,在这种情况下,它将是{6: 30}
最好的方法是什么?
答案 0 :(得分:6)
你也可以使用numpy的polyfit:
data = np.array([[1,5], [2,10], [3,15], [4,20], [5,25]])
fit = np.polyfit(data[:,0], data[:,1] ,1) #The use of 1 signifies a linear fit.
fit
[ 5.00000000e+00 1.58882186e-15] #y = 5x + 0
line = np.poly1d(fit)
new_points = np.arange(5)+6
new_points
[ 6, 7, 8, 9, 10]
line(new_points)
[ 30. 35. 40. 45. 50.]
这允许您很容易地改变多项式拟合的程度,因为函数polyfit
采用以下参数np.polyfit(x data, y data, degree)
。显示的是线性拟合,对于任何度fit[0]*x^n + fit[1]*x^(n-1) + ... + fit[n-1]*x^0
,返回的数组看起来像n
。 poly1d
函数允许您将此数组转换为函数,该函数返回任意给定值x
的多项式的值。
一般来说,如果没有一个很好理解的模型,推断就会产生零星的结果。
from scipy.optimize import curve_fit
def func(x, a, b, c):
return a * np.exp(-b * x) + c
x = np.linspace(0,4,5)
y = func(x, 2.5, 1.3, 0.5)
yn = y + 0.2*np.random.normal(size=len(x))
fit ,cov = curve_fit(func, x, yn)
fit
[ 2.67217435 1.21470107 0.52942728] #Variables
y
[ 3. 1.18132948 0.68568395 0.55060478 0.51379141] #Original data
func(x,*fit)
[ 3.20160163 1.32252521 0.76481773 0.59929086 0.5501627 ] #Fit to original + noise
答案 1 :(得分:6)
在Python聊天中与您讨论后,将数据拟合为指数级。这应该是一个相对较好的指标,因为你不是在寻找长期的推断。
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def exponential_fit(x, a, b, c):
return a*np.exp(-b*x) + c
if __name__ == "__main__":
x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([30, 50, 80, 160, 300, 580])
fitting_parameters, covariance = curve_fit(exponential_fit, x, y)
a, b, c = fitting_parameters
next_x = 6
next_y = exponential_fit(next_x, a, b, c)
plt.plot(y)
plt.plot(np.append(y, next_y), 'ro')
plt.show()
最右侧轴上的红点显示下一个“预测”点。
答案 2 :(得分:5)
正如answer对相关问题的指出,从scipy的0.17.0版开始,scipy.interpolate.interp1d中有一个允许线性外推的选项。在您的情况下,您可以这样做:
>>> import numpy as np
>>> from scipy import interpolate
>>> x = [1, 2, 3, 4, 5]
>>> y = [5, 10, 15, 20, 25]
>>> f = interpolate.interp1d(x, y, fill_value = "extrapolate")
>>> print(f(6))
30.0
答案 3 :(得分:1)
由于您的数据大致是线性的,您可以执行linear regression,然后使用该回归的结果来计算下一个点,使用y = w[0]*x + w[1]
(保留 y = mx + b )。
如果您的数据不是近似线性的,并且您没有其他理论形式的回归,那么一般的推断(使用多项式或样条)就不那么可靠了,因为它们可能会比已知数据点有点疯狂。例如,请参阅接受的答案here。
答案 4 :(得分:0)
>>> from scipy.interpolate import splrep, splev
>>> d = {1:5, 2:10, 3:15, 4:20, 5:25}
>>> x, y = zip(*d.items())
>>> spl = splrep(x, y, k=1, s=0)
>>> splev(6, spl)
array(30.0)
>>> splev(7, spl)
array(35.0)
>>> int(splev(7, spl))
35
>>> splev(10000000000, spl)
array(50000000000.0)
>>> int(splev(10000000000, spl))
50000000000L
请参阅How to make scipy.interpolate give an extrapolated result beyond the input range?