Как я могу минимизировать -p-значение в python, предоставляемое тестом kstest для одного дистрибутива, основываясь на возврате данных? - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь загрузить из библиотеки pandas datareader цену акций и рассчитать доход (ежедневно, еженедельно, ежемесячно и т. Д. c ...) на основе предоставленного мной тикера.

После загрузки данных я выполняю kstest при распределении этих данных и оцениваю, является ли он похожим на бинарное распределение (сумма двух нормальных распределений), основываясь на предоставленном p-значении.

Поскольку я я выполняю только один тест kstest для этого распределения. Я хочу максимизировать p-значение (минимизировать -p-значение), используя библиотеку «минимизации» в Python, меняя значения среднего, стандартного отклонения и веса этого двух распределений.

import warnings
import numpy as np
import pandas as pd
import scipy.stats as st
from scipy.optimize import minimize
import statsmodels as sm
import matplotlib
import matplotlib.pyplot as plt
from pandas_datareader import data
import time
import xlwt
import matplotlib.ticker as mtick
from sklearn import datasets

def Puxa_Preco(ticker,start_date,end_date,lag):    
    dados= data.get_data_yahoo(ticker, start_date, end_date )

    from sklearn import datasets
    data_set =  np.log(dados['Close'])-np.log(dados['Close'] .shift(lag))

    data_set = data_set.fillna(method='ffill') 
    data_set = data_set.dropna() 

    y = pd.DataFrame()
    y=data_set

    x = np.arange(len(y))
    size = len(y)
    print(y)
    return y

def mixnormal_cdf(distribuicao, weight1, mean1, stdv1,weight2, mean2, stdv2):
    """
    CDF of a mixture of two normal distributions.
    """
    return (weight1*st.norm.cdf(distribuicao, mean1, stdv1) +
            weight2*st.norm.cdf(distribuicao, mean2, stdv2))

def Objetivo(X,distribuicao):
    peso_dist_1 = X[0]
    mi1 = X[1]
    sigma1 = X[2]
    peso_dist_2 = 1-X[0]
    mi2 = X[3]
    sigma2 = X[4]

    stat2, pvalue = st.kstest(distribuicao, cdf=mixnormal_cdf,
                                args=(peso_dist_1, mi1, sigma1,peso_dist_2, mi2, sigma2))
    ''' Kolmogorov-Smirnov Test, to test whether or not the data is from a given distribution. The 
        returned p-value indicates the probability that the data is from the given distribution, 
        i.e. a low p-value means the data are likely not from the tested distribution.
        Note that, for this test, it is necessary to specify shape, location, and scale parameters,
        to obtain meaningful results (c,loc,scale). 

        stat2:     the test statistic, e.g. the max distance between the
        cumulated distributions '''

    return -pvalue

ticker = 'PETR4.SA'
start_date  = '2010-01-02'      #yyyy-mm-dd
end_date    = '2015-01-02'

for lag in range(1,503):

    distribuicao = Puxa_Preco(ticker,start_date,end_date,lag)
    n = len(distribuicao)

    ChuteInicial=[0.3,0.0010,0.0010,-0.0030,0.0830]                                      #peso_dist_1, mi1, sigma1, mi2, sigma2
    test = [0.2,0.0020,0.0110,0.8,-0.0020,0.0230]
    Limites = ([0,1],[-50,+50],[0,+50],[0,1],[-50,+50],[0,+50])                              #peso_dist_1, mi1, sigma1, peso_dist_2,mi2, sigma2
    print("------------------------------------------------------------------------------------------------")
    print("Validation Test:")

    print(-Objetivo(test,distribuicao))                                             #the value should be around -0.90 to verify that the objective function it is ok

    solution = minimize(fun=Objetivo,x0=ChuteInicial,args=distribuicao,method='SLSQP',bounds = Limites)             #minimize - p-valor
    print("------------------------------------------------------------------------------------------------")
    print("solution:")
    print(solution)

Находим следующее решение:

         fun: -8.098252265651002e-53
         jac: array([-2.13080032e-35,  0.00000000e+00,  0.00000000e+00, -1.93307671e-34, 7.91878934e-35])
     message: 'Optimization terminated successfully.'
        nfev: 8
         nit: 1
        njev: 1
      status: 6
     success: True
           x: array([ 0.3  ,  0.001,  0.001, -0.003,  0.083])

