我一直在尝试使用遗传算法来使我的幂定律适合不同的实验。问题是我不太了解它。我想我了解所有内容,但sumOfSquaredError(parameterTuple)函数除外。
我一直试图理解和使用的代码,它是社区中普遍共享的一种,它是由称为
的函数构建的func(x,a,b)-适合我们的实验数据的模型函数
sumOfSquaredError(parameterTuple)-通过遗传算法最小化的功能
generate_Initial_Parameters()-基于SciPy的遗传算法生成初始参数
然后我要做的是使用具有pandas.DataFrame作为输入的main函数。此功能从数据框中选择特定的行和列(以进行单个实验)并进行处理。
我与发布的一般代码的不同之处在于,我具有使用熊猫数据框输入的此功能,这仅是索引数据集。然后,我对其施加了一些条件,以便从数据集中提取特定数据,以便每次迭代仅对整个数据集进行一次实验,然后尝试将其定义为xData和yData。
精算
如果尝试输入xData和yData:
yData = np.asarray(y_eff)
xData = np.asarray(x)
# diff_evolution completes by calling curve_fit() using param. bounds
geneticParameters = generate_Initial_Parameters(xData, yData)
为了定义sumOfSquaredError(xData,yData,parameterTuple):
# "seed" the numpy random number generator for repeatable results
result = scipy.optimize.differential_evolution(
sumOfSquaredError(xData, yData, parameterBounds),
parameterBounds, seed=3)
它返回:
get_Results中的文件“ /home/josep/programa.py”,第361行 GeneticParameters = generate_Initial_Parameters(xData,yData)
generate_Initial_Parameters中的文件“ /home/josep/programa.py”,第267行 parameterBounds,seed = 3)
文件“ /home/josep/anaconda3/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py”,第276行,在differential_evolution中 ret = Solver.solve()
文件“ /home/josep/anaconda3/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py”,第688行,正在解决 人口)
文件“ /home/josep/anaconda3/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py”,第794行,在_calculate_population_energies中 提高RuntimeError(“类似地图的可调用对象必须是”
RuntimeError:类似于地图的可调用对象必须采用f(func,iterable)的形式,并返回与'iterable'相同长度的数字序列。
我遇到的错误是:
我认为在函数内部调用sumOfSquaredError(parameterTuple)时遇到问题,因为该函数使用的是定义为全局变量的变量。这可能还与 scipy.optimize.differential_evolution()有关。
如果我尝试输入xData和yData作为输入参数,那么它会要求我也输入 parameterTuple ,我不知道它的来源,因为它是在任何地方都没有定义。
def sumOfSquaredError(parameterTuple):
"""
Input to the genetic algorithm.
Function for the genetic algorithm to minimize (sum of squared error).
Parameters: xData, yData, parameterTuple
----------
Returns
-------
Squared difference between experimental data and predicted data
"""
# do not print warnings by genetic algorithm
warnings.filterwarnings("ignore")
val = func(xData, *parameterTuple)
return np.sum((yData - val) ** 2.0)
我正在使用的其他功能是:
def generate_Initial_Parameters():
"""
Generate initial parameters based on SciPy's genetic algorithm.
Returns
-------
result.x is the optimization result
"""
parameterBounds = []
parameterBounds.append([0, 100.0]) # search bounds for a
parameterBounds.append([0, 100.0]) # search bounds for b
# "seed" the numpy random number generator for repeatable results
result = differential_evolution(sumOfSquaredError, parameterBounds, seed=3)
return result.x
这是我在代码中调用的主要函数,在该代码中我输入df并在每次迭代中选择特定的行。 (如果有人要导入,我也会在这里写出来)
import numpy
import pandas as pd
import matplotlib.pyplot as plt
import scipy as scipy
from scipy.optimize import differential_evolution
from sklearn import linear_model
from sklearn.metrics import mean_squared_error, r2_score
import warnings
def get_Results(df):
"""
Process df.
Parameters.
----------
df : Dataframe with the data
Returns results which is a DataFrame with columns describing
regression coefficients
-------
"""
columns_results = 'Full_Name', 'Slope', 'Y-intercept', 'MSE', 'R2_score'
results = pd.DataFrame(columns=columns_results)
# Processing - Ht(%) = 0
sample_names = df['Sample'][
df['Ht(%)'] == 0].drop_duplicates()
for i in range(len(sample_names)):
df_i = df[(df['Sample'] == sample_names.values[i])
& (df['Ht(%)'] == 0.0)]
name = 'Ht(%)=' + str(df_i['Ht(%)'].values[i]) \
+ ' ' + 'Sample: ' + df_i['Sample'].values[i]
y_o = pd.DataFrame(df_i['Pressure(Pa)'].values)
x_o = pd.DataFrame(df_i['Velocity(um/s)'].values)
# Create linear regression object
regr = linear_model.LinearRegression()
# Train the model using the dataset
regr.fit(x_o, y_o) # fit(self, X, y[, sample_weight]) - Fit linear model.
# Make predictions using the estimator set
y_pred = regr.predict(x_o)
yData = numpy.asarray(y_o)
xData = numpy.asarray(x_o)
# diff_evolution completes by calling curve_fit() using param. bounds
geneticParameters = generate_Initial_Parameters()
# now call curve_fit without passing bounds from the genetic algorithm,
# just in case the best fit parameters are aoutside those bounds
fittedParameters, pcov = scipy.optimize.curve_fit(
func, xData, yData, geneticParameters)
print('Fitted parameters:', fittedParameters)
print()
modelPredictions = func(xData, *fittedParameters)
absError = modelPredictions - yData
SE = numpy.square(absError) # Squared Errors
MSE = numpy.mean(SE) # Mean Squared Errors
RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (numpy.var(absError) / numpy.var(y_o))
print()
print('RMSE:', RMSE)
print('R-squared:', Rsquared)
# Fill up results DataFrame
df = pd.DataFrame(
[[name,
regr.coef_[0, 0], regr.intercept_[0],
mean_squared_error(y_o, y_pred),
r2_score(y_o, y_pred)]], columns=columns_results)
results = results.append(df, ignore_index=True)
return results
启动-解决方案
正如@jeremy_rutman所建议的,这只是在函数内部全局定义xData和yData的问题。但是,问题是我定义的数组的尺寸不是必需的。
定义它们时要引入的正确代码如下
global xData
global yData
yData = np.asarray(y_eff).reshape(len(y_eff))
xData = np.asarray(x).reshape(len(x))
(对于我来说,问题是在全局定义时返回: 值错误:对象对于所需数组而言太深 错误:函数调用的结果不是正确的浮点数组 )
答案 0 :(得分:0)
问题可能完全是由于声明
def sumOfSquaredError(parameterTuple):
显然应该是
def sumOfSquaredError(xdata,ydata,parameterTuple):
尽管这里似乎也未声明使用func
。