我正在嘗試創建自己的模型擬合函式(我知道 SciPy 存在,但我想自己做)并且我希望它能夠采用任意數量的模型引數。但是,我遇到的問題是我不知道如何概括未知數量的模型引數。
假設我有兩個引數(例如,擬合一條簡單的 y=mx c 直線)。對于每個引數,我都有一個包含一系列值的串列。然后,我想嘗試這兩個串列中所有可能的元素組合,并使用最小二乘擬合來找到最佳的引陣列合。示例代碼:
import numpy as np
#define parameter lists
p_list_1 = np.linspace(0, 10, 11)
p_list_2 = np.linspace(0, 10, 11)
# get every combination of parameter values
for param_1 in p_list_1:
for param_2 in p_list_2:
p_combo = [param_1, param_2]
# and then I would use this parameter combination to fit a model, compute the residuals, etc.
但是,這種方法只有在我知道我要適應的引數數量時才有效,如果我想添加對可變數量引數的支持,這種方法會變得非常麻煩。例如,嘗試適應 5 個引數意味著我需要執行以下操作:
import numpy as np
# define parameter lists
p_list_1 = np.linspace(0, 10, 11)
p_list_2 = np.linspace(0, 10, 11)
p_list_3 = np.linspace(0, 10, 11)
p_list_4 = np.linspace(0, 10, 11)
p_list_5 = np.linspace(0, 10, 11)
# define number of parameters
n_params = 5
### Skip lines for 1, 2, 3, 4 parameters ###
if n_params == 5:
for param_1 in p_list_1:
for param_2 in p_list_2:
for param_3 in p_list_3:
for param_4 in p_list_4:
for param_5 in p_list_5:
p_combo = [param_1, param_2, param_3, param_4, param_5]
# and then I would use this parameter combination to fit a model, compute the residauls, etc.
這種方法顯然不是最好的方法,并且需要我手動添加對特定數量引數的支持。
所以,我的問題是,給定任意數量的串列,是否有一種簡潔的方法可以從所述串列中獲取每個可能的元素組合?
編輯:
我在這里找到了答案。下面是一些代碼供參考:
import itertools
import numpy as np
# define parameter ranges
p_list_1 = np.linspace(0, 10, 11)
p_list_2 = np.linspace(0, 10, 11)
p_list_3 = np.linspace(0, 10, 11)
# combine parameter ranges into single list
long_list = [p_list_1, p_list_2, p_list_3]
# generate Cartesian product/all combinations/all permutations
for combo in itertools.product(*long_list): # note the asterisk
print(combo)
這會從任意數量的串列中生成每個可能的元素組合,前提是這些串列位于主串列中。這正是我一直在尋找的。
uj5u.com熱心網友回復:
我建議使用 itertools 的功能產品
import itertools
import numpy as np
p_list_1 = np.linspace(0, 10, 11)
p_list_2 = np.linspace(0, 10, 11)
p_list_3 = np.linspace(0, 10, 11)
for combo in itertools.product(p_list_1,p_list_2,p_list_3):
print(combo)
print (len(list(itertools.product(p_list_1,p_list_2,p_list_3)))) #prins 1331
uj5u.com熱心網友回復:
假設您想為每個引數使用相同的引數串列(例如,每個引數應該從 0 到 10 以 1 為步長),對于r引數,那么沒有理由維護單獨的引數串列:
def param_list_builder(r, a=0, b=10, n=11):
return list(itertools.product(np.linspace(a, b, n), repeat=r))
不過,您可能不想同時將所有組合存盤在記憶體中。如果您一次只訓練一個模型,那么沒有理由一次需要一組以上的引數。在這種情況下,您應該使用生成器:
def param_generator(r, a=0, b=10, n=11):
return itertools.product(np.linspace(a, b, n), repeat=r)
然后,在測驗您的模型時:
for params in param_generator(3, 0, 10, 11):
test_model(params)
或者,如果您想隨時獲取一些引數:
In [10]: p_gen = param_generator(2, 0, 3, 4)
In [11]: next(p_gen)
Out[11]: (0.0, 0.0)
In [12]: next(p_gen)
Out[12]: (0.0, 1.0)
In [13]: next(p_gen)
Out[13]: (0.0, 2.0)
In [14]: next(p_gen)
Out[14]: (0.0, 3.0)
In [15]: next(p_gen)
Out[15]: (1.0, 0.0)
In [16]: next(p_gen)
Out[16]: (1.0, 1.0)
.
.
.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/488930.html