Но я знаю, что правильный ответ должен быть примерно таким (тест): [0.2,0.0020,0.0110,0.8, -0.0020,0.0230] получение p-значения 0,90

Мне кажется, что он выполняет только несколько симуляций и, поскольку он не меняет P-значение, он останавливается.

Есть ли способ что я с гарантировать, что «сворачивание» прекратится только после нахождения значения p больше 0,9? Может кто-нибудь, пожалуйста, помогите мне?

Я пытался использовать метод минимизации с учетом Nelder Mead, и кажется более точным, но даже не близким к 0,9 p-значению, которое должно быть ответом, и я не знаю если метод Nelder Mead учитывает ограничения, которые я предоставил.

#solution = minimize(fun=Objetivo,x0=(ChuteInicial),args=distribuicao,method='Nelder-Mead',bounds = Limites,options={'int':1000000})            

Ответы [ 2 ]

0 голосов
/ 16 апреля 2020

Я нашел способ обеспечить это, но это не самый разумный способ ...

  for lag in range(1,10):
     distribuicao = Puxa_Preco(ticker,start_date,end_date,lag)
     delta1 = 0
     delta2 = 0
     delta3 = 0
     for j in range(1,101): 
        ChuteInicial=[0.05+delta1,0.0010+delta2,0.0010+delta3,-0.0030+delta2,0.0830+delta3]                                      #peso_dist_1, mi1, sigma1, mi2, sigma2

        Limites = ([0,1],[-0.5,+0.5],[0,None],[-0.5,0.5],[0,None])                              #peso_dist_1, mi1, sigma1, peso_dist_2,mi2, sigma2

        print("------------------------------------------------------------------------------------------------")
        print("------------------------------------Lag " + str(lag) + " -------------------------------------")
        print("------------------------------------------------------------------------------------------------")
        print("Intial Guess")
        print(" weight1: {:.4f}, mean1: {:.4f}, stdv1: {:.4f}, mean2: {:.4f}, stdv2: {:.4f}".format(*ChuteInicial))
        ks_stat, p_value = st.kstest(distribuicao, cdf=mixnormal_cdf, args=ChuteInicial)
        print("k-s stat: {}, p-value: {}".format(ks_stat, p_value))
        print("------------------------------------------------------------------------------------------------")

        solution = minimize(fun=Objetivo,x0=ChuteInicial,args=(distribuicao), method='SLSQP',bounds = Limites)             #minimize - p-valor

        print("Optimized Solution:")
        print("------------------------------------------------------------------------------------------------")
        print(solution)
        ks_stat, p_value = st.kstest(distribuicao, cdf=mixnormal_cdf, args=solution.x)
        print("Optimized k-s stat: {}, p-value: {}".format(ks_stat, p_value))
        print("Optimized weight1: {:.4f}, mean1: {:.4f}, stdv1: {:.4f}, mean2: {:.4f}, stdv2: {:.4f}".format(*solution.x))
        print("------------------------------------------------------------------------------------------------")
        if ((p_value <= 0.9) or (ks_stat >= 0.02)):
          delta1 += 0.005
          delta2 += 0.001
          delta3 += 0.001
        else:

          break
0 голосов
/ 15 апреля 2020

