【问题标题】:Plotting the Convergence Results of scipy.optimize.differential_evolution绘制 scipy.optimize.differential_evolution 的收敛结果
【发布时间】:2020-09-13 13:13:07
【问题描述】:

我有两个数据框 (df_1, df_2)、一些变量 (A,B,C)、一个函数 (fun) 和一个全局遗传优化器,它可以在给定的 A、B 范围内找到 fun 的最大值, C.

from scipy.optimize import differential_evolution

df_1 = pd.DataFrame({'O' : [1,2,3], 'M' : [2,8,3]})

df_2 = pd.DataFrame({'O' : [1,1,1, 2,2,2, 3,3,3],
                     'M' : [9,2,4, 6,7,8, 5,3,4],
                     'X' : [2,4,6, 4,8,7, 3,1,9],
                     'Y' : [3,6,1, 4,6,5, 1,0,7],
                     'Z' : [2,4,8, 3,5,4, 7,5,1]})

# Index
df_1 = df_1.set_index('O')
df_1_M = df_1.M
df_1_M = df_1_M.sort_index()

# Fun
def fun(z, *params):
    A,B,C = z
        
    # Score
    df_2['S'] = df_2['X']*A + df_2['Y']*B + df_2['Z']*C
    
    # Top score
    df_Sort = df_2.sort_values(['S', 'X', 'M'], ascending=[False, True, True])
    df_O    = df_Sort.set_index('O')
    M_Top   = df_O[~df_O.index.duplicated(keep='first')].M
    M_Top   = M_Top.sort_index()
        
    # Compare the top scoring row for each O to df_1
    df_1_R = df_1_M.reindex(M_Top.index) # Nan
    T_N_T  = M_Top == df_1_R

    # Record the results for the given values of A,B,C
    df_Res = pd.DataFrame({'it_is':T_N_T}) # is this row of df_1 the same as this row of M_Top?
        
    # p_hat =         TP / (TP + FP)
    p_hat = df_Res.sum() / len(df_Res.index)
    
    print(z)
        
    return -p_hat[0]

# Bounds
min_ = 0
max_ = 1
ran_ge = (min_, max_)
bounds = [ran_ge,ran_ge,ran_ge]

# Params
params = (df_1, df_2)

# DE
DE = differential_evolution(fun, bounds, args=params)

它在每次迭代时打印出 [A B C],例如最后三行是:

[0.04003901 0.50504249 0.56332845]
[0.040039   0.5050425  0.56332845]
[0.040039   0.50504249 0.56332846]

要查看它是如何收敛的,我该如何绘制 A、B、C 与迭代的关系?

我尝试将 A、B、C 存储在:

df_P = pd.DataFrame({0})

在增加乐趣的同时:

df_P.append(z)

但我得到了:

RuntimeError: The map-like callable must be of the form f(func, iterable), returning a sequence of numbers the same length as 'iterable'

【问题讨论】:

  • 遗憾的是,您需要找到一种方法在您的 ABC 上应用降维,因为 4 维图还不是一件事……例如,使用 ABC 的方法可能有效。
  • 这个方法听起来很有趣,请问我该怎么做?我曾想象 A、B、C 都可以在 y 轴上进行迭代,在 X 轴上进行迭代,但你的想法听起来更容易阅读,只有一行。我的问题是每次迭代都记录结果。

标签: python pandas matplotlib genetic-algorithm scipy-optimize


【解决方案1】:

所以我不确定是否找到了最好的方法,但我找到了一个。 它使用列表通过引用传递的事实。这意味着如果您将列表传递给函数并对其进行修改,那么即使函数没有返回它,它也会为程序的其余部分进行修改。

# Params
results = []  # this list will hold our restuts
params = (df_1, df_2, results)  # add it to the params of the functions

# now in the function add the output to the list, Instead of the mean here I used the distance to the origin (as if you 3 value were a 3d vector) 

p_hat = df_Res.sum() / len(df_Res.index)

distance_to_zeros = sum([e**2 for e in z]) ** 1/2
results.append(distance_to_zeros)
# Indeed you can also append z directly.

# Then after DE call
DE = differential_evolution(fun, bounds, args=params)

x = range(0, len(results))

plt.scatter(x, results, alpha=0.5)
plt.show()

【讨论】:

    【解决方案2】:

    使用 RomainL 的代码绘制 A、B、C:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.optimize import differential_evolution
    
    df_1 = pd.DataFrame({'O' : [1,2,3], 'M' : [2,8,3]})
    
    df_2 = pd.DataFrame({'O' : [1,1,1, 2,2,2, 3,3,3],
                         'M' : [9,2,4, 6,7,8, 5,3,4],
                         'X' : [2,4,6, 4,8,7, 3,1,9],
                         'Y' : [3,6,1, 4,6,5, 1,0,7],
                         'Z' : [2,4,8, 3,5,4, 7,5,1]})
    
    # Index
    df_1 = df_1.set_index('O')
    df_1_M = df_1.M
    df_1_M = df_1_M.sort_index()
    
    # Fun
    def fun(z, *params):
        A,B,C = z
            
        # Score
        df_2['S'] = df_2['X']*A + df_2['Y']*B + df_2['Z']*C
        
        # Top score
        df_Sort = df_2.sort_values(['S', 'X', 'M'], ascending=[False, True, True])
        df_O    = df_Sort.set_index('O')
        M_Top   = df_O[~df_O.index.duplicated(keep='first')].M
        M_Top   = M_Top.sort_index()
            
        # Compare the top scoring row for each O to df_1
        df_1_R = df_1_M.reindex(M_Top.index) # Nan
        T_N_T  = M_Top == df_1_R
    
        # Record the results for the given values of A,B,C
        df_Res = pd.DataFrame({'it_is':T_N_T}) # is this row of df_1 the same as this row of M_Top?
            
        # p_hat =         TP / (TP + FP)
        p_hat = df_Res.sum() / len(df_Res.index)
        
        results.append(z)
            
        return -p_hat[0]
    
    # Bounds
    min_ = 0
    max_ = 1
    ran_ge = (min_, max_)
    bounds = [ran_ge,ran_ge,ran_ge]
    
    # Params
    results = []
    params = (df_1, df_2, results)
    
    # DE
    DE = differential_evolution(fun, bounds, args=params)
    
    # Plot
    df_R = pd.DataFrame(list(map(np.ravel, results)), columns=('A','B','C'))
    plt.figure()
    ax = df_R.plot()
    ax.set_ylim(min_,max_)
    

    【讨论】:

      猜你喜欢
      • 2019-03-12
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 2021-04-24
      • 2019-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多