def test_2D_fitting(): """ Makes sure that a scalar model with 2 independent variables has the proper signature, and that the fit result is of the correct type. """ xdata = np.random.randint(-10, 11, size=(2, 400)) zdata = 2.5 * xdata[0]**2 + 7.0 * xdata[1]**2 a = Parameter('a') b = Parameter('b') x = Variable('x') y = Variable('y') new = a * x**2 + b * y**2 fit = Fit(new, xdata[0], xdata[1], zdata) result = fit.model(xdata[0], xdata[1], 2, 3) assert isinstance(result, tuple) for arg_name, name in zip(('x', 'y', 'a', 'b'), inspect_sig.signature(fit.model).parameters): assert arg_name == name fit_result = fit.execute() assert isinstance(fit_result, FitResults)
def app(self, n): n = n + 1 x, y = variables('x, y') w, = parameters('w') model_dict = {y: self.fourier_series(x, f=w, n=n)} fit = Fit(model_dict, x=self.xdata, y=self.ydata) fit_result = fit.execute() return fit.model(x=self.xdata, **fit_result.params).y
def symfit_fourier(freq, signal): x, y = variables('x, y') w, = parameters('w') model_dict = {y: fourier_series(x, f=w, n=3)} # Define a Fit object for this model and data fit = Fit(model_dict, freq, signal) fit_result = fit.execute() return fit.model(x=freq, **fit_result.params).y
def fourier_gbm(price: float, mu: float, sigma: float, dt: float, n: int, order: int) -> np.array: x, y = variables('x, y') w, = parameters('w') model_dict = {y: fourier_series(x, f=w, n=order)} xdata = np.arange(-np.pi, np.pi, 2 * np.pi / n) ydata = np.log(gbm(price, mu, sigma, dt, n)) fit = Fit(model_dict, x=xdata, y=ydata) fit_result = fit.execute() return np.exp(fit.model(x=xdata, **fit_result.params).y)
def fourier_gbm(price, mu, sigma, dt, n, order): x, y = variables('x, y') w, = parameters('w') model_dict = {y: fourier_series(x, f=w, n=order)} # Make step function data xdata = np.arange(-np.pi, np.pi, 2 * np.pi / n) ydata = np.log(gbm(price, mu, sigma, dt, n)) # Define a Fit object for this model and data fit = Fit(model_dict, x=xdata, y=ydata) fit_result = fit.execute() return np.exp(fit.model(x=xdata, **fit_result.params).y)
def fourier_fit(self, x_train, y_train, x_test, y_test): for com in self.components: fit = Fit(self.fourier_model(com), x=x_train, y=y_train) fit_result = fit.execute() x_test = x_test.reshape(-1, 1) y_test_pred = fit.model(x=x_test, **fit_result.params).y fourier_mse = mean_squared_error(y_test, y_test_pred) self.mses.append(fourier_mse) # degree交叉验证 if self.min_mse > fourier_mse: self.min_mse = fourier_mse self.min_com = com print('degree = %s, MSE = %.2f' % (com, fourier_mse)) if com == 18: self.best.append(y_test_pred)
def regress(self, save_plot=False): # for each tsr in given directory tsr_list = [ f[-15:-12] for f in glob.glob(self.data_dir + "*_q_table.csv") ] # for each tsr on list fsr_params = [] for tsr in tsr_list: # load optimal path csv op_file = self.data_dir + "tsr{}".format(tsr) + "_op.csv" op_df = pd.read_csv(op_file, index_col=0) # load coverage table csv coverage_file = self.data_dir + "tsr{}".format( tsr) + "_coverage.csv" coverage_df = pd.read_csv(coverage_file, index_col=0) # translate indexes of optimal path to radians using cover_table # TODO it should be done with recreating environment and with env.data op_df['theta'] = coverage_df.index.values[op_df['theta']] op_df['pitch'] = coverage_df.columns.values[op_df['pitch']] op_df['theta'] = op_df['theta'].astype(float) op_df['pitch'] = op_df['pitch'].astype(float) # fourier regress xdata = op_df['theta'] ydata = op_df['pitch'] fit = Fit(self.model_dict, x=xdata, y=ydata) fit_result = fit.execute() # add fourier params to params list fsr_params.append(fit_result.params) if save_plot: # plot optimal path points ax = op_df.plot.scatter(x='theta', y='pitch') # plot regression function xdata = np.linspace(-np.pi, np.pi) f_model = fit.model(x=xdata, **fit_result.params) ax.plot(xdata, f_model.y) save_file_name = self.data_dir + "tsr{}".format( tsr) + '_fsr{}.png'.format(self.degree) plt.savefig(save_file_name, bbox_inches='tight') # save fourier params fsr_df = pd.DataFrame(fsr_params, index=tsr_list) file_name = self.data_dir + "_fsr{}.csv".format(self.degree) fsr_df.to_csv(file_name)
def test_likelihood_fitting_exponential(): """ Fit using the likelihood method. """ b = Parameter('b', value=4, min=3.0) x, y = variables('x, y') pdf = {y: Exp(x, 1 / b)} # Draw points from an Exp(5) exponential distribution. np.random.seed(100) # TODO: Do we *really* need 1m points? xdata = np.random.exponential(5, 1000000) # Expected parameter values mean = np.mean(xdata) stdev = np.std(xdata) mean_stdev = stdev / np.sqrt(len(xdata)) with pytest.raises(TypeError): fit = Fit(pdf, x=xdata, sigma_y=2.0, objective=LogLikelihood) fit = Fit(pdf, xdata, objective=LogLikelihood) fit_result = fit.execute() pdf_i = fit.model(x=xdata, **fit_result.params).y # probabilities likelihood = np.product(pdf_i) loglikelihood = np.sum(np.log(pdf_i)) assert fit_result.value(b) == pytest.approx(mean, 1e-3) assert fit_result.value(b) == pytest.approx(mean, 1e-3) assert fit_result.value(b) == pytest.approx(mean, 1e-3) assert fit_result.value(b) == pytest.approx(mean, 1e-3) assert fit_result.value(b) == pytest.approx(mean, 1e-3) assert fit_result.value(b) == pytest.approx(mean, 1e-3) assert fit_result.value(b) == pytest.approx(stdev, 1e-3) assert fit_result.stdev(b) == pytest.approx(mean_stdev, 1e-3) assert likelihood == pytest.approx(fit_result.likelihood) assert loglikelihood == pytest.approx(fit_result.log_likelihood)
def test_2D_fitting(self): """ Makes sure that a scalar model with 2 independent variables has the proper signature, and that the fit result is of the correct type. """ xdata = np.random.randint(-10, 11, size=(2, 400)) zdata = 2.5*xdata[0]**2 + 7.0*xdata[1]**2 a = Parameter() b = Parameter() x = Variable() y = Variable() new = a*x**2 + b*y**2 fit = Fit(new, xdata[0], xdata[1], zdata) result = fit.model(xdata[0], xdata[1], 2, 3) self.assertIsInstance(result, tuple) for arg_name, name in zip(('x', 'y', 'a', 'b'), inspect_sig.signature(fit.model).parameters): self.assertEqual(arg_name, name) fit_result = fit.execute() self.assertIsInstance(fit_result, FitResults)
class Fourier : """ Fits data with a Fourier Series """ def __init__(self,file_name,y_label=None,revenue_goal=None,freq=None,number_of_terms=5) : if isinstance(file_name,str) : df = pd.read_excel(file_name) ydata = df['{}'.format(y_label)].values elif isinstance(file_name,list) : ydata = np.asarray(file_name) if len(ydata) == 3 : self.x = np.linspace(0,1,1000) y = np.full_like(self.x,ydata[0]) y[self.x>0.333] = ydata[1]; y[self.x>0.666] = ydata[2] self.y = y else : self.y = ydata self.x = np.linspace(0,1,len(ydata)) ''' insAvg = [(a + b) / 2 for a, b in zip(ydata[::2], ydata[1::2])] ins = np.arange(1,len(ydata),2) for i,j in zip(ins,insAvg) : ydata.insert(i,j) self.x = np.linspace(0,1,len(ydata)) ''' self.label = y_label self.revenueGoal = revenue_goal self.n = number_of_terms if not freq == None : self.w = freq else : self.w = Parameter('w',1*2*np.pi) def fourier(self) : n=self.n w = self.w lst = range(n+1) self.a_n = parameters(','.join(['a{}'.format(i) for i in lst])) self.b_n = parameters(','.join(['b{}'.format(i) for i in lst])) self.coeff = self.a_n + self.b_n self.eqn = sum([i * sp.cos(k * w * Symbol('x')) + j * sp.sin(k * w * Symbol('x')) for k,(i,j) in enumerate(zip(self.a_n,self.b_n))]) return self.eqn def fit(self) : x, y = variables('x, y') model_dict = {y: self.fourier()} self.ffit = Fit(model_dict, x=self.x, y=self.y) self.fit_result = self.ffit.execute() self.orderedDict = self.fit_result.params return self.fit_result.params def fitFunc(self) : self.fiteqn = self.eqn for k,v in self.orderedDict.items() : self.fiteqn = self.fiteqn.subs(Parameter('{}'.format(k)),self.orderedDict[k]) return self.fiteqn def fFunc(self,x) : """Function for plugging into distConst to get constant c""" return self.fiteqn.subs(Symbol('x'),x) def adjustFunc(self) : integral = quad(self.fFunc,0,1) c = self.revenueGoal/integral[0] self.orderedDict.update((k, v*c) for k, v in self.orderedDict.items()) #print(self.eqn) self.adjeqn = self.eqn for k,v in self.orderedDict.items() : self.adjeqn = self.adjeqn.subs(Parameter('{}'.format(k)),self.orderedDict[k]) print(self.orderedDict) print(self.adjeqn) return self.adjeqn def adjFunc(self,x) : """Function for plugging into AttainmentCalc""" return self.adjeqn.subs(Symbol('x'),x) def fitPlot(self,plot_data=True,color='red') : if plot_data == True : plt.plot(self.x, self.y,lw=3,alpha=0.7, label=self.label,color=color) # plots line that is being fit plt.plot(self.x, self.ffit.model(self.x, **self.fit_result.params).y, color='red', ls='--',label='_nolegend_') formatter = ticker.StrMethodFormatter('{x:,.0f}') plt.gca().yaxis.set_major_formatter(formatter)
fit = Fit(model_dict, x=xdata, y=ydata) fit_result = fit.execute() fit2 = Fit(model_dict, x=xdata2, y=ydata2) fit_result2 = fit2.execute() print(fit_result) print(fit_result2) # Define a Fit object for this model and data fit = Fit(model_dict, x=xdata, y=ydata) fit_result = fit.execute() fit2 = Fit(model_dict, x=xdata2, y=ydata2) fit_result2 = fit2.execute() print(fit_result) print(fit_result2) dataderivative = ((fit.model(x=xdata, **fit_result.params).y)[1:]) data1derivative = ((fit.model(x=xdata2, **fit_result2.params).y)[1:]) fitxdata = np.arange(0, 2.0, 0.001) fitxdata2 = np.arange(0, 2.0, 0.001) # Plot the result fig, ax = plt.subplots() ax.set_xlabel('Displacement ($\AA$)', fontsize=15) ax.set_ylim(0, 7.0) ax.set_ylabel('Shear Stress (GPa)', fontsize=15) ax.set_xlim(0, 2.1) ax.tick_params(axis='both', which='major', labelsize=10, colors='black') ax.tick_params(axis='both', which='minor', labelsize=10, color='black') plt.plot(fitxdata, fit.model(x=fitxdata, **fit_result.params).y,
:param n: Order of the fourier series. :param x: Independent variable :param f: Frequency of the fourier series """ # Make the parameter objects for all the terms a0, *cos_a = parameters(','.join(['a{}'.format(i) for i in range(0, n + 1)])) sin_b = parameters(','.join(['b{}'.format(i) for i in range(1, n + 1)])) # Construct the series series = a0 + sum(ai * cos(i * f * x) + bi * sin(i * f * x) for i, (ai, bi) in enumerate(zip(cos_a, sin_b), start=1)) return series x, y = variables('x, y') w, = parameters('w') model_dict = {y: fourier_series(x, f=((2*np.pi)/(time[n2max]-time[nmax])), n=10)} print(model_dict) fit = Fit(model_dict, x=time, y=airCorrMag) fit_result = fit.execute() print(fit_result) plt.plot(time, fit.model(x=time, **fit_result.params).y, 'b') plt.plot(time,airCorrMag,'.') plt.title("Fourier Model") plt.xlabel("Julian Date") plt.ylabel("Differential Magnitude") plt.show() plt.savefig("fourier_model.pdf") plt.close()
deaths: sd_sim(r0)['Deaths'][x] } # specify the data for the veriables xdata = t ydata = { 'confirmed': df['confirmed'].to_numpy(), 'deaths': df['deaths'].to_numpy() } print('I m about to fit') # optimize the model fit = Fit(func, x=xdata, **ydata) fit_result = fit.execute() # visualize results confirmed_fit, deaths_fit = fit.model(x=xdata, **fit_result.params) import matplotlib.pyplot as plt plt.plot(xdata, confirmed_fit) plt.plot(xdata, ydata['confirmed']) plt.legend() plt.show() plt.plot(xdata, deaths_fit) plt.plot(xdata, ydata['deaths']) plt.legend() plt.show()
def test_error_advanced(self): """ Compare the error propagation of Fit against NumericalLeastSquares. Models an example from the mathematica docs and try's to replicate it: http://reference.wolfram.com/language/howto/FitModelsWithMeasurementErrors.html """ data = [ [0.9, 6.1, 9.5], [3.9, 6., 9.7], [0.3, 2.8, 6.6], [1., 2.2, 5.9], [1.8, 2.4, 7.2], [9., 1.7, 7.], [7.9, 8., 10.4], [4.9, 3.9, 9.], [2.3, 2.6, 7.4], [4.7, 8.4, 10.] ] xdata, ydata, zdata = [np.array(data) for data in zip(*data)] # errors = np.array([.4, .4, .2, .4, .1, .3, .1, .2, .2, .2]) a = Parameter('a', 3.0) b = Parameter('b', 0.9) c = Parameter('c', 5.0) x = Variable('x') y = Variable('y') z = Variable('z') model = {z: a * log(b * x + c * y)} const_fit = Fit(model, xdata, ydata, zdata, absolute_sigma=False) self.assertEqual(len(const_fit.model(x=xdata, y=ydata, a=2, b=2, c=5)), 1) self.assertEqual( const_fit.model(x=xdata, y=ydata, a=2, b=2, c=5)[0].shape, (10,) ) self.assertEqual(len(const_fit.model.eval_jacobian(x=xdata, y=ydata, a=2, b=2, c=5)), 1) self.assertEqual( const_fit.model.eval_jacobian(x=xdata, y=ydata, a=2, b=2, c=5)[0].shape, (3, 10) ) self.assertEqual(len(const_fit.model.eval_hessian(x=xdata, y=ydata, a=2, b=2, c=5)), 1) self.assertEqual( const_fit.model.eval_hessian(x=xdata, y=ydata, a=2, b=2, c=5)[0].shape, (3, 3, 10) ) self.assertEqual(const_fit.objective(a=2, b=2, c=5).shape, tuple()) self.assertEqual( const_fit.objective.eval_jacobian(a=2, b=2, c=5).shape, (3,) ) self.assertEqual( const_fit.objective.eval_hessian(a=2, b=2, c=5).shape, (3, 3) ) self.assertNotEqual( const_fit.objective.eval_hessian(a=2, b=2, c=5).dtype, object ) const_result = const_fit.execute() fit = Fit(model, xdata, ydata, zdata, absolute_sigma=False, minimizer=MINPACK) std_result = fit.execute() self.assertEqual(const_fit.absolute_sigma, fit.absolute_sigma) self.assertAlmostEqual(const_result.value(a), std_result.value(a), 4) self.assertAlmostEqual(const_result.value(b), std_result.value(b), 4) self.assertAlmostEqual(const_result.value(c), std_result.value(c), 4) # This used to be a tighter equality test, but since we now use the # Hessian we actually get a more accurate value from the standard fit # then for MINPACK. Hence we check if it is roughly equal, and if our # stdev is greater than that of minpack. self.assertAlmostEqual(const_result.stdev(a) / std_result.stdev(a), 1, 2) self.assertAlmostEqual(const_result.stdev(b) / std_result.stdev(b), 1, 1) self.assertAlmostEqual(const_result.stdev(c) / std_result.stdev(c), 1, 2) self.assertGreaterEqual(const_result.stdev(a), std_result.stdev(a)) self.assertGreaterEqual(const_result.stdev(b), std_result.stdev(b)) self.assertGreaterEqual(const_result.stdev(c), std_result.stdev(c))
:param x: Independent variable :param f: Frequency of the fourier series """ # Make the parameter objects for all the terms a0, *cos_a = parameters(','.join(['a{}'.format(i) for i in range(0, n + 1)])) sin_b = parameters(','.join(['b{}'.format(i) for i in range(1, n + 1)])) # Construct the series series = a0 + sum(ai * cos(i * f * x) + bi * sin(i * f * x) for i, (ai, bi) in enumerate(zip(cos_a, sin_b), start=1)) return series x, y = variables('x, y') w, = parameters('w') model_dict = {y: fourier_series(x, f=w, n=3)} print(model_dict) # Make step function data xdata = np.linspace(-np.pi, np.pi) ydata = np.zeros_like(xdata) ydata[xdata > 0] = 1 # Define a Fit object for this model and data fit = Fit(model_dict, x=xdata, y=ydata) fit_result = fit.execute() print(fit_result) # Plot the result plt.plot(xdata, ydata) plt.plot(xdata, fit.model(x=xdata, **fit_result.params).y, ls=':') plt.xlabel('x') plt.ylabel('y') plt.show()
# Make the parameter objects for all the terms a0, *A = parameters(','.join([f'a{i}' for i in range(0, n + 1)])) B = parameters(','.join([f'b{i}' for i in range(1, n + 1)])) # Construct the series series = a0 + sum(ai*cos(i*f*x) + bi*sin(i*f*x) for i, (ai, bi) in enumerate(zip(A, B), start=1)) return series x_, y_ = variables('x, y') w_, = parameters('w') model_dict = {y_: fourier_series(x_, f=w_, n=5)}; print(model_dict) X = np.arange(len(y)); Y = time_series fit = Fit(model_dict, x=X, y=Y); # Define a Fit object for this model and data fit_result = fit.execute(); print(fit_result) y = Y - fit.model(x=X, **fit_result.params).y axes[3].plot(X, fit.model(x=X, **fit_result.params).y, 'o-', c='r', alpha=0.5, label='fit value') axes[3].plot(X, Y, 'o-', c='gray', label='previous') axes[3].plot(X, y, 'o-', label='current') # time series (y) removed season axes[3].set_title("[d+=1] Random Process : Differencing") axes[3].legend() axes[3].grid(True) smt.graphics.plot_acf(y, lags=40, ax=axes[4]) axes[4].set_xlim(-1, 41) axes[4].set_ylim(-1.1, 1.1) axes[4].set_title("[d+=1] : Experimental partial autocorrelation function of an random process") axes[4].grid(True) smt.graphics.plot_pacf(y, lags=40, ax=axes[5])
def test_error_advanced(): """ Compare the error propagation of Fit against NumericalLeastSquares. Models an example from the mathematica docs and tries to replicate it: http://reference.wolfram.com/language/howto/FitModelsWithMeasurementErrors.html """ data = [[0.9, 6.1, 9.5], [3.9, 6., 9.7], [0.3, 2.8, 6.6], [1., 2.2, 5.9], [1.8, 2.4, 7.2], [9., 1.7, 7.], [7.9, 8., 10.4], [4.9, 3.9, 9.], [2.3, 2.6, 7.4], [4.7, 8.4, 10.]] xdata, ydata, zdata = [np.array(data) for data in zip(*data)] # errors = np.array([.4, .4, .2, .4, .1, .3, .1, .2, .2, .2]) a = Parameter('a', 3.0) b = Parameter('b', 0.9) c = Parameter('c', 5.0) x = Variable('x') y = Variable('y') z = Variable('z') model = {z: a * log(b * x + c * y)} const_fit = Fit(model, xdata, ydata, zdata, absolute_sigma=False) assert len(const_fit.model(x=xdata, y=ydata, a=2, b=2, c=5)) == 1 assert const_fit.model(x=xdata, y=ydata, a=2, b=2, c=5)[0].shape == (10, ) assert len(const_fit.model.eval_jacobian(x=xdata, y=ydata, a=2, b=2, c=5)) == 1 assert const_fit.model.eval_jacobian(x=xdata, y=ydata, a=2, b=2, c=5)[0].shape == (3, 10) assert len(const_fit.model.eval_hessian(x=xdata, y=ydata, a=2, b=2, c=5)) == 1 assert const_fit.model.eval_hessian(x=xdata, y=ydata, a=2, b=2, c=5)[0].shape == (3, 3, 10) assert const_fit.objective(a=2, b=2, c=5).shape == tuple() assert const_fit.objective.eval_jacobian(a=2, b=2, c=5).shape == (3, ) assert const_fit.objective.eval_hessian(a=2, b=2, c=5).shape == (3, 3) assert const_fit.objective.eval_hessian(a=2, b=2, c=5).dtype != object const_result = const_fit.execute() fit = Fit(model, xdata, ydata, zdata, absolute_sigma=False, minimizer=MINPACK) std_result = fit.execute() assert const_fit.absolute_sigma == fit.absolute_sigma assert const_result.value(a) == pytest.approx(std_result.value(a), 1e-4) assert const_result.value(b) == pytest.approx(std_result.value(b), 1e-4) assert const_result.value(c) == pytest.approx(std_result.value(c), 1e-4) # This used to be a tighter equality test, but since we now use the # Hessian we actually get a more accurate value from the standard fit # then for MINPACK. Hence we check if it is roughly equal, and if our # stdev is greater than that of minpack. assert const_result.stdev(a) / std_result.stdev(a) == pytest.approx( 1, 1e-2) assert const_result.stdev(b) / std_result.stdev(b) == pytest.approx( 1, 1e-1) assert const_result.stdev(c) / std_result.stdev(c) == pytest.approx( 1, 1e-2) assert const_result.stdev(a) >= std_result.stdev(a) assert const_result.stdev(b) >= std_result.stdev(b) assert const_result.stdev(c) >= std_result.stdev(c)
a0, *cos_a = parameters(','.join( ['a{}'.format(i) for i in range(0, n + 1)])) sin_b = parameters(','.join(['b{}'.format(i) for i in range(1, n + 1)])) # Construct the series series = a0 + sum(ai * cos(i * f * x) + bi * sin(i * f * x) for i, (ai, bi) in enumerate(zip(cos_a, sin_b), start=1)) return series x, y = variables('x, y') w, = parameters('w') model_dict = {y: fourier_series(x, f=w, n=3)} print(model_dict) # Make step function data xdata = np.linspace(-np.pi, np.pi) ydata = np.zeros_like(xdata) ydata[xdata > 0] = 1 # Define a Fit object for this model and data fit = Fit(model_dict, x=xdata, y=ydata) fit_result = fit.execute() print(fit_result) # Plot the result plt.plot(xdata, ydata) model = fit.model(x=xdata, **fit_result.params) plt.plot(xdata, model.y, ls=':') plt.xlabel('x') plt.ylabel('y') plt.show()
x, y = variables('x, y') w, = parameters('fbest') model_dict = {y: fourier_series(x, f=w, n=9)} print(model_dict) # Make step function data xdata = phase_con ydata = mag_con # Define a Fit object for this model and data fit = Fit(model_dict, x=xdata, y=ydata) fit_result = fit.execute() print(fit_result) # Plot the result f1_ax2.scatter(xdata, ydata) f1_ax2.plot(xdata, fit.model(x=xdata, **fit_result.params).y, lw=5, alpha=0.3, c='crimson') f1_ax2.set_xlabel('Phase', fontsize=15) f1_ax2.set_ylabel('Magnitude', fontsize=15) f1_ax2.set_title('Fourier Fit of the Phase Folded Light Curve', fontsize=25) f1_ax2.grid() #f1_ax2.set_ylim(-1.28, -0.98) plt.savefig('output_example.pdf')