最小化方差python

时间:2017-10-06 16:10:03

标签: python variance minimization

不确定如何处理此问题。我有一个数字列表(确切的数字列表),但这些数字有一个歧义:x,x + 1和x-1对我来说完全相同。但是,我想通过更改元素来最小化列表的方差。这是我到目前为止的想法(我知道它不起作用的样本列表):

import numpy as np
from scipy import stats

lst = [0.474, 0.122, 0.0867, 0.896, 0.979]
def min_var(lst):
    mode = np.mean(lst)
    var = np.var(lst)
    result = []
    for item in list(lst):
        if item < mean: # not sure this is a good test
            new_item = item + 1
        elif item > mean:
            new_item = item - 1
        else:
            new_item = item
        new_list = [new_item if x==item else x for x in lst]
        new_var = np.var(new_list)
        if new_var < var:
            var = new_var
            lst = new_list
    return lst

该功能的作用是将第1个元素添加1。但是,当您从第4和第5中减去1时,会出现最小方差。这是因为我在每个项目之后最小化方差,不允许多次更改。我怎样才能实现多项更改,最好不要考虑所有可能的解决方案(3 ** n,如果我没有弄错的话)? 非常感谢

2 个答案:

答案 0 :(得分:0)

您可以将此视为一个问题,即找到最小化delta var((x + delta) % 1) x数组值的delta - 1 <= x[i] < delta。然后,从值中添加和减去整数,直到它们位于delta范围内。这不是scipy.optimize的连续函数,因此您无法使用var((x + delta) % 1)中的求解器。但我们可以使用x的值仅在x的每个值处更改的信息,这意味着我们只需要将delta中的每个值作为可能的import numpy as np x = np.array([0.474, 0.122, 0.0867, 0.896, 0.979]) # find the value of delta delta = x[0] min_var = np.var((x - delta) % 1) for val in x: current_var = np.var((x - val) % 1) if current_var < min_var: min_var = current_var delta = val print(delta) # use `delta` to subtract and add the right integer from each value # we want values in the range delta - 1 <= val < delta for i, val in enumerate(x): while val >= delta: val -= 1. while val < delta - 1.: val += 1. x[i] = val print(x) 进行测试,然后找到最小化方差的那个。

[ 0.474   0.122   0.0867 -0.104  -0.021 ]

对于此示例,它会找到所需的0.0392解决方案,其方差为mydict = { "root['toto']": {'new_value': 'abcdef', 'old_value': 'ghijk'}, "test['aaa']": {'new_value': 'abcdef', 'old_value': 'ghijk'}, "root['bb']": {'new_value': 'abcdef', 'old_value': 'ghijk'}, "ccc": {'new_value': 'abcdef', 'old_value': 'ghijk'} } for key, value in mydict.items(): new_key = re.sub(r"(\w+\[')(\w+)('\])", r"\2", key) if new_key != key: mydict[new_key] = mydict.pop(key) # Remove the old entry and add the entry back with new key print mydict

答案 1 :(得分:0)

为了避免每次计算新的var(O(n²)),您可以看到当您影响xx+u的项目时,var会受u*(u/2+x-m-u/n)影响

所以这是一个准线性时间解决方案:

l=np.array([0.474, 0.122, 0.0867, 0.896, 0.979])
l.sort()
n=len(l)
m=np.mean(l)
print(l,np.var(l))
u=1 # increase little terms

for i in range(n):
   if u*(u/2+l[i]-m-u/n) < 0:
       l[i]= l[i] + u
       m = m+u/n # mean evolution
   else: u = -1  # decrease big terms

print(l,np.var(l))  

和运行:

[ 0.0867  0.122   0.474   0.896   0.979 ] 0.1399936064
[ 1.0867  1.122   1.474   0.896   0.979 ] 0.0392256064