<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gisely Alves Brandão</title>
    <description>The latest articles on DEV Community by Gisely Alves Brandão (@giselyalves13).</description>
    <link>https://dev.to/giselyalves13</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F249193%2Fcbadb34b-fe82-446d-a339-6107a707ad36.jpg</url>
      <title>DEV Community: Gisely Alves Brandão</title>
      <link>https://dev.to/giselyalves13</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/giselyalves13"/>
    <language>en</language>
    <item>
      <title>Séries Temporais: Parte 2</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Fri, 03 Apr 2020 13:23:37 +0000</pubDate>
      <link>https://dev.to/giselyalves13/series-temporais-parte-2-5806</link>
      <guid>https://dev.to/giselyalves13/series-temporais-parte-2-5806</guid>
      <description>&lt;p&gt;Continuando os meus estudos do post &lt;a href="https://dev.to/giselyalves13/series-temporais-parte-1-13l8"&gt;Séries Temporais: Parte 1&lt;/a&gt;, onde abordei alguns conceitos básicos de séries temporais e preparação dos dados. Nesse post falo mais sobre alguns modelos chave para esse tipo de análise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autocorrelação e Autocorrelação parcial
&lt;/h3&gt;

&lt;p&gt;Uma análise de série temporal simples é sempre uma análise sobre o que já aconteceu na própria série e com a correlação não seria diferente. Uma correlação nos diz o quão relacionado é um valor com outro valor (isso não significa que um valor influenciou o outro) e uma autocorrelação (ACF) é quando comparamos o valor do presente com valores do passado da mesma série. A diferença entre a autocorrelação e a autocorrelação parcial (PACF) é quase um detalhe: em uma ACF temos a correlação direta e indireta e em uma PACF apenas a correlação direta. Exemplificando, com a ACF vemos a correlação direta do mês de janeiro em março e também a correlação indireta que o mês de janeiro teve em fevereiro que também teve em março.&lt;/p&gt;

&lt;p&gt;Conseguimos ver a ACF e PACF de um jeito bem simples com esses dois gráficos da biblioteca &lt;em&gt;statsmodels:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;statsmodels.graphics.tsaplots&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;plot_acf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plot_pacf&lt;/span&gt;

&lt;span class="n"&gt;plot_acf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;meantemp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plot_pacf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;meantemp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bsP_zCvx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ak4lamiYGAeFk40B-R-bfeQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bsP_zCvx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ak4lamiYGAeFk40B-R-bfeQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FrdMT-gi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2ASqxg6XzO2tGiI1bG2wGJfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FrdMT-gi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2ASqxg6XzO2tGiI1bG2wGJfw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O intervalo de confiança por padrão é 95%, mostrado como essa marca azul. Observações que estão para fora da marca são consideradas estatisticamente correlacionadas.&lt;/p&gt;

&lt;h3&gt;
  
  
  White Noise
&lt;/h3&gt;

&lt;p&gt;Uma série white noise é uma série na qual a média 0, a variância é constante ao longo da série toda e não há correlação entre os períodos de tempo. O valores de uma série white noise são totalmente aleatórios, ou seja, essa é um tipo de série que não é previsível.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J3us2rRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AG9qr2q7SJ_OQGJDoZN7a4w.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J3us2rRg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AG9qr2q7SJ_OQGJDoZN7a4w.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;Visão de uma série White Noise&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;As séries temporais são compostas por uma componente de white noise e a componente dos sinais (outras componentes que explicam os dados). Por esse motivo esse tipo de série é usada na avaliação de modelos. Quando o erro gerado por um modelo é white noise significa que toda a parte previsível dos dados foi ajustada ao modelo e restou apenas o que era aleatório.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modelos para Séries Temporais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Autorregressão (AR)
&lt;/h3&gt;

&lt;p&gt;Para quem já está habituado ao conceito de regressão esse tipo de modelo é bem simples. Se você não conhece como uma regressão funciona, eu explico nesse outro &lt;a href="https://dev.to/giselyalves13/regressao-linear-1lf5"&gt;post aqui.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma autoregressão é basicamente uma regressão onde seus parâmetros são regressões em tempos anteriores.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;X(t) = a + b1*X(t-1) + b2*X(t-2)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Onde &lt;em&gt;a,&lt;/em&gt; &lt;em&gt;b1 e b2&lt;/em&gt; são os coeficientes da regressão e &lt;em&gt;t&lt;/em&gt; é o indicador de qual tempo estamos usando na regressão &lt;em&gt;X.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;statsmodels.tsa.ar_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AR&lt;/span&gt;  
&lt;span class="n"&gt;ar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;ar_fit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;predicted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ar_fit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#ao contrário da maioria dos modelos de machine leaning, quando usamos o predict em séries temporais colocamos o início e fim das predições, como índice ou como datas  
&lt;/span&gt;
&lt;span class="n"&gt;ar_fit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;k_ar&lt;/span&gt; &lt;span class="c1"&gt;#Essa função mostra o Lag usado na função
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Lag operator&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;= número de períodos anteriores&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Moving Average Model (MA)
&lt;/h3&gt;

&lt;p&gt;Apesar do nome o Moving Average Model não é a mesma coisa que apenas calcular a média móvel da série temporal. O MA é um modelo linear, assim como a regressão, que usa os resíduos dos passos anteriores como variáveis. Esses resíduos são calculados a partir da diferença com a média dessa série, tendo uma série que se move em volta da sua média.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uNMXJO1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AxZv16krcMoSUuQ4CROoXQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uNMXJO1d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AxZv16krcMoSUuQ4CROoXQQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Onde &lt;strong&gt;μ&lt;/strong&gt; é a média da série, &lt;strong&gt;ε&lt;/strong&gt; são os resíduos de acordo com o tempo &lt;strong&gt;&lt;em&gt;t&lt;/em&gt;&lt;/strong&gt; até &lt;strong&gt;&lt;em&gt;t-q&lt;/em&gt;&lt;/strong&gt; e &lt;strong&gt;θ&lt;/strong&gt; são os coeficientes de cada variável.&lt;/p&gt;

&lt;p&gt;O modelo MA pode ser usado como parte do modelo ARMA (AR + MA) deixando a ordem da AR em zero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;statsmodels.tsa.arima_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ARMA&lt;/span&gt;  
&lt;span class="n"&gt;ma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ARMA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  
&lt;span class="n"&gt;ma_fit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;predicted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ma_fit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Autoregressive Integrated Moving Average (ARIMA)
&lt;/h3&gt;

&lt;p&gt;Esse modelo é uma combinação dos dois últimos modelos que eu apresentei aqui (Autorregressão e MA), mas não somente isso (porque aí estaríamos falando do modelo ARMA que não vou explicar aqui). Esse modelo também leva em consideração que os dados &lt;strong&gt;não apresentam estacionariedade&lt;/strong&gt;, o que nos leva a parte Integrada (I), que é a utilização dos dados diferenciados uma ou mais vezes, ao invés dos dados “crus”.&lt;/p&gt;

&lt;p&gt;Então, basicamente, ao invés de predizer uma série temporal baseada nela mesma em seus períodos anteriores, ARIMA prediz uma série temporal baseada na diferença entre um período e outro anterior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;statsmodels.tsa.arima_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ARIMA&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ARIMA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  
&lt;span class="c1"&gt;#No ARIMA a ordem é para a AR, as diferenciações e a MA, respectivamente.  
&lt;/span&gt;&lt;span class="n"&gt;model_fit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;predicted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model_fit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exponential Smoothing / Suavização exponencial
&lt;/h3&gt;

&lt;p&gt;Esse modelo ainda é um modelo linear, como todos que eu mostrei aqui que, ignorando certa complexidade, são uma soma ponderada dos períodos anteriores da série. A diferença da suavização exponencial é que os coeficientes da soma do modelo linear vão caindo exponencialmente, fazendo com que os períodos mais próximos sejam “mais importantes” na conta do que os períodos mais antigos.&lt;/p&gt;

&lt;p&gt;Usando a suavização exponencial simples como exemplo, temos um fator alpha multiplicado pelos coeficientes e variáveis. Esse alpha é um valor entre 0 e 1, sendo que um alpha grande aumenta a diferença da “importância” entre os períodos próximos e os antigos, e um alpha muito pequeno diminui essa diferença.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;statsmodels.tsa.holtwinters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SimpleExpSmoothing&lt;/span&gt;  

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SimpleExpSmoothing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;model_fit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;predicted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model_fit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Aqui estão alguns resultados quando apliquei esses modelos ao dataset com o clima da cidade de Delhi, o mesmo que usei na parte 1 desse post. Usei os dados já diferenciados.&lt;/p&gt;

&lt;h4&gt;
  
  
  Autorregressão:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Lag: 23&lt;br&gt;&lt;br&gt;
Mean squared error: 3.687&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FLwcRon---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2A1s2YiOAy7_tVNjWP3gfupA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FLwcRon---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2A1s2YiOAy7_tVNjWP3gfupA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  ARIMA
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Lag: 23&lt;br&gt;&lt;br&gt;
Mean squared error: 0.925&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--erQ8bakP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AsUuyyQ36MwJUvUBmnPPRmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--erQ8bakP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AsUuyyQ36MwJUvUBmnPPRmg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.kaggle.com/sumanthvrao/daily-climate-time-series-data"&gt;Dataset usado&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://machinelearningmastery.com/time-series-forecasting-methods-in-python-cheat-sheet/"&gt;11 Classical Time Series Forecasting Methods&lt;/a&gt; — Machine Learning Mastery&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=DeORzP0go5I&amp;amp;list=PLvcbYUQ5t0UHOLnBzl46_Q6QKtFgfMGc3"&gt;Time Series Talk&lt;/a&gt; — YouTube&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>timeseries</category>
      <category>datascience</category>
      <category>statistics</category>
    </item>
    <item>
      <title>Séries Temporais: Parte 1</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Thu, 27 Feb 2020 20:41:58 +0000</pubDate>
      <link>https://dev.to/giselyalves13/series-temporais-parte-1-13l8</link>
      <guid>https://dev.to/giselyalves13/series-temporais-parte-1-13l8</guid>
      <description>&lt;p&gt;Séries temporais são conjuntos de dados onde o tempo guia todas as outras variáveis. Pode conter qualquer forma de tempo, anos, dias, minutos, etc. Essa ideia de ordem temporal no conjunto de dados faz com que as análises das séries sejam um pouco diferentes.&lt;/p&gt;

&lt;p&gt;Existe todo um campo de estudo em volta do assunto e, mesmo escrevendo sobre conceitos básicos, terei mais do que um artigo para abordar o tema (que também estou estudando). Nesse artigo vamos ver uma introdução a séries temporais, suas componentes e estacionariedade.&lt;/p&gt;

&lt;p&gt;Antes de tudo precisamos preparar os nosso dados para a análise. Muitos datasets apresentam o tempo como uma string então a primeira coisa a se fazer é a conversão para o tipo Date. Também vamos passar essa coluna para o index do dataframe e plotar os dados logo depois. Esse dataset possui informações sobre o clima da cidade Delhi — Temperatura média, humidade, velocidade do vento e pressão.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;  
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;  
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;matplotlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pltdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DailyDelhiClimateTest.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'date'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subplots&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mkZrVr6i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/608/1%2AkSRgLXV8JSeJyF_iwjT6MQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mkZrVr6i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/608/1%2AkSRgLXV8JSeJyF_iwjT6MQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esses dados são diários e eu vou trabalhar com eles assim, entretanto, podemos trabalhar numa frequência de tempo diferente usando a função  &lt;code&gt;resample&lt;/code&gt;  . Como exemplo vou redimensionar os dados para mostrar por meses, agrupando os valores pela média e também vou redimensionar por hora e preencher os campos nulos que aparecem por não termos informações tão granuladas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#Por mês:  
&lt;/span&gt;&lt;span class="n"&gt;df_exemple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'M'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nwp4QNSJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/413/1%2AFkMFlA5JDwEyxvUzC5tWMQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nwp4QNSJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/413/1%2AFkMFlA5JDwEyxvUzC5tWMQ.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#Por hora:  
#Ffil preenche com o último valor anterior aos campos  
&lt;/span&gt;&lt;span class="n"&gt;df_exemple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'H'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ffill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;#Bfil preenche com os campos com o próximo valor válido na caluna
&lt;/span&gt;&lt;span class="n"&gt;df_exemple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'H'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;bfill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lDD8G9yv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1390/1%2A18gSF4vR90EBoZ8OG5zYig.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lDD8G9yv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1390/1%2A18gSF4vR90EBoZ8OG5zYig.jpeg" alt="método ffill versus método bfill"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;&lt;em&gt;método ffill versus método bfill&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Agora, para fazer as análises é preciso entender as séries temporais. Do modo como esse dataset está montado podemos tratar cada coluna como uma série. E as séries temporais são compostas por 4 componentes:&lt;/p&gt;
&lt;h2&gt;
  
  
  Tendência / Trend
&lt;/h2&gt;

&lt;p&gt;Aqui é a tendência dos dados de crescer ou diminuir em longo período de tempo. Essa análise pode ser feita observando um gráfico de linha, onde conseguimos ver um crescimento ou uma diminuição suave com o tempo.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sazonalidade
&lt;/h2&gt;

&lt;p&gt;Essa é uma variação dos dados que se repete, de acordo com algum padrão, dentro de um curto intervalo de tempo bem definido (um ano no máximo). Podemos observar a sazonalidade no trânsito, que aumenta sempre nos horários de começo e fim de expediente, ou nas vendas de sorvete que aumentam sempre no verão e caem sempre no inverno.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ciclicidade
&lt;/h2&gt;

&lt;p&gt;Também é uma variação nos dados observada com algum padrão só que em longos períodos de tempo (mais de um ano) que nem sempre são iguais. Como a venda de casas, que por mais que possa ter alguma sazonalidade durante o ano, tem um ciclo de altas e baixas vendas quando observadas ao longo de décadas.&lt;/p&gt;
&lt;h2&gt;
  
  
  Resíduos / Ruído
&lt;/h2&gt;

&lt;p&gt;São variações que não são explicadas pelas variáveis do dataset. Em geral são aleatórias.&lt;/p&gt;