Благодаря возможности минимизировать ks statisti c вместо p-значения и других модификаций в определении функции cdf, я думаю, что я смог оценить параметры. Вот мой код и оптимизированные оценки параметров. Я получил идею минимизировать ks statisti c из этой статьи (https://www.researchgate.net/publication/250298633_Minimum_Kolmogorov-Smirnov_test_statistic_parameter_estimates)

import warnings
import numpy as np
import pandas as pd
import scipy.stats as st
from scipy.optimize import minimize
import statsmodels as sm
import matplotlib
import matplotlib.pyplot as plt
from pandas_datareader import data
import time
import xlwt
import matplotlib.ticker as mtick
from sklearn import datasets

def Puxa_Preco(ticker,start_date,end_date,lag):    
    dados= data.get_data_yahoo(ticker, start_date, end_date )

    data_set =  np.log(dados['Close'])-np.log(dados['Close'] .shift(lag))

    data_set = data_set.fillna(method='ffill') 
    data_set = data_set.dropna() 

    y = pd.DataFrame()
    y=data_set

    x = np.arange(len(y))
    size = len(y)

    return y

def mixnormal_cdf(distribuicao, weight1, mean1, stdv1,mean2, stdv2):
    ## CDF of a mixture of two normal distributions.

    return (weight1*st.norm.cdf(distribuicao, mean1, stdv1) +
            (1-weight1)*st.norm.cdf(distribuicao, mean2, stdv2))

def Objetivo(X, distribuicao):
    stat2, pvalue = st.kstest(distribuicao, cdf=mixnormal_cdf, args=X)
    return stat2

ticker = 'PETR4.SA'
start_date  = '2010-01-02'      #yyyy-mm-dd
end_date    = '2015-01-02'

for lag in range(1,10):
    distribuicao = Puxa_Preco(ticker,start_date,end_date,lag)

    ChuteInicial=[0.2,0.0020,0.0110,-0.0020,0.0230]                                      #peso_dist_1, mi1, sigma1, mi2, sigma2

    Limites = ([0,1],[-0.1,+0.1],[0,None],[-0.1,0.1],[0,None])                              #peso_dist_1, mi1, sigma1, peso_dist_2,mi2, sigma2

    print("------------------------------------------------------------------------------------------------")
    print("Intial Guess")
    print(" weight1: {:.4f}, mean1: {:.4f}, stdv1: {:.4f}, mean2: {:.4f}, stdv2: {:.4f}".format(*ChuteInicial))
    ks_stat, p_value = st.kstest(distribuicao, cdf=mixnormal_cdf, args=ChuteInicial)
    print("k-s stat: {}, p-value: {}".format(ks_stat, p_value))
    print("------------------------------------------------------------------------------------------------")

    solution = minimize(fun=Objetivo,x0=ChuteInicial,args=(distribuicao), method='SLSQP',bounds = Limites, options={'ftol':1e-12})

    print("Optimized Solution:")
    print("------------------------------------------------------------------------------------------------")
    print(solution.message)
    ks_stat, p_value = st.kstest(distribuicao, cdf=mixnormal_cdf, args=solution.x)
    print("Optimized k-s stat: {}, p-value: {}".format(ks_stat, p_value))
    print("Optimized weight1: {:.4f}, mean1: {:.4f}, stdv1: {:.4f}, mean2: {:.4f}, stdv2: {:.4f}".format(*solution.x))
    print("------------------------------------------------------------------------------------------------")

, что приводит к

 LAG: 1
------------------------------------------------------------------------------------------------
Intial Guess
 weight1: 0.2000, mean1: 0.0020, stdv1: 0.0110, mean2: -0.0020, stdv2: 0.0230
k-s stat: 0.016419395777755863, p-value: 0.9027260234690881
------------------------------------------------------------------------------------------------
Optimized Solution:
------------------------------------------------------------------------------------------------
Optimization terminated successfully.
Optimized k-s stat: 0.014896801186217778, p-value: 0.952748910069967
Optimized weight1: 0.2016, mean1: 0.0016, stdv1: 0.0108, mean2: -0.0017, stdv2: 0.0227
------------------------------------------------------------------------------------------------
LAG: 2
------------------------------------------------------------------------------------------------
Intial Guess
 weight1: 0.2000, mean1: 0.0020, stdv1: 0.0110, mean2: -0.0020, stdv2: 0.0230
k-s stat: 0.0791846286223467, p-value: 5.496852766236095e-07
------------------------------------------------------------------------------------------------
Optimized Solution:
------------------------------------------------------------------------------------------------
Optimization terminated successfully.
Optimized k-s stat: 0.013690695822088705, p-value: 0.978164746056248
Optimized weight1: 0.2291, mean1: -0.0047, stdv1: 0.0125, mean2: -0.0012, stdv2: 0.0351
------------------------------------------------------------------------------------------------
LAG: 3
------------------------------------------------------------------------------------------------
Intial Guess
 weight1: 0.2000, mean1: 0.0020, stdv1: 0.0110, mean2: -0.0020, stdv2: 0.0230
k-s stat: 0.13436209329730314, p-value: 2.533666062868497e-19
------------------------------------------------------------------------------------------------
Optimized Solution:
------------------------------------------------------------------------------------------------
Optimization terminated successfully.
Optimized k-s stat: 0.01622740259609401, p-value: 0.9106251238446841
Optimized weight1: 0.2638, mean1: -0.0058, stdv1: 0.0199, mean2: -0.0020, stdv2: 0.0433
------------------------------------------------------------------------------------------------
...