找到合适的截止值

2024-09-24 22:30:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试实现Hampel tanh estimators来规范化高度不对称的数据。为此,我需要执行以下计算:

给定x-一个经过排序的数字列表和mx的中值,我需要找到a,这样x中大约70%的值都在(m-a; m+a)范围内。我们对x中的值分布一无所知。我使用numpy编写python,我的最佳想法是编写某种随机迭代搜索(例如,如Solis and Wets所述),但我怀疑有更好的方法,无论是以更好的算法形式还是作为就绪函数。我搜索了numpy和scipy的文档,但是没有找到任何有用的提示。在

编辑

Sethsuggested使用scipy.stats.mstats.trimbboth,但是在我的偏态分布测试中,这个建议不起作用:

from scipy.stats.mstats import trimboth
import numpy as np

theList = np.log10(1+np.arange(.1, 100))
theMedian = np.median(theList)

trimmedList = trimboth(theList, proportiontocut=0.15)
a = (trimmedList.max() - trimmedList.min()) * 0.5

#check how many elements fall into the range
sel = (theList > (theMedian - a)) * (theList < (theMedian + a))

print np.sum(sel) / float(len(theList))

输出为0.79(~80%,而不是70)


Tags: importnumpystatsnpscipy规范化estimatorstanh
3条回答

首先需要将所有小于平均值的值向右折叠,使分布对称化。然后您可以在此单面分布上使用标准scipy.stats函数:

from scipy.stats import scoreatpercentile
import numpy as np

theList = np.log10(1+np.arange(.1, 100))
theMedian = np.median(theList)

oneSidedList = theList[:]               # copy original list
# fold over to the right all values left of the median
oneSidedList[theList < theMedian] = 2*theMedian - theList[theList < theMedian]

# find the 70th centile of the one-sided distribution
a = scoreatpercentile(oneSidedList, 70) - theMedian

#check how many elements fall into the range
sel = (theList > (theMedian - a)) * (theList < (theMedian + a))

print np.sum(sel) / float(len(theList))

这将根据需要给出0.7的结果。在

你想要的是scipy.stats.mstats.trimboth。设置proportiontocut=0.15。修剪后,取(max-min)/2。在

稍微重申一下这个问题。你知道列表的长度和列表中要考虑的数字的分数。鉴于此,您可以确定列表中第一个和最后一个索引之间的差异,这些索引为您提供了所需的范围。然后,目标是找到指标,使成本函数最小化,对应于中位数的期望对称值。在

让较小的索引是n1,而大索引是n2;它们不是独立的。索引列表中的值是x[n1] = m-b和{}。现在要选择n1(因此n2),以便b和{}尽可能接近。当(b - c)**2最小时会发生这种情况。使用numpy.argmin很容易。与问题中的示例类似,下面是一个交互式会话,演示了该方法:

$ python
Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01)
[GCC 4.3.4 20090804 (release) 1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> theList = np.log10(1+np.arange(.1, 100))
>>> theMedian = np.median(theList)
>>> listHead = theList[0:30]
>>> listTail = theList[-30:]
>>> b = np.abs(listHead - theMedian)
>>> c = np.abs(listTail - theMedian)
>>> squaredDiff = (b - c) ** 2
>>> np.argmin(squaredDiff)
25
>>> listHead[25] - theMedian, listTail[25] - theMedian
(-0.2874888056626983, 0.27859407466756614)

相关问题 更多 >