&lt;p&gt;A biblioteca “Statsmodels” é uma grande amiga quando o assunto é séries temporais. Vou usá-la para mostrar a decomposição da série da coluna  &lt;em&gt;meantemp&lt;/em&gt;  (temperatura média). O resultado da função  &lt;em&gt;seasonal_decompose&lt;/em&gt; é um conjunto de séries dessa decomposição que você pode plotar como quiser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;statsmodels.tsa.seasonal&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;seasonal_decompose&lt;/span&gt;  
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seasonal_decompose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;meantemp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--72gHM7iq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/619/1%2AE2lvx1Cg9yj_E60ZMSSMbw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--72gHM7iq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/619/1%2AE2lvx1Cg9yj_E60ZMSSMbw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Existem dois modos nos quais as componentes podem se relacionar com os seus dados, o modelo aditivo onde suas observações são fruto dessas componentes somadas e o modelo multiplicativo onde as componentes são multiplicadas. A componente cíclica é mostrada junto da componente de resíduos pois as duas não possuem um tempo certo de acontecimento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estacionariedade
&lt;/h2&gt;

&lt;p&gt;Para trabalhar com séries temporais precisamos que ela seja  &lt;strong&gt;estacionária&lt;/strong&gt;. Essa característica além de ser necessária para algum modelos, facilita a projeção dos dados.&lt;/p&gt;

&lt;p&gt;Simplificando bastante podemos entender a estacionariedade como uma série temporal com sua média, variância e co-variância permanecendo iguais quando comparados os períodos de tempo da série, ou seja, as estatísticas da série não sofrem variações com o tempo, não são dependentes dele.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pJUAANRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1147/1%2Am0E2_nOE1oFhMc1L01oKsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pJUAANRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/1147/1%2Am0E2_nOE1oFhMc1L01oKsg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A “forma” dos dados nos gráficos podem nos dar uma noção se a série é ou não estacionária. Uma maneira legal de enxergar isso é plotando as estatísticas de rolagem, isso é, ao invés de mostrar todas as observações ou calcular as estatísticas do conjunto inteiro, cada ponto é a estatística (média, desvio, variância, etc) dos pontos da “janela” anterior.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;janela é um subconjunto de observações seguidas&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mediamovel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'meantemp'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;rolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   
&lt;span class="c1"&gt;#window = 7 diz que a janela usada para média móvel é de 7 observações (no caso 7 dias)  
&lt;/span&gt;&lt;span class="n"&gt;desviomovel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'meantemp'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;rolling&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;orig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'meantemp'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'blue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Observado'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;media&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mediamovel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'red'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Média Móvel'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;desvio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;desviomovel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'black'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'Desvio Padrão Móvel'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'best'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Estatísticas de rolagem'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7KCLWZ9m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/619/1%2AjSKv_t7Dvvx5F8nGxFHVSQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7KCLWZ9m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/619/1%2AjSKv_t7Dvvx5F8nGxFHVSQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com essa imagem conseguimos ter uma noção que a série não é estacionária, mas para termos certeza existe um teste estatístico chamado Augmented Dickey–Fuller (ADCF). O teste considera como hipótese nula a não estacionariedade e como hipótese alternativa a estacionariedade. Para interpretar o teste podemos olhar para o p-valor que tem ser menor do que o nível de significância escolhido e o valor do teste tem que ser menor que o valor crítico para esse mesmo nível de significância.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;statsmodels.tsa.stattools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;adfuller&lt;/span&gt;  
&lt;span class="n"&gt;adftest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adfuller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'meantemp'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="c1"&gt;#Para printar os resultados de maneira elegante:  
&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Series&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adftest&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Teste'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'p-valor'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'Lags'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;'Número de observações usadas'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;adftest&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;  
    &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Valor crítico (%s)'&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;  
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Teste&lt;/span&gt;                            &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.096474&lt;/span&gt;  
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;                           &lt;span class="mf"&gt;0.716476&lt;/span&gt;  
&lt;span class="n"&gt;Lags&lt;/span&gt;                              &lt;span class="mf"&gt;0.000000&lt;/span&gt;  
&lt;span class="n"&gt;Número&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;observações&lt;/span&gt; &lt;span class="n"&gt;usadas&lt;/span&gt;    &lt;span class="mf"&gt;113.000000&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.580604&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.887477&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;3.489590&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos ver essa série não é estacionária ainda. Pensando num nível de significância de 5%, o p-valor e o valor do teste estão muito altos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como deixar uma série estacionária?
&lt;/h2&gt;

&lt;p&gt;Podemos aplicar algumas técnicas nos dados para conseguir uma série estacionária, como exemplo, transformações (logarítmica, a raiz quadrada, boxcox), diferenciação, etc.&lt;/p&gt;

