Dan*_*ans 4 curve-fitting scipy
curve_fit在我继续讨论更复杂的问题之前,我正试图用一个简单的正弦波(甚至没有任何噪声)作为测试.不幸的是,它甚至没有给出正确的答案.这是我的语法:
x = linspace(0,100,300)
y = sin(1.759*x)
def mysine(x, a):
return sin(a*x)
popt, pcov = curve_fit(mysine, x, y)
popt
array([ 0.98679056])
Run Code Online (Sandbox Code Playgroud)
如果我尝试初始猜测(比如1.5):
popt, pcov = curve_fit(mysine, x, y, p0=1.5)
popt
array([ 1.49153365])
Run Code Online (Sandbox Code Playgroud)
......仍然没有正确的答案.
我想我很惊讶,鉴于函数的采样效果如何,拟合效果不佳.
曲线拟合并不总是那么简单.该curve_fit算法基于最小二乘曲线拟合,通常需要对输入参数进行初始猜测.根据您想要适合的功能类型,您的初始猜测必须是一个好的.
即使您尝试了初步猜测,我也会说您还有一个问题,那就是您的采样频率和波的频率.有关详细信息,您可以查看维基百科的奈奎斯特 - 香农采样定理.简单来说,波的频率为1.759 /(2*pi)= 0.28,结果非常接近x阵列的采样频率(~0.33).可能出现的另一个问题是有太多振荡以适应您的功能.
为了使您的代码能够正常工作,我建议您增加波形的频率(a> 4*0.33),或者增加采样频率并减小空间矢量的长度x.
我运行了以下代码并获得了如下所示的结果:
# -*- coding: utf-8 -*-
import numpy as np
import pylab as pl
from scipy.optimize import curve_fit
def mysine(x, a):
return 1. * np.sin(a * x)
a = 1.759 # Wave frequency
x = np.linspace(0, 10, 100) # <== This is what I changed
y = np.sin(a * x) + 0. * np.random.normal(size=len(x))
# Runs curve fitting with initial guess.
popt, pcov = curve_fit(mysine, x, y, p0=[1.5])
# Calculates the fitted curve
yf = mysine(x, *popt)
# Plots results for comparison.
pl.ion()
pl.close('all')
fig = pl.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, '-', c=[0.5, 0.5, 0.5])
ax.plot(x, yf, 'k-', linewidth=2.0)
ax.text(0.97, 0.97, ur'a=%.4f, ã=%.4f' % (a, popt[0]), ha='right', va='top',
fontsize=14, transform=ax.transAxes)
fig.savefig('stow_curve_fit.png')
Run Code Online (Sandbox Code Playgroud)
如果您知道正在尝试拟合的正弦波的频率,则可以使用线性回归来拟合正弦波.任何正弦波都可以用正弦和余弦函数的线性组合来表示.您可以使用线性回归找到正弦和余弦的系数.这种方法的好处是不需要初始猜测,只有一个答案满足回归公式(例如,你不会得到'错误'的答案).
http://exnumerus.blogspot.com/2010/04/how-to-fit-sine-wave-example-in-python.html有一个带有示例代码的简短教程.
| 归档时间: |
|
| 查看次数: |
3726 次 |
| 最近记录: |