在函数中使用遗传算法(本地) - 最小化函数



我一直在尝试使用遗传算法,以便在不同的实验中拟合我的幂律。问题是我并不完全理解它。我想我理解了除 sumOfSquaredError(parameterTuple( 函数之外的所有内容。

我一直试图理解和使用的代码,它是社区中常见的代码,它是由以下函数构建的

  • func(x, a, b( - 拟合实验数据的模型函数

  • sumOfSquaredError(parameterTuple( - 通过遗传算法最小化的函数

  • generate_Initial_Parameters(( - 基于 SciPy 的遗传算法生成初始参数

然后我所做的是使用具有熊猫的主函数。数据帧作为输入。此函数从数据帧中选择特定的行和列(以便获取单个试验(并对其进行处理。

我与发布的通用代码不同的是,我有一个带有熊猫数据框输入的函数,它只不过是一个索引数据集。然后,我对其施加了一些条件,以便从数据集中提取特定数据,以便每次迭代仅对整个数据集进行一次实验,并尝试将其定义为 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)

它返回:

文件 "/home/josep/programa.py",第 361 行,get_Results geneticParameters = generate_Initial_Parameters(xData, yData(

文件"/home/josep/programa.py",第 267 行,generate_Initial_Parameters 参数边界,种子=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 行 引发运行时错误("类似地图的可调用对象必须是">

运行时错误:类似映射的可调用对象必须是 f(func, iterable( 的形式,返回与 'iterable' 长度相同的数字序列


我面临的错误是:

  • 名称错误: 未定义名称"xData" 文件 "/home/josep/programa.py",第 245 行,在 sumOfSquaredError 中 val = func(xData, *parameterTuple(

我想我在函数内部调用 sumOfSquaredError(parameterTuple( 时遇到了问题,因为这个函数使用的是定义为全局变量的变量。这可能也与scipy.optimize.differential_evolution((有关。

如果我尝试输入 xData 和 yData 作为输入参数,那么它还要求我输入参数元组我不明白它来自哪里,因为它没有在任何地方定义。

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)) 

(就我而言,问题是在全局定义时它返回: 值错误:对象对于所需的数组来说太深 错误:函数调用的结果不是正确的浮点数组 )

问题可能完全是由于声明

def sumOfSquaredError(parameterTuple):

显然应该是

def sumOfSquaredError(xdata,ydata,parameterTuple):

尽管似乎这里也没有声明使用func

最新更新