我为我的场景提出了一个更简单的虚拟示例,可以用数学方法解决我的示例,而不是使用优化器,但是让我们开头,我必须使用优化器。对不起,如果太详细了。
我有这个功能,它会根据两个列表,一个权重列表和一系列因素给我一个结果。
def validate_vector(vector, factors):
return sum([x * y for x, y in zip(vector, factors)])
我有一个3个元素的起点,但后来我引入了第四个元素。
initial_vector_weights = [.2, .3, .5]
initial_factors = [.09, .07, .01]
new_element_in_vector_weights = [.2, .3, .5, 0]
new_element_factors = [.09, .07, .01, .2]
每当添加一个新元素时,我最初会以零权重添加它,然后我需要验证并确保我的验证结果高于.05的阈值。如果是,我将新元素保持在0重量。
validate_weights(new_element_in_vector_weights, new_element_factors)
0.044
这个新增加的结果会导致0.05以下的验证,所以我不能将新元素保持为0,必须给它一个权重,使得我的验证是.05。我需要针对abs(validate_weights(new_element_in_vector_weights,new_element_factors) - .05)= 0的解决方案进行优化。
我有一些约束,所有权重必须是正数,并且必须总计为1。
cons = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1.0},
{'type': 'ineq', 'fun': lambda x: x})
我还有一个额外的约束,我必须以一种方式优化,从而将新元素权重(新的第4个)从0增加,但是以与初始权重成比例的方式减少我的初始权重
例如,这可能是我的例子
的解决方案[.2, .3, .5, 0]
[.18, .27, .45, .1]
其中old / new是一个常数比率,.2 / .18 = .3 / .27 = .45 / .5,我高于.05。
validate_weights([.18, .27, .45, .1], [.09, .07, .01, .2])
0.059600000000000014
然而,我希望第4个元素的重量能够让我完全接受.05。
我试图这样做,但这不起作用。
def calculate_proportional_weights(original_vector_weights, new_element_weight):
remaining_weight = 1 - new_element_weight
proportional_weights = [x * (1-new_element_weight) for x in original_vector_weights[:(len(original_vector_weights) - 1)]]
return proportional_weights
def prorated_weights_cons(original_weights, new_weights):
original_weights_core = original_weights[:len(original_weights) - 1]
new_weights_core = new_weights[:len(new_weights) -1]
H_new_weight = new_weights[-1]
redistributed_weights = calculate_proportional_weights(original_weights, H_new_weight)
return sum(redistributed_weights) + H_new_weight - 1
def min_validate_weights_objective(vector, factors):
validation_ = validate_vector(vector, factors)
val_to_min = abs(validation, .05)
return val_to_min
cons = ({'type': 'eq', 'fun': prorated_weights_cons(new_element_in_vector_weights, new_element_factors)},
{'type': 'eq', 'fun': lambda x: np.sum(x) - 1.0},
{'type': 'ineq', 'fun': lambda x: x})
res = minimize(min_validate_weights_objective, new_element_in_vector_weights, args=[new_element_in_vector_weights, new_element_factors], method='SLSQP',constraints=cons,
options={'disp': False, 'ftol': .0000000001, 'eps' : .0000000001, 'maxiter':10000})
虽然我确定它还有其他问题,但是还是爆炸了。
TypeError: 'float' object is not callable
你们在这个场景中看到任何不正确的错误吗?非常感谢你!