<p>下面的代码看起来与数据匹配良好。这使用scipy的差分进化(DE)遗传算法来估计曲线拟合()的初始参数。为了加速遗传算法,代码使用前500个数据点的数据子集进行初始参数估计。虽然结果看起来很好,但是这个问题有一个复杂的错误空间,有很多参数,而且遗传算法需要一些时间来运行(在我的史前笔记本上大约15分钟)。您应该考虑在午餐时间或晚上使用完整的数据集进行测试,以验证拟合的参数是否有任何有用的改进。DE的scipy实现使用拉丁超立方体算法来确保对参数空间的彻底搜索,这需要搜索范围-请检查示例的边界是否合理。在</p>
<pre><code>import numpy as np
from scipy.optimize import differential_evolution
import warnings
data=np.genfromtxt('signal.data')
time=data[:,0]
signal=data[:,1]
signalerror=data[:,2]
# value for reduced size data set used in initial parameter estimation
# to sllow the genetic algorithm to run faster than with all data
geneticAlgorithmSlice = 500
import matplotlib.pyplot as plt
plt.figure()
plt.plot(time,signal)
plt.scatter(time,signal,s=5)
plt.show()
from gatspy.periodic import LombScargleFast
dmag=0.000005
nyquist_factor=40
model = LombScargleFast().fit(time, signal, dmag)
periods, power = model.periodogram_auto(nyquist_factor)
model.optimizer.period_range=(0.2, 10)
period = model.best_period
LSPfreq=1/period
def G(x, A_0,
A_1, phi_1,
A_2, phi_2,
A_3, phi_3,
A_4, phi_4,
A_5, phi_5,
A_6, phi_6,
A_7, phi_7,
A_8, phi_8,
A_9, phi_9,
A_10, phi_10,
freq):
return (A_0 + A_1 * np.sin(2 * np.pi * 1 * freq * x + phi_1) +
A_2 * np.sin(2 * np.pi * 2 * freq * x + phi_2) +
A_3 * np.sin(2 * np.pi * 3 * freq * x + phi_3) +
A_4 * np.sin(2 * np.pi * 4 * freq * x + phi_4) +
A_5 * np.sin(2 * np.pi * 5 * freq * x + phi_5) +
A_6 * np.sin(2 * np.pi * 6 * freq * x + phi_6) +
A_7 * np.sin(2 * np.pi * 7 * freq * x + phi_7) +
A_8 * np.sin(2 * np.pi * 8 * freq * x + phi_8) +
A_9 * np.sin(2 * np.pi * 9 * freq * x + phi_9) +
A_10 * np.sin(2 * np.pi * 10 * freq * x + phi_10))
# function for genetic algorithm to minimize (sum of squared error)
def sumOfSquaredError(parameterTuple):
warnings.filterwarnings("ignore") # do not print warnings by genetic algorithm
val = G(time[:geneticAlgorithmSlice], *parameterTuple)
return np.sum((signal[:geneticAlgorithmSlice] - val) ** 2.0)
def generate_Initial_Parameters():
parameterBounds = []
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([-50.0, 50.0])
parameterBounds.append([LSPfreq/2.0, LSPfreq*2.0])
# "seed" the numpy random number generator for repeatable results
result = differential_evolution(sumOfSquaredError, parameterBounds, seed=3)
return result.x
print("Starting genetic algorithm...")
# by default, differential_evolution completes by calling curve_fit() using parameter bounds
geneticParameters = generate_Initial_Parameters()
print("Genetic algorithm completed")
def fitter(time, signal, signalerror, initialParameters):
from scipy import optimize
pfit, pcov = optimize.curve_fit(G, time, signal, p0=initialParameters,
sigma=signalerror, absolute_sigma=True)
error = [] # DEFINE LIST TO CALC ERROR
for i in range(len(pfit)):
try:
error.append(np.absolute(pcov[i][i]) ** 0.5) # CALCULATE SQUARE ROOT OF TRACE OF COVARIANCE MATRIX
except:
error.append(0.00)
perr_curvefit = np.array(error)
return pfit, perr_curvefit
pfit, perr_curvefit = fitter(time, signal, signalerror, geneticParameters)
plt.figure()
model=G(time,*pfit)
plt.scatter(time,model,marker='+')
plt.plot(time,model)
plt.plot(time,signal,c='r')
plt.show()
</code></pre>