&lt;p&gt;O primeiro método que vou tentar é a  &lt;strong&gt;diferenciação&lt;/strong&gt;. Esse processo cria uma nova série a partir da diferença de uma observação com a observação anterior.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;diff(t) = obs(t) - obs(t-1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Através da diferenciação também é possível remover a dependência temporal de uma série, reduzindo a tendência e a sazonalidade. Por esse motivo esse método pode ser usado para atingir a estacionariedade. Pode-se diferenciar uma série mais de uma vez, caso seja necessário para remover a dependência.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dfdiff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;meantemp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;dfdiff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dfdiff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;dfdiff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7BQV6p5R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/374/1%2Ay3DDdqCsdo8_nZxhFbu4Vg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7BQV6p5R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/374/1%2Ay3DDdqCsdo8_nZxhFbu4Vg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E aplicando o ADCF teste temos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Teste&lt;/span&gt;                         &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.203580e+01&lt;/span&gt;  
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;                        &lt;span class="mf"&gt;2.805321e-22&lt;/span&gt;  
&lt;span class="n"&gt;Lags&lt;/span&gt;                           &lt;span class="mf"&gt;0.000000e+00&lt;/span&gt;  
&lt;span class="n"&gt;Número&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;observações&lt;/span&gt; &lt;span class="n"&gt;usadas&lt;/span&gt;   &lt;span class="mf"&gt;1.120000e+02&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.580730e+00&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.887712e+00&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;3.490131e+00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esses valores já teríamos uma série estacionária, considerando um nível de significância de 5%, e já daria para prosseguir com outras análises.&lt;/p&gt;

&lt;p&gt;O segundo método que vou usar é a transformação de  &lt;strong&gt;Box-cox&lt;/strong&gt;. Essa transformação tem como objetivo deixar os dados mais normalizados e consequentemente estabiliza a variância durante os dados. A sua função tem apenas um parâmetro, lambda, que denota como será feita essa transformação, podemos definir esse valor ou deixar a função achar “o melhor valor”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;scipy.stats&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boxcox&lt;/span&gt;  
&lt;span class="n"&gt;meantemp_bcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boxcox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'meantemp'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Lambda: %f'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;lam&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suptitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BoxCox resultados"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="c1"&gt;# line plot  
&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;211&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meantemp_bcx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="c1"&gt;# histogram  
&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;212&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meantemp_bcx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;#resultado: 
&lt;/span&gt;&lt;span class="n"&gt;Lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.118270&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hBd94PwY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/382/1%2AvuIx0hbZue2tiBlCyJ1UZg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hBd94PwY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/382/1%2AvuIx0hbZue2tiBlCyJ1UZg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Olhando para o gráfico e para o resultado do teste abaixo vemos que esse método não foi muito eficaz para conseguir a estacionariedade.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Teste&lt;/span&gt;                           &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.444017&lt;/span&gt;  
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;                          &lt;span class="mf"&gt;0.561001&lt;/span&gt;  
&lt;span class="n"&gt;Lags&lt;/span&gt;                             &lt;span class="mf"&gt;0.000000&lt;/span&gt;  
&lt;span class="n"&gt;Número&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;observações&lt;/span&gt; &lt;span class="n"&gt;usadas&lt;/span&gt;   &lt;span class="mf"&gt;113.000000&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;3.489590&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.887477&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.580604&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seguindo para o último método, vou tentar também uma abordagem bem legal que vi em uma das  &lt;a href="https://www.kaggle.com/freespirit08/time-series-for-beginners-with-arima"&gt;referências&lt;/a&gt;  que usei para estudar. Vou fazer uma  &lt;strong&gt;transformação logarítmica&lt;/strong&gt;  e  &lt;strong&gt;subtrair a média móvel&lt;/strong&gt;  dos dados transformados. O gráfico abaixo mostra as duas séries comparadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;temp_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'meantemp'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;#Transformação logarítmica 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ldV9QBLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/510/1%2A1YgkvMa1AVkM8Xi7d_8oWg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ldV9QBLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/510/1%2A1YgkvMa1AVkM8Xi7d_8oWg.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;log_menos_media&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp_log&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mediamovel_log&lt;/span&gt;  
&lt;span class="n"&gt;log_menos_media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dropna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inplace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3uqJqety--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/495/1%2AXIkq-OFTtNZHWObCTSlFRA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3uqJqety--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/495/1%2AXIkq-OFTtNZHWObCTSlFRA.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;&lt;em&gt;Estatísticas de rolagem referentes a série “log_menos_media”&lt;/em&gt;&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Teste&lt;/span&gt;                         &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.988135e+00&lt;/span&gt;  
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;valor&lt;/span&gt;                        &lt;span class="mf"&gt;1.771911e-07&lt;/span&gt;  
&lt;span class="n"&gt;Lags&lt;/span&gt;                           &lt;span class="mf"&gt;3.000000e+00&lt;/span&gt;  
&lt;span class="n"&gt;Número&lt;/span&gt; &lt;span class="n"&gt;de&lt;/span&gt; &lt;span class="n"&gt;observações&lt;/span&gt; &lt;span class="n"&gt;usadas&lt;/span&gt;   &lt;span class="mf"&gt;1.040000e+02&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;3.494850e+00&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.889758e+00&lt;/span&gt;  
&lt;span class="n"&gt;Valor&lt;/span&gt; &lt;span class="n"&gt;Crítico&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.581822e+00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conseguimos uma série estacionária \o/, mas por que deu certo?&lt;/p&gt;

&lt;p&gt;Quando plotamos a média móvel dessa série e a série transformada é possível ver nos dois casos que existe uma tendência nos dados. A teoria era que subtraindo as duas essa tendência fosse perdida e sobraria apenas as partes estacionárias da série final.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MM = tendênciaM + estacionariedadeM  
TL = tendênciaL + estacionariedadeL  
TL-MM = (tendênciaL + estacionariedadeL)-(tendênciaM + estacionariedadeM) = tendênciaL - tendênciaM + estacionariedadeL - estacionariedadeM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Referências e sugestões:
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.kaggle.com/sumanthvrao/daily-climate-time-series-data"&gt;Dataset usado&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/giselyalves/introduction-to-time-series-concepts"&gt;Link para o código completo do artigo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/thebrownviking20/everything-you-can-do-with-a-time-series"&gt;Everything you can do with a time series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/freespirit08/time-series-for-beginners-with-arima"&gt;Time Series for beginners with ARIMA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.inf.ufsc.br/~marcelo.menezes.reis/Cap4.pdf"&gt;Análise de séries temporais — UFSC&lt;/a&gt;  : Explica decomposição em detalhes e em português!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>datascience</category>
      <category>statistics</category>
      <category>timeseries</category>
    </item>
    <item>
      <title>Viés, Variância e Regularização</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Thu, 31 Oct 2019 00:48:26 +0000</pubDate>
      <link>https://dev.to/giselyalves13/vies-variancia-e-regularizacao-2me7</link>
      <guid>https://dev.to/giselyalves13/vies-variancia-e-regularizacao-2me7</guid>
      <description>&lt;p&gt;Regularização é um tema importante quando o assunto é uma boa modelagem mas antes de entrarmos no assunto precisamos entender o conceito de viés e variância. Eles são o propósito do uso das regularizações.&lt;/p&gt;

&lt;h3&gt;
  
  
  Viés e Variância
&lt;/h3&gt;

&lt;p&gt;A incapacidade de um modelo de capturar a verdadeira relação entre variáveis e o objeto a ser predito é o que chamamos de VIÉS (Bias em inglês).&lt;/p&gt;

&lt;p&gt;Então, quando o erro de viés é alto significa que o modelo não está aprendendo nada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GzxdGdWx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Aq_hdLouaSQwUkshCe5rY4Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GzxdGdWx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Aq_hdLouaSQwUkshCe5rY4Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nessa imagem temos a linha azul como sendo o nosso modelo onde queremos separar esse dataset em duas categoriais. Veja que há muitos X vermelhos juntos com as bolinhas, as categorias não foram muito bem separadas, isso significa que o modelo ainda não entendeu a “curva” que ele deveria fazer para categorizar esses dados corretamente. Chamamos isso de Underfitting.&lt;/p&gt;

&lt;p&gt;Por outro lado, se há um viés muito pequeno o modelo fica tão ajustado aos dados de treinamento que quando é usado com dados diferentes acaba errando muito. Aqui entra o conceito de variância.&lt;/p&gt;

&lt;p&gt;A variância é a sensibilidade de um modelo ao ser usado com outros datasets diferentes do treinamento. Se o modelo é muito sensível aos dados de treinamento, ou seja, identificou tão bem a relação entre os dados de treinamento, que quando colocado em teste irá errar justamente a variação que existe entre os datasets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---hxCCpp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AQfGXli0jP1QDAUuAeWOTeA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---hxCCpp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AQfGXli0jP1QDAUuAeWOTeA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veja na última imagem como o nosso modelo está acertando absolutamente todos os dados. Chamamos isso de Overfitting. O modelo ideal seria algo parecido com o modelo do meio da próxima imagem, gerando uma curva mais generalizada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gck-jzq3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A0ezlGge0OqGhzMo6HDEA8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gck-jzq3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A0ezlGge0OqGhzMo6HDEA8A.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora observem a imagem abaixo, nela está representado o Trade-off. Percebam que o erro total do modelo é soma do viés (bias) com a variância e que conforme o modelo vai “aprendendo” (&lt;em&gt;model complexity&lt;/em&gt; aumenta) temos um momento de baixa e logo depois o erro volta a crescer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6PWiCoYK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AUDp6phojWvlixHO9" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6PWiCoYK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AUDp6phojWvlixHO9" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É muito comum modelos que aprendem muito bem no conjunto de treino, mas acabam apresentando Overfitting. Isso faz com que o modelo esteja do lado direito desse diagrama, entretanto, o ideal é que fique mais próximo ao meio. Então para diminuir a variância acrescentamos um pouquinhos de viés, assim ele “desaprende” o suficiente para conseguir generalizar e ser usado além dos dados de treino.&lt;/p&gt;

&lt;h3&gt;
  
  
  REGULARIZAÇÕES
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A regularização introduz um RUÍDO no modelo para diminuir o erro de variância.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As regularizações que veremos também são chamadas de Regressões penalizadas. Regressões são modelos estatísticos inferenciais que tem como objetivo minimizar a soma dos resíduos ao quadrado (&lt;a href="https://dev.to/giselyalves13/regressao-linear-1lf5"&gt;leia mais sobre regressões aqui&lt;/a&gt;). Abaixo temos o exemplo de uma Regressão Linear Simples, onde os dados vermelhos seriam o nosso conjunto de treino. A reta dessa Regressão foi escolhida por ser a que possui a menor soma dos resíduos ao quadrado de acordo com a sua base de treino, mas isso não fez com que essa fosse a melhor reta contando com todos os outros pontos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K4Rx0uNM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AfLGdCEWSrofw-zMe" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K4Rx0uNM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AfLGdCEWSrofw-zMe" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nas Regularizações o objetivo não é minimizar apenas a soma dos resíduos ao quadrado (SRQ) mas também um valor penalizado em cima dos parâmetros da regressão.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ridge Regression
&lt;/h3&gt;

&lt;p&gt;Nessa vamos minimizar a soma dos resíduos ao quadrado + uma penalização em cima de todos os parâmetros ao quadrado. A função a ser minimizada pela regressão ficaria (onde λ é um número utilizado para penalização):&lt;/p&gt;

&lt;p&gt;SRQ + λ * ( parâmetro₁² + parâmetro₂² + …)&lt;/p&gt;

&lt;p&gt;Agora podemos observar a diferença nas retas de uma Regressão Simples e uma Regularização. Veja que, apesar da reta não estar totalmente ajustada aos dados de treino, o seu ajuste ao total dos dados melhorou.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ryUKFN_i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AAqfbge8ThDtMJuZf" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ryUKFN_i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AAqfbge8ThDtMJuZf" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As regularizações funcionam de forma muito parecida mas não servem apenas para evitar o overfitting. Isso é o que podemos ver mais claramente na Lasso Regression.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lasso Regression
&lt;/h3&gt;

&lt;p&gt;A Lasso também penaliza os parâmetros, entretanto, ao invés de colocá-los ao quadrado, eles são usados em módulo. A função minimizada então seria essa:&lt;/p&gt;

&lt;p&gt;SRQ + λ * ( |parâmetro₁| + |parâmetro₂| + …)&lt;/p&gt;

&lt;p&gt;Beleza, mas e daí?&lt;/p&gt;

&lt;p&gt;A grande diferença entre Lasso e Rigde é que a Lasso pode levar os parâmetros a (exatamente) 0 enquanto a Ridge apenas próximo à 0.&lt;/p&gt;

&lt;p&gt;Isso significa que:&lt;/p&gt;

&lt;p&gt;Parâmetros ruins usados na modelagem podem ser &lt;strong&gt;EXCLUÍDOS&lt;/strong&gt; da equação. Ou seja, Regularizações também podem ser úteis na escolha dos parâmetros para as nossas modelagens.&lt;/p&gt;

&lt;p&gt;Ridge Regression seria bem utilizada quando sabemos que a maioria dos parâmetros são úteis para o modelo. Já uma Lasso Regression quando temos muitos parâmetros e alguns deles podem ser inúteis. Além das duas, ainda temos mais um tipo de regressão penalizada que combina as duas últimas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Elastic-Net Regression
&lt;/h3&gt;

&lt;p&gt;Elastic-Net é uma combinação da penalização da Lasso e Ridge. Sua função de minimização fica como mostrado abaixo:&lt;/p&gt;

&lt;p&gt;SRQ +&lt;/p&gt;

&lt;p&gt;λ₁ * ( |parâmetro₁| + |parâmetro₂| + …) +&lt;/p&gt;

&lt;p&gt;λ₂ * ( parâmetro₁² + parâmetro₂² + …)&lt;/p&gt;

&lt;p&gt;Lasso + Ridge&lt;/p&gt;

&lt;p&gt;Essa técnica ainda é boa para quando há parâmetros correlacionados. Já que no Lasso a maioria deles seria excluída e no Ridge esses parâmetros apenas teriam valores muito baixo.&lt;/p&gt;




&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;Algumas referências que usei para aprender sobre o assunto do post :D :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.datacamp.com/community/tutorials/tutorial-ridge-lasso-elastic-net"&gt;Regularization Tutorial — DataCamp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://becominghuman.ai/machine-learning-bias-vs-variance-641f924e6c57?gi=a3e2389c3add"&gt;Bias vs Variance — Becoming Human&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCtYLUTtgS3k1Fg4y5tAhLbw"&gt;StatQuest with Josh Starmer&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>machinelearning</category>
      <category>statistics</category>
    </item>
    <item>
      <title>Descobrindo SOM, uma Rede Neural com aprendizado não supervisionado</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Mon, 28 Oct 2019 02:11:16 +0000</pubDate>
      <link>https://dev.to/giselyalves13/descobrindo-som-uma-rede-neural-com-aprendizado-nao-supervisionado-1l8c</link>
      <guid>https://dev.to/giselyalves13/descobrindo-som-uma-rede-neural-com-aprendizado-nao-supervisionado-1l8c</guid>
      <description>&lt;p&gt;Self Organizing Map (SOM) é uma Rede Neural de aprendizado não supervisionado. SOM é muito utilizada quando se tem datasets com muitos atributos porque é possível que a saída produzida tenha um número muito menor de dimensões, geralmente duas. Essa saída, chamada de map (ou feature map), é uma representação discreta dos dados de entrada.&lt;/p&gt;

&lt;p&gt;Um ponto interessante sobre a SOM é que seu sistema é baseado em aprendizado competitivo. Os neurônios (ou nós) competem para decidir quem responderá (será ativado) com um conjunto de entradas e esse neurônio será chamado de winner. SOM pode ser implementada tendo conexões com inibições laterais, ou seja, uma capacidade do neurônio winner de reduzir a atividade dos seus vizinhos dando um feedback negativo a eles. Outro conceito que a SOM trabalha é o chamado mapa topográfico. A informação gerada de um input é representada por alguns neurônios vizinhos e contam com uma interação com conexões curtas. Um neurônio do output de um mapa topográfico é uma característica dos dados de entrada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2A4hCbxP1OLCQJDLZs.jpg%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2A4hCbxP1OLCQJDLZs.jpg%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F500%2F0%2A4hCbxP1OLCQJDLZs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F500%2F0%2A4hCbxP1OLCQJDLZs.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exemplo de inibição lateral dos nossos neurônios produzindo uma ilusão de óptica&lt;/p&gt;

&lt;h1&gt;
  
  
  Como a SOM funciona?
&lt;/h1&gt;

&lt;p&gt;Os pontos no espaço dos dados de entrada têm pontos correspondentes no espaço de saída. Na Kohonen Networks, um tipo de SOM, há uma única camada computacional com duas dimensões e os pontos da entrada são totalmente conectados com os neurônios nessa camada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Ffreeze%2Fmax%2F30%2F0%2Atqifhm1yjWLetoTG.gif%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Ffreeze%2Fmax%2F30%2F0%2Atqifhm1yjWLetoTG.gif%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F420%2F0%2Atqifhm1yjWLetoTG.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F420%2F0%2Atqifhm1yjWLetoTG.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No começo do processo de organização os pesos são inicializados com valores aleatórios. Após esse procedimento, para a competição, todos os neurônios calculam a função de discriminação, apresentada abaixo, sobre as características do dataset. O neurônio de menor valor é considerado o campeão (winner).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AiqxpENhkzkiLErlqssmIOw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AiqxpENhkzkiLErlqssmIOw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F221%2F1%2AiqxpENhkzkiLErlqssmIOw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F221%2F1%2AiqxpENhkzkiLErlqssmIOw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;D = dimensão do espaço de entrada; x = as entradas; w = os pesos&lt;/p&gt;

&lt;p&gt;Essa função mostra qual neurônio tem mais similaridade com o vetor de entradas.&lt;/p&gt;

&lt;p&gt;Quando um neurônio é ativado seus vizinhos ficarão mais excitados comparados com neurônios que estão mais distantes. Esse processo é chamado de vizinhança topológica e é calculada como mostrado abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A-xPWPbYvL3rP7fO_AjfQXA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A-xPWPbYvL3rP7fO_AjfQXA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F294%2F1%2A-xPWPbYvL3rP7fO_AjfQXA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F294%2F1%2A-xPWPbYvL3rP7fO_AjfQXA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Onde  &lt;em&gt;S&lt;/em&gt;  é a distância lateral entre os neurônios, &lt;em&gt;I(x)&lt;/em&gt;  é o índice do neurônio winner e o  &lt;em&gt;σ&lt;/em&gt; é o número de vizinhos que decresce com o tempo. A vizinhança topográfica irá diminuir, tendendo a zero quando um neurônio estiver muito distante do winner.&lt;/p&gt;

&lt;p&gt;Com  &lt;em&gt;t&lt;/em&gt;  sendo a quantidade de épocas e  &lt;em&gt;η(t)&lt;/em&gt;  o learning rate no tempo, os pesos são atualizados dessa forma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AWVy7thSMQJPmzjdCu-bOPA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AWVy7thSMQJPmzjdCu-bOPA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F352%2F1%2AWVy7thSMQJPmzjdCu-bOPA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F352%2F1%2AWVy7thSMQJPmzjdCu-bOPA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como pode-se ver, os pesos são movidos de acordo com a vizinhança tooplógica, fazendo com que os neurônios mais distantes tenham atualizações menores. Isso produz um efeito como se o neurônio winner "puxasse" os outros neurônios.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2AHOuIfZ3DzWKqAXuq.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2AHOuIfZ3DzWKqAXuq.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1280%2F0%2AHOuIfZ3DzWKqAXuq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1280%2F0%2AHOuIfZ3DzWKqAXuq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O algoritmo da SOM termina quando a feature map para de mudar.&lt;/p&gt;




&lt;h1&gt;
  
  
  Na Prática!
&lt;/h1&gt;

&lt;p&gt;Neste artigo vamos criar uma SOM que aprende cores. Aqui usamos uma biblioteca chamada MiniSom, que contém uma implementação simples do Self Organizing Maps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import sys
sys.path.insert(0, '../')
from minisom import MiniSom
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
%matplotlib inline

# read the image
img = plt.imread('style.jpg')
# reshaping the pixels matrix
pixels = np.reshape(img, (img.shape[0]*img.shape[1], 3))

# SOM initialization and training
print('training...')
som = MiniSom(3, 3, 3, sigma=1.,
learning_rate=0.2, neighborhood_function='bubble') # 3x3 = 9 final colors
som.random_weights_init(pixels)
starting_weights = som.get_weights().copy() # saving the starting weights
som.train_random(pixels, 500)
print('quantization...')
qnt = som.quantization(pixels) # quantize each pixels of the image
print('building new image...')
clustered = np.zeros(img.shape)
for i, q in enumerate(qnt): # place the quantized values into a new image
    clustered[np.unravel_index(i, dims=(img.shape[0], img.shape[1]))] = q
print('done.')

# show the result
plt.figure(figsize=(7, 7))
plt.figure(1)
plt.subplot(221)
plt.title('original')
plt.imshow(img)
plt.subplot(222)
plt.title('result')
plt.imshow(clustered)
plt.subplot(223)
plt.title('initial colors')
plt.imshow(starting_weights, interpolation='none')
plt.subplot(224)
plt.title('learned colors')
plt.imshow(som.get_weights(), interpolation='none')
plt.tight_layout()
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Treinar uma rede SOM com essa biblioteca é extremamente simples, com apenas 4 linhas foi possível treinar o nosso modelo e produzir as saídas abaixo, mostrando as cores aprendidas pela rede.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A6GiM1OY2GKblsLlaJxMGew.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A6GiM1OY2GKblsLlaJxMGew.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F503%2F1%2A6GiM1OY2GKblsLlaJxMGew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F503%2F1%2A6GiM1OY2GKblsLlaJxMGew.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Referências:
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://www.cs.bham.ac.uk/~jxb/NN/l16.pdf" rel="noopener noreferrer"&gt;Self Organizing Maps: Fundamentals&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JustGlowing/minisom" rel="noopener noreferrer"&gt;Library MiniSom&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://towardsdatascience.com/self-organizing-maps-ff5853a118d4" rel="noopener noreferrer"&gt;Self Organizing Maps — Towards Data Science&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>neuralnetwork</category>
    </item>
    <item>
      <title>Aprendizado não supervisionado com K-means</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Mon, 28 Oct 2019 01:59:16 +0000</pubDate>
      <link>https://dev.to/giselyalves13/aprendizado-nao-supervisionado-com-k-means-106f</link>
      <guid>https://dev.to/giselyalves13/aprendizado-nao-supervisionado-com-k-means-106f</guid>
      <description>&lt;p&gt;Este artigo trata sobre aprendizado não supervisionado, o método de aprendizado de máquina sem precisar de dados pré-rotulados. No aprendizado não supervisionado existe uma técnica chamada Clustering (ou Aglomeração) que serve exatamente para agrupar dados que tenham algumas características parecidas. Muitas vezes essas técnicas são usadas justamente para rotular dados para que seja possível utilizá-los em um aprendizado supervisionado. O agrupamento dos dados podem ser calculados de muitos modos. Aqui explico um deles, o algoritmo de K-means.&lt;/p&gt;

&lt;h1&gt;
  
  
  K-means
&lt;/h1&gt;

&lt;p&gt;Este é um dos mais simples e mais rápidos métodos de Clustering. Ele tenta separar os dados em K (um número predefinido) clusters, de acordo com a distância de cada ponto até algo chamado de centroide. Um centroide é como um protótipo para um cluster. Na maioria das técnicas, K pontos aleatórios do dataset são escolhidos para serem as coordenadas dos centroides iniciais. Então cada instância desses dados é atribuída ao centroide mais próximo. Nas demais iterações a posição dos centroides é calculada através da distancia média entre todos os pontos atribuídos àquele centroide na última iteração. O algoritmo termina quando a posição dos centroides não é mais modificada ou a distancia dessa mudança é menor que um threshold predefinido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A8eKtGLTpuThr6Q-pSiGn4g.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A8eKtGLTpuThr6Q-pSiGn4g.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F367%2F1%2A8eKtGLTpuThr6Q-pSiGn4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F367%2F1%2A8eKtGLTpuThr6Q-pSiGn4g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AfTMJ0hlH6SByilzPQ3wHpA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AfTMJ0hlH6SByilzPQ3wHpA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F369%2F1%2AfTMJ0hlH6SByilzPQ3wHpA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F369%2F1%2AfTMJ0hlH6SByilzPQ3wHpA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AWF3AdvRSenOtuvUHTaphEA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AWF3AdvRSenOtuvUHTaphEA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F372%2F1%2AWF3AdvRSenOtuvUHTaphEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F372%2F1%2AWF3AdvRSenOtuvUHTaphEA.png"&gt;&lt;/a&gt;&lt;/p&gt;
 Mudança de centroides 

 

&lt;p&gt;Criar clusters com K-means em Python é muito simples também. Vejamos o código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=5)
kmeans.fit(data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas, como escolher o número correto de clusters? A resposta para essa pergunta é bastante subjetiva, entretanto, existem muitos métodos para calcular o melhor número e dois deles explico abaixo, Elbow e Average Silhouette métodos.&lt;/p&gt;

&lt;h1&gt;
  
  
  Elbow
&lt;/h1&gt;

&lt;p&gt;Neste método é preciso rodar seu algoritmo de clustering com alguns valores, por exemplo, de 1 a 10. Calcular a função de custo, a soma dos quadrados das distâncias internas dos clusters, e traçá-la em um gráfico. O melhor número para a quantidade de clusters é quando a adição de um novo cluster não muda significativamente a função de custo. Isso geralmente acontece no "cotovelo" da linha.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fproxy%2F0%2AjWe7Ns_ubBpOaemM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fproxy%2F0%2AjWe7Ns_ubBpOaemM.png"&gt;&lt;/a&gt;&lt;/p&gt;
 Exemplo de um gráfico com a soma dos quadrados das distancias 



&lt;h1&gt;
  
  
  Average Silhouette
&lt;/h1&gt;

&lt;p&gt;A análise por Silhouette mede o quão bem um ponto se encaixa em um cluster. Neste método um gráfico é feito medindo quão perto os pontos de um cluster estão dos pontos de outro cluster mais próximo. O coeficiente de Silhouette quando próximo de +1, indica que os pontos estão muito longe dos pontos do outro cluster, e quando próximo de 0, indica que os pontos então muito perto ou até interseccionando um outro cluster.&lt;/p&gt;

&lt;p&gt;Para calcular o coeficiente de Silhouette é preciso definir a distância média de um ponto para todos os outros pontos em seu cluster  &lt;em&gt;(a(i))&lt;/em&gt; e também definir a distância média até os pontos do cluster mais próximo  &lt;em&gt;(b(i))&lt;/em&gt;. Então, o coeficiente de Silhouette é calculado assim:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;s(i) = (b(i) - a(i)) / max(b(i), a(i))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para visualizar a análise feita com Silhouette, vamos olhar para o cluster inteiro. Para isso podemos calcular o score médio do Silhouette pegando a média de todos os exemplos no dataset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2A43jiGnUr-eDyQ1OO.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2A43jiGnUr-eDyQ1OO.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F0%2A43jiGnUr-eDyQ1OO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F0%2A43jiGnUr-eDyQ1OO.png"&gt;&lt;/a&gt;&lt;/p&gt;
 Exemplo de análise com Silhouette 






&lt;p&gt;Agora, vamos ver o K-means e os métodos para avaliar o número de clusters utilizados em um dataset real. Os dados usado aqui são sobre o consumo em e-commerces de clientes brasileiros. Abaixo está o código para normalizar os dados e criar os gráficos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mms = MinMaxScaler()
mms.fit(costumers_dataset)
data_transformed = mms.transform(costumers_dataset)
def plot_clustering(data, labels, title=None):
    x_min, x_max = np.min(data, axis=0), np.max(data, axis=0)
    data = (data - x_min) / (x_max - x_min)
    fig = plt.figure(1, figsize=(4, 3))
    plt.figure(figsize=(6, 4))
    plt.scatter(data[:, 0], data[:, 1],
                 c=labels.astype(np.float))
    plt.xticks([])
    plt.yticks([])
    if title is not None:
        plt.title(title, size=17)
    plt.axis('off')
    plt.tight_layout(rect=[0, 0.03, 1, 0.95]) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, vamos tentar usar o K-means com 5 clusters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kmeans = KMeans(n_clusters=5)
kmeans.fit(data_transformed)
labels = kmeans.labels_
plot_clustering(data_transformed, labels)
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A3XrPBt6EHJWiEbQ0c-kRcQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A3XrPBt6EHJWiEbQ0c-kRcQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F424%2F1%2A3XrPBt6EHJWiEbQ0c-kRcQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F424%2F1%2A3XrPBt6EHJWiEbQ0c-kRcQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então, essa separação parece um pouco estranha, não? Temos 5 clusters mas temos muita ocorrência de intersecções. Vamos avaliar o dataset com o método Elbow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sum_of_squared_distances = []
K = range(1,15)
for k in K:
    km = KMeans(n_clusters=k)
    km = km.fit(data_transformed)
    Sum_of_squared_distances.append(km.inertia_)
plt.plot(K, Sum_of_squared_distances, 'bx-')
plt.xlabel('k')
plt.ylabel('Sum_of_squared_distances')
plt.title('Elbow Method For Optimal k')
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AMZyDw-_eKeltZ-4j7BXd8w.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AMZyDw-_eKeltZ-4j7BXd8w.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F408%2F1%2AMZyDw-_eKeltZ-4j7BXd8w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F408%2F1%2AMZyDw-_eKeltZ-4j7BXd8w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O gráfico mostra que esse dataset não possui exatamente um "cotovelo". Talvez o número correto de clusters esteja entre 4 e 6. Mas talvez este dataset que construímos não possa ser separado com essa configuração… Vamos ver o coeficiente de Silhouette sobre alguns valores para a quantidade de clusters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;range_n_clusters = [2, 3, 4, 5, 6]
for n_clusters in range_n_clusters:
    # Create a subplot with 1 row and 2 columns
    fig, (ax1, ax2) = plt.subplots(1, 2)
    fig.set_size_inches(18, 7)
    # The 1st subplot is the silhouette plot
    # The silhouette coefficient can range from -1, 1 but in this example all
    # lie within [-0.1, 1]
    ax1.set_xlim([-0.1, 1])
    # The (n_clusters+1)*10 is for inserting blank space between silhouette
    # plots of individual clusters, to demarcate them clearly.
    ax1.set_ylim([0, len(data_transformed) + (n_clusters + 1) * 10])
    # Initialize the clusterer with n_clusters value and a random generator
    # seed of 10 for reproducibility.
    clusterer = KMeans(n_clusters=n_clusters, random_state=10)
    cluster_labels = clusterer.fit_predict(data_transformed)
# The silhouette_score gives the average value for all the samples.
    # This gives a perspective into the density and separation of the formed
    # clusters
    silhouette_avg = silhouette_score(data_transformed, cluster_labels)
    print("Para n_clusters =", n_clusters,
          "O score_silhouette médio é :", silhouette_avg)
    # Compute the silhouette scores for each sample
    sample_silhouette_values = silhouette_samples(data_transformed, cluster_labels)
    y_lower = 10
    for i in range(n_clusters):
        # Aggregate the silhouette scores for samples belonging to
        # cluster i, and sort them
        ith_cluster_silhouette_values = \
            sample_silhouette_values[cluster_labels == i]
        ith_cluster_silhouette_values.sort()
        size_cluster_i = ith_cluster_silhouette_values.shape[0]
        y_upper = y_lower + size_cluster_i
        color = cm.nipy_spectral(float(i) / n_clusters)
        ax1.fill_betweenx(np.arange(y_lower, y_upper),
                          0, ith_cluster_silhouette_values,
                          facecolor=color, edgecolor=color,       alpha=0.7)
        # Label the silhouette plots with their cluster numbers at the middle
        ax1.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))
        # Compute the new y_lower for next plot
        y_lower = y_upper + 10  # 10 for the 0 samples
    ax1.set_title("The silhouette plot for the various clusters.")
    ax1.set_xlabel("The silhouette coefficient values")
    ax1.set_ylabel("Cluster label")
    # The vertical line for average silhouette score of all the values
    ax1.axvline(x=silhouette_avg, color="red", linestyle="--")
    ax1.set_yticks([])  # Clear the yaxis labels / ticks
    ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])
    # 2nd Plot showing the actual clusters formed
    colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
    ax2.scatter(data_transformed[:, 0], data_transformed[:, 1], marker='.', s=30, lw=0, alpha=0.7,
                c=colors, edgecolor='k')
    # Labeling the clusters
    centers = clusterer.cluster_centers_
    # Draw white circles at cluster centers
    ax2.scatter(centers[:, 0], centers[:, 1], marker='o',
                c="white", alpha=1, s=200, edgecolor='k')
    for i, c in enumerate(centers):
        ax2.scatter(c[0], c[1], marker='$%d$' % i, alpha=1,
                    s=50, edgecolor='k')
    ax2.set_title("The visualization of the clustered data.")
    ax2.set_xlabel("Feature space for the 1st feature")
    ax2.set_ylabel("Feature space for the 2nd feature")
    plt.suptitle(("Silhouette analysis for KMeans clustering on sample data "
                  "with n_clusters = %d" % n_clusters),
                 fontsize=14, fontweight='bold')
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abaixo temos a resposta desse algoritmo. Os gráficos estão separados por quantidade de clusters utilizados. Os gráficos da esquerda nos mostram o score da análise com Silhouette e da direita uma visualização dos clusters.&lt;/p&gt;

