Python - непредвиденное поведение параметра формы в экстремальной форме - PullRequest
0 голосов
/ 21 сентября 2018

Я пытался приспособить распределение GEV к некоторому максимальному годовому стоку реки, используя функцию Scipy stats.genextreme, но я обнаружил странное поведение подбора.В зависимости от того, насколько малы ваши данные (т. Е. 1e-5 против 1e-1), возвращаемый параметр формы может существенно отличаться.Например:

import scipy as scipy
import numpy as np
from scipy.stats import genextreme as gev
from scipy.stats import gumbel_r as gumbel

#Set up arrays of values to fit curve to 
sample=np.random.rand(1,30) #Random set of decimal values 
smallVals = sample*1e-5     #Scale to smaller values 

#If the above is not creating different values, this instance of random numbers has:
bugArr = np.array([[0.25322987, 0.81952358, 0.94497455, 0.36295543, 0.72272746, 0.49482558,0.65674877, 0.40876558, 0.64952248, 0.23171052, 0.24645658, 0.35359126,0.27578928, 0.24820775, 0.69789187, 0.98876361, 0.22104156,0.40019593,0.0756707,  0.12342556, 0.3601186,  0.54137089,0.43477705, 0.44622486,0.75483338, 0.69766687, 0.1508741,  0.75428996, 0.93706003, 0.1191987]])
bugArr_small = bugArr*1e-5

#This array of random numbers gives the same shape parameter regardless 
fineArr = np.array([[0.7449611,  0.82376693, 0.32601009, 0.18544293, 0.56779629, 0.30495415,
        0.04670362, 0.88106521, 0.34013959, 0.84598841, 0.24454428, 0.57981437,
        0.57129427, 0.8857514,  0.96254429, 0.64174078, 0.33048637, 0.17124045,
        0.11512589, 0.31884749, 0.48975204, 0.87988863, 0.86898236, 0.83513966,
        0.05858769, 0.25889509, 0.13591874, 0.89106616, 0.66471263, 0.69786708]])
fineArr_small = fineArr*1e-5

#GEV fit for both arrays - shouldn't dramatically change distribution 
gev_fit      = gev.fit(sample)
gevSmall_fit = gev.fit(smallVals)

gevBug      = gev.fit(bugArr)
gevSmallBug = gev.fit(bugArr_small)

gevFine      = gev.fit(fineArr)
gevSmallFine = gev.fit(fineArr_small)

Я получаю следующий вывод для параметров GEV, оцененных для bugArr / bugArr_small и fineArr / fineArr_small:

Known bug array
Random values:         (0.12118250540401079, 0.36692231766996053, 0.23142400358716353)
Random values scaled:  (-0.8446554391074808, 3.0751769299431084e-06, 2.620390405092363e-06)

Known fine array
Random values:         (0.6745399522587823, 0.47616297212022757, 0.34117425062278584)
Random values scaled:  (0.6745399522587823, 4.761629721202293e-06, 3.411742506227867e-06)

Почему параметр формы изменяется так резко, когдаединственная разница в данных - это изменение в масштабировании?Я ожидал бы, что поведение будет соответствовать результатам FineArr (без изменения параметра формы и соответствующего масштабирования параметров местоположения и масштаба).Я повторил тест в Matlab, но результаты там совпадают с тем, что я ожидал (т.е. без изменений в параметре формы).

1 Ответ

0 голосов
/ 22 сентября 2018

Я думаю, я знаю, почему это может происходить.При подгонке можно передать начальные оценки параметров формы, см. Документацию для scipy.stats.rv_continuous.fit, где говорится «Начальные значения для любых параметров, характеризующих форму (те, которые не предоставлены, будут определены вызовом _fitstart»).(данные)). Нет значения по умолчанию. "Вот некоторый чрезвычайно уродливый, функциональный код, использующий мой сборщик статистических распределений pyeq3, который внутренне пытается использовать разные оценки, подбирать их и возвращать параметры для наилучшего nnlf из различных подгонок.Этот пример кода не показывает поведение, которое вы наблюдаете, и дает одинаковые параметры формы независимо от масштабирования.Вам нужно установить pyeq3 с "pip3 install pyeq3", чтобы запустить этот код.Код pyeq3 предназначен для ввода текста из веб-интерфейса на zunzun.com, так что держите нос - вот пример кода:

