Я изучил вопрос Графики распределения наилучшего соответствия и обнаружил, что в ответах использовался критерий Колмогорова-Смирнова для нахождения распределения наилучшего соответствия. Я также узнал, что есть тест Андерсона-Дарлинга, который также используется для получения наилучшего распределения соответствия. Итак, у меня есть несколько вопросов:
Вопрос 1:
Если я хочу объединить оба теста, как я могу это сделать? Какие параметры лучше всего использовать для поиска наиболее подходящего распределения? Вот моя попытка объединить оба теста.
from statsmodels.stats.diagnostic import anderson_statistic as adtest
def get_best_distribution(data):
dist_names = ['alpha', 'anglit', 'arcsine', 'beta', 'betaprime', 'bradford', 'burr', 'cauchy', 'chi', 'chi2', 'cosine', 'dgamma', 'dweibull', 'erlang', 'expon', 'exponweib', 'exponpow', 'f', 'fatiguelife', 'fisk', 'foldcauchy', 'foldnorm', 'frechet_r', 'frechet_l', 'genlogistic', 'genpareto', 'genexpon', 'genextreme', 'gausshyper', 'gamma', 'gengamma', 'genhalflogistic', 'gilbrat', 'gompertz', 'gumbel_r', 'gumbel_l', 'halfcauchy', 'halflogistic', 'halfnorm', 'hypsecant', 'invgamma', 'invgauss', 'invweibull', 'johnsonsb', 'johnsonsu', 'ksone', 'kstwobign', 'laplace', 'logistic', 'loggamma', 'loglaplace', 'lognorm', 'lomax', 'maxwell', 'mielke', 'moyal', 'nakagami', 'ncx2', 'ncf', 'nct', 'norm', 'pareto', 'pearson3', 'powerlaw', 'powerlognorm', 'powernorm', 'rdist', 'reciprocal', 'rayleigh', 'rice', 'recipinvgauss', 'semicircular', 't', 'triang', 'truncexpon', 'truncnorm', 'tukeylambda', 'uniform', 'vonmises', 'wald', 'weibull_min', 'weibull_max', 'wrapcauchy']
dist_ks_results = []
dist_ad_results = []
params = {}
for dist_name in dist_names:
dist = getattr(st, dist_name)
param = dist.fit(data)
params[dist_name] = param
# Applying the Kolmogorov-Smirnov test
D_ks, p_ks = st.kstest(data, dist_name, args=param)
print("Kolmogorov-Smirnov test Statistics value for " + dist_name + " = " + str(D_ks))
# print("p value for " + dist_name + " = " + str(p_ks))
dist_ks_results.append((dist_name, p_ks))
# Applying the Anderson-Darling test:
D_ad = adtest(x=data, dist=dist, fit=False, params=param)
print("Anderson-Darling test Statistics value for " + dist_name + " = " + str(D_ad))
dist_ad_results.append((dist_name, D_ad))
print(dist_ks_results)
print(dist_ad_results)
for D in range (len(dist_ks_results)):
KS_D = dist_ks_results[D][1]
AD_D = dist_ad_results[D][1]
if KS_D < 0.25 and AD_D < 0.05:
best_ks_D = KS_D
best_ad_D = AD_D
if dist_ks_results[D][1] == best_ks_D:
best_ks_dist = dist_ks_results[D][0]
if dist_ad_results[D][1] == best_ad_D:
best_ad_dist = dist_ad_results[D][0]
print(best_ks_D)
print(best_ad_D)
print(best_ks_dist)
print(best_ad_dist)
print('\n################################ Kolmogorov-Smirnov test parameters #####################################')
print("Best fitting distribution (KS test): " + str(best_ks_dist))
print("Best test Statistics value (KS test): " + str(best_ks_D))
print("Parameters for the best fit (KS test): " + str(params[best_ks_dist])
print('################################################################################\n')
print('################################ Anderson-Darling test parameters #########################################')
print("Best fitting distribution (AD test): " + str(best_ad_dist))
print("Best test Statistics value (AD test): " + str(best_ad_D))
print("Parameters for the best fit (AD test): " + str(params[best_ad_dist]))
print('################################################################################\n')
Вопрос 2:
Как я могу получить p-значение для теста Андерсона-Дарлинга?
Вопрос 3:
Скажите, что мне удалось получить наиболее подходящий дистрибутив, как можно ранжировать распределения на основе тестов? как на фото ниже.
Тесты на соответствие требованиям с рейтингом
Редактировать 1
Я не уверен, но является ли normal_ad из общего теста Андерсона-Дарлинга statsmodel для какого-либо непрерывного распределения вероятности? Если да, я бы хотел выбрать общий дистрибутив для обоих тестов. Если я выполню те же шаги, что и в вопросе 1, будет ли это правильным подходом? Также, скажем, если я хочу найти наибольшее значение p, и оно является общим в обоих тестах, как я могу извлечь общее имя распределения с помощью значений p?
def get_best_distribution(data, sensor_no):
dist_names = ['beta', 'bradford', 'burr', 'cauchy', 'chi', 'chi2', 'erlang', 'expon', 'f', 'fatiguelife', 'fisk', 'gamma', 'genlogistic', 'genpareto', 'invgauss', 'johnsonsb', 'johnsonsu', 'laplace', 'logistic', 'loggamma', 'loglaplace', 'lognorm', 'maxwell', 'mielke', 'norm', 'pareto', 'reciprocal', 'rayleigh', 't', 'triang', 'uniform', 'weibull_min', 'weibull_max']
dist_ks_results = []
dist_ad_results = []
params = {}
for dist_name in dist_names:
dist = getattr(st, dist_name)
param = dist.fit(data)
params[dist_name] = param
# Applying the Kolmogorov-Smirnov test
D_ks, p_ks = st.kstest(data, dist_name, args=param)
print("Kolmogorov-Smirnov test Statistics value for " + dist_name + " = " + str(D_ks))
print("p value (KS test) for " + dist_name + " = " + str(p_ks))
dist_ks_results.append((dist_name, p_ks))
# Applying the Anderson-Darling test:
D_ad, p_ad = adnormtest(x=data, axis=0)
print("Anderson-Darling test Statistics value for " + dist_name + " = " + str(D_ad))
print("p value (AD test) for " + dist_name + " = " + str(p_ad))
dist_ad_results.append((dist_name, p_ad))
# select the best fitted distribution:
best_ks_dist, best_ks_p = (max(dist_ks_results, key=lambda item: item[1]))
best_ad_dist, best_ad_p = (max(dist_ad_results, key=lambda item: item[1]))
print('\n################################ Kolmogorov-Smirnov test parameters #####################################')
print("Best fitting distribution (KS test) :" + str(best_ks_dist))
print("Best p value (KS test) :" + str(best_ks_p))
print("Parameters for the best fit (KS test) :" + str(params[best_ks_dist]))
print('###########################################################################################################\n')
print('################################ Anderson-Darling test parameters #########################################')
print("Best fitting distribution (AD test) :" + str(best_ad_dist))
print("Best p value (AD test) :" + str(best_ad_p))
print("Parameters for the best fit (AD test) :" + str(params[best_ad_dist]))
print('###########################################################################################################\n')
if best_ks_dist == best_ad_dist:
best_common_dist = best_ks_dist
print('##################################### Both test parameters ############################################')
print("Best fitting distribution (Both test) :" + str(best_common_dist))
print("Best p value (KS test) :" + str(best_ks_p))
print("Best p value (AD test) :" + str(best_ad_p))
print("Parameters for the best fit (Both test) :" + str(params[best_common_dist]))
print('###########################################################################################################\n')
return best_common_dist, best_ks_p, params[best_common_dist]