&lt;p&gt;Para n_clusters = 2 O score_silhouette médio é: 0.24604273339845253&lt;br&gt;&lt;br&gt;
Para n_clusters = 3 O score_silhouette médio é : 0.20670607133321856&lt;br&gt;&lt;br&gt;
Para n_clusters = 4 O score_silhouette médio é : 0.188444914764597&lt;br&gt;&lt;br&gt;
Para n_clusters = 5 O score_silhouette médio é : 0.19090629903451375&lt;br&gt;&lt;br&gt;
Para n_clusters = 6 O score_silhouette médio é : 0.18047082769472864&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Aphs26z7ottYAzh_suClTkg.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Aphs26z7ottYAzh_suClTkg.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2Aphs26z7ottYAzh_suClTkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2Aphs26z7ottYAzh_suClTkg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A0mNvvtuU8KZPV73I0lO58Q.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A0mNvvtuU8KZPV73I0lO58Q.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2A0mNvvtuU8KZPV73I0lO58Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2A0mNvvtuU8KZPV73I0lO58Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AoGB5GT7AxTR6nuJUZkRPvA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AoGB5GT7AxTR6nuJUZkRPvA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2AoGB5GT7AxTR6nuJUZkRPvA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2AoGB5GT7AxTR6nuJUZkRPvA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ASBpQ5TLybsTDVUUaA01MWg.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ASBpQ5TLybsTDVUUaA01MWg.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2ASBpQ5TLybsTDVUUaA01MWg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2ASBpQ5TLybsTDVUUaA01MWg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ACGWTuCPIa8FiUoEL81Q1hA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ACGWTuCPIa8FiUoEL81Q1hA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2ACGWTuCPIa8FiUoEL81Q1hA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1039%2F1%2ACGWTuCPIa8FiUoEL81Q1hA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como podem ver, os coeficientes de Silhouette não nos mostraram números muito bons sobre nenhum dos cenários apresentados. O melhor que podemos fazer aqui é remontar o dataset com outras informações. Talvez remover algumas das informações pode melhorar os resultados.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;O aprendizado não supervisionado usando análise com Cluster pode ser muito fácil de produzir e ao mesmo tempo muito útil e importante para muitas áreas do conhecimento, por exemplo, quais tipos de cliente uma empresa tem, para ter conhecimento sobre qual o jeito certo para fazer propagandas ou para criar produtos melhores para cada tipo de cliente, além disso, outro exemplo é entender sobre algumas espécies na biologia, o pesquisador pode agrupar animais, células, ou qualquer outra coisa de acordo com suas características.&lt;/p&gt;

&lt;p&gt;É importante lembrar que K-means não é a única técnica de Clustering. Existem outras métodos muito úteis como o Hierárquico, que também é muito simples de aprender, ou Expectation-maximization, que é muito utilizado pelos Cientístas de Dados.&lt;/p&gt;




&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;p&gt;O os códigos completos usados para as experiências nesse artigo estão  &lt;a href="https://github.com/giselyalves13/brazillian-ecommerce-analysis" rel="noopener noreferrer"&gt;nesse repositório do Github.&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.datanovia.com/en/lessons/determining-the-optimal-number-of-clusters-3-must-know-methods/" rel="noopener noreferrer"&gt;Methods to determining the optimal number of clusters&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://blog.cambridgespark.com/how-to-determine-the-optimal-number-of-clusters-for-k-means-clustering-14f27070048f" rel="noopener noreferrer"&gt;How to determine the optimal number of clusters for K-means&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_silhouette_analysis.html" rel="noopener noreferrer"&gt;Plot silhouette analysis&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://kapilddatascience.wordpress.com/2015/11/10/using-silhouette-analysis-for-selecting-the-number-of-cluster-for-k-means-clustering/" rel="noopener noreferrer"&gt;Silhouette Analysis&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.kaggle.com/olistbr/brazilian-ecommerce" rel="noopener noreferrer"&gt;Dataset usado no artigo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
    </item>
    <item>
      <title>Análise de Sentimento com Aprendizado Supervisionado e não Supervisionado</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Mon, 28 Oct 2019 01:38:34 +0000</pubDate>
      <link>https://dev.to/giselyalves13/analise-de-sentimento-com-aprendizado-supervisionado-e-nao-supervisionado-3j9h</link>
      <guid>https://dev.to/giselyalves13/analise-de-sentimento-com-aprendizado-supervisionado-e-nao-supervisionado-3j9h</guid>
      <description>&lt;p&gt;A Análise de sentimento, ou mineração de opinião, tem como objetivo identificar o sentimento de alguém por qualquer coisa através de um texto em linguagem natural. A análise é feita para encontrar polaridades no texto, se algo escrito é positivo ou negativo, e não necessariamente encontra emoções mais detalhadas. Essa técnica é extremamente usada pelas empresas para, por exemplo, medir a aceitação de um produto.&lt;/p&gt;

&lt;p&gt;As técnicas utilizadas para a análise são de estatística e de machine learning. Neste artigo vou explicar como classificar esses textos usando Redes Neurais, para aprendizado supervisionado, e Orientação Semântica, para um aprendizado não supervisionado (para entender melhor conceitos iniciais de machine learning veja esse artigo  &lt;a href="https://medium.com/infosimples-br/principais-conceitos-por-tras-do-machine-learning-a4b942d5d309?source=collection_home---4------2---------------------" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;).&lt;/p&gt;




