2012-07-03 4 views
1

У меня есть два разных набора случайных распределенных экспериментальных данных. Мне нужно сделать одно из распределений максимально похожим на другое, применив некоторую функцию к каждому из своих значений. Пример функции: F (x) = x * (1+ (x + p1) * p2, где p1 и p2 - некоторые произвольные параметры. Чтобы выяснить, возможно ли и если да, то с какими значениями p1 и p2, я написал простой питон скрипт:.Оптимизация необычного алгоритма подгонки

#!/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') 

Я понимаю, что из всех возможных путей это самое уродливые и самая медленной к сожалению, у меня нет программирования фона на всех, и это мои первые скромные усилия. Учитывая, что среднее значение результирующего распределения является константой khown, число подходящих пар p1-p2 очень ограничено, но здесь я использую просто грубую силу. Думаю, должен быть какой-то способ выразить p2 как функцию p1, но я не знаю, как это сделать. Может быть, вы можете подумать над мной?
Извините за мой плохой английский ...

+0

Замечание: '... rstrip() ... для i в open ('1460.txt'). Readlines()' может быть просто '... для i в open ('1460.txt')' (нет необходимости в rstrip и readlines). Еще один момент: поскольку вы используете SciPy, у вас, вероятно, установлен NumPy, который может напрямую читать файлы с номерами. – EOL

+0

Вы также можете прочитать файлы с помощью функции 'numpy.loadtxt' и преобразователя. В более общем плане, используя массивы NumPy, вы получите «mean()» бесплатно, а также расчет вашей модели ('model = control * (1+ (control + p1) * p2)'). – EOL

+0

Большое спасибо, 'numpy.loadtxt' сделал его намного проще и удобочитаемо! – Axon

ответ

0

scipy.optimize твой друг, здесь.

Что вы обычно делаете, так это создать функцию, которая принимает два параметра (p1, p2) и возвращает значение, указывающее, насколько далеки два распределения (тестовое и измененное управление) друг от друга; в вашем случае это может быть (mean(model)-mean(test))**2. Функции минимизации SciPy дают вам параметры (p1, p2), которые минимизируют расстояние между двумя вашими дистрибутивами.

Возможно, вы захотите попробовать несколько функций минимизации, которые предлагает SciPy: некоторые работают лучше других, в зависимости от проблемы.

+0

Большое спасибо за ваш ответ. Я еще не понял фактического алгоритма, но, по крайней мере, сейчас у меня есть направление мысли. – Axon

Смежные вопросы