亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

這個字典條目的笛卡爾積可以使用遞歸來完成嗎?

這個字典條目的笛卡爾積可以使用遞歸來完成嗎?

桃花長相依 2023-03-16 16:35:50
我正在研究一種簡單的方法,以緊湊的方式定義要自動實例化和評估的不同分類實驗,以獲得針對特定問題的最佳算法和參數組合。下面是使笛卡爾積產生所有可能的參數值組合的代碼的特定部分:def unpack_parameters(parameters_list):    parameters = []    for parameter_name, parameter_values in parameters_list.items():        if len(parameters) == 0:            parameters = [{parameter_name: parameter_value} for parameter_value in parameter_values]        else:            parameters = [dict(parameter.items() + {parameter_name: parameter_value}.items())                          for parameter_value in parameter_values for parameter in parameters]    return parameters?我可以通過使用遞歸得到相同的結果嗎?上面的代碼有效并產生了預期的結果。我也知道我可以使用 itertools.product 來獲得相同的結果。但這是一個學習是否可以在這里使用遞歸的問題,而不是它是否是解決特定問題的正確工具(盡管我不介意對此發表評論)。如果有人感興趣,這里是如何使用此代碼的:experiment_definitions = {    'sklearn.tree.DecisionTreeClassifier':        {'criterion': ['entropy', 'gini'],         'min_samples_split': [2, 4, 8, 16, 32, 64]}}classifiers = {}for classifier_class, parameters_list in experiment_definitions.items():    classifiers[classifier_class] = unpack_parameters(parameters_list)要產生這個:{'sklearn.tree.DecisionTreeClassifier': [{'min_samples_split': 2, 'criterion': 'entropy'}, {'min_samples_split': 4, 'criterion': 'entropy'}, {'min_samples_split': 8, 'criterion': 'entropy'}, {'min_samples_split': 16, 'criterion': 'entropy'}, {'min_samples_split': 32, 'criterion': 'entropy'}, {'min_samples_split': 64, 'criterion': 'entropy'}, {'min_samples_split': 2, 'criterion': 'gini'}, {'min_samples_split': 4, 'criterion': 'gini'}, {'min_samples_split': 8, 'criterion': 'gini'}, {'min_samples_split': 16, 'criterion': 'gini'}, {'min_samples_split': 32, 'criterion': 'gini'}, {'min_samples_split': 64, 'criterion': 'gini'}]}
查看完整描述

2 回答

?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

所以訣竅是能夠編寫一個函數cartesian_product(),該函數將數字列表作為輸入并返回索引的笛卡爾積,考慮到數字可能是列表的大小。


例如,如果我們有 2 個大小為 2 和 6 的列表(根據您的示例),則cartesian_product([2, 6])應該生成輸出:


[[0, 0], [1, 0], [0, 1], [1, 1], [0, 2], [1, 2], [0, 3], [1, 3], [0, 4], [1, 4], [0, 5], [1, 5]]


def cartesian_product(sizes, start=0):

    if not sizes:

        return []

    if start == len(sizes) - 1:

        return [[i] for i in range(sizes[-1])]

    sub_answer_lists = cartesian_product(sizes, start+1)

    ans = []

    for sub_ans_list in sub_answer_lists:

        for j in range(sizes[start]):

            list_copy = [j]

            list_copy.extend(sub_ans_list)

            ans.append(list_copy)

    return ans



def unpack_parameters(params_dict):

    param_keys = []

    param_lists = []

    for key, lst in params_dict.items():

        param_keys.append(key)

        param_lists.append(lst)

    param_lists_sizes = [len(lst) for lst in param_lists]

    cartesian_product_indices = cartesian_product(param_lists_sizes)

    param_map_list = []

    for indices in cartesian_product_indices:

        param_map = {}

        for i, index in enumerate(indices):

            param_key = param_keys[i]

            param_map[param_key] = param_lists[i][index]

        param_map_list.append(param_map)

    return param_map_list



experiment_definitions = {

    'sklearn.tree.DecisionTreeClassifier':

        {'criterion': ['entropy', 'gini'],

         'min_samples_split': [2, 4, 8, 16, 32, 64]}

}

classifiers = {}

for classifier_class, params_dict in experiment_definitions.items():

    classifiers[classifier_class] = unpack_parameters(params_dict)


print(classifiers)

輸出:


{'sklearn.tree.DecisionTreeClassifier': [{'criterion': 'entropy', 'min_samples_split': 2}, {'criterion': 'gini', 'min_samples_split': 2}, {'criterion': 'entropy', 'min_samples_split': 4}, {'criterion': 'gini', 'min_samples_split': 4}, {'criterion': 'entropy', 'min_samples_split': 8}, {'criterion': 'gini', 'min_samples_split': 8}, {'criterion': 'entropy', 'min_samples_split': 16}, {'criterion': 'gini', 'min_samples_split': 16}, {'criterion': 'entropy', 'min_samples_split': 32}, {'criterion': 'gini', 'min_samples_split': 32}, {'criterion': 'entropy', 'min_samples_split': 64}, {'criterion': 'gini', 'min_samples_split': 64}]}

編輯:


使用更少內存的生成器版本:


def cartesian_product(sizes, start=0):

    if not sizes:

        yield []

        return

    if start == len(sizes) - 1:

        for i in range(sizes[-1]):

            yield [i]

        return

    for sub_ans_list in cartesian_product(sizes, start+1):

        for j in range(sizes[start]):

            list_copy = [j]

            list_copy.extend(sub_ans_list)

            yield list_copy


查看完整回答
反對 回復 2023-03-16
?
POPMUISE

TA貢獻1765條經驗 獲得超5個贊

是的,像這樣:


def product(names, values, current=[])

  pos = len(current)

  if pos >= len(names):

     # a solution

     solutions.append(current.copy())

     return

  for v in values[pos]:

    current.append((names[pos], v)

    product(names, values, current)

    current.pop()


查看完整回答
反對 回復 2023-03-16
  • 2 回答
  • 0 關注
  • 149 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號