&lt;h1&gt;
  
  
  Redes Neurais Recorrentes (RNN)
&lt;/h1&gt;

&lt;p&gt;As RNNs reconhecem padrões em entradas sequenciais e são usadas para diversos tipos de entradas. As decisões tomadas no tempo t-1 afetarão as decisões no tempo t. Diferente das Redes Neurais comuns, as Redes Recorrentes não recebem apenas a entrada vinda do dataset, mas também recebem o estado da unidade anterior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ANKhwsOYNUT5xU7Pyf6Znhg.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ANKhwsOYNUT5xU7Pyf6Znhg.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2706%2F1%2ANKhwsOYNUT5xU7Pyf6Znhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2706%2F1%2ANKhwsOYNUT5xU7Pyf6Znhg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entretanto, RNNs básicas não são muito boas para sequências que dependam de uma longa memória. Por este motivo iremos usar a LSTM (Long-Short Term Memory), uma arquitetura baseada na RNN.&lt;/p&gt;

&lt;h1&gt;
  
  
  LSTM
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A8v0YY4gZ8YC8MgCgHMXGXw.jpeg%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A8v0YY4gZ8YC8MgCgHMXGXw.jpeg%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1044%2F1%2A8v0YY4gZ8YC8MgCgHMXGXw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1044%2F1%2A8v0YY4gZ8YC8MgCgHMXGXw.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;
 σ = função sigmoid; tanh = tangente hiperbólica 



&lt;p&gt;A imagem acima demonstra a arquitetura de uma LSTM. Esse tipo de rede possui 3 componentes:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;forget gate&lt;/em&gt;: Aqui a rede vai “esquecer” o que for desnecessário. Passando a nova entrada e a saída da camada anterior por uma camada sigmoidal, onde tudo que for removido será transformado em 0. Essa camada ainda é multiplicada pelo estado (memória) da célula anterior.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;input gate&lt;/em&gt;: Essa parte é responsável por adicionar informação ao estado da célula. Primeiro é feita uma verificação, parecida com o forget gate, com uma sigmoid. Isto é feito para repassar apenas as informações importantes, que precisam ser adicionadas. Depois um vetor é criado pela tanh, contendo todos os possíveis valores que podem ser adicionados. O resultado desses dois passos são multiplicados e depois somados com a saída do forget gate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;output gate&lt;/em&gt;: Nesse passo, a rede decide qual será a sua saída. Assim como nas etapas anteriores, existe uma sigmoid para normalizar e selecionar quais os valores que precisam estar na saída. Além disso, o estado atual da célula é passado por outra tanh para gerar todos os valores possíveis. Essas duas camadas são multiplicadas, formando o output gate.&lt;/p&gt;

&lt;h1&gt;
  
  
  Na prática!
&lt;/h1&gt;

&lt;p&gt;O dataset usado aqui é um dataset público, chamado "Yelp" que contém milhares de revisões sobre vários tipos de comércios.&lt;/p&gt;

&lt;p&gt;Este dataset vem com uma coluna chamada "stars", com a classificação de cada uma das revisões. Aqui adiciono a coluna "sentiment" para categorizar a polarização das revisões.&lt;/p&gt;

&lt;p&gt;Para qualquer tarefa envolvendo textos são necessários alguns pré-processamentos. Nesse caso, vamos utilizar a tokenização. Esse método usa uma sequência de texto e separa todas as suas palavras, removendo algumas pontuações. No código abaixo também foram retirados todos os caracteres especiais.&lt;/p&gt;

&lt;p&gt;O modelo que vamos utilizar é bem simples, apenas com uma camada do LSTM e uma camada densa no final.&lt;/p&gt;

&lt;p&gt;Essa rede super simples, com uma época, conseguiu 75% de acurácia com 15.000 dados (pouquíssimos dados).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Train on 10800 samples, validate on 1200 samples  
Epoch 1/1  
10800/10800 [==============================] - 1334s 124ms/step - loss: 0.7541 - acc: 0.6944 - val_loss: 0.6426 - val_acc: 0.7492  
Loss score: 0.61  
Test Accuracy: 75.37
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O dataset  &lt;code&gt;(pos = 9908; neutral = 2385; neg = 2707)&lt;/code&gt;  tem "pos" como a classe predominante, com 66% dos dados. Dado isso, o baseline para esse teste teria que ser uma acurácia de 66%, porque caso "chutássemos" todas as labels como positivas acertaríamos exatamente isso. O que nos mostra que esse modelo realmente aprendeu algo.&lt;/p&gt;

&lt;p&gt;Entretanto, devemos tomar cuidado. O método de amostragem usado, apesar de ter a mesma proporção de dados da classe dominante no dataset, não considera a distribuição dos dados quando seleciona as instâncias. Isso pode gerar um modelo enviesado. Um método melhor seria selecionar essas instancias mantendo a proporção da população.&lt;/p&gt;

&lt;p&gt;Mas, e se os dados não conterem nenhuma classificação numérica, ou seja, nenhum rótulo?&lt;/p&gt;




&lt;h1&gt;
  
  
  Orientação Semântica
&lt;/h1&gt;