import numpy as np

#Set up arrays of values to fit curve to 
sample=np.random.rand(1,30) #Random set of decimal values 
smallVals = sample*1e-5     #Scale to smaller values 

#If the above is not creating different values, this instance of random numbers has:
bugArr = np.array([0.25322987, 0.81952358, 0.94497455, 0.36295543, 0.72272746, 0.49482558,0.65674877, 0.40876558, 0.64952248, 0.23171052, 0.24645658, 0.35359126,0.27578928, 0.24820775, 0.69789187, 0.98876361, 0.22104156,0.40019593,0.0756707,  0.12342556, 0.3601186,  0.54137089,0.43477705, 0.44622486,0.75483338, 0.69766687, 0.1508741,  0.75428996, 0.93706003, 0.1191987])
bugArr_small = bugArr*1e-5

#This array of random numbers gives the same shape parameter regardless 
fineArr = np.array([0.7449611,  0.82376693, 0.32601009, 0.18544293, 0.56779629, 0.30495415,
        0.04670362, 0.88106521, 0.34013959, 0.84598841, 0.24454428, 0.57981437,
        0.57129427, 0.8857514,  0.96254429, 0.64174078, 0.33048637, 0.17124045,
        0.11512589, 0.31884749, 0.48975204, 0.87988863, 0.86898236, 0.83513966,
        0.05858769, 0.25889509, 0.13591874, 0.89106616, 0.66471263, 0.69786708])
fineArr_small = fineArr*1e-5

bugArr_str = ''
for i in range(len(bugArr)):
    bugArr_str += str(bugArr[i]) + '\n'
bugArr_small_str = ''
for i in range(len(bugArr_small)):
    bugArr_small_str += str(bugArr_small[i]) + '\n'
fineArr_str = ''
for i in range(len(fineArr)):
    fineArr_str += str(fineArr[i]) + '\n'
fineArr_small_str = ''
for i in range(len(fineArr_small)):
    fineArr_small_str += str(fineArr_small[i]) + '\n'
import pyeq3

simpleObject_bugArr = pyeq3.IModel.IModel()
simpleObject_bugArr._dimensionality = 1
pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(bugArr_str, simpleObject_bugArr, False)
solver = pyeq3.solverService()
result_bugArr = solver.SolveStatisticalDistribution('genextreme', simpleObject_bugArr.dataCache.allDataCacheDictionary['IndependentData'][0], 'nnlf')
simpleObject_bugArr_small = pyeq3.IModel.IModel()
simpleObject_bugArr_small._dimensionality = 1
pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(bugArr_small_str, simpleObject_bugArr_small, False)
solver = pyeq3.solverService()
result_bugArr_small = solver.SolveStatisticalDistribution('genextreme', simpleObject_bugArr_small.dataCache.allDataCacheDictionary['IndependentData'][0], 'nnlf')

simpleObject_fineArr = pyeq3.IModel.IModel()
simpleObject_fineArr._dimensionality = 1
pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(fineArr_str, simpleObject_fineArr, False)
solver = pyeq3.solverService()
result_fineArr = solver.SolveStatisticalDistribution('genextreme', simpleObject_fineArr.dataCache.allDataCacheDictionary['IndependentData'][0], 'nnlf')

simpleObject_fineArr_small = pyeq3.IModel.IModel()
simpleObject_fineArr_small._dimensionality = 1
pyeq3.dataConvertorService().ConvertAndSortColumnarASCII(fineArr_small_str, simpleObject_fineArr_small, False)
solver = pyeq3.solverService()
result_fineArr_small = solver.SolveStatisticalDistribution('genextreme', simpleObject_fineArr_small.dataCache.allDataCacheDictionary['IndependentData'][0], 'nnlf')

print('ba',result_bugArr[1]['fittedParameters'])
print('ba_s',result_bugArr_small[1]['fittedParameters'])
print()
print('fa',result_fineArr[1]['fittedParameters'])
print('fa_s',result_fineArr_small[1]['fittedParameters'])
...