diff --git "a/(Jo\303\243o_Marcos_M_Ribeiro)Tradu\303\247\303\243o_de_Models_Quick_Fit.ipynb" "b/(Jo\303\243o_Marcos_M_Ribeiro)Tradu\303\247\303\243o_de_Models_Quick_Fit.ipynb" new file mode 100644 index 0000000..caa0b95 --- /dev/null +++ "b/(Jo\303\243o_Marcos_M_Ribeiro)Tradu\303\247\303\243o_de_Models_Quick_Fit.ipynb" @@ -0,0 +1,998 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JEokaUCSLnR1" + }, + "source": [ + "# Modelo 1: fazer um rápido ajuste usando astropy.modeling\n", + "\n", + "## Autores\n", + "Rocio Kiman, Lia Corrales, Zé Vinícius, Kelle Cruz, Stephanie T. Douglas\n", + "\n", + "#Tradução\n", + "\n", + "João Marcos Modesto Ribeiro\n", + "\n", + "## Objetivo do aprendizado\n", + "* Uso do `astroquery` para baixar os dados do Vizier.\n", + "* Uso de modelos basicos em `astropy.modeling´.\n", + "* Aprender funções comuns para o ajuste. \n", + "* Gerar um ajuste rápido para os dados.\n", + "* Plotar o modelo com os dados data.\n", + "* Comparar diferentes modelos e fittros.\n", + "\n", + "## Palavras chaves\n", + "modelagem, ajuste de modelo, astrostatística, astroquery, Vizier, scipy, matplotlib, barras de erro, gráficos de dispersão.\n", + "\n", + "## Objetivo\n", + "Neste tutorial, nós iremos nos familiarizar com modelos disponiveis em [astropy.modeling](http://docs.astropy.org/en/stable/modeling/ ) e aprendermos como fazer um ajuste rápido para nossos dados." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5ZYL2UHrLnR7" + }, + "source": [ + "### Pacotes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "D5lcB1YLLnR8" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from astropy.modeling import models, fitting\n", + "from astroquery.vizier import Vizier\n", + "import scipy.optimize\n", + "# Fazer estrutura de plots nos notebooks\n", + "%matplotlib inline " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fONHcszZLnR-" + }, + "source": [ + "## 1) Ajustando um modelo linear: Três passos para ajustar dados usando astropy.modeling" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4csPto6KLnR-" + }, + "source": [ + "Vamos começar com um **ajuste linear para dados reais**. Os dados vem de um paper [Bhardwaj et al. 2017](https://ui.adsabs.harvard.edu/?#abs/2017A%26A...605A.100B). Este é um catalogo de **Cefeidas Tipo II**, que é um tipo de **estrelas variáveis** que pulsam com um periodo entre 1 e 50 dias. Nesta parte do tutorial, Nós vamos medir a relação do ** Periodo-Luminosidade das Cefeidas** usando `astropy.modeling. Esta relação afirma que se uma estrela tem um período mais longo, a luminosidade que medimos é maior.\n", + "\n", + "Para obtê-lo , nós vamos importar do [Vizier](http://vizier.u-strasbg.fr/viz-bin/VizieR) usando [astroquery](http://astroquery.readthedocs.io/en/latest/vizier/vizier.html)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "cFupFneHLnR_" + }, + "outputs": [], + "source": [ + "catalog = Vizier.get_catalogs('J/A+A/605/A100')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "W-jSkpMyLnR_" + }, + "source": [ + "Este catálogo contém muitas informações, mas para este tutorial vamos trabalhar apenas com períodos e magnitudes. Vamos tomá-las usando as palvaras chaves `'Periodo'` and `__Ksmag__`. Note que `'e__Ksmag_'` se refere às barras de erro nas medidas de magnitude." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "P_FptMfjLnSA" + }, + "outputs": [], + "source": [ + "period = np.array(catalog[0]['Period']) \n", + "log_period = np.log10(period)\n", + "k_mag = np.array(catalog[0]['__Ksmag_'])\n", + "k_mag_err = np.array(catalog[0]['e__Ksmag_'])" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eEfnjdTBLnSB" + }, + "source": [ + "Vamos olhar as medidas de magnitude como função do período" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "PsC4Isb6LnSC" + }, + "outputs": [], + "source": [ + "plt.errorbar(log_period, k_mag, k_mag_err, fmt='k.')\n", + "plt.xlabel(r'$\\log_{10}$(Period [days])')\n", + "plt.ylabel('Ks')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mWFEzQ_zLnSD" + }, + "source": [ + "Poderia-se dizer que existe uma relação linear o periodo logaritimo ae magnitudes. Para provar isso, nós queremos fazer um ajuste para os dados. This is where `astropy.modeling` é util. Nós vamos entender como em três linhas simples , nós podemos fazer qualquer ajuste que nós queremos. Nós vamos começar com o ajuste linear , mas primeiro, vamos entender o que o modelo e o ajustador são." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YZGB1pK_LnSE" + }, + "source": [ + "### Modelos em Astropy\n", + "[Modelos](http://docs.astropy.org/en/stable/modeling/#using-models) em Astropy are funções parametri8zadas conhecidas. Com este formato, eles asão faceis para definir e para usar, dados que não precisamos escrever a expressão da função todo tempo que queremos usar no modelo, justo o nome. Eles podem ser lineares ou não lineares nas variaveis. São alguns exemplos de modelos:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4Ev0WisiLnSF" + }, + "source": [ + "* [Gaussian1D](http://docs.astropy.org/en/stable/api/astropy.modeling.functional_models.Gaussian1D.html#astropy.modeling.functional_models.Gaussian1D)\n", + "* [Trapezoid1D](http://docs.astropy.org/en/stable/api/astropy.modeling.functional_models.Trapezoid1D.html#astropy.modeling.functional_models.Trapezoid1D)\n", + "* [Polynomial1D](http://docs.astropy.org/en/stable/api/astropy.modeling.polynomial.Polynomial1D.html#astropy.modeling.polynomial.Polynomial1D)\n", + "* [Sine1D](http://docs.astropy.org/en/stable/api/astropy.modeling.functional_models.Sine1D.html#astropy.modeling.functional_models.Sine1D)\n", + "* [Linear1D](http://docs.astropy.org/en/stable/api/astropy.modeling.functional_models.Linear1D.html#astropy.modeling.functional_models.Linear1D)\n", + "* A [lista](http://docs.astropy.org/en/stable/modeling/#module-astropy.modeling.functional_models) continua." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xO8eXZ78LnSG" + }, + "source": [ + "Ajustadores em Astropy\n", + "\n", + "Ajustadores em Astropy são classes responsaveis por fazer o ajuste. Eles podem ser lineares ou não-lineares nos parãmetros (não na variavel, como os mopdelos). Alguns exemplos são:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "hpfKA8jHLnSH" + }, + "source": [ + "* [LevMarLSQFitter()](http://docs.astropy.org/en/stable/api/astropy.modeling.fitting.LevMarLSQFitter.html#astropy.modeling.fitting.LevMarLSQFitter) Algorimo de Levenberg-Marquardt e estatística de mínimos quadrados. \n", + "* [LinearLSQFitter()](http://docs.astropy.org/en/stable/api/astropy.modeling.fitting.LinearLSQFitter.html#astropy.modeling.fitting.LinearLSQFitter) Uma classe que executa um ajuste linear de mínimos quadrados.\n", + "* [SLSQPLSQFitter()](http://docs.astropy.org/en/stable/api/astropy.modeling.fitting.SLSQPLSQFitter.html#astropy.modeling.fitting.SLSQPLSQFitter) Algoritimo de otimização SLSQP e estatística de mínimos quadrados.\n", + "* [SimplexLSQFitter()](http://docs.astropy.org/en/stable/api/astropy.modeling.fitting.SimplexLSQFitter.html#astropy.modeling.fitting.SimplexLSQFitter) algoritimo Simplex e estatistica de minimos quadrados .\n", + "\n", + "* Mais detailhes [aqui](http://docs.astropy.org/en/stable/modeling/#id21)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "kaolG2RrLnSH" + }, + "source": [ + "Agora vamos continuar com nosso ajuste." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JkJM3EJpLnSI" + }, + "source": [ + "#### Passo 1: Modelo" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JGdAHLACLnSJ" + }, + "source": [ + "Primeiro, precisamos escolher qual modelo vamos usar para ajustar nossos dados. Como dissemos antes, nossos dados parecem uma relação linear, então vamos usar um modelo linear. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "iyhhDWjQLnSK" + }, + "outputs": [], + "source": [ + "model = models.Linear1D()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cHSksp8MLnSK" + }, + "source": [ + "#### Passo 2: Ajustador" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q2XrkSz7LnSL" + }, + "source": [ + "Em segundo lugar, vamos escolher o ajustador que queremos usar. Esta escolha é basicamente qual método queremos usar para ajustar o modelo aos dados. Neste caso, nós vamos usar o [Linear Least Square Fitting](https://www.mathworks.com/help/curvefit/least-squares-fitting.html). No proximo Exerciciso ([Modelo 2: Criando um Modelo de Usuario de Definido](http://learn.astropy.org/rst-tutorials/User-Defined-Model.html)) Nós vamos analisar como escolher o ajustador. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "RWRHJncILnSL" + }, + "outputs": [], + "source": [ + "fitter = fitting.LinearLSQFitter() " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dMsEIgGkLnSM" + }, + "source": [ + "#### Passo 3: Ajuste de dados " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "foBlWXVRLnSM" + }, + "source": [ + "Por fim, entregamos ao nosso **ajustador** (método para ajustar os dados) o **modelo** e os **dados** para realizar o ajuste. Observe que estamos incluindo pesos: Isso significa que valores com maior erro terão menor peso (menor importância) no ajuste, e o contrário para dados com erros menores. Essa forma de encaixe é chamada *Weighted Linear Least Squares* e vovê pode encontar mais informações sobre isto [aqui](https://www.mathworks.com/help/curvefit/least-squares-fitting.html) or [aqui](https://en.wikipedia.org/wiki/Least_squares#Weighted_least_squares)." ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true, + "id": "NHtNZCfLLnSN" + }, + "outputs": [], + "source": [ + "best_fit = fitter(model, log_period, k_mag, weights=1.0/k_mag_err**2)\n", + "print(best_fit)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "8q5paUbdLnSN" + }, + "source": [ + "E é isso !\n", + "\n", + "Nós podemos avaliar o ajuste do eixo x em particular pelo `best_fit(x)`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "0NYK6vZDLnSO" + }, + "outputs": [], + "source": [ + "plt.errorbar(log_period,k_mag,k_mag_err,fmt='k.')\n", + "plt.plot(log_period, best_fit(log_period), color='g', linewidth=3) \n", + "plt.xlabel(r'$\\log_{10}$(Period [days])')\n", + "plt.ylabel('Ks')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "C4hoFGtVLnSO" + }, + "source": [ + "**Conclusão:** Lembre, que você pode fazer um ajusate de dedos com tres linhas de codigo:\n", + "\n", + "1) Escolha um [modelo](http://docs.astropy.org/en/stable/modeling/#module-astropy.modeling.functional_models).\n", + "\n", + "2) Escolha o [ajustador](http://docs.astropy.org/en/stable/modeling/#id21).\n", + "\n", + "3)Passe para o ajustador o modelo e os dados para realizar o ajuste." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7bI4ksLOLnSP" + }, + "source": [ + "## Exercício" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "M5G4x0WwLnSP" + }, + "source": [ + "Use o modelo `Polynomial1D(degree=1)` para ajustar os mesmos dados e compare os resultados." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "02ExWlwWLnSP" + }, + "outputs": [], + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6yuXEJDTLnSQ" + }, + "source": [ + "## 2) Ajustando um modelo Polinomial: Escolha um ajustador corretamente \n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Z7Ays5GBLnSQ" + }, + "source": [ + "Para nosso segundo exemplo, vamos ajustar um polinõmio de grau maior que 1. Neste caso, vamos criar dados mascarados para fazer o ajuste. Note que nós adicionamos um ruido gaussiano para os dados com a função `np.random.normal(0,2)` onde é dado um numero aleatório da distribuição gaussiana com media 0 e desvio padrão 2." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "QvJmamvvLnSQ" + }, + "outputs": [], + "source": [ + "N = 100\n", + "x1 = np.linspace(0, 4, N) # Makes an array from 0 to 4 of N elements\n", + "y1 = x1**3 - 6*x1**2 + 12*x1 - 9 \n", + "# Agora vamos adicionar algum ruido para estes dados\n", + "y1 += np.random.normal(0, 2, size=len(y1)) #Uma maneira de gerar ruido aleatorio gaussiano\n", + "sigma = 1.5\n", + "y1_err = np.ones(N)*sigma " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FFR9xu3tLnSR" + }, + "source": [ + "Vamos plotar para ver como fica: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "oyq7a5lJLnSR" + }, + "outputs": [], + "source": [ + "plt.errorbar(x1, y1, yerr=y1_err,fmt='k.')\n", + "plt.xlabel('$x_1$') \n", + "plt.ylabel('$y_1$')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vIpzc-kgLnSS" + }, + "source": [ + "Para ajustar esses dados vamos lembrar os três passos: modelar, ajustar e realizar o ajuste. \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "9VclbzMvLnSS" + }, + "outputs": [], + "source": [ + "model_poly = models.Polynomial1D(degree=3)\n", + "fitter_poly = fitting.LinearLSQFitter() \n", + "best_fit_poly = fitter_poly(model_poly, x1, y1, weights = 1.0/y1_err**2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "BUKHfb3SLnSS" + }, + "outputs": [], + "source": [ + "print(best_fit_poly)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "h33c4vUVLnST" + }, + "source": [ + "O que aconteceria se usássemos um ajustador (método) diferente? Vamos usar o mesmo modelo, mas com `SimplexLSQFitter` como ajustador." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "DS5UielRLnSU" + }, + "outputs": [], + "source": [ + "fitter_poly_2 = fitting.SimplexLSQFitter()\n", + "best_fit_poly_2 = fitter_poly_2(model_poly, x1, y1, weights = 1.0/y1_err**2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "DTtmkz15LnSV" + }, + "outputs": [], + "source": [ + "print(best_fit_poly_2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T4j3vu73LnSV" + }, + "source": [ + "Note que nós recebemos um aviso após usar `SimplexLSQFitter` para ajustar os dados. A primeira linha nos diz:\n", + "\n", + "`WARNING: Modelo é linear nos parÂmetros; considere usando metodos de ajuste linear. [astropy.modeling.fitting]`\n", + "\n", + "Se Nós olharmos para o modelo que escolhemos : $y = c_0 + c_1\\times x + c_2\\times x^2 + c_3\\times x^3$, Isto é linear inos parametros $c_i$. O aviso nos traz que `SimplexLSQFitter` trabalha melhor com modelos que não são lineares nos parametros, e que precisamos usar um ajustador linear como `LinearLSQFitter`. A segunda linha nos diz:\n", + "\n", + "`WARNING: The fit may be unsuccessful; Maximum number of iterations reached. [astropy.modeling.optimizers]`\n", + "\n", + "Portanto, não é de surpreender que os resultados sejam diferentes, porque isso significa que o montador não está funcionando corretamente. Vamos discutir um método de escolha entre ajustes e lembre-se de **prestar atenção** quando se escolhe o **ajustador**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "62FIOEn8LnSW" + }, + "source": [ + "#### Compare os resultados" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YzncRRdwLnSW" + }, + "source": [ + "Uma maneira de verificar onde os parâmetros são os melhores ajustados é calculando o [o valor quadratico do Chi Reduzido](https://en.wikipedia.org/wiki/Reduced_chi-squared_statistic). Vamos definir uma função para fazer porque vamos usá-la várias vezes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "0fENXxA8LnSW" + }, + "outputs": [], + "source": [ + "def calc_reduced_chi_square(fit, x, y, yerr, N, n_free):\n", + " '''\n", + " fit (array) values for the fit\n", + " x,y,yerr (arrays) data\n", + " N total number of points\n", + " n_free number of parameters we are fitting\n", + " '''\n", + " return 1.0/(N-n_free)*sum(((fit - y)/yerr)**2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "yoqq7HjkLnSX" + }, + "outputs": [], + "source": [ + "reduced_chi_squared = calc_reduced_chi_square(best_fit_poly(x1), x1, y1, y1_err, N, 4)\n", + "print('Reduced Chi Squared with LinearLSQFitter: {}'.format(reduced_chi_squared))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "23jysecaLnSX" + }, + "outputs": [], + "source": [ + "reduced_chi_squared = calc_reduced_chi_square(best_fit_poly_2(x1), x1, y1, y1_err, N, 4)\n", + "print('Reduced Chi Squared with SimplexLSQFitter: {}'.format(reduced_chi_squared))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Kf2FulCaLnSY" + }, + "source": [ + "Como podemos ver, o *Quadrado Reduzido do Chi* para o primeiro ajuste é fechado para um , onde significa que este ajuste é melhor. Note que isso é o que nós esperamos após a discussão dos avisos.\n", + "\n", + "Nós podemos então comparar dois ajustes visualmente:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Cp_8VCQBLnSY" + }, + "outputs": [], + "source": [ + "plt.errorbar(x1, y1, yerr=y1_err,fmt='k.')\n", + "plt.plot(x1, best_fit_poly(x1), color='r', linewidth=3, label='LinearLSQFitter()') \n", + "plt.plot(x1, best_fit_poly_2(x1), color='g', linewidth=3, label='SimplexLSQFitter()')\n", + "plt.xlabel(r'$\\log_{10}$(Period [days])')\n", + "plt.ylabel('Ks')\n", + "plt.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wZWkNJdELnSZ" + }, + "source": [ + "Os resultados são os esperados, o ajuste realizado com o filtro linear é melhor que o segundo, não linear. \n", + "\n", + "**Conclusão:** Preste atenção quando escolher o ajustador." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "42nQBVFwLnSZ" + }, + "source": [ + "## 3) Ajustando uma Gaussiana: Vamos comparar com o scipy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "MAU9T2uILnSZ" + }, + "source": [ + "Scipy tem uma função [scipy.optimize.curve_fit](https://docs.scipy.org/doc/scipy-1.0.0/reference/generated/scipy.optimize.curve_fit.html) para ajustar de maneira semelhante ao que nós fazemos. Vamos comparar os dois metodos com dados mascarados na forma de uma gaussiana. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "hThaNHoKLnSa" + }, + "outputs": [], + "source": [ + "mu, sigma, amplitude = 0.0, 10.0, 10.0\n", + "N2 = 100\n", + "x2 = np.linspace(-30, 30, N)\n", + "y2 = amplitude * np.exp(-(x2-mu)**2 / (2*sigma**2))\n", + "y2 = np.array([y_point + np.random.normal(0, 1) for y_point in y2]) #Another way to add random gaussian noise\n", + "sigma = 1\n", + "y2_err = np.ones(N)*sigma" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "DMnZYm2uLnSa" + }, + "outputs": [], + "source": [ + "plt.errorbar(x2, y2, yerr=y2_err, fmt='k.')\n", + "plt.xlabel('$x_2$')\n", + "plt.ylabel('$y_2$')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jhlQ1BmGLnSb" + }, + "source": [ + "Vamos fazer nossos três passos para fazer os ajustes que nós queremos . Para este ajuste, nós vamos usar um ajustador não linear, `LevMarLSQFitter`, porque o modelo que nós precisamaos (`Gaussian1D`) é não linear nos parâmetros. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "kMyQ-tgOLnSb" + }, + "outputs": [], + "source": [ + "model_gauss = models.Gaussian1D()\n", + "fitter_gauss = fitting.LevMarLSQFitter()\n", + "best_fit_gauss = fitter_gauss(model_gauss, x2, y2, weights=1/y2_err**2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "_1tb3DjlLnSd" + }, + "outputs": [], + "source": [ + "print(best_fit_gauss)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "25AV6cvuLnSd" + }, + "source": [ + "Vamos tomar a [matriz de covariãncia](http://mathworld.wolfram.com/CovarianceMatrix.html) do`LevMarLSQFitter`, o qual fornece um erro para nosso ajuste dos parâmetros pelo fazer do ajuste. `fitter.fit_info['param_cov']`. Os elementos na diagonal desta matriz são os quadrados dos erros. Nós podemos verificara ordem dos parâmetros:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "sn99jSznLnSe" + }, + "outputs": [], + "source": [ + "model_gauss.param_names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "EZgtGVxTLnSe" + }, + "outputs": [], + "source": [ + "cov_diag = np.diag(fitter_gauss.fit_info['param_cov'])\n", + "print(cov_diag)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l4Qcy1SGLnSe" + }, + "source": [ + "Então:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true, + "id": "HE2Xoi8WLnSf" + }, + "outputs": [], + "source": [ + "print('Amplitude: {} +\\- {}'.format(best_fit_gauss.amplitude.value, np.sqrt(cov_diag[0])))\n", + "print('Mean: {} +\\- {}'.format(best_fit_gauss.mean.value, np.sqrt(cov_diag[1])))\n", + "print('Standard Deviation: {} +\\- {}'.format(best_fit_gauss.stddev.value, np.sqrt(cov_diag[2])))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R-ws9EabLnSf" + }, + "source": [ + "Nós podemos aplicar o mesmso método com `scipy.optimize.curve_fit`, e compare os resultados usando de novo o *valor quadratico reduzido do Chi*." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "x9JCFm8SLnSg" + }, + "outputs": [], + "source": [ + "def f(x,a,b,c):\n", + " return a * np.exp(-(x-b)**2/(2.0*c**2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "JD0fuQcaLnSg" + }, + "outputs": [], + "source": [ + "p_opt, p_cov = scipy.optimize.curve_fit(f,x2, y2, sigma=y1_err)\n", + "a,b,c = p_opt\n", + "best_fit_gauss_2 = f(x2,a,b,c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ZFGF45SsLnSg" + }, + "outputs": [], + "source": [ + "print(p_opt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "FI19IdFULnSh" + }, + "outputs": [], + "source": [ + "print('Amplitude: {} +\\- {}'.format(p_opt[0], np.sqrt(p_cov[0,0])))\n", + "print('Mean: {} +\\- {}'.format(p_opt[1], np.sqrt(p_cov[1,1])))\n", + "print('Standard Deviation: {} +\\- {}'.format(p_opt[2], np.sqrt(p_cov[2,2])))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ymSC7Gn7LnSh" + }, + "source": [ + "#### Compare os resultados" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "2lVZt46FLnSi" + }, + "outputs": [], + "source": [ + "reduced_chi_squared = calc_reduced_chi_square(best_fit_gauss(x2), x2, y2, y2_err, N2, 3)\n", + "print('Reduced Chi Squared using astropy.modeling: {}'.format(reduced_chi_squared))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "7YTrVcCkLnSi" + }, + "outputs": [], + "source": [ + "reduced_chi_squared = calc_reduced_chi_square(best_fit_gauss_2, x2, y2, y2_err, N2, 3)\n", + "print('Reduced Chi Squared using scipy: {}'.format(reduced_chi_squared))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "7z5QdBXOLnSi" + }, + "source": [ + "Como podemos ver, há uma diferença muito pequena no *Quadrado Reduzidp do Chi*. Nisto realmente precisava acontecer, porque o pacote `astropy.modeling` usa scipy para ajustar. A vantagem de usar `astropy.modeling` é somente precisar mudar o nome do ajustador e o modelo execute um diferente ajuste, onde o scipy nos requere lembrar a expressão da função que queremos usar." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "vctxWgxdLnSj" + }, + "outputs": [], + "source": [ + "plt.errorbar(x2, y2, yerr=y2_err, fmt='k.')\n", + "plt.plot(x2, best_fit_gauss(x2), 'g-', linewidth=6, label='astropy.modeling')\n", + "plt.plot(x2, best_fit_gauss_2, 'r-', linewidth=2, label='scipy')\n", + "plt.xlabel('$x_2$')\n", + "plt.ylabel('$y_2$')\n", + "plt.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Czqn56qsLnSj" + }, + "source": [ + "**Conclusão:** Escolha o método mais conveniente para todo caso que precise ajustar. Nós recomendamos `astropy.modeling` porque é facilitador para escrever o nome da função que queremos ajustar para relembrar a expressão todo tempo que queremos usar. Então, `astropy.modeling` torna-se útil com modelos mais complicados como [duas gaussianas](http://docs.astropy.org/en/stable/modeling/#compound-models) mais um [corpo negro](http://docs.astropy.org/en/stable/modeling/#blackbody-radiation), mas isso é outro tutorial." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rLM_EsaaLnSj" + }, + "source": [ + "## Revendo:\n", + "\n", + "vamos rever a conclusão que nós tomamos neste tutorial:\n", + "\n", + "1. Você pode ajustar os dados com **três linhas de codigo**:\n", + " * modelo\n", + " * ajustador\n", + " * Execução de ajuste aos dados \n", + " \n", + " \n", + "2. **Preste atenção** quando você escolher o **ajustador**.\n", + "\n", + "3. Escolha o metodo mais conveniente para todo caso que precise ajustar. nós recomendamos `astropy.modeling` para fazer **rápidos ajustes de funções conhecidas**." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q5_c3h-VLnSk" + }, + "source": [ + "## 4) Exercício: Sua vez de escolher" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R5ZPMJWtLnSk" + }, + "source": [ + "Para os proximos dados:\n", + " * Escolha o modelo e ajustador para ajustar estes dados.\n", + " * Compare diderentes opções." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "xrH-h4uXLnSk" + }, + "outputs": [], + "source": [ + "N3 = 100\n", + "x3 = np.linspace(0, 3, N3)\n", + "y3 = 5.0 * np.sin(2 * np.pi * x3)\n", + "y3 = np.array([y_point + np.random.normal(0, 1) for y_point in y3])\n", + "sigma = 1.5\n", + "y3_err = np.ones(N)*sigma " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true, + "id": "b079Et2iLnSl" + }, + "outputs": [], + "source": [ + "plt.errorbar(x3, y3, yerr=y3_err, fmt='k.')\n", + "plt.xlabel('$x_3$')\n", + "plt.ylabel('$y_3$')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "id": "vH_Ri3BVLnSl" + }, + "outputs": [], + "source": [ + "" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.2" + }, + "colab": { + "name": "(João Marcos M.Ribeiro)Tradução de Models-Quick-Fit.ipynb ", + "provenance": [], + "collapsed_sections": [ + "JkJM3EJpLnSI", + "cHSksp8MLnSK", + "dMsEIgGkLnSM", + "62FIOEn8LnSW", + "ymSC7Gn7LnSh" + ], + "include_colab_link": true + } + }, + "nbformat": 4, + "nbformat_minor": 0 +}