&lt;p&gt;Existem algumas outras formas de classificar textos sem nenhum rótulo. A utilizada neste artigo é a orientação semântica (SO) de uma palavra, que calcula a distância de um termo para outro termo como ‘bom’ ou ‘mal’. O cálculo dessa distância é dado pelo PMI (Pointwise Mutual Information). Onde  &lt;em&gt;t1&lt;/em&gt;  e  &lt;em&gt;t2&lt;/em&gt; podem ser quaisquer palavras e  &lt;em&gt;P(tx)&lt;/em&gt;  são suas probabilidades de aparecerem no texto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AeceM1h65vUxwlQJ-X9HF7w.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AeceM1h65vUxwlQJ-X9HF7w.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F304%2F1%2AeceM1h65vUxwlQJ-X9HF7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F304%2F1%2AeceM1h65vUxwlQJ-X9HF7w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E a orientação semântica de uma palavra é calculada com base nos resultados do PMI, usando um termo (&lt;em&gt;t&lt;/em&gt;) da frase analisada e comparando com algum termo pertencente ao conjunto de termos (&lt;em&gt;t’&lt;/em&gt;) positivos (&lt;em&gt;V+&lt;/em&gt;) ou negativos (&lt;em&gt;V-&lt;/em&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Au8DrJfGwfDqaAsCtzaHA7w.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Au8DrJfGwfDqaAsCtzaHA7w.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F571%2F1%2Au8DrJfGwfDqaAsCtzaHA7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F571%2F1%2Au8DrJfGwfDqaAsCtzaHA7w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Na prática!&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Para essa tarefa coletei alguns tweets que continham a hashtag #WomensWave (um dos Trending Topics no Twitter sobre as eleições americanas).&lt;/p&gt;

&lt;p&gt;Como no código anterior, aqui também é feita uma tokenização no pré-processamento. Como os tweets podem ter muitas expressões que não são reconhecidas como token é preciso deixá-las explícitas. Essas expressões estão sendo identificadas aqui com regex.&lt;/p&gt;

&lt;p&gt;Além do pré-processamento, é necessário tirar algumas  &lt;em&gt;stopwords&lt;/em&gt;. Stopwords são palavras que em geral não tem um significado, como algumas conjunções e artigos.&lt;/p&gt;

&lt;p&gt;Nessa parte coletamos a frequência de cada palavra e a frequência da co-ocorrência entre duas palavras no texto.&lt;/p&gt;

&lt;p&gt;Quando um texto é analisado, usar um contexto torna essa análise mais real do que olhar para as palavras separadamente. Por isso a matriz de co-ocorrência é montada.&lt;/p&gt;

&lt;p&gt;Aqui é calculada a probabilidade dos termos para que, posteriormente, seja calculado o PMI e o SO.&lt;/p&gt;

&lt;p&gt;Abaixo seguem os vocabulários positivos e negativos e os cálculos do PMI e SO&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;As palavras mais positivas e as mais negativas: TOP POS:   
[(‘diversity’, 13.247582522786834),   
(‘#usmidtermelections’, 11.880054410636202),   
(‘guy’, 10.995531628056138),   
(‘beating’, 10.647393653845928),   
(‘general’, 10.647393653845928),  
(‘function’, 10.440942776378503),   
(‘adding’, 10.358613835175579),   
(‘diverse’, 9.880054410636202),  
(‘goddamned’, 8.866248611111173),   
(‘#electionresults2’, 8.866248611111173)]TOP NEG:   
[(‘control’, -6.451211111832329),   
(‘sad’, -9.451211111832329),   
(‘believe’, -9.451211111832329),   
(‘1950’, -9.451211111832329),   
(‘blinded’, -10.451211111832329),   
(‘[https://t.co/nsvwwzd1dx'](https://t.co/nsvwwzd1dx'), -10.451211111832329),   
(‘cant’, -10.451211111832329),   
(‘feel’, -10.451211111832329),   
(‘civilty’, -10.451211111832329),   
(‘flow’, -10.451211111832329)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vocês podem perceber que algumas palavras não parecem ser o que elas foram classificadas. Isso porque a análise feita aqui foi bem simples, olhando apenas para termos próximos. Para que um aprendizado não supervisionado seja mais assertivo pode ser preciso também uma análise linguística, de como a frase é formada, e com isso identificar meios naturais de expressão.&lt;/p&gt;

&lt;p&gt;Para finalizar, criei uma word cloud com o resultado dos termos positivos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A04fetI8dOJY4DOGlD3qdzw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A04fetI8dOJY4DOGlD3qdzw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F600%2F1%2A04fetI8dOJY4DOGlD3qdzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F600%2F1%2A04fetI8dOJY4DOGlD3qdzw.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;p&gt;Esse artigo foi baseado principalmente nesses dois outros artigos sobre  &lt;a href="https://marcobonzanini.com/2015/05/17/mining-twitter-data-with-python-part-6-sentiment-analysis-basics/" rel="noopener noreferrer"&gt;Mineração de dados do Twitter&lt;/a&gt; e sobre  &lt;a href="https://towardsdatascience.com/understanding-lstm-and-its-quick-implementation-in-keras-for-sentiment-analysis-af410fd85b47" rel="noopener noreferrer"&gt;LSTM&lt;/a&gt;. Abaixo deixo mais algumas outras referências e meus repositórios no github com os dois projetos completos, incluindo o código da coleta dos tweets e da word cloud.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/giselyalves13/sentiment_analyses" rel="noopener noreferrer"&gt;Meu github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.datacamp.com/community/tutorials/wordcloud-python" rel="noopener noreferrer"&gt;Generating WordClouds in Python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=9zhrxE5PQgY" rel="noopener noreferrer"&gt;LSTM Networks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/yelp-dataset/yelp-dataset/version/4#yelp_review.csv" rel="noopener noreferrer"&gt;Yelp dataset&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
    </item>
    <item>
      <title>Entendendo Redes Convolucionais (CNNs)</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Mon, 28 Oct 2019 01:28:40 +0000</pubDate>
      <link>https://dev.to/giselyalves13/entendendo-redes-convolucionais-cnns-42h9</link>
      <guid>https://dev.to/giselyalves13/entendendo-redes-convolucionais-cnns-42h9</guid>
      <description>&lt;p&gt;O reconhecimento de imagem é um clássico problema de classificação, e as Redes Neurais Convolucionais possuem um histórico de alta acurácia para esse problema. A primeira aplicação com sucesso de uma CNN foi desenvolvida por  &lt;a href="http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf" rel="noopener noreferrer"&gt;Yann LeCun em 1998&lt;/a&gt;, com sete camadas entre convoluções e fully connected. Desde então as CNNs ficaram cada vez mais profundas e complexas, como AlexNet em 2012, que, apesar de ter apenas oito camadas (cinco convoluções e três fully connected), apresenta sessenta milhões de parâmetros, e a GoogleNet com vinte e duas camadas e quatro milhões de parâmetros.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2154%2F1%2AHMP8TthpVRljInDPoNHS5A.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2154%2F1%2AHMP8TthpVRljInDPoNHS5A.jpeg" alt="Rede AlexNet com 8 camadas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt; &lt;em&gt;Arquitetura da rede LeNet5&lt;/em&gt; &lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Antes de entender como funciona uma Rede Convolucional, é interessante conhecer qual foi a inspiração biológica para essa arquitetura. Em 1962, Hubel e Wiesel fizeram um experimento mostrando que alguns neurônios são ativados juntos quando expostos a algumas linhas ou curvas, conseguindo assim produzir o reconhecimento visual.&lt;/p&gt;

&lt;p&gt;Essa é a basicamente a ideia principal de uma Rede Convolucional: filtrar linhas, curvas e bordas e em cada camada acrescida transformar essa filtragem em uma imagem mais complexa. Vamos entender mais detalhadamente nos próximos tópicos.&lt;/p&gt;

&lt;h1&gt;
  
  
  Entradas
&lt;/h1&gt;

&lt;p&gt;Quando falamos em reconhecimento/classificação de imagens, as entradas são usualmente matrizes tridimensionais com altura e largura (de acordo com as dimensões da imagem) e profundidade, determinada pela quantidade de canais de cores. Em geral as imagens utilizam três canais, RGB, com os valores de cada pixel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F598%2F1%2AVZ2D3BS9avtqzOMvj-9vbQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F598%2F1%2AVZ2D3BS9avtqzOMvj-9vbQ.png" alt="3 Matrizes de entrada de dados equivalente aos 3 canais rgb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Convoluções
&lt;/h1&gt;

&lt;p&gt;As convoluções funcionam como filtros que enxergam pequenos quadrados e vão “escorregando” por toda a imagem captando os traços mais marcantes. Explicando melhor, com uma imagem 32x32x3 e um filtro que cobre uma área de 5x5 da imagem com movimento de 2 saltos (chamado de stride), o filtro passará pela imagem inteira, por cada um dos canais, formando no final um feature map ou activation map de 28x28x1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F502%2F1%2AOj4LnMvcbPRw2P9rf7TAgA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F502%2F1%2AOj4LnMvcbPRw2P9rf7TAgA.png" alt="Matriz de entrada com filtro 5x5 gerando a matriz da primeira camada"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt; &lt;em&gt;Entrada de 28x28 dimensões com receptive field de área 5x5.&lt;/em&gt; &lt;/small&gt;&lt;/p&gt;

&lt;p&gt;A profundidade da saída de uma convolução é igual a quantidade de filtros aplicados. Quanto mais profundas são as camadas das convoluções, mais detalhados são os traços identificados com o activation map.&lt;/p&gt;

&lt;p&gt;O filtro, que também é conhecido por kernel, é formado por pesos inicializados aleatoriamente, atualizando-os a cada nova entrada durante o processo de backpropagation. A pequena região da entrada onde o filtro é aplicado é chamada de receptive field.&lt;/p&gt;

&lt;p&gt;Para exemplificar, aqui temos um filtro que representa a curva ao seu lado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F624%2F1%2AcjYNCxLB1n1Q7MNzqSvuRA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F624%2F1%2AcjYNCxLB1n1Q7MNzqSvuRA.png" alt="Matriz de 0s com númerais apenas onde é o filtro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem a abaixo está destacado o receptive field no qual será multiplicado pelo filtro acima.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F329%2F1%2Afgv2LNp9pfQHAWnYYf0H2Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F329%2F1%2Afgv2LNp9pfQHAWnYYf0H2Q.png" alt="Parte da imagem de um rato para ser usada na comparação"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com essa combinação temos como resultado um número alto, indicando uma compatibilidade entre as curvas. Quando a imagem não possui nenhuma compatibilidade esse resultado chega mais próximo a zero.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F711%2F1%2AiCd_mNzjBBv_CcGhzYgwag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F711%2F1%2AiCd_mNzjBBv_CcGhzYgwag.png" alt="Comparação da matriz do filtro com a matriz gerada com a parte da imagem do rato"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além do tamanho do filtro e o stride da convolução como hiperparâmetro, quem está modelando uma CNN também tem que escolher como será o padding. O padding pode ser nenhum, no qual o output da convolução ficará no seu tamanho original, ou zero pad, onde uma borda é adicionada e preenchida com 0's. O padding serve para que as camadas não diminuam muito mais rápido do que é necessário para o aprendizado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1280%2F1%2AciDgQEjViWLnCbmX-EeSrA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1280%2F1%2AciDgQEjViWLnCbmX-EeSrA.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;Exemplo de uma convolução de filtro 3x3 e stride 1 com a entrada utilizando zero pad.&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Função de ativação
&lt;/h1&gt;

&lt;p&gt;As funções de ativação servem para trazer a não-linearidades ao sistema, para que a rede consiga aprender qualquer tipo de funcionalidade. Há muitas funções, como  &lt;a href="https://en.wikipedia.org/wiki/Sigmoid_function" rel="noopener noreferrer"&gt;sigmoid&lt;/a&gt;,  &lt;a href="https://pt.wikipedia.org/wiki/Tangente_hiperb%C3%B3lica" rel="noopener noreferrer"&gt;tanh&lt;/a&gt;  e  &lt;a href="https://pt.wikipedia.org/wiki/Fun%C3%A7%C3%A3o_log%C3%ADstica" rel="noopener noreferrer"&gt;softmax&lt;/a&gt;, mas a mais indicada para redes convolucionais é a  &lt;a href="https://en.wikipedia.org/wiki/Rectifier_(neural_networks)" rel="noopener noreferrer"&gt;Relu&lt;/a&gt;  por ser mais eficiente computacionalmente sem grandes diferenças de acurácia quando comparada a outras funções. Essa função zera todos os valores negativos da saída da camada anterior.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pooling
&lt;/h1&gt;

&lt;p&gt;Uma camada de pooling serve para simplificar a informação da camada anterior. Assim como na convolução, é escolhida uma unidade de área, por exemplo 2x2, para transitar por toda a saída da camada anterior. A unidade é responsável por resumir a informação daquela área em um único valor. Se a saída da camada anterior for 24x24, a saída do pooling será 12x12. Além disso, é preciso escolher como será feita a sumarização. O método mais utilizado é o maxpooling, no qual apenas o maior número da unidade é passado para a saída. Essa sumarização de dados serve para diminuir a quantidade de pesos a serem aprendidos e também para evitar overfitting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F728%2F1%2AWvHC5bKyrHa7Wm3ca-pXtg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F728%2F1%2AWvHC5bKyrHa7Wm3ca-pXtg.gif" alt="Matriz de entrada 4x4 passando por maxpooling e saindo 2x2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt; &lt;em&gt;Maxpooling com 2x2 de área&lt;/em&gt; &lt;small&gt;&lt;/small&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Fully connected
&lt;/h1&gt;

&lt;p&gt;Ao final da rede é colocada uma camada Fully connected, onde sua entrada é a saída da camada anterior e sua saída são  &lt;em&gt;N&lt;/em&gt;  neurônios, com  &lt;em&gt;N&lt;/em&gt;  sendo a quantidade de classes do seu modelo para finalizar a classificação.&lt;/p&gt;




&lt;h1&gt;
  
  
  Na Prática!
&lt;/h1&gt;

&lt;p&gt;Abaixo apresento um código simples de exemplo para a construção de um modelo usando CNNs. No código utilizo o  &lt;a href="https://www.tensorflow.org/" rel="noopener noreferrer"&gt;Tensorflow&lt;/a&gt;, um framework de machine learning, com o  &lt;a href="https://keras.io/" rel="noopener noreferrer"&gt;Keras&lt;/a&gt;, uma API de alto nível para redes neurais. Neste exemplo uso o conjunto de dados Cifar-10 com 60.000 imagens de 32x32 dimensões e dez classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import matplotlib.pyplot as plt  
import numpy as np  
import tensorflow as tf  
from keras.models import Sequential  
from keras.layers import Dense  
from keras.layers import Flatten  
from keras.layers import Dropout  
from keras.optimizers import SGD  
from keras.layers.convolutional import Conv2D  
from keras.layers.convolutional import MaxPooling2D  
from keras.utils import np_utils  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Loading the CIFAR-10 datasets
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from keras.datasets import cifar10batch_size = 32   
n_classes = 10   
epochs = 40(x_train, y_train), (x_test, y_test) = cifar10.load_data()height = x_train.shape[1]  
width = x_train.shape[2]# Validation dataset splitting  
x_val = x_train[:5000,:,:,:]  
y_val = y_train[:5000]  
x_train = x_train[5000:,:,:,:]  
y_train = y_train[5000:]print('Training dataset: ', x_train.shape, y_train.shape)  
print('Validation dataset: ', x_val.shape, y_val.shape)  
print('Test dataset: ', x_test.shape, y_test.shape)

Training dataset: (45000, 32, 32, 3) (45000, 1)  
Validation dataset: (5000, 32, 32, 3) (5000, 1)  
Test dataset: (10000, 32, 32, 3) (10000, 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Printing some images
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cols=2  
fig = plt.figure()  
print('training:')  
for i in range(5):  
    a = fig.add_subplot(cols, np.ceil(n_classes/float(cols)), i + 1)  
    img_num = np.random.randint(x_train.shape[0])  
    image = x_train[i]  
    id = y_train[i]  
    plt.imshow(image)  
    a.set_title(label_names[id[0]])  
fig.set_size_inches(8,8)  
plt.show()fig = plt.figure()  
print('validation:')  
for i in range(5):  
    a = fig.add_subplot(cols, np.ceil(n_classes/float(cols)), i + 1)  
    img_num = np.random.randint(x_train.shape[0])  
    image = x_val[i]  
    id = y_val[i]  
    plt.imshow(image)  
    a.set_title(label_names[id[0]])  
fig.set_size_inches(8,8)  
plt.show()fig = plt.figure()  
print('test:')  
for i in range(5):  
    a = fig.add_subplot(cols, np.ceil(n_classes/float(cols)), i + 1)  
    img_num = np.random.randint(x_train.shape[0])  
    image = x_test[i]  
    id = y_test[i]  
    plt.imshow(image)  
    a.set_title(label_names[id[0]])  
fig.set_size_inches(8,8)  
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F511%2F1%2AMMIOyG2BN1NOEq_DsPDrTA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F511%2F1%2AMMIOyG2BN1NOEq_DsPDrTA.png" alt="Exemplos de fotos dos conjuntos de treino, validação e teste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Convert labels to categorical
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y_train = np_utils.to_categorical(y_train, n_classes)  
y_val = np_utils.to_categorical(y_val, n_classes)  
y_test = np_utils.to_categorical(y_test, n_classes)# Datasets pre-processing  
x_train = x_train.astype('float32')  
x_val = x_val.astype('float32')  
x_test = x_test.astype('float32')  
x_train /= 255  
x_val /= 255  
x_test /= 255
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este modelo conta com cinco camadas de convoluções e duas camadas de rede fully connected. O otimizador utilizado é o Stochastic Gradient Descent (SGD) com learning rate de 0.01.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_model():  
  model = Sequential()  
  model.add(Conv2D(filters=128, kernel_size=(3, 3), input_shape=(height, width, 3), strides=1, padding='same', activation='relu'))  
  model.add(MaxPooling2D(pool_size=(2,2)))  
  model.add(Conv2D(filters=128, kernel_size=(3, 3), strides=1, activation='relu'))  
  model.add(MaxPooling2D(pool_size=(2,2)))  
  model.add(Dropout(0.25))  
  model.add(Conv2D(filters=64, kernel_size=(2, 2), strides=1, activation='relu'))  
  model.add(MaxPooling2D(pool_size=(1,1)))  
  model.add(Conv2D(filters=32, kernel_size=(2, 2), strides=1, activation='relu'))  
  model.add(MaxPooling2D(pool_size=(1,1)))  
  model.add(Conv2D(filters=32, kernel_size=(2, 2), strides=1, activation='relu'))  
  model.add(MaxPooling2D(pool_size=(1,1)))  
  model.add(Dropout(0.25))  
  model.add(Flatten())  
  model.add(Dense(64, activation='relu'))  
  model.add(Dense(n_classes, activation='softmax'))  
  return modeldef optimizer():  
    return SGD(lr=1e-2)model = create_model()  
model.compile(optimizer=optimizer(),  
              loss='categorical_crossentropy',  
              metrics=['accuracy']  
              )  
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_val,y_val),verbose=1)  
model.summary()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando summary() mostra algumas informações sobre as camadas do seu modelo. Podemos ver as dimensões de cada camada e os parâmetros aprendidos em cada etapa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F566%2F1%2AE9t3dfAiiOBS4IdV9-IdOA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F566%2F1%2AE9t3dfAiiOBS4IdV9-IdOA.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scores = model.evaluate(x_test, y_test, verbose=0)  
print("Accuracy: %.2f%%" % (scores[1]*100), "| Loss: %.5f" % (scores[0]))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como resultado desse modelo temos:&lt;br&gt;&lt;br&gt;
**Accuracy: 75.24% | Loss: 0.71711&lt;br&gt;&lt;br&gt;
**Apesar da acurácia desse modelo nesse dataset ser de apenas 75%, com CNNs mais complexas a acurácia atingida no Cifar-10 pode chegar a 95%. Esse  &lt;a href="http://rodrigob.github.io/are_we_there_yet/build/classification_datasets_results.html#43494641522d3130" rel="noopener noreferrer"&gt;link&lt;/a&gt;  mostra as redes que obtiveram resultados com as mais altas acurácias em cima do Cifar-10.&lt;/p&gt;




&lt;p&gt;Deixo aqui alguns links de referências usados por mim para escrever este artigo, de onde também peguei algumas imagens. Recomendo a leitura de todos (;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— Stanford CS class CS231n: Convolutional Neural Networks for Visual Recognition :  &lt;a href="http://cs231n.github.io/" rel="noopener noreferrer"&gt;http://cs231n.github.io/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
— A Beginner’s Guide To Understanding Convolutional Neural Networks:  &lt;a href="https://adeshpande3.github.io/adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks/" rel="noopener noreferrer"&gt;https://adeshpande3.github.io/adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
— Neural Networks and Deep Learning Book:  &lt;a href="http://neuralnetworksanddeeplearning.com/chap6.html" rel="noopener noreferrer"&gt;http://neuralnetworksanddeeplearning.com/chap6.html&lt;/a&gt;&lt;br&gt;&lt;br&gt;
— Machine Learning Guru Blog:  &lt;a href="http://machinelearninguru.com/computer_vision/basics/convolution/convolution_layer.html" rel="noopener noreferrer"&gt;http://machinelearninguru.com/computer_vision/basics/convolution/convolution_layer.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>machinelearning</category>
      <category>keras</category>
      <category>python</category>
      <category>deeplearnig</category>
    </item>
    <item>
      <title>Visualização de dados com Seaborn</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Mon, 28 Oct 2019 01:14:58 +0000</pubDate>
      <link>https://dev.to/giselyalves13/visualizacao-de-dados-com-seaborn-2892</link>
      <guid>https://dev.to/giselyalves13/visualizacao-de-dados-com-seaborn-2892</guid>
      <description>&lt;p&gt;Nesse artigo vamos entender um pouco melhor como fazer uma análise exploratória simples e como a biblioteca Seaborn pode ajudar nesse processo melhorando a visualização dos dados.&lt;/p&gt;

&lt;p&gt;Na análise exploratória dos dados, também conhecida como EDA, é feita uma investigação para que se possa ter um resumo do que os dados podem nos dizer. Por exemplo, a média, o desvio padrão e a distribuição dos dados são informações importantes para entender o comportamento de um dataset portanto sempre estão presentes quando uma EDA é feita. Essa análise também é a base para que se possa criar hipóteses e posteriormente fazer inferências sobre os dados.&lt;/p&gt;

&lt;p&gt;Vou usar um dataset criado pelo site PetFinder.my com diversas informações sobre a adoção de 150.000 cães e gatos. Esse dataset está  &lt;a href="https://www.kaggle.com/c/petfinder-adoption-prediction" rel="noopener noreferrer"&gt;disponível no Keaggle&lt;/a&gt;  para uma competição. Abaixo mostro alguns dados do conjunto para entendermos melhor o que será analisado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AWJSYktW53tzDtDf7WtvL4Q.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AWJSYktW53tzDtDf7WtvL4Q.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F722%2F1%2AWJSYktW53tzDtDf7WtvL4Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F722%2F1%2AWJSYktW53tzDtDf7WtvL4Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui podemos ver que temos nome (Name), idade (Age), raça (Breed), cores (Color), entre outras variáveis no dataset e, apesar da maioria das colunas possuir apenas números, não se enganem, tirando a idade e ‘Fee’ que é a taxa paga pela adoção, todos os outros dados são categóricos. Nesse dataset também existem alguns arquivos com a correspondência desses números com a devida categoria, por exemplo, na variável ‘tipo’ (Type) 1 significa cão e 2 significa gato.&lt;/p&gt;

&lt;p&gt;Aqui está o início do código que estou usando, com os imports. Aqui também usei o Jupyter notebook :)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd  
import seaborn as sns  
import matplotlib.pyplot as plt  
%matplotlib inline #usar esse comando para não precisar dar plt.show em cada gráfico  
df = pd.read_csv('train.csv') #esse é o nosso dataframe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vou usar o comando  &lt;code&gt;df.describe()&lt;/code&gt; para ver informações como a média, a quantidade de dados e o desvio padrão de cada coluna.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Asv7JzEq3nEu1Kk_Nq1Sz4g.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Asv7JzEq3nEu1Kk_Nq1Sz4g.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F255%2F1%2Asv7JzEq3nEu1Kk_Nq1Sz4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F255%2F1%2Asv7JzEq3nEu1Kk_Nq1Sz4g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A gente já consegue ver que a média de idade (coluna ‘Age’) dos animais é de 10 meses entretanto nesse caso a média não nos dá uma visão da realidade já que a mediana (50%) é 3, ou seja, metade dos animais do dataset tinha até 3 meses na adoção. Também vemos que a idade máxima relatada são 255 meses, ou 21 anos (velhinhos❤). Como esse dataset possui muitos dados categóricos numéricos, algumas das descrições podem não fazer sentido mas podemos extrair algumas coisas já de cara como em ‘Type’ a média é 1,45 e com isso já sabemos que há mais animais do tipo 1 (cachorros) do que do tipo 2 (gatos).&lt;/p&gt;

&lt;p&gt;Se usarmos o comando  &lt;code&gt;df.describe(include=`all`)&lt;/code&gt;  é possível ver informações sobre os nossos dados categóricos também, como quantidade de dados únicos.&lt;/p&gt;

&lt;p&gt;É importante entender a distribuição dos dados e isso pode ser feito de diversas formas. Começando pela mais comum, o gráfico distplot mostra a combinação de um histograma com a linha do KDE. Um histograma é basicamente um gráfico de barras para variáveis quantitativas, que são divididas em intervalos, e nos mostra a frequência de dados que se tem em cada intervalo; o KDE é uma estimativa da densidade desses dados, calculando a probabilidade de se ter um ponto naquele local do gráfico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sns.distplot(df['Age'])  
sns.distplot(df['Age'], kde=False) #Para não ver a linha do KDE no gráfico use o parâmetro 'kde' igual a 'False', que por padrão é igual a 'True' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AxVU6COvXgPETWoizHK1fbA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AxVU6COvXgPETWoizHK1fbA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F381%2F1%2AxVU6COvXgPETWoizHK1fbA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F381%2F1%2AxVU6COvXgPETWoizHK1fbA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AC09KlH-yQ2ZPKEw4GFp4iQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AC09KlH-yQ2ZPKEw4GFp4iQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F391%2F1%2AC09KlH-yQ2ZPKEw4GFp4iQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F391%2F1%2AC09KlH-yQ2ZPKEw4GFp4iQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesses gráficos vemos que as idades dos animais, em meses, estão concentradas no começo do gráfico, ou seja, a maior parte dos animais adotados ainda é filhote (Como já mostrei usando a mediana no comando ‘describe’). Outra coisa para se notar é que o gráfico não segue uma distribuição normal, sua distribuição é enviesada para direita, essa é uma informação usada na escolha de outros métodos estatísticos a serem usados nesse dataset.&lt;/p&gt;

&lt;p&gt;Um gráfico simples mas muito útil que podemos usar é o countplot, um gráfico de barras mostrando a contagem das variáveis. Vamos ver como estão distribuídos os valores de ‘MaturitySize’. Essa coluna representa o tamanho do animal quando atinge a maturidade e seus valores são de 1 à 4, sendo 1 pequeno e 4 grande.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sns.countplot(x='MaturitySize', data=df)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A6LuLmvqBNTLkPMO1VjG39A.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A6LuLmvqBNTLkPMO1VjG39A.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F405%2F1%2A6LuLmvqBNTLkPMO1VjG39A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F405%2F1%2A6LuLmvqBNTLkPMO1VjG39A.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O gráfico mostra que a maior parte dos animais tinham porte médio-pequeno. Esse gráfico também pode ser feito utilizando a função catplot ao invés do countplot, interface para construção de vários tipos de gráficos categóricos, com o parâmetro  &lt;code&gt;kind=count&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No próximo gráfico, um barplot, conseguimos ver a média de velocidade de adoção por tipo de animal. A linha preta vertical no meio das barras mostra o desvio padrão, no caso dos nossos dados o desvio padrão é bem pequeno então os dados não variam tanto dessa média.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sns.barplot(x='Type', y='AdoptionSpeed', data=df,)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AXQk7ckBdldtNbTUBQduBTw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AXQk7ckBdldtNbTUBQduBTw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2AXQk7ckBdldtNbTUBQduBTw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2AXQk7ckBdldtNbTUBQduBTw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os próximos gráficos são boxplots, um tipo de gráfico com muita informação sobre os dados: Nele conseguimos ver o limite inferior e superior, os quartis, a mediana, como os dados estão distribuídos e os possíveis outliers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Quartis: Os quartis dividem os dados em quatro partes. Ordenando os dados cada quartil vai possuir 25% das observações. Ou seja, os primeiros 25% das observação estarão até o corte do 1º quartil, os próximos 25% até o corte do 2º quartil, etc.&lt;/li&gt;
&lt;li&gt;  Limites: O limite inferior é calculado sendo, geralmente, 1,5 vezes o corte do 1º quartil e o limite superior sendo 1,5 vezes o corte do 3º quartil.&lt;/li&gt;
&lt;li&gt;  O corte do segundo quartil é igual a mediana.&lt;/li&gt;
&lt;li&gt;  Outliers são observações atípicas, muito afastadas da maioria dos dados. Num boxplot esses valores ficam abaixo do limite inferior ou acima do limite superior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2ATmxBdUzCLOmZu6zB.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2ATmxBdUzCLOmZu6zB.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1024%2F0%2ATmxBdUzCLOmZu6zB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1024%2F0%2ATmxBdUzCLOmZu6zB.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora com os dados que estamos usando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sns.boxplot(x='Type', y='AdoptionSpeed', data=df)  
sns.boxplot(x='Type', y='AdoptionSpeed', data=df, hue='Gender')  
sns.boxplot(x='Type', y='Fee', data=df) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AQyOeiqzrPV2xoxqD6k2LVA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AQyOeiqzrPV2xoxqD6k2LVA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2AQyOeiqzrPV2xoxqD6k2LVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2AQyOeiqzrPV2xoxqD6k2LVA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse primeiro boxplot (Velocidade de adoção por tipo de animal) conseguimos ver que não há grande variação na velocidade de adoção dos cães mas que a maior parte deles demora um pouco mais que os gatos para serem adotados, comparando as medianas e as caixas que comportam metade dos dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ABexa8qI29fGDNvONbwQdfQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ABexa8qI29fGDNvONbwQdfQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2ABexa8qI29fGDNvONbwQdfQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F389%2F1%2ABexa8qI29fGDNvONbwQdfQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse gráfico é o quase o mesmo que o anterior mas aqui foi feita uma divisão por gênero do animal ( 1=macho, 2=fêmea, 3=misturado, em casos de grupos adotados) com o parâmetro  &lt;code&gt;hue&lt;/code&gt;  no comando.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AwHVDvWCKamC8ITR7cnR8uQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AwHVDvWCKamC8ITR7cnR8uQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F398%2F1%2AwHVDvWCKamC8ITR7cnR8uQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F398%2F1%2AwHVDvWCKamC8ITR7cnR8uQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse último, a taxa paga pela adoção por tipo de animal, é interessante. Não vemos as caixas e mal se vê a linha da mediana, apenas pontos, isso é porquê a maior parte das adoções não teve custo nenhum, então os quartis são 0 e a mediana também, os pontos do gráfico são todos outliers.&lt;/p&gt;

&lt;p&gt;Alguns outros gráficos que mostram a distribuição dos dados são stripplot e o swarmplot. Os dois primeiros gráficos abaixo são stripplots de idade por gênero, o segundo ainda foi subdivido pelo tipo de animal através do parâmetro  &lt;code&gt;hue&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sns.stripplot(x='Gender', y='Age', data=df)  
sns.stripplot(x='Gender', y='Age', data=df, hue='Type', split=True)  
sns.swarmplot(x='Gender', y='Age', data=df)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AZkJHMTmnHiwRKP3omH-hAQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AZkJHMTmnHiwRKP3omH-hAQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F392%2F1%2AZkJHMTmnHiwRKP3omH-hAQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F392%2F1%2AZkJHMTmnHiwRKP3omH-hAQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ASSaDUWp9pkWs7CUUSYHaxw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ASSaDUWp9pkWs7CUUSYHaxw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F392%2F1%2ASSaDUWp9pkWs7CUUSYHaxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F392%2F1%2ASSaDUWp9pkWs7CUUSYHaxw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ATIdCD5WDAyt7wMB-NBr7IQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2ATIdCD5WDAyt7wMB-NBr7IQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F392%2F1%2ATIdCD5WDAyt7wMB-NBr7IQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F392%2F1%2ATIdCD5WDAyt7wMB-NBr7IQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse último é o swarmplot, com as mesmas informações que os stripplots mas não há sobreposição dos dados.&lt;/p&gt;

&lt;p&gt;Os próximos gráficos são sobre correlação, uma métrica do quão relacionadas duas variáveis são. Existem alguns jeitos de calcular a correlação mas vou usar a de Pearson, linear e mais comumente usada, onde os coeficientes da correlação vão de -1 a 1. Valores próximos a -1 significam que as variáveis são fortemente e inversamente correlacionadas: quando uma cresce a outra diminui; valores próximos a 1 são variáveis fortemente e positivamente correlacionadas: as duas crescem ou diminuem juntas, e 0 significa nenhuma correlação.&lt;/p&gt;

&lt;p&gt;Um ponto importante de entender quando falamos de correlação é que uma variável ter correlação com a outra  &lt;strong&gt;não implica que uma cause a outra&lt;/strong&gt;. Por exemplo, um aumento nas vendas de meias em julho pode estar correlacionado com um aumento nas vendas de chás no mesmo mês, mas isso não significa que as pessoas compraram chás porque compraram meias.&lt;/p&gt;

&lt;p&gt;Além dos coeficientes também podemos ver uma correlação em um diagrama de dispersão ou, como é chamado no Seaborn, um scatterplot. Para identificar uma correlação no diagrama os dados devem estar parecidos com o primeiro e último gráfico da imagem abaixo (correlação negativa e positiva, respectivamente). O gráfico do meio representa dados não correlacionados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AXF1FxLmLJBjsmxBChBG-ow.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AXF1FxLmLJBjsmxBChBG-ow.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F768%2F1%2AXF1FxLmLJBjsmxBChBG-ow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F768%2F1%2AXF1FxLmLJBjsmxBChBG-ow.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E abaixo está o scatterplot da idade (Age) versus a taxa de adoção (Fee). No caso dessas duas variáves não há uma correlação aparente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A8k3qEmLFhLXU9C5aAVAtJw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A8k3qEmLFhLXU9C5aAVAtJw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F398%2F1%2A8k3qEmLFhLXU9C5aAVAtJw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F398%2F1%2A8k3qEmLFhLXU9C5aAVAtJw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No pandas existe uma função que mostra os coeficientes de correlação de todas as variáveis, a tabela logo abaixo, e você pode usar esses valores para criar um heatmap, que mapeia os valores de uma matriz usando cores. Isso pode facilitar a identificação de variáveis correlacionadas quando se tem muitas variáveis.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;df.corr()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2APNF_Q9WxUWXhvlRl3JxKQQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2APNF_Q9WxUWXhvlRl3JxKQQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F629%2F1%2APNF_Q9WxUWXhvlRl3JxKQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F629%2F1%2APNF_Q9WxUWXhvlRl3JxKQQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Parte da matriz de correlação&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sns.heatmap(df.corr())&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A5iDS1kjKfMce6SfkTVK44A.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A5iDS1kjKfMce6SfkTVK44A.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F907%2F1%2A5iDS1kjKfMce6SfkTVK44A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F907%2F1%2A5iDS1kjKfMce6SfkTVK44A.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entretanto, o comando  &lt;code&gt;df.corr()&lt;/code&gt;  usa por padrão a correlação de Pearson, que não é a mais indicada quando estamos tratando de dados categóricos como a maioria desse dataset, então criei um outro heatmap usando a correlação V de Crámer, cujo os coeficiente vão de 0 a 1, só para termos números mais reais.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sns.heatmap(corr, annot=True) #annot mostra os coeficientes da matriz&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F28%2F1%2ACuwqeEkP2TXgGN0KJn3Kuw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F28%2F1%2ACuwqeEkP2TXgGN0KJn3Kuw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1122%2F1%2ACuwqeEkP2TXgGN0KJn3Kuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1122%2F1%2ACuwqeEkP2TXgGN0KJn3Kuw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vendo a imagem e os coeficientes percebemos que há bem poucas correlações fortes no dataset, informação útil caso você vá criar modelos preditivos.&lt;/p&gt;

&lt;p&gt;Um exemplo da importância da correlação é a Regressão. A Regressão Linear (existem outros tipos) é um modelo estatístico que tenta encontrar a melhor reta/plano que descreva a relação entre os dados. Assim é possível inferir valores sobre uma das variáveis. Mas para se usar uma regressão os dados (tirando a variável que se quer estimar) não devem estar correlacionados, e daí vem a importância do método. No Seaborn é possível ver graficamente a linha criada por uma regressão usando o comando lmplot ou regplot (o lmplot possui mais opções gráficas como a criação de grids).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2Aofh1EEo3JTTOn-H4.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F0%2Aofh1EEo3JTTOn-H4.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F300%2F0%2Aofh1EEo3JTTOn-H4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F300%2F0%2Aofh1EEo3JTTOn-H4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa não é uma regressão do nosso dataset, mas trouxe aqui para mostrar como seria um boa regressão, capturando boa parte da relação entre os dados.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sns.lmplot(x='Age', y='AdoptionSpeed', data=df, hue='Type' , col='Type')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AQXexCBBhcWC2d1EQgWH8dQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AQXexCBBhcWC2d1EQgWH8dQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F712%2F1%2AQXexCBBhcWC2d1EQgWH8dQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F712%2F1%2AQXexCBBhcWC2d1EQgWH8dQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esses gráficos mostram as retas das regressões entre as variáveis idade e velocidade de adoção, separado em duas colunas pelo tipo de animal, usando os parâmentos  &lt;code&gt;hue&lt;/code&gt;  e  &lt;code&gt;col&lt;/code&gt;. Junto da reta também é mostrada a dispersão dos dados. Só pelo gráfico já é possível ver que uma regressão talvez não se dê tão bem caso precisássemos estimar alguns valores, mas também é possível entender que cães (Type 1) não sofrem muita diferença na velocidade de adoção mesmo estando mais velhos, diferente dos gatos (Type 2) onde a velocidade de adoção aumenta quando idosos.&lt;/p&gt;

&lt;p&gt;Também é possível juntar mais de um gráfico em um só. O jointplot é a junção de um gráfico univariado, nesse caso um histograma, e um bivariado, um scatterplot.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sns.jointplot(x='Age', y='Fee', data=df)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Argeto1n99iZ9_bAG8m9CaQ.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Argeto1n99iZ9_bAG8m9CaQ.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F434%2F1%2Argeto1n99iZ9_bAG8m9CaQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F434%2F1%2Argeto1n99iZ9_bAG8m9CaQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usei novamente a relação idade versus taxa de adoção. A idade está no eixo horizontal, assim como seu histograma na parte superior do gráfico, na vertical está a taxa de adoção e o seu histograma. No meio está o scatterplot mostrando a relação entre as duas variáveis. Podemos ver que para animais mais novos não há muito consenso sobre as taxas, mas para os poucos animais mais velhos, nenhum deles possui taxa para adoção.&lt;/p&gt;

&lt;p&gt;O jointplot pode ser usado com vários outros gráficos mudando seu parâmetro  &lt;code&gt;kind&lt;/code&gt;e dentre as opções estão gráfico de kde ou gráfico de hexágonos que te dá um mapa de calor da relação das variáveis.&lt;/p&gt;

&lt;p&gt;O FacetGrid cria uma matriz/grid em branco que podemos preencher com qualquer gráfico. Abaixo criei um FacetGrid em branco separando as linhas para o tipo de animal e as colunas para o gênero e na linha abaixo preenchi o grid usando o countplot do Seaborn (poderia ser de outra biblioteca) e usei também a velocidade de adoção como valor dos gráficos. Assim temos uma visão da velocidade de adoção separada por tipo e gênero dos animais.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;g = sns.FacetGrid(df, row='Type', col='Gender') #Cria um grid vazio  
g.map(sns.countplot, 'AdoptionSpeed') #preenche com o gráfico
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A_gV9xWV8sNwz5V0573BN1g.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2A_gV9xWV8sNwz5V0573BN1g.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F640%2F1%2A_gV9xWV8sNwz5V0573BN1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F640%2F1%2A_gV9xWV8sNwz5V0573BN1g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É possível mudar as cores e o tamanho do gráficos. Um exemplo é o heatmap que criei para a correlação. O gráfico que usei está estilizado com o mapa de cores (parâmetro  &lt;code&gt;cmap&lt;/code&gt;  ) chamado ‘coolwarm’ . O Seaborn consegue criar gráficos com quaisquer mapas de cores da biblioteca matplotlib (&lt;a href="https://matplotlib.org/users/colormaps.html" rel="noopener noreferrer"&gt;veja aqui&lt;/a&gt;) e também com listas de cores personalizadas. Em um heatmap ainda é possível mudar a cor e espessura das linhas da matriz com os parâmetros  &lt;code&gt;linecolor&lt;/code&gt;  e  &lt;code&gt;linewidths&lt;/code&gt;  .&lt;br&gt;&lt;br&gt;
Outro ponto importante na visualização de dados é o tamanho da imagem. Alguns gráficos tem parâmetros para personalizar seu tamanho mas no geral podemos usar o matplotlib para criar uma figura em branco do tamanho necessário e criar o gráfico por cima. Abaixo é um exemplo do heatmap estilizado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plt.subplots(figsize=(15, 8))  
sns.heatmap(corr, cmap='plasma', linecolor='gray', linewidths=1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Aqos4XleVY1X1RevkjjS2uA.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2Aqos4XleVY1X1RevkjjS2uA.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F853%2F1%2Aqos4XleVY1X1RevkjjS2uA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F853%2F1%2Aqos4XleVY1X1RevkjjS2uA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para finalizar, vou mostrar também o set_style e o set_context do Seaborn. O set_style defini o estilo do gráfico: com ou sem grid, fundo claro ou escuro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sns.set_style('darkgrid')  
sns.countplot(x='MaturitySize', data=df)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AxY2EojED3mMOXvIuTykmiw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AxY2EojED3mMOXvIuTykmiw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F405%2F1%2AxY2EojED3mMOXvIuTykmiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F405%2F1%2AxY2EojED3mMOXvIuTykmiw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já o set_context muda o gráfico de acordo com o contexto que ele vai ser apresentado, por exemplo, a visualização em um poster precisa ser diferente da visualização em relatório comum.&lt;/p&gt;

&lt;p&gt;sns.set_style('whitegrid')&lt;br&gt;&lt;br&gt;
sns.set_context('poster')&lt;br&gt;&lt;br&gt;
sns.countplot(x='MaturitySize', data=df)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AwPs927_ghOAhJfsf8tXyOw.png%3Fq%3D20" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F30%2F1%2AwPs927_ghOAhJfsf8tXyOw.png%3Fq%3D20"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F475%2F1%2AwPs927_ghOAhJfsf8tXyOw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F475%2F1%2AwPs927_ghOAhJfsf8tXyOw.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Claro que muitas análises mostradas nesse artigo são redundantes, mas é importante perceber que há diversas formas de conseguir extrair algo do dados e mostrar, cabe a você decidir o que vai ser melhor para seus dados. Além disso, existem algumas técnicas para uma boa visualização de dados, como o Data Storytelling, mas isso é assunto para um outro artigo ;).&lt;/p&gt;




&lt;h1&gt;
  
  
  Referências e Recomendações
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;  1º  &lt;a href="http://seaborn.pydata.org/" rel="noopener noreferrer"&gt;seaborn.pydata.org/&lt;/a&gt;: Deitem em cima da documentação do Seaborn, é uma biblioteca bem rica!&lt;/li&gt;
&lt;li&gt;  2º  &lt;a href="https://www.udemy.com/share/1001AGA0sfeFtSR3w=/?xref=E0ETdVdXRX4BSUQvCz0GJVUWTx4dChQ%2BVFE=" rel="noopener noreferrer"&gt;Python para Data Science e Machine Learning — COMPLETO&lt;/a&gt;: Fiz esse curso da Udemy e achei bem completo para quem tá começando na área.&lt;/li&gt;
&lt;li&gt;  3º e não menos importante:  &lt;strong&gt;NÃO COMPREM, ADOTEM! ❤&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>datascience</category>
      <category>python</category>
      <category>dataviz</category>
      <category>seaborn</category>
    </item>
    <item>
      <title>Regressão Linear</title>
      <dc:creator>Gisely Alves Brandão</dc:creator>
      <pubDate>Sun, 13 Oct 2019 22:33:02 +0000</pubDate>
      <link>https://dev.to/giselyalves13/regressao-linear-1lf5</link>
      <guid>https://dev.to/giselyalves13/regressao-linear-1lf5</guid>
      <description>&lt;p&gt;Nesse artigo vou explicar o que eu considero como primeiro passo no mundo do Machine Learning: as Regressões. Mas primeiro vamos entender o conceito de regressão linear.&lt;/p&gt;

&lt;p&gt;Em uma visão bem simplista uma regressão é a melhor linha que descreve a relação entre alguns dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Bfmt8mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vw1t7txehpxxeswu6gmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Bfmt8mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vw1t7txehpxxeswu6gmy.png" alt="Reta de regressão linear simples"&gt;&lt;/a&gt; &lt;small&gt; &lt;em&gt;Reta de regressão linear simples&lt;/em&gt; &lt;small&gt;&lt;/small&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Esses dados se dividem em variável dependente, que é a variável que vamos predizer, é a nossa resposta, e uma ou mais variáveis independentes que são as que vamos utilizar para entender a relação e conseguir os resultados.&lt;/p&gt;

&lt;p&gt;Quando ouvimos falar de modelos regressivos, em geral, estamos falando de variáveis dependentes quantitativas. Mas isso não é regra existem regressões para variáveis dependentes qualitativas, como a Regressão Logística.&lt;/p&gt;

&lt;p&gt;Apesar de nesse artigo eu descrever apenas regressões lineares (“retas”) existem regressões para descrever relações não-lineares também.&lt;/p&gt;

&lt;p&gt;Agora, uma regressão serve apenas predizer valores? Não.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;O que uma regressão pode nos dizer?&lt;/strong&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;  Existe relação entre a minha variável dependente (resposta) e a outras variáveis?&lt;/li&gt;
&lt;li&gt;  Quão forte é a relação das variáveis com a variável resposta?&lt;/li&gt;
&lt;li&gt;  Qual delas contribui mais para variável resposta?&lt;/li&gt;
&lt;li&gt;  O quanto cada variável afeta a variável resposta?&lt;/li&gt;
&lt;li&gt;  Essa relação é realmente linear?&lt;/li&gt;
&lt;li&gt;  Quão acurado conseguimos predizer a variável resposta?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Além disso tudo as regressões são modelos explicáveis, ou seja, não são uma caixa-preta que ninguém entende o porquê daquela resposta e dependendo do assunto essa explicabilidade é mais importante do que uma boa acurácia nas predições.&lt;/p&gt;

&lt;h1&gt;
  
  
  Regressão Linear Simples
&lt;/h1&gt;

&lt;p&gt;Uma regressão tem a cara dessa equação aqui (uma equação de reta):&lt;/p&gt;

&lt;p&gt;Y ≈ α + βX.&lt;/p&gt;

&lt;p&gt;Onde Y é a variável dependente, que irá ser predita, X é a minha variável independente, o nosso preditor e α e β são coeficientes/parâmetros que o modelo vai tentar encontrar. Exemplificando: Y podem ser as vendas de uma empresa e X o valor gasto com uma campanha de marketing, assim conseguimos identificar quanto o gasto com marketing pode influenciar nas vendas.&lt;/p&gt;

&lt;p&gt;Lembrem que a regressão quer encontrar melhor reta que descreve a relação entre os dados e para isso é preciso entrar os melhores α e β.&lt;/p&gt;

&lt;p&gt;Para encontrar os coeficientes, essa equação y = a + bx é feita para cada ponto do dataset gerando vários y, a, b estimados. Como o modelo não é perfeito y estimado vai ser diferente do Y real que temos no dataset e essa diferença é chamada de resíduo.  &lt;strong&gt;O objetivo de uma regressão é então encontrar uma reta com os menores resíduos possíveis.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Veja que na primeira equação eu escrevi aproximado ≈ e não igual =, porque a equação completa ainda é somada com os erros acarretados das estimativas.&lt;/p&gt;

&lt;p&gt;Y = α + βX + Є.&lt;/p&gt;

&lt;p&gt;Existem algumas formas diferentes de calcular o erro final do modelo para que ele não fique enviesado e que seja possível medir a qualidade do nosso modelo, entretanto vou explicar uma das mais simples aqui chamada de Média dos Erros ao Quadrado (MSE) que é a soma dos resíduos ao quadrado, ou seja, para cada resíduo de cada ponto iremos colocá-lo ao quadrado e somar todos eles, dividido pelo número de observações. Portanto, esse modelo vai procurar pela reta que possui o menor MSE e declará-la como a que melhor descreve essas relações.&lt;/p&gt;

&lt;p&gt;Não foi tão difícil né?&lt;/p&gt;

&lt;h1&gt;
  
  
  Regressão Linear Múltipla
&lt;/h1&gt;

&lt;p&gt;Agora essa fica bem fácil, pois funciona da mesma forma que a simples só que é usada para mais do que uma variável independente.&lt;/p&gt;

&lt;p&gt;Y = α + βX1 + γX2+ Є.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uAJ9Mu8T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2nnz59u5ebr4n1wpxi51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uAJ9Mu8T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2nnz59u5ebr4n1wpxi51.png" alt="Plano de regressão linear múltipla"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;&lt;em&gt;Plano de regressão linear múltipla&lt;/em&gt; &lt;small&gt;&lt;br&gt;
fonte:  &lt;a href="http://marcelojo.org/2017/10/multiple-linear-regression.html"&gt;http://marcelojo.org/2017/10/multiple-linear-regression.html&lt;/a&gt;&lt;/small&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Nesse exemplo a gente conseguiria entender a escolaridade de alguém (grade) usando a idade (age) e o gênero.&lt;/p&gt;

&lt;p&gt;Bom, agora a gente já entendeu como funciona uma regressão, mas ainda não sabemos como responder todas aquelas perguntas do começo do artigo. A maioria delas pode ser respondida olhando para os coeficientes e o erro da nossa equação.&lt;/p&gt;

&lt;p&gt;O erro é o que a gente perde com o modelo, já que , no geral, as relações não são exatamente lineares. Por exemplo, se estamos predizendo algum preço, em reais, e o erro final ficou no valor de 200, isso significa que o modelo provavelmente vai errar o valor predito em 200 reais em média.&lt;/p&gt;

&lt;p&gt;Já os coeficientes conseguem nos explicar justamente o quão forte aquela variável se relaciona com a variável resposta, ou seja, a variável independente que tiver o maior coeficiente será a variável que mais contribui para esse modelo. Além disso, cada coeficiente vai representar o quanto em média a variável resposta vai mudar para cada unidade da sua variável dependente. Por exemplo, se a nossa resposta for a altura, em cm, de uma pessoa nos baseando em variáveis como idade e peso, observando o coeficiente da idade em 20 significa que para cada ano adquirido uma pessoa cresce em média 20 cm (isso com o peso constante).&lt;/p&gt;




&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;p&gt;Vou deixar um livro que usei para aprender algumas técnicas, não só regressão, e também um canal que eu gosto muito e explica estatística de forma bem didádica (em inglês 🙁)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An Introduction to Statistical Learning — Gareth James et al&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/channel/UCtYLUTtgS3k1Fg4y5tAhLbw"&gt;StatQuest — Canal do YouTube&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>machinelearning</category>
      <category>estatística</category>
      <category>datascience</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
