2016-06-16 3 views
1

Я пытаюсь передать два массива для функции фитинга, которая принимает оба значения.Python - curve_fit дает неправильные коэффициенты

файл данных:

Колонка 1: Время Колонка 2: Температура Колонка 3: Объем Колонка 4: Давление

0.000,0.946,4.668,0.981 
0.050,0.946,4.668,0.981 
0.100,0.946,4.669,0.981 
0.150,0.952,4.588,0.996 
0.200,1.025,4.008,1.117 
0.250,1.210,3.093,1.361 
0.300,1.445,2.299,1.652 
0.350,1.650,1.803,1.887 
0.400,1.785,1.524,2.038 
0.450,1.867,1.340,2.145 
0.500,1.943,1.138,2.280 
0.550,2.019,0.958,2.411 
0.600,2.105,0.750,2.587 
0.650,2.217,0.542,2.791 
0.700,2.332,0.366,2.978 
0.750,2.420,0.242,3.116 
0.800,2.444,0.219,3.114 
0.850,2.414,0.219,3.080 

здесь код

import numpy as np 
from scipy.optimize import curve_fit 

# Importing the Data 
Time_Air1 = [] 
Vol_Air1 = [] 
Temp_Air1 = [] 
Pres_Air1 = [] 
with open('Good_Air_Run1.csv', 'r') as Air1: 
    reader = csv.reader(Air1, delimiter=',') 
    for row in reader: 
     Time_Air1.append(row[0]) 
     Temp_Air1.append(row[1]) 
     Vol_Air1.append(row[2]) 
     Pres_Air1.append(row[3]) 

# Arrays are now passable floats 
Time_Air1 = np.float32(np.array(Time_Air1)) 
Vol_Air1 = np.float32(np.array(Vol_Air1)) 
Temp_Air1 = np.float32(np.array(Temp_Air1)) 
Pres_Air1 = np.float32(np.array(Pres_Air1)) 

# fitting Model 
def model_Gamma(V, gam, C): 
    return -gam*np.log(V) + C 

# Air Data Fitting Data 
x1 = Vol_Air1 
y1 = Pres_Air1 

p0_R1 = (1.0 ,1.0) 
optR1, pcovR1 = curve_fit(model_Gamma, x1, y1, p0_R1) 
gam_R1, C_R1 = optR1 
gam_R1p, C_R1p = pcovR1 
y1Mair = model_Gamma2(x_air1, gam_R1, C_R1) 

вычислим гамма-коэффициент, но это не дает мне значение, которое я ожидаю, ~ 1.2. Это дает мне ~ 0.72

Да, это правильное значение, потому что мой друг вписывает данные в gnuplot и получает это значение.

Если у вас есть какая-либо информация, необходимая для фактического тестирования, я рад ее предоставить.

+0

* Если есть какая-либо информация необходима на самом деле попробовать это, я счастлив для его поставки *. Файл данных будет приятным. –

+0

@OliverW. Дайте мне один момент. – DarthLazar

+0

У вас есть два параметра, которые вам подходят: вы уверены, что они не (частично) вырождены. Вы сравнили значения для другой переменной, C? – Evert

ответ

1

Caveat: результат, полученный здесь для gamma (около 1,7), по-прежнему отклоняется от постулата 1.2. Этот ответ просто освещает источник возможных ошибок и показывает, как может выглядеть хорошая подгонка.

Вы пытаетесь подобрать данные, в которых зависимая переменная связана с независимой переменной моделью, похожей на модель адиабатических процессов для идеальных газов. Здесь, давление и объем Гасс связаны через

pressure * volume**gamma = constant 

Когда вы переставить левую часть и правую сторону, вы получите:

pressure = constant * volume**-gamma 

или в логарифмической форме:

log(pressure) = log(constant) - gamma * log(volume) 

Вы можете поместить данные давления в данные объема с помощью любой из этих двух форм, , но пригонка может быть не оптимальной из-за ошибок измерения. Одной из таких ошибок может быть фиксированное смещение (например, какой-либо твердый объект присутствует в стакане: шкала объема на стакане не будет точно представлять объем любой жидкости, которую вы вливаете в нее). Когда вы учитываете такие ошибки, часто время подгонки становится заметно лучше.

Ниже я показал установку ваших данных с использованием 3 моделей: первая - ваша модель, вторая учитывает смещение объема, а третья - не логарифмический вариант 2-й модели (это в основном 2-го уравнения, с дополнительным смещением объема). Обратите внимание, что в вашем коде, когда вы вписываетесь в то, что я называю model1, вы не передаете log(pressure) модели, что имело бы смысл только в том случае, если ваши данные о дате уже приведены в таблицу в логарифмическом масштабе.

>>> import numpy as np 
>>> from scipy.optimize import curve_fit 
>>> data = np.genfromtxt('/tmp/datafile.txt', 
...  names=('time', 'temp', 'vol', 'press'), delimiter=',', usecols=range(4)) 
>>> def model1(volume, gamma, c): 
...   return np.log(c) - gamma*np.log(volume) 
... 
>>> def model2(volume, gamma, c, volume_offset): 
...   return np.log(c) - gamma*np.log(volume + volume_offset) 
... 
>>> def model3(volume, gamma, c, volume_offset): 
...   return c * (volume + volume_offset)**(-gamma) 
... 
>>> vol, press = data['vol'], data['press'] 
>>> guess1, _ = curve_fit(model1, vol, np.log(press)) 
>>> guess2, _ = curve_fit(model2, vol, np.log(press)) 
>>> guess3, _ = curve_fit(model3, vol, press) 
>>> guess1, guess2, guess3 
(array([ 0.38488521, 2.04536926]), 
array([ 1.7269364 , 44.57369479, 4.44625865]), 
array([ 1.73186133, 45.20087949, 4.46364872])) 
>>> rms = lambda x: np.sqrt(np.mean(x**2)) 
>>> rms(press - np.exp(model1(vol, *guess1))) 
0.29464410744456304 
>>> rms(press - model3(vol, *guess3)) 
0.012672077620951249 

Обратите внимание, как guess2 и guess3 почти идентичны Последние две строки указывают на ошибку среднеквадратичного. Вы заметите, что он меньше для модели, которая учитывает смещение (если вы их замышляете, вы увидите, что размер подходит much лучше, чем при использовании model1 *).

adiabatic process - curve fitting

В качестве последнего замечания, посмотрите на numpy's excellent functions for importing data, как тот, я показал здесь (np.genfromtxt), так как они могут сэкономить много утомительных набрав, как я показал в этом коде.

Сноска: * при печати с использованием model1, не забудьте положить все обратно в линейном масштабе, как это:

plt.plot(vol, np.exp(model1(vol, *guess1))) 
Смежные вопросы