2012-07-03 67 views
1

我有两组不同的随机分布实验数据。我需要通过对其每个值应用一些函数,使其中一个分布与另一个分布尽可能相似。函数举例:F(x)= x *(1+(x + p1)* p2,其中p1和p2是一些任意的参数,要找出它是否可能,如果是,那么p1和p2,我写了一个简单的Python脚本:非常规拟合算法的优化

#!/usr/bin/python 
from scipy.stats import ks_2samp 
from frange import frange 
control = [float(i.rstrip().replace(',', '.')) for i in open('control.txt').readlines()] 
test = [float(i.rstrip().replace(',', '.')) for i in open('1460.txt').readlines()] 
def mean(x): 
    res = sum(x)/len(x) 
    return res 
def testargs(p1, p2): 
    model = [i*(1+(i+p1)*p2) for i in control] 
    if round(mean(model), 4) == round(mean(test), 4): 
     return True 
    else: 
     return False 
results = {} 
for p1 in frange(0, 0.02, 0.001): 
    for p2 in frange(5, 20, 0.01): 
     if testargs(p1, p2): 
      ks = ks_2samp([i*(1+(i+p1)*p2) for i in control], test)[1] 
      results[ks] = (p1, p2) 
result = sorted(results.keys(), reverse=True)[0] 
print('Result: ', result, '\n', 'p1, p2: ', results[result], '\n') 

据我了解,所有可能的方式,这是最丑的和最慢的一个不幸的是,我根本没有编程背景,这是我的第一个卑微的努力。考虑到由此产生的分布的平均值是一个常数,适当的p1-p2对的数量是非常有限的,但我在这里使用了一个简单的蛮力。我认为,应该有某种方式来表示p2作为p1,但是我完全不知道该怎么做,也许你可以想一想我吗?
对不起,我的英语不好......

+0

边注:'... rstrip()可以...对于我在开( '1460.txt')readlines方法()'可能是简单的'......因为我在开( '1460.txt')'(无需rstrip和readlines)。另一点:由于您使用的是SciPy,您可能已经安装了NumPy,它可以直接读取带有数字的文件。 – EOL

+0

你也可以用'numpy.loadtxt'和一个转换函数读取这些文件。更一般地,使用NumPy的阵列会给你'平均()'自由,以及对模型的计算('模型=控制*(1+(控制+ P1)* P2)')。 – EOL

+0

非常感谢,'numpy.loadtxt'使它更加简单易读! – Axon

回答

0

scipy.optimize是你的朋友,在这里。

您通常会做什么是创建一个功能采用两个参数(P1,P2)并返回一个值,它指示两个分布(试验和改进的控制)多远彼此;在你的情况下,这可以是(mean(model)-mean(test))**2。 SciPy最小化函数为您提供最小化两个分布之间距离的参数(p1,p2)。

您可能想尝试一些SciPy提供的最小化函数:根据问题,某些工作比其他工作更好。

+0

非常感谢您的回答。我还没有弄清楚实际的算法,但至少我现在有一个思路。 – Axon