Estou usando Python e Numpy para calcular um polinômio de melhor ajuste de grau arbitrário. Eu passo uma lista de valores x, valores y e o grau do polinômio que desejo ajustar (linear, quadrático, etc.).
Isso funciona, mas também quero calcular r (coeficiente de correlação) e r-quadrado (coeficiente de determinação). Estou comparando meus resultados com a capacidade de linha de tendência de melhor ajuste do Excel e o valor de r quadrado que ele calcula. Usando isso, sei que estou calculando r-quadrado corretamente para o melhor ajuste linear (grau igual a 1). No entanto, minha função não funciona para polinômios com grau maior que 1.
O Excel é capaz de fazer isso. Como calculo r-quadrado para polinômios de ordem superior usando Numpy?
Esta é minha função:
import numpy
# Polynomial Regression
def polyfit(x, y, degree):
results = {}
coeffs = numpy.polyfit(x, y, degree)
# Polynomial Coefficients
results['polynomial'] = coeffs.tolist()
correlation = numpy.corrcoef(x, y)[0,1]
# r
results['correlation'] = correlation
# r-squared
results['determination'] = correlation**2
return results
fonte
Respostas:
A partir da documentação numpy.polyfit , é uma regressão linear adequada. Especificamente, numpy.polyfit com o grau 'd' ajusta uma regressão linear com a função média
E (y | x) = p_d * x ** d + p_ {d-1} * x ** (d-1) + ... + p_1 * x + p_0
Portanto, você só precisa calcular o R-quadrado desse ajuste. A página da Wikipedia sobre regressão linear fornece detalhes completos. Você está interessado em R ^ 2, que você pode calcular de algumas maneiras, provavelmente a mais fácil
Onde eu uso 'y_bar' para a média dos y, e 'y_ihat' para ser o valor de ajuste para cada ponto.
Não estou muito familiarizado com o numpy (geralmente trabalho com R), então provavelmente há uma maneira mais organizada de calcular seu R ao quadrado, mas o seguinte deve estar correto
fonte
R^2 = 1 - SS_err/SS_tot
,R^2 = SS_reg/SS_tot
sendo apenas um caso especial.Uma resposta muito tardia, mas apenas no caso de alguém precisar de uma função pronta para isso:
scipy.stats.linregress
ie
como na resposta de @Adam Marples.
fonte
From yanl (yet-another-library)
sklearn.metrics
tem umar2_score
função;fonte
r2_score([1,2,3],[4,5,7])
=-16
?Tenho usado isso com sucesso, em que xey são semelhantes a uma matriz.
fonte
Eu originalmente postei os benchmarks abaixo com o propósito de recomendar
numpy.corrcoef
, tolamente não percebendo que a pergunta original já usacorrcoef
e, na verdade, estava perguntando sobre ajustes polinomiais de ordem superior. Eu adicionei uma solução real para a questão polinomial r-quadrado usando modelos de estatísticas e deixei os benchmarks originais, que embora fora do tópico, são potencialmente úteis para alguém.statsmodels
tem a capacidade de calcular or^2
de um ajuste polinomial diretamente, aqui estão 2 métodos ...Para aproveitar ainda mais
statsmodels
, deve-se também olhar o resumo do modelo ajustado, que pode ser impresso ou exibido como uma rica tabela HTML no bloco de notas Jupyter / IPython. O objeto de resultados fornece acesso a muitas métricas estatísticas úteis, além dersquared
.Abaixo está minha resposta original, onde comparei vários métodos de regressão linear r ^ 2 ...
A função corrcoef usada na pergunta calcula o coeficiente de correlação ,,
r
apenas para uma única regressão linear, portanto, não aborda a questão der^2
para ajustes polinomiais de ordem superior. No entanto, pelo que vale a pena, descobri que, para a regressão linear, é de fato o método de cálculo mais rápido e diretor
.Estes foram os meus resultados timeit comparando um monte de métodos para 1000 pontos aleatórios (x, y):
r
cálculo direto )r
cálculo direto )r
cálculo direto )r
saída)O método corrcoef supera o cálculo de r ^ 2 "manualmente" usando métodos numpy. É> 5X mais rápido do que o método polyfit e ~ 12X mais rápido do que o scipy.linregress. Apenas para reforçar o que o numpy está fazendo por você, ele é 28 vezes mais rápido do que o python puro. Não sou muito versado em coisas como numba e pypy, então outra pessoa teria que preencher essas lacunas, mas acho que isso é muito convincente para mim que
corrcoef
é a melhor ferramenta para calcularr
uma regressão linear simples.Aqui está o meu código de benchmarking. Copiei e colei de um Notebook Jupyter (difícil não chamá-lo de Notebook IPython ...), então peço desculpas se alguma coisa quebrou no caminho. O comando mágico% timeit requer IPython.
fonte
statsmodels
e me desculpei pelo benchmarking desnecessário dos métodos de regressão linear r ^ 2, que mantive como informações interessantes, mas fora do tópico.np.column_stack([x**i for i in range(k+1)])
pode ser vetorizado em numpy comx[:,None]**np.arange(k+1)
ou usando as funções vander de numpy que têm a ordem reversa nas colunas.R-quadrado é uma estatística que se aplica apenas à regressão linear.
Essencialmente, ele mede quanta variação em seus dados pode ser explicada pela regressão linear.
Assim, você calcula a "Soma Total dos Quadrados", que é o desvio quadrático total de cada uma das variáveis de resultado de sua média. . .
\ sum_ {i} (y_ {i} - y_bar) ^ 2
onde y_bar é a média dos y's.
Então, você calcula a "soma dos quadrados da regressão", que é o quanto seus valores FITTED diferem da média
\ sum_ {i} (yHat_ {i} - y_bar) ^ 2
e encontre a proporção desses dois.
Agora, tudo que você teria que fazer para um ajuste polinomial é conectar o y_hat desse modelo, mas não é preciso chamar isso de r ao quadrado.
Aqui está um link que encontrei que fala um pouco sobre isso.
fonte
O artigo da Wikipedia sobre r-quadrados sugere que ele pode ser usado para ajuste de modelo geral, em vez de apenas regressão linear.
fonte
Aqui está uma função para calcular o r-quadrado ponderado com Python e Numpy (a maior parte do código vem de sklearn):
Exemplo:
saídas:
Isso corresponde à fórmula ( espelho ):
com f_i é o valor previsto do ajuste, y_ {av} é a média dos dados observados y_i é o valor dos dados observados. w_i é a ponderação aplicada a cada ponto de dados, geralmente w_i = 1. SSE é a soma dos quadrados devido ao erro e SST é a soma total dos quadrados.
Se estiver interessado, o código em R: https://gist.github.com/dhimmel/588d64a73fa4fef02c8f ( espelho )
fonte
Aqui está uma função python muito simples para calcular R ^ 2 a partir dos valores reais e previstos, assumindo y e y_hat são séries pandas:
fonte
Da fonte scipy.stats.linregress. Eles usam o método da soma média dos quadrados.
fonte
Você pode executar este código diretamente, ele encontrará o polinômio e o valor R. Você pode colocar um comentário abaixo se precisar de mais explicações.
fonte