1

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

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

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

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

  • generate_Initial_Parameters() - 根据 SciPy 的遗传算法生成初始参数

然后我要做的是使用具有 pandas.DataFrame 作为输入的 main 函数。此函数从数据框中选择特定的行和列(以便获得单个实验)并对其进行处理。

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

文件“/home/josep/programa.py”,第 267 行,在 generate_Initial_Parameters parameterBounds,seed=3)

文件“/home/josep/anaconda3/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py”,第 276 行,在different_evolution ret = solver.solve()

文件“/home/josep/anaconda3/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py”,第 688 行,在解决 self.population 中)

_calculate_population_energies 中的文件“/home/josep/anaconda3/lib/python3.7/site-packages/scipy/optimize/_differentialevolution.py”,第 794 行引发 RuntimeError(“类似地图的可调用对象必须属于”

RuntimeError:类似地图的可调用对象必须是 f(func, iterable) 的形式,返回与“可迭代”长度相同的数字序列


我面临的错误是:

  • NameError: name 'xData' is not defined File "/home/josep/programa.py", line 245, in sumOfSquaredError val = func(xData, *parameterTuple)

我认为在函数内部调用 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)) 

(在我的情况下,问题是在全局定义时它返回:值错误:对象太深,无法满足所需的数组错误:函数调用的结果不是正确的浮点数组)

4

1 回答 1

0

问题可能完全是由于声明

def sumOfSquaredError(parameterTuple):

显然应该是

def sumOfSquaredError(xdata,ydata,parameterTuple):

虽然似乎func这里的使用也未声明。

于 2019-12-19T09:58:41.850 回答