首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >最小方差python

最小方差python
EN

Stack Overflow用户
提问于 2017-10-06 16:10:02
回答 2查看 1.4K关注 0票数 0

不知道该怎么做。我有一个数字列表(确切地说是一个数字列表),但是这些数字有一个歧义: x,x+1和x-1对我来说是完全一样的。但是,我想通过更改元素来最小化列表的差异。到目前为止,我的想法如下(有一个样本列表,我知道它不起作用):

代码语言:javascript
代码运行次数:0
运行
复制
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添加到第三个元素中。然而,当你从第4和第5减去1时,就会出现最小的方差。之所以会出现这种情况,是因为我正在将每个项目之后的差异最小化,而不允许进行多个更改。我如何实现多个更改,最好不考虑所有可能的解决方案(3**n,如果我没有弄错的话)?非常感谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-06 16:52:15

您可以将此视为查找最小化deltavar((x + delta) % 1)的问题,其中x是您的值数组。然后从值中添加和减去整数,直到它们位于delta - 1 <= x[i] < delta范围内。这不是delta的一个连续函数,所以您不能像在scipy.optimize中那样使用求解器。但是我们可以使用var((x + delta) % 1)值仅在x的每个值上变化的信息,这意味着我们只需要测试x中的每个值作为一个可能的delta,并找到一个使方差最小化的值。

代码语言:javascript
代码运行次数:0
运行
复制
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的变化很大。

票数 0
EN

Stack Overflow用户

发布于 2017-10-06 17:41:47

为了避免每次计算新的变量(O(n平方)),您可以看到,当您影响从xx+u的项目时,变量会像u*(u/2+x-m-u/n)一样受到影响。

这里有一个准线性时间解:

代码语言:javascript
代码运行次数:0
运行
复制
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))  

而跑步:

代码语言:javascript
代码运行次数:0
运行
复制
[ 0.0867  0.122   0.474   0.896   0.979 ] 0.1399936064
[ 1.0867  1.122   1.474   0.896   0.979 ] 0.0392256064
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46609853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档