commit
0425110f27
@ -0,0 +1,214 @@
|
||||
# Começar com Python e Scikit-learn para modelos de regressão
|
||||
|
||||

|
||||
|
||||
> Sketchnote by [Tomomi Imura](https://www.twitter.com/girlie_mac)
|
||||
|
||||
## [Questionário pré-palestra](https://white-water-09ec41f0f.azurestaticapps.net/quiz/9/)
|
||||
|
||||
> ### [Esta lição está disponível em R!](./solution/R/lesson_1-R.ipynb)
|
||||
|
||||
## Introdução
|
||||
|
||||
Nestas quatro lições, você vai descobrir como construir modelos de regressão. Discutiremos para que são em breve. Mas antes de fazer qualquer coisa, certifique-se de ter as ferramentas certas para iniciar o processo!
|
||||
|
||||
Nesta lição, aprenderá a:
|
||||
|
||||
- Configurar o seu computador para tarefas locais de aprendizagem automática.
|
||||
- Trabalhe com cadernos Jupyter.
|
||||
- Utilize scikit-learn, incluindo a instalação.
|
||||
- Explore a regressão linear com um exercício prático.
|
||||
|
||||
## Instalações e configurações
|
||||
|
||||
[](https://youtu.be/yyQM70vi7V8 "Configurar Python com código de estúdio visual
|
||||
")
|
||||
|
||||
> 🎥 Clique na imagem acima para um vídeo: utilizando Python dentro do Código VS.
|
||||
|
||||
1. **Instalar Python**. Certifique-se de que [Python](https://www.python.org/downloads/) está instalado no seu computador. Você usará Python para muitas tarefas de ciência de dados e machine learning. A maioria dos sistemas informáticos já inclui uma instalação Python. Há úteis [Python Pacotes de codificação](https://code.visualstudio.com/learn/educators/installers?WT.mc_id=academic-15963-cxa) disponível também, para facilitar a configuração para alguns utilizadores.
|
||||
|
||||
Alguns usos de Python, no entanto, requerem uma versão do software, enquanto outros requerem uma versão diferente. Por esta razão, é útil trabalhar dentro de um [ambiente virtual](https://docs.python.org/3/library/venv.html).
|
||||
|
||||
2. **Instalar código de estúdio visual**. Certifique-se de que tem o Código do Estúdio Visual instalado no seu computador. Siga estas instruções para
|
||||
[instalar Código do Estúdio Visual](https://code.visualstudio.com/) para a instalação básica. Você vai usar Python em Código estúdio visual neste curso, então você pode querer relembrá-lo [configurar código de estúdio visual](https://docs.microsoft.com/learn/modules/python-install-vscode?WT.mc_id=academic-15963-cxa) para o desenvolvimento de Python.
|
||||
|
||||
> Fique confortável com python trabalhando através desta coleção de [Aprender módulos](https://docs.microsoft.com/users/jenlooper-2911/collections/mp1pagggd5qrq7?WT.mc_id=academic-15963-cxa)
|
||||
|
||||
3. **Instale Scikit-learn**, seguindo [estas instruções]
|
||||
(https://scikit-learn.org/stable/install.html). Uma vez que precisa de garantir que utiliza o Python 3, recomenda-se que utilize um ambiente virtual. Note que se estiver a instalar esta biblioteca num Mac M1, existem instruções especiais na página acima ligada.
|
||||
|
||||
1. **Instale o Caderno Jupyter**. Você precisará [instalar o pacote Jupyter](https://pypi.org/project/jupyter/).
|
||||
|
||||
## O seu ambiente de autoria ML
|
||||
Você vai usar **cadernos** para desenvolver o seu código Python e criar modelos de aprendizagem automática. Este tipo de ficheiro é uma ferramenta comum para cientistas de dados, e podem ser identificados pelo seu sufixo ou extensão `.ipynb`.
|
||||
|
||||
Os cadernos são um ambiente interativo que permite ao desenvolvedor codificar e adicionar notas e escrever documentação em torno do código que é bastante útil para projetos experimentais ou orientados para a investigação.
|
||||
|
||||
## Exercício - trabalhe com um caderno
|
||||
|
||||
Nesta pasta, encontrará o ficheiro _notebook.ipynb_.
|
||||
|
||||
1. Abra _notebook.ipynb_ em Código de Estúdio Visual.
|
||||
|
||||
Um servidor Jupyter começará com o Python 3+ iniciado. Encontrará áreas do caderno que podem ser `executadas`, peças de código. Pode executar um bloco de código, selecionando o ícone que parece um botão de reprodução.
|
||||
|
||||
2. Selecione o ícone `md` e adicione um pouco de marcação, e o seguinte texto **# Bem-vindo ao seu caderno**.
|
||||
|
||||
Em seguida, adicione um pouco de código Python.
|
||||
|
||||
5. Escreva **print ('olá caderno')** no bloco de código.
|
||||
|
||||
6. Selecione a seta para executar o código.
|
||||
|
||||
Deve ver a declaração impressa:
|
||||
|
||||
```saída
|
||||
Olá caderno
|
||||
```
|
||||

|
||||
|
||||
Pode interligar o seu código com comentários para auto-documentar o caderno.
|
||||
|
||||
✅ Pense por um minuto como o ambiente de trabalho de um web developer é diferente do de um cientista de dados.
|
||||
|
||||
## Em funcionamento com Scikit-learn
|
||||
|
||||
Agora que python está montado no seu ambiente local, e você está confortável com os cadernos jupyter, vamos ficar igualmente confortáveis com Scikit-learn (pronunciá-lo 'sci' como em 'ciência'). Scikit-learn fornece uma [API extensiva](https://scikit-learn.org/stable/modules/classes.html#api-ref) para ajudá-lo a executar tarefas ML.
|
||||
|
||||
De acordo com o seu [site](https://scikit-learn.org/stable/getting_started.html), "O Scikit-learn é uma biblioteca de aprendizagem automática de código aberto que suporta a aprendizagem supervisionada e sem supervisão. Também fornece várias ferramentas para a montagem de modelos, pré-processamento de dados, seleção e avaliação de modelos, e muitas outras utilidades."
|
||||
|
||||
Neste curso, você usará scikit-learn e outras ferramentas para construir modelos de machine learning para executar o que chamamos de tarefas tradicionais de aprendizagem automática. Evitámos deliberadamente redes neurais e aprendizagem profunda, uma vez que estão melhor cobertas no nosso próximo currículo de IA para principiantes.
|
||||
|
||||
|
||||
|
||||
O scikit-learn torna simples construir modelos e avaliá-los para uso. Está focado principalmente na utilização de dados numéricos e contém vários conjuntos de dados prontos para uso como ferramentas de aprendizagem. Também inclui modelos pré-construídos para os alunos experimentarem. Vamos explorar o processo de carregamento de dados pré-embalados e usar um modelo ml incorporado no estimador com o Scikit-learn com alguns dados básicos.
|
||||
|
||||
## Exercício - o seu primeiro caderno Scikit-learn
|
||||
|
||||
> Este tutorial foi inspirado no exemplo [de regressão linear](https://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html#sphx-glr-auto-examples-linear-model-plot-ols-py) no site da Scikit-learn.
|
||||
|
||||
No ficheiro _notebook.ipynb_ associado a esta lição, limpe todas as células premindo o ícone 'caixote do lixo'.
|
||||
|
||||
Nesta secção, você vai trabalhar com um pequeno conjunto de dados sobre diabetes que é incorporado em Scikit-learn para fins de aprendizagem. Imagine que queria testar um tratamento para pacientes diabéticos. Os modelos de Machine Learning podem ajudá-lo a determinar quais os pacientes que responderiam melhor ao tratamento, com base em combinações de variáveis. Mesmo um modelo de regressão muito básico, quando visualizado, pode mostrar informações sobre variáveis que o ajudariam a organizar os seus ensaios clínicos teóricos.
|
||||
|
||||
✅ There are many types of regression methods, and which one you pick depends on the answer you're looking for. If you want to predict the probable height for a person of a given age, you'd use linear regression, as you're seeking a **numeric value**. If you're interested in discovering whether a type of cuisine should be considered vegan or not, you're looking for a **category assignment** so you would use logistic regression. You'll learn more about logistic regression later. Think a bit about some questions you can ask of data, and which of these methods would be more appropriate.
|
||||
|
||||
Vamos começar com esta tarefa.
|
||||
|
||||
### Bibliotecas de importação
|
||||
|
||||
Para esta tarefa importaremos algumas bibliotecas:
|
||||
|
||||
- **matplotlib**. É uma ferramenta útil [de grafimento](https://matplotlib.org/) e vamos usá-lo para criar um enredo de linha.
|
||||
- **numpy**. [numpy](https://numpy.org/doc/stable/user/whatisnumpy.html) é uma biblioteca útil para o tratamento de dados numéricos em Python.
|
||||
- **sklearn**. Este é o [Scikit-learn](https://scikit-learn.org/stable/user_guide.html) biblioteca.
|
||||
|
||||
Importe algumas bibliotecas para ajudar nas suas tarefas.
|
||||
|
||||
1. Adicione as importações digitando o seguinte código:
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from sklearn import datasets, linear_model, model_selection
|
||||
```
|
||||
|
||||
Acima está a importar `matplottlib`, `numpy` e está a importar `datasets`, `linear_model` e `model_selection` de `sklearn`. É utilizado `model_selection` para dividir dados em conjuntos de treino e teste.
|
||||
|
||||
## O conjunto de dados da diabetes
|
||||
O conjunto de dados incorporado [diabetes](https://scikit-learn.org/stable/datasets/toy_dataset.html#diabetes-dataset) Inclui 442 amostras de dados em torno da diabetes, com 10 variáveis de características, algumas das quais incluem:
|
||||
|
||||
- idade: idade em anos
|
||||
- bmi: índice de massa corporal
|
||||
- bp: pressão arterial média
|
||||
- s1 tc: T-Cells (um tipo de glóbulos brancos)
|
||||
|
||||
✅ Este conjunto de dados inclui o conceito de 'sexo' como uma variável de característica importante para a investigação em torno da diabetes. Muitos conjuntos de dados médicos incluem este tipo de classificação binária. Pense um pouco sobre como categorizações como esta podem excluir certas partes de uma população de tratamentos.
|
||||
|
||||
Agora, carregue os dados X e Y.
|
||||
|
||||
> 🎓 Lembre-se, isto é aprendizagem supervisionada, e precisamos de um alvo chamado "y".
|
||||
|
||||
Numa nova célula de código, carregue o conjunto de dados da diabetes chamando `load_diabetes()` A entrada `return_X_y=True` indica que `X` será uma matriz de dados, e `y` será o alvo de regressão.
|
||||
|
||||
1. Adicione alguns comandos de impressão para mostrar a forma da matriz de dados e o seu primeiro elemento:
|
||||
|
||||
```python
|
||||
X, y = datasets.load_diabetes(return_X_y=True)
|
||||
print(X.shape)
|
||||
print(X[0])
|
||||
```
|
||||
|
||||
O que estás a receber como resposta, é um tuple. O que está a fazer é atribuir os dois primeiros valores da tuple para `X` and `y` respectivamente. Saiba mais [sobre tuples](https://wikipedia.org/wiki/Tuple).
|
||||
|
||||
Pode ver que estes dados têm 442 itens moldados em matrizes de 10 elementos:
|
||||
|
||||
```text
|
||||
(442, 10)
|
||||
[ 0.03807591 0.05068012 0.06169621 0.02187235 -0.0442235 -0.03482076
|
||||
-0.04340085 -0.00259226 0.01990842 -0.01764613]
|
||||
```
|
||||
|
||||
✅ Pense um pouco sobre a relação entre os dados e o alvo de regressão. A regressão linear prevê relações entre a característica X e a variável alvo. Pode encontrar o [alvo](https://scikit-learn.org/stable/datasets/toy_dataset.html#diabetes-dataset) para o conjunto de dados da diabetes na documentação? O que é que este conjunto de dados está a demonstrar, tendo em conta esse objetivo?
|
||||
|
||||
2. Em seguida, selecione uma parte deste conjunto de dados para traçar, organizando-o numa nova matriz usando a função `newaxis` da Numpy. Vamos usar a regressão linear para gerar uma linha entre valores nestes dados, de acordo com um padrão que determina.
|
||||
|
||||
```python
|
||||
X = X[:, np.newaxis, 2]
|
||||
```
|
||||
|
||||
✅ A qualquer momento, imprima os dados para verificar a sua forma.
|
||||
|
||||
3. Agora que tem dados prontos a serem traçados, pode ver se uma máquina pode ajudar a determinar uma divisão lógica entre os números deste conjunto de dados. Para isso, é necessário dividir os dados (X) e o alvo (y) em conjuntos de teste e treino. O Scikit-learn tem uma forma simples de o fazer; pode dividir os seus dados de teste num dado momento.
|
||||
|
||||
```python
|
||||
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.33)
|
||||
```
|
||||
|
||||
4. Agora está pronto para treinar o seu modelo! Carregue o modelo linear de regressão e treine-o com os seus conjuntos de treinamento X e y usando `modelo.fit()`:
|
||||
|
||||
```python
|
||||
model = linear_model.LinearRegression()
|
||||
model.fit(X_train, y_train)
|
||||
```
|
||||
|
||||
✅ `modelo.fit()` é uma função que você verá em muitas bibliotecas ML, como TensorFlow
|
||||
|
||||
5. Em seguida, crie uma previsão utilizando dados de teste, utilizando a função `predict()`. Isto será usado para traçar a linha entre grupos de dados
|
||||
```python
|
||||
y_pred = model.predict(X_test)
|
||||
```
|
||||
|
||||
6. Agora é hora de mostrar os dados num enredo. Matplotlib é uma ferramenta muito útil para esta tarefa. Crie uma dispersão de todos os dados de teste X e y, e use a previsão para traçar uma linha no local mais apropriado, entre os agrupamentos de dados do modelo.
|
||||
|
||||
```python
|
||||
plt.scatter(X_test, y_test, color='black')
|
||||
plt.plot(X_test, y_pred, color='blue', linewidth=3)
|
||||
plt.xlabel('Scaled BMIs')
|
||||
plt.ylabel('Disease Progression')
|
||||
plt.title('A Graph Plot Showing Diabetes Progression Against BMI')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
✅ Pense um pouco sobre o que está acontecendo aqui. Uma linha reta está a passar por muitos pequenos pontos de dados, mas o que está a fazer exatamente? Consegue ver como deve ser capaz de usar esta linha para prever onde um novo ponto de dados invisível se deve encaixar em relação ao eixo y do enredo? Tente colocar em palavras o uso prático deste modelo.
|
||||
|
||||
Parabéns, construíste o teu primeiro modelo linear de regressão, criaste uma previsão com ele, e exibiste-o num enredo!
|
||||
---
|
||||
## 🚀Challenge
|
||||
|
||||
Defina uma variável diferente deste conjunto de dados. Dica: edite esta linha:`X = X[:, np.newaxis, 2]`. Tendo em conta o objetivo deste conjunto de dados, o que é que consegue descobrir sobre a progressão da diabetes como uma doença?
|
||||
## [Questionário pós-palestra](https://white-water-09ec41f0f.azurestaticapps.net/quiz/10/)
|
||||
|
||||
## Review & Self Study
|
||||
|
||||
Neste tutorial, trabalhou com uma simples regressão linear, em vez de univariado ou regressão linear múltipla. Leia um pouco sobre as diferenças entre estes métodos, ou dê uma olhada[este vídeo](https://www.coursera.org/lecture/quantifying-relationships-regression-models/linear-vs-nonlinear-categorical-variables-ai2Ef)
|
||||
|
||||
Leia mais sobre o conceito de regressão e pense sobre que tipo de perguntas podem ser respondidas por esta técnica. Tome este [tutorial](https://docs.microsoft.com/learn/modules/train-evaluate-regression-models?WT.mc_id=academic-15963-cxa) para aprofundar a sua compreensão.
|
||||
## Missão
|
||||
|
||||
[Um conjunto de dados diferente](assignment.md)
|
@ -0,0 +1,13 @@
|
||||
# Regressão com Scikit-learn
|
||||
|
||||
## Instruções
|
||||
|
||||
Dê uma olhada no conjunto de [dados Linnerud](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_linnerud.html#sklearn.datasets.load_linnerud) em Scikit-learn. Este conjunto de dados tem vários [alvos](https://scikit-learn.org/stable/datasets/toy_dataset.html#linnerrud-dataset): 'Consiste em três variáveis de exercício (dados) e três variáveis fisiológicas (alvo) recolhidas de vinte homens de meia-idade num clube de fitness'
|
||||
|
||||
Nas suas próprias palavras, descreva como criar um modelo de Regressão que traçaria a relação entre a cintura e quantos situps são realizados. Faça o mesmo para os outros pontos de dados neste conjunto de dados.
|
||||
|
||||
## Rubrica
|
||||
|
||||
| Critérios | exemplares | Adequado | Necessidades de Melhoria |
|
||||
| ------------------------------ | ----------------------------------- | ----------------------------- | -------------------------- |
|
||||
| Enviar um parágrafo descritivo | Parágrafo bem escrito é submetido | Algumas frases são submetidas | Nenhuma descrição é fornecida |
|
@ -0,0 +1,207 @@
|
||||
# Crie um modelo de regressão usando o Scikit-learn: preparar e visualizar dados
|
||||
|
||||

|
||||
|
||||
Infographic by [Dasani Madipalli](https://twitter.com/dasani_decoded)
|
||||
|
||||
## [Teste de pré-aula](https://white-water-09ec41f0f.azurestaticapps.net/quiz/11/)
|
||||
|
||||
> ### [Esta lição está disponível em R!](./solution/R/lesson_2-R.ipynb)
|
||||
|
||||
## Introdução
|
||||
|
||||
Agora que você está configurado com as ferramentas necessárias para começar a lidar com a construção de modelos de aprendizagem automática com o Scikit-learn, você está pronto para começar a fazer perguntas sobre seus dados. Como você trabalha com dados e aplica soluções ML, é muito importante entender como fazer a pergunta certa para desbloquear adequadamente os potenciais de seu conjunto de dados.
|
||||
|
||||
Nesta lição, você aprenderá:
|
||||
|
||||
- Como preparar seus dados para a criação de modelos.
|
||||
- Como usar Matplotlib para visualização de dados.
|
||||
|
||||
[](https://youtu.be/11AnOn_OAcE "Preparando e Visualizando vídeo de dados - Clique para Assistir!")
|
||||
> 🎥 Clique na imagem acima para ver um vídeo que aborda os principais aspectos desta lição
|
||||
|
||||
|
||||
## Fazendo a pergunta certa sobre seus dados
|
||||
|
||||
A pergunta que você precisa responder determinará que tipo de algoritmos de ML você utilizará. E a qualidade da resposta que você recebe de volta será fortemente dependente da natureza de seus dados.
|
||||
|
||||
Dê uma olhada nos [dados](../data/US-pumpkins.csv) fornecidos para esta lição. Você pode abrir este arquivo .csv no Código VS. Um skim rápido imediatamente mostra que há espaços em branco e uma mistura de strings e dados numéricos. Há também uma coluna estranha chamada 'Package' onde os dados são uma mistura entre 'sacks', 'bins' e outros valores. Os dados, de fato, são um pouco confusos.
|
||||
|
||||
Na verdade, não é muito comum ser dotado de um conjunto de dados que está completamente pronto para usar para criar um modelo ML pronto para uso. Nesta lição, você aprenderá como preparar um conjunto de dados bruto usando bibliotecas Python padrão. Você também aprenderá várias técnicas para visualizar os dados.
|
||||
|
||||
## Estudo de caso: "mercado da abóbora"
|
||||
|
||||
Nesta pasta você encontrará um arquivo .csv na pasta raiz `data` chamada [US-pumpkins.csv](../data/US-pumpkins.csv) que inclui 1757 linhas de dados sobre o mercado de abóboras, classificadas em agrupamentos por cidade. Estes são dados brutos extraídos dos [Specialty Crops Terminal Markets Standard Reports](https://www.marketnews.usda.gov/mnp/fv-report-config-step1?type=termPrice) distribuídos pelo Departamento de Agricultura dos Estados Unidos.
|
||||
|
||||
### Preparando dados
|
||||
|
||||
Estes dados são do domínio público. Ele pode ser baixado em muitos arquivos separados, por cidade, a partir do site USDA. Para evitar muitos arquivos separados, nós concatenamos todos os dados da cidade em uma planilha, assim nós já _preparamos_ os dados um pouco. A seguir, vamos dar uma olhada nos dados.
|
||||
|
||||
### Os dados da abóbora - primeiras conclusões
|
||||
|
||||
O que você nota sobre esses dados? Vocês já viram que há uma mistura de strings, números, espaços em branco e valores estranhos que você precisa entender.
|
||||
|
||||
Que pergunta você pode fazer sobre esses dados, usando uma técnica de Regressão? E quanto a "Prever o preço de uma abóbora à venda durante um determinado mês". Observando novamente os dados, há algumas alterações que você precisa fazer para criar a estrutura de dados necessária para a tarefa.
|
||||
## Exercício - analisar os dados da abóbora
|
||||
|
||||
Vamos usar [Pandas](https://pandas.pydata.org/), (o nome significa `Python Data Analysis`) uma ferramenta muito útil para moldar dados, para analisar e preparar esses dados de abóbora.
|
||||
|
||||
### Primeiro, verifique se há datas ausentes
|
||||
|
||||
Primeiro, você precisará seguir as etapas para verificar se há datas ausentes:
|
||||
|
||||
1. Converta as datas em um formato de mês (essas são datas americanas, portanto o formato é `MM/DD/AAAA`).
|
||||
2. Extraia o mês para uma nova coluna.
|
||||
|
||||
Abra o arquivo _notebook.ipynb_ no Visual Studio Code e importe a planilha para um novo quadro de dados do Pandas.
|
||||
|
||||
1. Use a função `head()` para exibir as cinco primeiras linhas.
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
pumpkins = pd.read_csv('../data/US-pumpkins.csv')
|
||||
pumpkins.head()
|
||||
```
|
||||
|
||||
Qual função você usaria para exibir as últimas cinco linhas?
|
||||
|
||||
1. Verifique se há dados ausentes no banco de dados atual:
|
||||
|
||||
```python
|
||||
pumpkins.isnull().sum()
|
||||
```
|
||||
|
||||
Faltam dados, mas talvez não seja importante para a tarefa em questão.
|
||||
|
||||
1. Para facilitar o trabalho com seu banco de dados, solte várias de suas colunas, usando `drop()`, mantendo apenas as colunas necessárias:
|
||||
|
||||
```python
|
||||
new_columns = ['Package', 'Month', 'Low Price', 'High Price', 'Date']
|
||||
pumpkins = pumpkins.drop([c for c in pumpkins.columns if c not in new_columns], axis=1)
|
||||
```
|
||||
|
||||
### Segundo, determinar o preço médio da abóbora
|
||||
|
||||
Pense sobre como determinar o preço médio de uma abóbora em um determinado mês. Que colunas você escolheria para esta tarefa? Dica: você precisará de 3 colunas.
|
||||
|
||||
Solução: utilize a média das colunas `Preço Baixo` e Preço Alto` para preencher a nova coluna Preço e converta a coluna Data para mostrar apenas o mês. Felizmente, de acordo com a verificação acima, não há dados ausentes para datas ou preços.
|
||||
|
||||
1. Para calcular a média, adicione o seguinte código:
|
||||
2.
|
||||
```python
|
||||
price = (pumpkins['Low Price'] + pumpkins['High Price']) / 2
|
||||
|
||||
month = pd.DatetimeIndex(pumpkins['Date']).month
|
||||
|
||||
```
|
||||
|
||||
✅Sinta-se à vontade para imprimir quaisquer dados que você gostaria de verificar usando `print(month)`.
|
||||
|
||||
3. Agora, copie seus dados convertidos em um novo dataframe Pandas:
|
||||
|
||||
```python
|
||||
new_pumpkins = pd.DataFrame({'Month': month, 'Package': pumpkins['Package'], 'Low Price': pumpkins['Low Price'],'High Price': pumpkins['High Price'], 'Price': price})
|
||||
```
|
||||
|
||||
A impressão do seu dataframe mostrará um conjunto de dados limpo e organizado no qual você pode construir seu novo modelo de regressão.
|
||||
|
||||
### Mas espere! Há algo estranho aqui
|
||||
|
||||
Se você observar a coluna `Package`, as abóboras são vendidas em várias configurações diferentes. Algumas são vendidas em medidas de "1 1/9 bushel", e algumas em medidas de "1/2 bushel", algumas por abóbora, algumas por libra, e algumas em caixas grandes com larguras variadas.
|
||||
|
||||
> Abóboras parecem muito difíceis de pesar consistentemente
|
||||
|
||||
Analisando os dados originais, é interessante que qualquer coisa com `Unidade de Venda` igual a 'CADA' ou 'POR CAIXA' também tenha o tipo `Pacote` por polegada, por caixa ou 'cada'. As abóboras parecem ser muito difíceis de pesar consistentemente, então vamos filtrá-las selecionando apenas as abóboras com a cadeia "bushel" na coluna `Pacote`.
|
||||
|
||||
1. Adicione um filtro na parte superior do arquivo, sob a importação .csv inicial:
|
||||
|
||||
```python
|
||||
pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]
|
||||
```
|
||||
|
||||
Se você imprimir os dados agora, você pode ver que você está apenas recebendo as 415 ou mais linhas de dados contendo abóboras pelo bushel.
|
||||
|
||||
### Mas espere! Há mais uma coisa a fazer
|
||||
|
||||
Você notou que o montante de bushel varia por linha? Você precisa normalizar o preço para que você mostre o preço por bushel, então faça algumas contas para padronizá-lo.
|
||||
|
||||
1. Adicione estas linhas após o bloco criar o dataframe new_pumpkins:
|
||||
|
||||
```python
|
||||
new_pumpkins.loc[new_pumpkins['Package'].str.contains('1 1/9'), 'Price'] = price/(1 + 1/9)
|
||||
|
||||
new_pumpkins.loc[new_pumpkins['Package'].str.contains('1/2'), 'Price'] = price/(1/2)
|
||||
```
|
||||
|
||||
✅ De acordo com [O Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308), o peso de um bushel depende do tipo de produto, pois é uma medida de volume. "Um bushel de tomates, por exemplo, deve pesar 56 libras... Folhas e verdes ocupam mais espaço com menos peso, então um alqueire de espinafre pesa apenas 20 libras." É tudo muito complicado! Não nos preocupemos em fazer uma conversão bushel-to-pound, e em vez disso o preço pelo bushel. Todo este estudo de bushels de abóboras, no entanto, vai para mostrar como é muito importante entender a natureza dos seus dados!
|
||||
|
||||
Agora, você pode analisar o preço por unidade com base em sua medição de bushel. Se você imprimir os dados mais uma vez, poderá ver como eles são padronizados.
|
||||
|
||||
Você notou que as abóboras vendidas pela metade do bushel são muito caras? Você pode descobrir por quê? Dica: abóboras pequenas são muito mais caras do que as grandes, provavelmente porque há muito mais delas por bushel, dado o espaço não utilizado tomado por uma grande abóbora de torta oca.
|
||||
|
||||
## Estratégias de visualização
|
||||
|
||||
Parte do papel do cientista de dados é demonstrar a qualidade e a natureza dos dados com os quais eles estão trabalhando. Para fazer isso, muitas vezes criam visualizações interessantes, ou gráficos, gráficos e gráficos, mostrando diferentes aspectos dos dados. Dessa forma, eles são capazes de mostrar visualmente relacionamentos e lacunas que de outra forma são difíceis de descobrir.
|
||||
|
||||
Visualizações também podem ajudar a determinar a técnica de aprendizado de máquina mais apropriada para os dados. Um gráfico de dispersão que parece seguir uma linha, por exemplo, indica que os dados são um bom candidato para um exercício de regressão linear.
|
||||
|
||||
Uma biblioteca de visualização de dados que funciona bem em notebooks Jupyter é [Matplotlib](https://matplotlib.org/) (que você também viu na lição anterior).
|
||||
|
||||
> Obtenha mais experiência com visualização de dados em [estes tutoriais](https://docs.microsoft.com/learn/modules/explore-analyze-data-with-python?WT.mc_id=university-15963-cxa).
|
||||
|
||||
## Exercício - experimente com Matplotlib
|
||||
|
||||
Tente criar alguns gráficos básicos para exibir o novo banco de dados que você acabou de criar. O que um gráfico de linha básica mostraria?
|
||||
|
||||
1. Importar Matplotlib no topo do arquivo, sob a importação Pandas:
|
||||
|
||||
```python
|
||||
import matplotlib.pyplot as plt
|
||||
```
|
||||
|
||||
1. Execute novamente todo o bloco de anotações para atualizar.
|
||||
1. Na parte inferior do notebook, adicione uma célula para plotar os dados como uma caixa:
|
||||
|
||||
```python
|
||||
price = new_pumpkins.Price
|
||||
month = new_pumpkins.Month
|
||||
plt.scatter(price, month)
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
Será isto um enredo útil? Alguma coisa sobre isso o surpreende?
|
||||
|
||||
Não é particularmente útil, uma vez que tudo o que apresenta nos seus dados como uma distribuição de pontos num determinado mês.
|
||||
|
||||
### Tornar útil
|
||||
|
||||
Para que os gráficos apresentem dados úteis, normalmente é necessário agrupar os dados de alguma forma. Vamos tentar criar um desenho onde o eixo Y mostre os meses e os dados demonstram a distribuição de dados.
|
||||
|
||||
1. Adicionar uma célula para criar um gráfico de barras agrupado:
|
||||
|
||||
```python
|
||||
new_pumpkins.groupby(['Month'])['Price'].mean().plot(kind='bar')
|
||||
plt.ylabel("Pumpkin Price")
|
||||
```
|
||||
|
||||

|
||||
|
||||
Esta é uma visualização de dados mais útil! Parece indicar que o preço mais alto para as abrigas ocorre em setembro e outubro. Isso atende às suas expetativas? Porque ou porque não?
|
||||
|
||||
—
|
||||
|
||||
## 🚀 desafio
|
||||
|
||||
Explore os diferentes tipos de visualização que o Matplotlib oferece. Que tipos são mais apropriados para problemas de regressão?
|
||||
|
||||
## [Questionário pós-palestra](https://white-water-09ec41f0f.azurestaticapps.net/quiz/12/)
|
||||
|
||||
## Revisão e Estudo Automático
|
||||
|
||||
Dê uma vista de olhos às muitas formas de visualizar dados. Disponibilize uma lista das várias bibliotecas e anote quais as melhores para determinados tipos de tarefas, por exemplo, visualizações 2D vs. visualizações 3D. O que você descobre?
|
||||
|
||||
## Atribuição
|
||||
|
||||
[A explorar visualização](assignment.md)
|
@ -0,0 +1,9 @@
|
||||
# Exploração de Visualizações
|
||||
|
||||
Existem várias bibliotecas diferentes que estão disponíveis para visualização de dados. Crie algumas visualizações utilizando os dados da Abóbora nesta lição com matplotlib e nascidos num caderno de amostras. Com que bibliotecas é mais fácil de trabalhar?
|
||||
|
||||
## Rubrica
|
||||
|
||||
Critérios | exemplares | Adequado | Necessidades de Melhoria |
|
||||
| -------- | --------- | -------- | ----------------- |
|
||||
| | Um caderno é submetido com duas explorações/visualizações| Um caderno é submetido com uma exploração/visualizações | Um caderno não é submetido |
|
@ -0,0 +1,11 @@
|
||||
# Criar um modelo de regressão
|
||||
|
||||
## Instruções
|
||||
|
||||
Nesta lição foi-lhe mostrado como construir um modelo usando a Regressão Linear e Polinomial. Utilizando este conhecimento, encontre um conjunto de dados ou use um dos conjuntos incorporados da Scikit-learn para construir um novo modelo. Explique no seu caderno porque escolheu a técnica que escolheu e demonstre a precisão do seu modelo. Se não for preciso, explique porquê.
|
||||
|
||||
## Rubrica
|
||||
|
||||
| Critérios | exemplares | Adequado | Necessidades de Melhoria |
|
||||
| -------- | ------------------------------------------------------------ | -------------------------- | ------------------------------- |
|
||||
| | apresenta um caderno completo com uma solução bem documentada | a solução está incompleta| a solução é imperfeita ou buggy |
|
@ -0,0 +1,302 @@
|
||||
# Regressão logística para prever categorias
|
||||
|
||||

|
||||
> Infographic by [Dasani Madipalli](https://twitter.com/dasani_decoded)
|
||||
## [Questionário pré-palestra](https://white-water-09ec41f0f.azurestaticapps.net/quiz/15/)
|
||||
|
||||
> ### [Esta lição está disponível em R!](./solution/R/lesson_4-R.ipynb)
|
||||
|
||||
## Introdução
|
||||
|
||||
Nesta lição final sobre Regressão, uma das técnicas básicas _classic_ ML, vamos dar uma olhada na Regressão Logística. Usaria esta técnica para descobrir padrões para prever categorias binárias. Isto é chocolate doce ou não? Esta doença é contagiosa ou não? Este cliente escolherá este produto ou não?
|
||||
|
||||
Nesta lição, aprenderá:
|
||||
- Uma nova biblioteca para visualização de dados
|
||||
- Técnicas de regressão logística
|
||||
|
||||
✅ aprofundar a sua compreensão de trabalhar com este tipo de regressão neste [módulo Aprender](https://docs.microsoft.com/learn/modules/train-evaluate-classification-models?WT.mc_id=academic-15963-cxa)
|
||||
## Pré-requisito
|
||||
|
||||
Tendo trabalhado com os dados da abóbora, estamos agora familiarizados o suficiente para perceber que há uma categoria binária com a qual podemos trabalhar:` Cor`.
|
||||
|
||||
Vamos construir um modelo de regressão logística para prever que, dadas algumas variáveis, _what cor de uma dada abóbora é provável que be_ (🎃 laranja ou 👻 branco).
|
||||
|
||||
> Porque estamos a falar de classificação binária num agrupamento de aulas sobre regressão? Apenas para conveniência linguística, uma vez que a regressão logística é [realmente um método de classificação](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression),embora um linear baseado. Saiba mais sobre outras formas de classificar os dados no próximo grupo de aulas.
|
||||
|
||||
## Definir a pergunta
|
||||
Para os nossos propósitos, vamos expressar isto como um binário: "Laranja" ou "Não Laranja". Existe também uma categoria de "listrado" no nosso conjunto de dados, mas há poucos casos dele, pelo que não a utilizaremos. Desaparece assim que removemos os valores nulos do conjunto de dados, de qualquer forma.
|
||||
|
||||
> 🎃 facto divertido, às vezes chamamos abóboras brancas de abóboras "fantasma". Não são muito fáceis de esculpir, por isso não são tão populares como os laranjas, mas são fixes!
|
||||
|
||||
## About logistic regression
|
||||
|
||||
A regressão logística difere da regressão linear, que aprendeu anteriormente, de algumas formas importantes.
|
||||
### Classificação binária
|
||||
|
||||
A regressão logística não oferece as mesmas características que a regressão linear. O primeiro oferece uma previsão sobre uma categoria binária ("laranja ou não laranja"),) enquanto esta é capaz de prever valores contínuos, por exemplo dada a origem de uma abóbora e a hora da colheita, _how muito o seu preço irá rise_.
|
||||
|
||||

|
||||
> Infographic by [Dasani Madipalli](https://twitter.com/dasani_decoded)
|
||||
### Outras classificações
|
||||
|
||||
Existem outros tipos de regressão logística, incluindo multinóia e ordinária:
|
||||
- **Multinomial**, que envolve ter mais de uma categoria - "Laranja, Branco e Listrado".
|
||||
- **Ordinal**, que envolve categorias ordenadas, úteis se quiséssemos encomendar os nossos resultados logicamente, como as nossas abóboras que são encomendadas por um número finito de tamanhos (mini,sm,med,lg,xl,xxl).
|
||||
|
||||

|
||||
> Infographic by [Dasani Madipalli](https://twitter.com/dasani_decoded)
|
||||
### Ainda é linear
|
||||
|
||||
Embora este tipo de Regressão seja tudo sobre "previsões de categoria", ainda funciona melhor quando há uma relação linear clara entre a variável dependente (cor) e as outras variáveis independentes (o resto do conjunto de dados, como o nome e o tamanho da cidade). É bom ter uma ideia de se há alguma linearidade dividindo estas variáveis ou não.
|
||||
|
||||
### Variáveis NÃO têm que correlacionar
|
||||
Lembras-te de como a regressão linear funcionou melhor com variáveis mais correlacionadas? A regressão logística é o oposto - as variáveis não têm que se alinhar. Isso funciona para estes dados que têm correlações um pouco fracas.
|
||||
|
||||
### Precisa de muitos dados limpos
|
||||
|
||||
A regressão logística dará resultados mais precisos se utilizar mais dados; nosso pequeno conjunto de dados não é o ideal para esta tarefa, por isso tenha isso em mente.
|
||||
|
||||
✅ Pense nos tipos de dados que se emprestariam bem à regressão logística
|
||||
|
||||
## Exercício - arrumar os dados
|
||||
|
||||
Primeiro, limpe um pouco os dados, baixando os valores nulos e selecionando apenas algumas das colunas:
|
||||
|
||||
1. Adicione o seguinte código:
|
||||
|
||||
```python
|
||||
from sklearn.preprocessing import LabelEncoder
|
||||
|
||||
new_columns = ['Color','Origin','Item Size','Variety','City Name','Package']
|
||||
|
||||
new_pumpkins = pumpkins.drop([c for c in pumpkins.columns if c not in new_columns], axis=1)
|
||||
|
||||
new_pumpkins.dropna(inplace=True)
|
||||
|
||||
new_pumpkins = new_pumpkins.apply(LabelEncoder().fit_transform)
|
||||
```
|
||||
|
||||
Pode sempre dar uma olhada no seu novo dataframe:
|
||||
|
||||
```python
|
||||
new_pumpkins.info
|
||||
```
|
||||
|
||||
### Visualização - grelha lado a lado
|
||||
|
||||
Por esta altura já já carregou o [caderno de entrada](./notebook.ipynb) com dados de abóbora mais uma vez e limpou-os de modo a preservar um conjunto de dados contendo algumas variáveis, incluindo `Color`. Vamos visualizar o quadro de dados no caderno usando uma biblioteca diferente: [Seaborn](https://seaborn.pydata.org/index.html), que é construída em Matplotlib que usamos anteriormente.
|
||||
|
||||
Seaborn oferece algumas maneiras limpas de visualizar os seus dados. Por exemplo, pode comparar distribuições dos dados por cada ponto numa grelha lado a lado.
|
||||
|
||||
1. Crie tal rede através da instantânea `PairGrid`, utilizando os nossos dados de abóbora `new_pumpkins`, seguidos de `map()`:
|
||||
|
||||
```python
|
||||
import seaborn as sns
|
||||
|
||||
g = sns.PairGrid(new_pumpkins)
|
||||
g.map(sns.scatterplot)
|
||||
```
|
||||
|
||||

|
||||
|
||||
Ao observar dados lado a lado, pode ver como os dados de Cor se relacionam com as outras colunas.
|
||||
|
||||
✅ Dada esta grelha de dispersão, quais são algumas explorações interessantes que podes imaginar?
|
||||
|
||||
### Use um enredo de enxame
|
||||
Uma vez que a Cor é uma categoria binária (Laranja ou Não), chama-se "dados categóricos" e precisa de "uma abordagem mais [especializada](https://seaborn.pydata.org/tutorial/categorical.html?highlight=bar) à visualização". Há outras formas de visualizar a relação desta categoria com outras variáveis.
|
||||
|
||||
Você pode visualizar variáveis lado a lado com parcelas seaborn.
|
||||
|
||||
1. Experimente um plano de 'enxame' para mostrar a distribuição de valores:
|
||||
|
||||
```python
|
||||
sns.swarmplot(x="Color", y="Item Size", data=new_pumpkins)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Enredo de violino
|
||||
|
||||
Um gráfico de tipo 'violino' é útil, pois você pode visualizar facilmente a forma como os dados nas duas categorias são distribuídos. Os gráficos de violino não funcionam tão bem com conjuntos de dados menores, pois a distribuição é exibida mais 'suavemente'.
|
||||
|
||||
1. Como parâmetros `x=Color`, `kind="violin"` e chamada `catplot()`:
|
||||
|
||||
```python
|
||||
sns.catplot(x="Color", y="Item Size",
|
||||
kind="violin", data=new_pumpkins)
|
||||
```
|
||||
|
||||

|
||||
|
||||
✅ Tente criar este enredo, e outros enredos de Seaborn, usando outras variáveis.
|
||||
|
||||
Agora que temos uma ideia da relação entre as categorias binárias de cor e o grupo maior de tamanhos, vamos explorar a regressão logística para determinar a cor provável de uma dada abóbora.
|
||||
|
||||
> **🧮 Mostre-Me A Matemática**
|
||||
>
|
||||
> Lembram-se como a regressão linear frequentemente usava mínimos quadrados ordinários para chegar a um valor? A regressão logística baseia-se no conceito de "máxima verossimilhança" utilizando [funções sigmoides](https://wikipedia.org/wiki/Sigmoid_function). Uma 'Função Sigmoide' em uma trama se parece com uma forma 'S'. Ele pega um valor e o mapeia para algum lugar entre 0 e 1. Sua curva também é chamada de "curva logística". Sua fórmula é assim:
|
||||
>
|
||||
> 
|
||||
>
|
||||
> onde o ponto médio do sigmoide se encontra no ponto 0 de x, L é o valor máximo da curva, e k é a inclinação da curva. Se o resultado da função for maior que 0,5, o rótulo em questão receberá a classe '1' da escolha binária. Caso contrário, será classificado como "0".
|
||||
|
||||
## Crie o seu modelo
|
||||
|
||||
Construir um modelo para encontrar essas classificações binárias é surpreendentemente simples no Scikit-learn.
|
||||
|
||||
1. Selecione as variáveis que deseja utilizar no seu modelo de classificação e divida os conjuntos de treino e teste que chamam `train_test_split()`:
|
||||
|
||||
```python
|
||||
from sklearn.model_selection import train_test_split
|
||||
|
||||
Selected_features = ['Origin','Item Size','Variety','City Name','Package']
|
||||
|
||||
X = new_pumpkins[Selected_features]
|
||||
y = new_pumpkins['Color']
|
||||
|
||||
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
|
||||
|
||||
```
|
||||
|
||||
1. Agora você pode treinar seu modelo, chamando `fit()` com seus dados de treinamento e imprimir o resultado:
|
||||
|
||||
```python
|
||||
from sklearn.model_selection import train_test_split
|
||||
from sklearn.metrics import accuracy_score, classification_report
|
||||
from sklearn.linear_model import LogisticRegression
|
||||
|
||||
model = LogisticRegression()
|
||||
model.fit(X_train, y_train)
|
||||
predictions = model.predict(X_test)
|
||||
|
||||
print(classification_report(y_test, predictions))
|
||||
print('Predicted labels: ', predictions)
|
||||
print('Accuracy: ', accuracy_score(y_test, predictions))
|
||||
```
|
||||
|
||||
Dê uma olhada no placar do seu modelo. Não é tão ruim, considerando que você tem apenas cerca de 1000 linhas de dados:
|
||||
|
||||
```output
|
||||
precision recall f1-score support
|
||||
|
||||
0 0.85 0.95 0.90 166
|
||||
1 0.38 0.15 0.22 33
|
||||
|
||||
accuracy 0.82 199
|
||||
macro avg 0.62 0.55 0.56 199
|
||||
weighted avg 0.77 0.82 0.78 199
|
||||
|
||||
Predicted labels: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 1 0 1 0 0 1 0 0 0 1 0]
|
||||
```
|
||||
|
||||
## Melhor compreensão através de uma matriz de confusão
|
||||
|
||||
Enquanto você pode obter um relatório de placar [termos](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html?highlight=classification_report#sklearn.metrics.classification_report) imprimindo os itens acima, você pode ser capaz de entender seu modelo mais facilmente usando uma [matriz confusão](https://scikit-learn.org/stable/modules/model_evaluation.html#confusion-matrix) para nos ajudar a entender como o modelo está se saindo.
|
||||
|
||||
> 🎓 A '[matriz de confusão](https://wikipedia.org/wiki/Confusion_matrix)' (ou 'matriz de erros') é uma tabela que expressa os verdadeiros versus falsos positivos e negativos do seu modelo, avaliando assim a precisão das previsões.
|
||||
|
||||
1. Para usar uma métrica de confusão, chame`confusion_matrix()`:
|
||||
|
||||
```python
|
||||
from sklearn.metrics import confusion_matrix
|
||||
confusion_matrix(y_test, predictions)
|
||||
```
|
||||
|
||||
Dê uma olhada na matriz de confusão do seu modelo:
|
||||
|
||||
```output
|
||||
array([[162, 4],
|
||||
[ 33, 0]])
|
||||
```
|
||||
|
||||
No Scikit-learn, matrizes de confusão Linhas (eixo 0) são rótulos reais e colunas (eixo 1) são rótulos previstos.
|
||||
|
||||
| | 0 | 1 |
|
||||
| :---: | :---: | :---: |
|
||||
| 0 | TN | FP |
|
||||
| 1 | FN | TP |
|
||||
|
||||
O que está acontecendo aqui? Digamos que nosso modelo é solicitado a classificar abóboras entre duas categorias binárias, categoria 'laranja' e categoria 'não-laranja'.
|
||||
|
||||
- Se o seu modelo prevê uma abóbora como não laranja e pertence à categoria 'não-laranja' na realidade chamamos-lhe um verdadeiro negativo, mostrado pelo número superior esquerdo.
|
||||
- Se o seu modelo prevê uma abóbora como laranja e pertence à categoria 'não-laranja' na realidade chamamos-lhe um falso negativo, mostrado pelo número inferior esquerdo.
|
||||
- Se o seu modelo prevê uma abóbora como não laranja e pertence à categoria 'laranja' na realidade chamamos-lhe um falso positivo, mostrado pelo número superior direito.
|
||||
- Se o seu modelo prevê uma abóbora como laranja e ela pertence à categoria 'laranja' na realidade nós chamamos de um verdadeiro positivo, mostrado pelo número inferior direito.
|
||||
|
||||
Como vocês devem ter adivinhado, é preferível ter um número maior de verdadeiros positivos e verdadeiros negativos e um número menor de falsos positivos e falsos negativos, o que implica que o modelo tem melhor desempenho.
|
||||
|
||||
Como a matriz de confusão se relaciona com precisão e evocação? Lembre-se, o relatório de classificação impresso acima mostrou precisão (0,83) e recuperação (0,98).
|
||||
|
||||
Precision = tp / (tp + fp) = 162 / (162 + 33) = 0.8307692307692308
|
||||
|
||||
Recall = tp / (tp + fn) = 162 / (162 + 4) = 0.9759036144578314
|
||||
|
||||
✅ Q: De acordo com a matriz de confusão, como foi o modelo? A: Nada mal. há um bom número de verdadeiros negativos, mas também vários falsos negativos.
|
||||
|
||||
Vamos revisitar os termos que vimos anteriormente com a ajuda do mapeamento da matriz confusão de TP/TN e FP/FN:
|
||||
|
||||
🎓 precisão: TP/(TP + FP) A fração de instâncias relevantes entre as instâncias recuperadas (por exemplo, quais rótulos estavam bem rotulados)
|
||||
|
||||
🎓 Chamada: TP/(TP + FN) A fração de instâncias relevantes que foram recuperadas, sejam bem rotuladas ou não
|
||||
|
||||
🎓 f1- score: (2 * precisão * recolha)/(precisão + recolha) Uma média ponderada da precisão e recolha, sendo a melhor 1 e a pior 0
|
||||
|
||||
Suporte 🎓: O número de ocorrências de cada rótulo recuperado
|
||||
|
||||
🎓 precisão: (TP + TN)/(TP + TN + FP + FN) A percentagem de rótulos previstos com precisão para uma amostra.
|
||||
|
||||
🎓 Méd. de Macro: O cálculo das métricas médias não ponderadas para cada rótulo, sem levar em conta o desequilíbrio do rótulo.
|
||||
|
||||
🎓 Média Ponderada: O cálculo das métricas médias para cada label, levando em conta o desequilíbrio de label ponderando-as pelo suporte (o número de instâncias verdadeiras para cada label).
|
||||
|
||||
Consegue pensar qual métrica deve observar se quiser que o seu modelo reduza o número de falsos negativos?
|
||||
|
||||
## Visualizar a curva de ROC deste modelo
|
||||
|
||||
Este não é um mau modelo; sua precisão está na faixa de 80%, então idealmente você poderia usá-lo para prever a cor de uma abóbora dado um conjunto de variáveis.
|
||||
|
||||
Vamos fazer mais uma visualização para ver a chamada pontuação 'ROC':
|
||||
|
||||
```python
|
||||
from sklearn.metrics import roc_curve, roc_auc_score
|
||||
|
||||
y_scores = model.predict_proba(X_test)
|
||||
# calculate ROC curve
|
||||
fpr, tpr, thresholds = roc_curve(y_test, y_scores[:,1])
|
||||
sns.lineplot([0, 1], [0, 1])
|
||||
sns.lineplot(fpr, tpr)
|
||||
```
|
||||
Usando Seaborn novamente, plote a [Característica de operação de recepção](https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html?highlight=roc) ou ROC do modelo. Curvas ROC são frequentemente usadas para obter uma visão da saída de um classificador em termos de seus verdadeiros versus falsos positivos. "As curvas ROC geralmente apresentam taxa positiva verdadeira no eixo Y e taxa positiva falsa no eixo X." Assim, a inclinação da curva e o espaço entre a linha do ponto médio e a matéria da curva: você quer uma curva que rapidamente se encaminha para cima e sobre a linha. No nosso caso, há falsos positivos para começar, e então a linha se encaminha para cima e para cima corretamente:
|
||||
|
||||

|
||||
|
||||
Finalmente, use o Scikit-learn [`roc_auc_score` API](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_auc_score.html?highlight=roc_auc#sklearn.metrics.roc_auc_score) para calcular a 'Área sob a curva' (AUC) real:
|
||||
|
||||
```python
|
||||
auc = roc_auc_score(y_test,y_scores[:,1])
|
||||
print(auc)
|
||||
```
|
||||
O resultado é `0,6976998904709748`. Dado que a AUC varia de 0 a 1, você quer uma grande pontuação, uma vez que um modelo que é 100% correto em suas previsões terá uma AUC de 1; nesse caso, o modelo é _muito bom_.
|
||||
|
||||
Em lições futuras sobre classificações, você aprenderá a iterar para melhorar as pontuações do seu modelo. Mas por enquanto, parabéns! Você completou essas lições de regressão!
|
||||
|
||||
---
|
||||
## 🚀Desafio
|
||||
|
||||
Há muito mais a desempacotar em relação à regressão logística! Mas a melhor maneira de aprender é experimentar. Encontre um conjunto de dados que se preste a esse tipo de análise e construa um modelo com ele. O que você aprende? dica: tente [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) para obter conjuntos de dados interessantes.
|
||||
|
||||
## [Teste pós-aula](https://white-water-09ec41f0f.azurestaticapps.net/quiz/16/)
|
||||
|
||||
## Análise e autoestudo
|
||||
|
||||
Leia as primeiras páginas de [este artigo de Stanford](https://web.stanford.edu/~jurafsky/slp3/5.pdf) sobre alguns usos práticos para regressão logística. Pense em tarefas que são mais adequadas para um ou outro tipo de tarefas de regressão que estudamos até agora. O que funcionaria melhor?
|
||||
|
||||
## Atribuição
|
||||
|
||||
[Repetindo esta regressão](assignment.md)
|
@ -0,0 +1,11 @@
|
||||
## Retrying alguma regressão
|
||||
|
||||
## Instruções
|
||||
|
||||
Na lição, usaste um subconjunto dos dados da abóbora. Agora, volte aos dados originais e tente usá-lo todo, limpo e padronizado, para construir uma Regressão Logística model.
|
||||
|
||||
## Rubrica
|
||||
|
||||
| Critérios | exemplares | Adequado | Necessidades de Melhoria |
|
||||
| -------- | ----------------------------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------- |
|
||||
| | Um caderno é apresentado com um modelo bem explicado e bem-adundo | Um caderno é apresentado com um modelo que funciona minimamente | Um caderno é apresentado com um modelo de sub-desempenho ou nenhum|
|
@ -0,0 +1,38 @@
|
||||
# Modelos de regressão para aprendizagem automática
|
||||
## Tópico regional: Modelos de regressão para preços de abóbora na América do Norte 🎃
|
||||
|
||||
Na América do Norte, as abóboras são muitas vezes esculpidas em rostos assustadores para o Halloween. Vamos descobrir mais sobre estes fascinantes vegetais!
|
||||
|
||||

|
||||
> Photo by <a href="https://unsplash.com/@teutschmann?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Beth Teutschmann</a> on <a href="https://unsplash.com/s/photos/jack-o-lanterns?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
|
||||
|
||||
## O que vai aprender
|
||||
|
||||
[](https://youtu.be/5QnJtDad4iQ "Regressão Vídeo de introdução - Clique para ver
|
||||
!")
|
||||
> 🎥 Clique na imagem acima para obter um vídeo de introdução rápida a esta lição
|
||||
|
||||
As lições nesta secção abrangem tipos de regressão no contexto da aprendizagem automática. Os modelos de regressão podem ajudar a determinar a _relação_ entre variáveis. Este tipo de modelo pode prever valores como comprimento, temperatura ou idade, descobrindo assim relações entre variáveis à medida que analisa pontos de dados.
|
||||
|
||||
Nesta série de lições, você vai descobrir a diferença entre regressão logística linear vs. e quando você deve usar uma ou outra.
|
||||
|
||||
Neste grupo de lições, você será configurado para iniciar tarefas de machine learning, incluindo configurar o Código do Estúdio Visual para gerir cadernos, o ambiente comum para cientistas de dados. Você vai descobrir Scikit-learn, uma biblioteca para machine learning, e você vai construir seus primeiros modelos, focando-se em modelos de Regressão neste capítulo.
|
||||
|
||||
> Existem ferramentas de baixo código úteis que podem ajudá-lo a aprender sobre trabalhar com modelos de regressão. Tente
|
||||
[Azure ML for this task](https://docs.microsoft.com/learn/modules/create-regression-model-azure-machine-learning-designer/?WT.mc_id=academic-15963-cxa)
|
||||
|
||||
### Lessons
|
||||
|
||||
1. [Ferramentas do comércio](1-Tools/README.md)
|
||||
2. [Gestão de dados](2-Data/README.md)
|
||||
3. [Linear and polynomial regression](3-Linear/README.md)
|
||||
4. [Logistic regression](4-Logistic/README.md)
|
||||
|
||||
---
|
||||
### Credits
|
||||
|
||||
"ML com regressão" foi escrito com ♥️ por[Jen Looper](https://twitter.com/jenlooper)
|
||||
|
||||
♥️ Os colaboradores do quiz incluem:[Muhammad Sakib Khan Inan](https://twitter.com/Sakibinan) e [Ornella Altunyan](https://twitter.com/ornelladotcom)
|
||||
|
||||
O conjunto de dados de abóbora é sugerido por [este projeto em Kaggle](https://www.kaggle.com/usda/a-year-of-pumpkin-prices) e os seus dados são obtidos a partir do [Relatórios padrão dos mercados de terminais de culturas especiais](https://www.marketnews.usda.gov/mnp/fv-report-config-step1?type=termPrice) distribuído pelo Departamento de Agricultura dos Estados Unidos. Adicionámos alguns pontos em torno da cor com base na variedade para normalizar a distribuição. Estes dados estão no domínio público.
|
@ -0,0 +1,347 @@
|
||||
# Criar um Aplicativo Web para usar um Modelo ML
|
||||
|
||||
Nesta lição, você treinará um modelo ML em um conjunto de dados que está fora deste mundo: _Avistamentos de OVNIs no último século_, provenientes do banco de dados do NUFORC.
|
||||
|
||||
Você aprenderá:
|
||||
|
||||
- Como "picles" um modelo treinado
|
||||
- Como usar esse modelo em um aplicativo Flask
|
||||
|
||||
Continuaremos a usar notebooks para limpar dados e treinar nosso modelo, mas você pode levar o processo um passo adiante explorando o uso de um modelo "selvagem", por assim dizer: em um aplicativo Web.
|
||||
|
||||
Para fazer isso, você precisa construir um aplicativo Web usando Flask.
|
||||
|
||||
## [Teste de pré-aula](https://white-water-09ec41f0f.azurestaticapps.net/quiz/17/)
|
||||
|
||||
## Criando um aplicativo
|
||||
|
||||
Há várias maneiras de criar aplicativos Web para consumir modelos de aprendizado de máquina. Sua arquitetura da Web pode influenciar a maneira como seu modelo é treinado. Imagine que você está trabalhando em um negócio onde o grupo de ciência de dados treinou um modelo que eles querem que você use em um aplicativo.
|
||||
|
||||
### Considerações
|
||||
|
||||
Há muitas perguntas que você precisa fazer:
|
||||
|
||||
- **É um aplicativo Web ou um aplicativo móvel?** Se você estiver criando um aplicativo móvel ou precisar usar o modelo em um contexto de IoT, poderá usar [TensorFlow Lite](https://www.tensorflow.org/lite/) e usar o modelo em um aplicativo Android ou iOS.
|
||||
- **Onde o modelo residirá?** Na nuvem ou localmente?
|
||||
- **Suporte off-line.** O aplicativo precisa trabalhar off-line?
|
||||
- **Que tecnologia foi usada para treinar o modelo?** A tecnologia escolhida pode influenciar as ferramentas que você precisa usar.
|
||||
|
||||
- **Usando fluxo de Tensor.** Se você estiver treinando um modelo usando TensorFlow, por exemplo, esse ecossistema oferece a capacidade de converter um modelo TensorFlow para uso em um aplicativo Web usando [TensorFlow.js](https://www.tensorflow.org/js/).
|
||||
- **Usando o PyTorch.** Se você estiver criando um modelo usando uma biblioteca como [PyTorch](https://pytorch.org/), terá a opção de exportá-lo no formato [ONNX](https://onnx.ai/) (Open Neural Network Exchange) para uso em aplicativos Web JavaScript que podem usar o [Onnx Runtime](https://www.onnxruntime.ai/). Essa opção será explorada em uma lição futura para um modelo treinado com o Scikit.
|
||||
- **Usando o Lobe.ai ou o Azure Custom Vision.** Se você estiver usando um sistema ML SaaS (Software as a Service) como [Lobe.ai](https://lobe.ai/) ou [Azure Custom Vision](https://azure.microsoft.com/services/cognitive-services/custom-vision-service/?WT.mc_id=academy-15963-cxa) para treinar um modelo, esse tipo de software fornece maneiras de exportar o modelo para várias plataformas, incluindo a criação de uma API sob medida ser consultado na nuvem pelo aplicativo online.
|
||||
|
||||
|
||||
Você também tem a oportunidade de construir um aplicativo web Flask inteiro que seria capaz de treinar o próprio modelo em um navegador da web. Isso também pode ser feito usando TensorFlow.js em um contexto JavaScript.
|
||||
|
||||
Para nossos propósitos, já que estamos trabalhando com notebooks baseados em Python, vamos explorar as etapas que você precisa seguir para exportar um modelo treinado de tal notebook para um formato legível por um aplicativo web construído em Python.
|
||||
|
||||
## Ferramenta
|
||||
|
||||
Para esta tarefa, você precisa de duas ferramentas: Flask e Pickle, ambos em Python.
|
||||
|
||||
O que é [Frasco](https://palletsprojects.com/p/flask/)? Definido como um 'microframework' por seus criadores, o Flask fornece as características básicas de frameworks web usando Python e um motor de modelagem para construir páginas web. Dê uma olhada em [este módulo de aprendizado](https://docs.microsoft.com/learn/modules/python-flask-build-ai-web-app?WT.mc_id=academic-15963-cxa) para praticar a construção com o Flask.
|
||||
|
||||
✅ O que é [Pickle](https://docs.python.org/3/library/pickle.html)? Pickle 🥒 é um módulo Python que serializa e desserializa uma estrutura de objeto Python. Ao "pichar" um modelo, você serializa ou achata sua estrutura para uso na web. Tenha cuidado: o pickle não é intrinsecamente seguro, portanto, tenha cuidado se for solicitado a `cancelar o pickle` de um arquivo. Um arquivo em conserto tem o sufixo `.pkl`.
|
||||
|
||||
## Exercício - limpar seus dados
|
||||
|
||||
Nesta lição, você usará dados de 80.000 avistamentos de UFO, coletados pelo [NUFORC](https://nuforc.org) (Centro Nacional de Relatórios de UFO). Estes dados têm algumas descrições interessantes de avistamentos de UFO, por exemplo:
|
||||
|
||||
- **Descrição de exemplo longo.** "Um homem emerge de um feixe de luz que brilha em um campo gramado à noite e corre em direção ao estacionamento da Texas Instruments".
|
||||
- **Breve descrição do exemplo.** "as luzes nos perseguiram".
|
||||
|
||||
A planilha [ufos.csv](./data/ufos.csv) inclui colunas sobre `city`, `state` e `country` onde ocorreu o avistamento, `shape` do objeto e sua `latitude` e `longitude`.
|
||||
|
||||
No espaço em branco [notebook](notebook.ipynb) incluído nesta lição:
|
||||
|
||||
1. importe `pandas`, `matplotlib` e `numpy` como fez nas lições anteriores e importe a planilha ufos. Você pode dar uma olhada em um conjunto de dados de amostra:
|
||||
|
||||
```python
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
ufos = pd.read_csv('./data/ufos.csv')
|
||||
ufos.head()
|
||||
```
|
||||
|
||||
1.Converta os dados ufos em um pequeno dataframe com títulos novos. Verifique os valores exclusivos no campo `País`.
|
||||
|
||||
```python
|
||||
ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})
|
||||
|
||||
ufos.Country.unique()
|
||||
```
|
||||
|
||||
1. Agora, você pode reduzir a quantidade de dados que precisamos lidar, eliminando quaisquer valores nulos e importando apenas avistamentos entre 1-60 segundos:
|
||||
|
||||
```python
|
||||
ufos.dropna(inplace=True)
|
||||
|
||||
ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]
|
||||
|
||||
ufos.info()
|
||||
```
|
||||
|
||||
1. Importe a biblioteca 'LabelEncoder' do Scikit-learn para converter os valores de texto dos países em um número:
|
||||
|
||||
✅ LabelEncoder codifica os dados em ordem alfabética
|
||||
|
||||
```python
|
||||
from sklearn.preprocessing import LabelEncoder
|
||||
|
||||
ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])
|
||||
|
||||
ufos.head()
|
||||
```
|
||||
|
||||
Seus dados devem ter esta aparência:
|
||||
|
||||
```output
|
||||
Seconds Country Latitude Longitude
|
||||
2 20.0 3 53.200000 -2.916667
|
||||
3 20.0 4 28.978333 -96.645833
|
||||
14 30.0 4 35.823889 -80.253611
|
||||
23 60.0 4 45.582778 -122.352222
|
||||
24 3.0 3 51.783333 -0.783333
|
||||
```
|
||||
|
||||
## Exercício - construa seu modelo
|
||||
|
||||
Agora você pode se preparar para treinar um modelo dividindo os dados no grupo de treinamento e teste.
|
||||
|
||||
1. Selecione os três recursos que você deseja treinar como seu vetor X, e o vetor y será o `País`. Você quer digitar `Segundos`, `Latitude` e `Longitude` e obter um ID de país para retornar.
|
||||
|
||||
```python
|
||||
from sklearn.model_selection import train_test_split
|
||||
|
||||
Selected_features = ['Seconds','Latitude','Longitude']
|
||||
|
||||
X = ufos[Selected_features]
|
||||
y = ufos['Country']
|
||||
|
||||
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
|
||||
```
|
||||
|
||||
1. Treine seu modelo usando regressão logística:
|
||||
|
||||
```python
|
||||
from sklearn.metrics import accuracy_score, classification_report
|
||||
from sklearn.linear_model import LogisticRegression
|
||||
model = LogisticRegression()
|
||||
model.fit(X_train, y_train)
|
||||
predictions = model.predict(X_test)
|
||||
|
||||
print(classification_report(y_test, predictions))
|
||||
print('Predicted labels: ', predictions)
|
||||
print('Accuracy: ', accuracy_score(y_test, predictions))
|
||||
```
|
||||
|
||||
A precisão não é ruim **(cerca de 95%)**, sem surpresas, já que `País` e `Latitude/Longitude` se correlacionam.
|
||||
|
||||
O modelo que você criou não é muito revolucionário, pois você deve ser capaz de inferir um `País` a partir de sua `Latitude` e `Longitude`, mas é um bom exercício para tentar treinar a partir de dados brutos que você limpou, exportou e, em seguida, usar esse modelo em um aplicativo Web.
|
||||
|
||||
## Exercício - 'pickle' seu modelo
|
||||
|
||||
Agora, é hora de _pickle_ seu modelo! Você pode fazer isso em algumas linhas de código. Uma vez que seja _pickled_, carregue seu modelo em pickles e teste-o em uma matriz de dados de amostra contendo valores para segundos, latitude e longitude,
|
||||
|
||||
```python
|
||||
import pickle
|
||||
model_filename = 'ufo-model.pkl'
|
||||
pickle.dump(model, open(model_filename,'wb'))
|
||||
|
||||
model = pickle.load(open('ufo-model.pkl','rb'))
|
||||
print(model.predict([[50,44,-12]]))
|
||||
```
|
||||
|
||||
O modelo retorna **'3'**, que é o código de país do Reino Unido. Selvagem! 👽
|
||||
|
||||
## Exercício - criar um aplicativo Flask
|
||||
|
||||
Agora você pode construir um aplicativo Flask para chamar seu modelo e retornar resultados semelhantes, mas de uma forma mais visualmente agradável.
|
||||
|
||||
1. Comece criando uma pasta chamada **web-app** ao lado do arquivo _notebook.ipynb_ onde reside seu arquivo _ufo-model.pkl_.
|
||||
|
||||
1. Nessa pasta, crie mais três pastas: **static**, com uma pasta **css** dentro dela e **templates**. Agora você deve ter os seguintes arquivos e diretórios:
|
||||
|
||||
```output
|
||||
web-app/
|
||||
static/
|
||||
css/
|
||||
templates/
|
||||
notebook.ipynb
|
||||
ufo-model.pkl
|
||||
```
|
||||
|
||||
✅ Consulte a pasta da solução para obter uma exibição do aplicativo concluído
|
||||
|
||||
1. O primeiro arquivo a ser criado na pasta _web-app_ é o arquivo **requirements.txt**. Como _package.json_ em um aplicativo JavaScript, esse arquivo lista as dependências exigidas pelo aplicativo. Em **requirements.txt** adicione as linhas:
|
||||
|
||||
```text
|
||||
scikit-learn
|
||||
pandas
|
||||
numpy
|
||||
flask
|
||||
```
|
||||
|
||||
1. Agora, execute este arquivo navegando para _web-app_:
|
||||
|
||||
```bash
|
||||
cd web-app
|
||||
```
|
||||
|
||||
1. Em seu terminal, digite `pip install` para instalar as bibliotecas listadas em _requirements.txt_:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
1.Agora, você está pronto para criar mais três arquivos para concluir o aplicativo:
|
||||
|
||||
1. Crie **app.py** na raiz.
|
||||
2. Crie **index.html** no diretório _templates_.
|
||||
3. Crie **styles.css** no diretório _static/css_.
|
||||
|
||||
1. Construa o arquivo _styles.css_ com alguns estilos:
|
||||
|
||||
```css
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: 'Helvetica';
|
||||
background: black;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
letter-spacing: 1.4px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
input {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
width: 300px;
|
||||
border: 1px solid #2d2d2d;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.box {
|
||||
color: #fff;
|
||||
background: #2d2d2d;
|
||||
padding: 12px;
|
||||
display: inline-block;
|
||||
}
|
||||
```
|
||||
|
||||
1. Em seguida, crie o arquivo _index.html_:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>🛸 UFO Appearance Prediction! 👽</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="grid">
|
||||
|
||||
<div class="box">
|
||||
|
||||
<p>According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?</p>
|
||||
|
||||
<form action="{{ url_for('predict')}}" method="post">
|
||||
<input type="number" name="seconds" placeholder="Seconds" required="required" min="0" max="60" />
|
||||
<input type="text" name="latitude" placeholder="Latitude" required="required" />
|
||||
<input type="text" name="longitude" placeholder="Longitude" required="required" />
|
||||
<button type="submit" class="btn">Predict country where the UFO is seen</button>
|
||||
</form>
|
||||
|
||||
<p>{{ prediction_text }}</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Dê uma olhada na modelagem neste arquivo. Observe a sintaxe do 'bigode' ao redor das variáveis que serão fornecidas pelo aplicativo, como o texto de previsão: `{{}}`. Há também uma forma que publica uma previsão da rota `/predict`.
|
||||
|
||||
Finalmente, você está pronto para construir o arquivo python que direciona o consumo do modelo e a exibição de previsões:
|
||||
|
||||
1. Em `app.py` adicione:
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
from flask import Flask, request, render_template
|
||||
import pickle
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
model = pickle.load(open("../ufo-model.pkl", "rb"))
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def home():
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route("/predict", methods=["POST"])
|
||||
def predict():
|
||||
|
||||
int_features = [int(x) for x in request.form.values()]
|
||||
final_features = [np.array(int_features)]
|
||||
prediction = model.predict(final_features)
|
||||
|
||||
output = prediction[0]
|
||||
|
||||
countries = ["Australia", "Canada", "Germany", "UK", "US"]
|
||||
|
||||
return render_template(
|
||||
"index.html", prediction_text="Likely country: {}".format(countries[output])
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
```
|
||||
|
||||
>Dica: quando você adiciona [`debug=True`](https://www.askpython.com/python-modules/flask/flask-debug-mode) ao executar o aplicativo Web usando Flask, todas as alterações feitas no aplicativo serão refletidas imediatamente sem a necessidade de reiniciar o servidor. Cuidado! Não habilite este modo em um aplicativo de produção.
|
||||
|
||||
Se você executar `python app.py` ou `python3 app.py` - seu servidor Web é iniciado localmente e você pode preencher um formulário curto para obter uma resposta para sua pergunta de gravação sobre onde os OVNIs foram avistados!
|
||||
|
||||
Antes de fazer isso, dê uma olhada nas partes de `app.py`:
|
||||
|
||||
1. Primeiro, as dependências são carregadas e o aplicativo inicia.
|
||||
1. Então, o modelo é importado.
|
||||
1. Então, index.html é renderizado na rota inicial.
|
||||
|
||||
Na rota `/predict`, várias coisas acontecem quando o formulário é publicado:
|
||||
|
||||
1. As variáveis de formulário são reunidas e convertidas em uma matriz numérica. Eles são então enviados para o modelo e uma previsão é retornada.
|
||||
2. Os Países que queremos exibir são renderizados novamente como texto legível de seu código de país previsto, e esse valor é enviado de volta para index.html para ser renderizado no modelo.
|
||||
|
||||
Usando um modelo desta maneira, com Flask e um modelo em conserva, é relativamente simples. A coisa mais difícil é entender qual é a forma dos dados que devem ser enviados ao modelo para obter uma previsão. Tudo depende de como o modelo foi treinado. Este tem três pontos de dados para serem inseridos a fim de obter uma previsão.
|
||||
|
||||
Em um ambiente profissional, você pode ver como uma boa comunicação é necessária entre as pessoas que treinam o modelo e aqueles que o consomem em um aplicativo web ou móvel. No nosso caso, é só uma pessoa, você!
|
||||
|
||||
---
|
||||
|
||||
## 🚀Desafio
|
||||
|
||||
Em vez de trabalhar em um notebook e importar o modelo para o aplicativo Flask, você poderia treinar o modelo dentro do aplicativo Flask! Tente converter seu código Python no notebook, talvez depois que seus dados forem limpos, para treinar o modelo de dentro do aplicativo em uma rota chamada `train`. Quais são os prós e contras de se buscar esse método?
|
||||
|
||||
## [Teste pós-aula](https://white-water-09ec41f0f.azurestaticapps.net/quiz/18/)
|
||||
|
||||
## Análise e autoestudo
|
||||
|
||||
Há muitas maneiras de construir um aplicativo Web para consumir modelos ML. Faça uma lista de maneiras de usar JavaScript ou Python para construir um aplicativo Web para aproveitar o aprendizado de máquina. Considere a arquitetura: o modelo deve permanecer no aplicativo ou viver na nuvem? Se o último, como você acessaria? Desenhe um modelo arquitetônico para uma solução web ML aplicada.
|
||||
|
||||
## Atribuição
|
||||
|
||||
[Tente um modelo diferente](assignment.md)
|
@ -0,0 +1,11 @@
|
||||
# Tente um modelo diferente
|
||||
|
||||
## Instruções
|
||||
|
||||
Agora que você construiu um aplicativo Web usando um modelo Regression treinado, use um dos modelos de uma lição Regression anterior para refazer esse aplicativo Web. Você pode manter o estilo ou design de forma diferente para refletir os dados da abóbora. Tenha cuidado para alterar as entradas para refletir o método de treinamento do seu modelo.
|
||||
|
||||
## Rubrica
|
||||
|
||||
| Critérios | Exemplar | Adequado | Necessidade de melhoria |
|
||||
| -------------------------- | --------------------------------------------------------- | --------------------------------------------------------- | -------------------------------------- |
|
||||
| | O aplicativo Web é executado conforme o esperado e implantado na nuvem | O aplicativo Web contém falhas ou exibe resultados inesperados | O aplicativo Web não funciona corretamente|
|
@ -0,0 +1,21 @@
|
||||
# Crie um aplicativo Web para usar seu modelo ML
|
||||
|
||||
Nesta seção do currículo, você será apresentado a um tópico ML aplicado: como salvar seu modelo Scikit-learn como um arquivo que pode ser usado para fazer previsões em uma aplicação Web. Uma vez que o modelo é salvo, você vai aprender como usá-lo em um aplicativo web construído em Flask. Você vai primeiro criar um modelo usando alguns dados que são tudo sobre avistamentos de UFO! Em seguida, você criará um aplicativo Web que permitirá inserir um número de segundos com uma latitude e um valor de longitude para prever qual país relatou ter visto um UFO.
|
||||
|
||||

|
||||
|
||||
Foto de <a href="https://unsplash.com/@mdherren?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Michael Herren</a> em <a href="https://unsplash.com/s/photos/ufo?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
|
||||
|
||||
## Lições
|
||||
|
||||
1. [Crie um aplicativo Web](1-Web-App/README.md)
|
||||
|
||||
## Créditos
|
||||
|
||||
"Build a Web App" foi escrito com ♥️ por[Jen Looper](https://twitter.com/jenlooper).
|
||||
|
||||
♥️ Os testes foram escritos por Rohan Raj.
|
||||
|
||||
O conjunto de dados provém de [Kaggle](https://www.kaggle.com/NUFORC/ufo-sightings).
|
||||
|
||||
A arquitetura do aplicativo Web foi sugerida em parte por [este artigo](https://towardsdatascience.com/how-to-easy-deploy-machine-learning-models-using-flask-b95af8fe34d4) e [este repositório](https://github.com/abhinavsagar/machine-learning-deployment) by Abhinav Sagar.
|
@ -0,0 +1,386 @@
|
||||
# Time Series Forecasting with Support Vector Regressor
|
||||
|
||||
In the previous lesson, you learned how to use ARIMA model to make time series predictions. Now you'll be looking at Support Vector Regressor model which is a regressor model used to predict continuous data.
|
||||
|
||||
## [Pre-lecture quiz](https://white-water-09ec41f0f.azurestaticapps.net/quiz/51/)
|
||||
|
||||
## Introduction
|
||||
|
||||
In this lesson, you will discover a specific way to build models with [**SVM**: **S**upport **V**ector **M**achine](https://en.wikipedia.org/wiki/Support-vector_machine) for regression, or **SVR: Support Vector Regressor**.
|
||||
|
||||
### SVR in the context of time series [^1]
|
||||
|
||||
Before understanding the importance of SVR in time series prediction, here are some of the important concepts that you need to know:
|
||||
|
||||
- **Regression:** Supervised learning technique to predict continuous values from a given set of inputs. The idea is to fit a curve (or line) in the feature space that has the maximum number of data points. [Click here](https://en.wikipedia.org/wiki/Regression_analysis) for more information.
|
||||
- **Support Vector Machine (SVM):** A type of supervised machine learning model used for classification, regression and outliers detection. The model is a hyperplane in the feature space, which in case of classification acts as a boundary, and in case of regression acts as the best-fit line. In SVM, a Kernel function is generally used to transform the dataset to a space of higher number of dimensions, so that they can be easily separable. [Click here](https://en.wikipedia.org/wiki/Support-vector_machine) for more information on SVMs.
|
||||
- **Support Vector Regressor (SVR):** A type of SVM, to find the best fit line (which in the case of SVM is a hyperplane) that has the maximum number of data points.
|
||||
|
||||
### Why SVR? [^1]
|
||||
|
||||
In the last lesson you learned about ARIMA, which is a very successful statistical linear method to forecast time series data. However, in many cases, time series data have *non-linearity*, which cannot be mapped by linear models. In such cases, the ability of SVM to consider non-linearity in the data for regression tasks makes SVR successful in time series forecasting.
|
||||
|
||||
## Exercise - build an SVR model
|
||||
|
||||
The first few steps for data preparation are the same as that of the previous lesson on [ARIMA](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA).
|
||||
|
||||
Open the _/working_ folder in this lesson and find the _notebook.ipynb_ file.[^2]
|
||||
|
||||
1. Run the notebook and import the necessary libraries: [^2]
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.append('../../')
|
||||
```
|
||||
|
||||
```python
|
||||
import os
|
||||
import warnings
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import datetime as dt
|
||||
import math
|
||||
|
||||
from sklearn.svm import SVR
|
||||
from sklearn.preprocessing import MinMaxScaler
|
||||
from common.utils import load_data, mape
|
||||
```
|
||||
|
||||
2. Load the data from the `/data/energy.csv` file into a Pandas dataframe and take a look: [^2]
|
||||
|
||||
```python
|
||||
energy = load_data('../../data')[['load']]
|
||||
```
|
||||
|
||||
3. Plot all the available energy data from January 2012 to December 2014: [^2]
|
||||
|
||||
```python
|
||||
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
|
||||
plt.xlabel('timestamp', fontsize=12)
|
||||
plt.ylabel('load', fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
Now, let's build our SVR model.
|
||||
|
||||
### Create training and testing datasets
|
||||
|
||||
Now your data is loaded, so you can separate it into train and test sets. Then you'll reshape the data to create a time-step based dataset which will be needed for the SVR. You'll train your model on the train set. After the model has finished training, you'll evaluate its accuracy on the training set, testing set and then the full dataset to see the overall performance. You need to ensure that the test set covers a later period in time from the training set to ensure that the model does not gain information from future time periods [^2] (a situation known as *Overfitting*).
|
||||
|
||||
1. Allocate a two-month period from September 1 to October 31, 2014 to the training set. The test set will include the two-month period of November 1 to December 31, 2014: [^2]
|
||||
|
||||
```python
|
||||
train_start_dt = '2014-11-01 00:00:00'
|
||||
test_start_dt = '2014-12-30 00:00:00'
|
||||
```
|
||||
|
||||
2. Visualize the differences: [^2]
|
||||
|
||||
```python
|
||||
energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \
|
||||
.join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \
|
||||
.plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)
|
||||
plt.xlabel('timestamp', fontsize=12)
|
||||
plt.ylabel('load', fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### Prepare the data for training
|
||||
|
||||
Now, you need to prepare the data for training by performing filtering and scaling of your data. Filter your dataset to only include the time periods and columns you need, and scaling to ensure the data is projected in the interval 0,1.
|
||||
|
||||
1. Filter the original dataset to include only the aforementioned time periods per set and only including the needed column 'load' plus the date: [^2]
|
||||
|
||||
```python
|
||||
train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]
|
||||
test = energy.copy()[energy.index >= test_start_dt][['load']]
|
||||
|
||||
print('Training data shape: ', train.shape)
|
||||
print('Test data shape: ', test.shape)
|
||||
```
|
||||
|
||||
```output
|
||||
Training data shape: (1416, 1)
|
||||
Test data shape: (48, 1)
|
||||
```
|
||||
|
||||
2. Scale the training data to be in the range (0, 1): [^2]
|
||||
|
||||
```python
|
||||
scaler = MinMaxScaler()
|
||||
train['load'] = scaler.fit_transform(train)
|
||||
```
|
||||
|
||||
4. Now, you scale the testing data: [^2]
|
||||
|
||||
```python
|
||||
test['load'] = scaler.transform(test)
|
||||
```
|
||||
|
||||
### Create data with time-steps [^1]
|
||||
|
||||
For the SVR, you transform the input data to be of the form `[batch, timesteps]`. So, you reshape the existing `train_data` and `test_data` such that there is a new dimension which refers to the timesteps.
|
||||
|
||||
```python
|
||||
# Converting to numpy arrays
|
||||
train_data = train.values
|
||||
test_data = test.values
|
||||
```
|
||||
|
||||
For this example, we take `timesteps = 5`. So, the inputs to the model are the data for the first 4 timesteps, and the output will be the data for the 5th timestep.
|
||||
|
||||
```python
|
||||
timesteps=5
|
||||
```
|
||||
|
||||
Converting training data to 2D tensor using nested list comprehension:
|
||||
|
||||
```python
|
||||
train_data_timesteps=np.array([[j for j in train_data[i:i+timesteps]] for i in range(0,len(train_data)-timesteps+1)])[:,:,0]
|
||||
train_data_timesteps.shape
|
||||
```
|
||||
|
||||
```output
|
||||
(1412, 5)
|
||||
```
|
||||
|
||||
Converting testing data to 2D tensor:
|
||||
|
||||
```python
|
||||
test_data_timesteps=np.array([[j for j in test_data[i:i+timesteps]] for i in range(0,len(test_data)-timesteps+1)])[:,:,0]
|
||||
test_data_timesteps.shape
|
||||
```
|
||||
|
||||
```output
|
||||
(44, 5)
|
||||
```
|
||||
|
||||
Selecting inputs and outputs from training and testing data:
|
||||
|
||||
```python
|
||||
x_train, y_train = train_data_timesteps[:,:timesteps-1],train_data_timesteps[:,[timesteps-1]]
|
||||
x_test, y_test = test_data_timesteps[:,:timesteps-1],test_data_timesteps[:,[timesteps-1]]
|
||||
|
||||
print(x_train.shape, y_train.shape)
|
||||
print(x_test.shape, y_test.shape)
|
||||
```
|
||||
|
||||
```output
|
||||
(1412, 4) (1412, 1)
|
||||
(44, 4) (44, 1)
|
||||
```
|
||||
|
||||
### Implement SVR [^1]
|
||||
|
||||
Now, it's time to implement SVR. To read more about this implementation, you can refer to [this documentation](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html). For our implementation, we follow these steps:
|
||||
|
||||
1. Define the model by calling `SVR()` and passing in the model hyperparameters: kernel, gamma, c and epsilon
|
||||
2. Prepare the model for the training data by calling the `fit()` function
|
||||
3. Make predictions calling the `predict()` function
|
||||
|
||||
Now we create an SVR model. Here we use the [RBF kernel](https://scikit-learn.org/stable/modules/svm.html#parameters-of-the-rbf-kernel), and set the hyperparameters gamma, C and epsilon as 0.5, 10 and 0.05 respectively.
|
||||
|
||||
```python
|
||||
model = SVR(kernel='rbf',gamma=0.5, C=10, epsilon = 0.05)
|
||||
```
|
||||
|
||||
#### Fit the model on training data [^1]
|
||||
|
||||
```python
|
||||
model.fit(x_train, y_train[:,0])
|
||||
```
|
||||
|
||||
```output
|
||||
SVR(C=10, cache_size=200, coef0=0.0, degree=3, epsilon=0.05, gamma=0.5,
|
||||
kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)
|
||||
```
|
||||
|
||||
#### Make model predictions [^1]
|
||||
|
||||
```python
|
||||
y_train_pred = model.predict(x_train).reshape(-1,1)
|
||||
y_test_pred = model.predict(x_test).reshape(-1,1)
|
||||
|
||||
print(y_train_pred.shape, y_test_pred.shape)
|
||||
```
|
||||
|
||||
```output
|
||||
(1412, 1) (44, 1)
|
||||
```
|
||||
|
||||
You've built your SVR! Now we need to evaluate it.
|
||||
|
||||
### Evaluate your model [^1]
|
||||
|
||||
For evaluation, first we will scale back the data to our original scale. Then, to check the performance, we will plot the original and predicted time series plot, and also print the MAPE result.
|
||||
|
||||
Scale the predicted and original output:
|
||||
|
||||
```python
|
||||
# Scaling the predictions
|
||||
y_train_pred = scaler.inverse_transform(y_train_pred)
|
||||
y_test_pred = scaler.inverse_transform(y_test_pred)
|
||||
|
||||
print(len(y_train_pred), len(y_test_pred))
|
||||
```
|
||||
|
||||
```python
|
||||
# Scaling the original values
|
||||
y_train = scaler.inverse_transform(y_train)
|
||||
y_test = scaler.inverse_transform(y_test)
|
||||
|
||||
print(len(y_train), len(y_test))
|
||||
```
|
||||
|
||||
#### Check model performance on training and testing data [^1]
|
||||
|
||||
We extract the timestamps from the dataset to show in the x-axis of our plot. Note that we are using the first ```timesteps-1``` values as out input for the first output, so the timestamps for the output will start after that.
|
||||
|
||||
```python
|
||||
train_timestamps = energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)].index[timesteps-1:]
|
||||
test_timestamps = energy[test_start_dt:].index[timesteps-1:]
|
||||
|
||||
print(len(train_timestamps), len(test_timestamps))
|
||||
```
|
||||
|
||||
```output
|
||||
1412 44
|
||||
```
|
||||
|
||||
Plot the predictions for training data:
|
||||
|
||||
```python
|
||||
plt.figure(figsize=(25,6))
|
||||
plt.plot(train_timestamps, y_train, color = 'red', linewidth=2.0, alpha = 0.6)
|
||||
plt.plot(train_timestamps, y_train_pred, color = 'blue', linewidth=0.8)
|
||||
plt.legend(['Actual','Predicted'])
|
||||
plt.xlabel('Timestamp')
|
||||
plt.title("Training data prediction")
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
Print MAPE for training data
|
||||
|
||||
```python
|
||||
print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')
|
||||
```
|
||||
|
||||
```output
|
||||
MAPE for training data: 1.7195710200875551 %
|
||||
```
|
||||
|
||||
Plot the predictions for testing data
|
||||
|
||||
```python
|
||||
plt.figure(figsize=(10,3))
|
||||
plt.plot(test_timestamps, y_test, color = 'red', linewidth=2.0, alpha = 0.6)
|
||||
plt.plot(test_timestamps, y_test_pred, color = 'blue', linewidth=0.8)
|
||||
plt.legend(['Actual','Predicted'])
|
||||
plt.xlabel('Timestamp')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
Print MAPE for testing data
|
||||
|
||||
```python
|
||||
print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')
|
||||
```
|
||||
|
||||
```output
|
||||
MAPE for testing data: 1.2623790187854018 %
|
||||
```
|
||||
|
||||
🏆 You have a very good result on the testing dataset!
|
||||
|
||||
### Check model performance on full dataset [^1]
|
||||
|
||||
```python
|
||||
# Extracting load values as numpy array
|
||||
data = energy.copy().values
|
||||
|
||||
# Scaling
|
||||
data = scaler.transform(data)
|
||||
|
||||
# Transforming to 2D tensor as per model input requirement
|
||||
data_timesteps=np.array([[j for j in data[i:i+timesteps]] for i in range(0,len(data)-timesteps+1)])[:,:,0]
|
||||
print("Tensor shape: ", data_timesteps.shape)
|
||||
|
||||
# Selecting inputs and outputs from data
|
||||
X, Y = data_timesteps[:,:timesteps-1],data_timesteps[:,[timesteps-1]]
|
||||
print("X shape: ", X.shape,"\nY shape: ", Y.shape)
|
||||
```
|
||||
|
||||
```output
|
||||
Tensor shape: (26300, 5)
|
||||
X shape: (26300, 4)
|
||||
Y shape: (26300, 1)
|
||||
```
|
||||
|
||||
```python
|
||||
# Make model predictions
|
||||
Y_pred = model.predict(X).reshape(-1,1)
|
||||
|
||||
# Inverse scale and reshape
|
||||
Y_pred = scaler.inverse_transform(Y_pred)
|
||||
Y = scaler.inverse_transform(Y)
|
||||
```
|
||||
|
||||
```python
|
||||
plt.figure(figsize=(30,8))
|
||||
plt.plot(Y, color = 'red', linewidth=2.0, alpha = 0.6)
|
||||
plt.plot(Y_pred, color = 'blue', linewidth=0.8)
|
||||
plt.legend(['Actual','Predicted'])
|
||||
plt.xlabel('Timestamp')
|
||||
plt.show()
|
||||
```
|
||||
|
||||

|
||||
|
||||
```python
|
||||
print('MAPE: ', mape(Y_pred, Y)*100, '%')
|
||||
```
|
||||
|
||||
```output
|
||||
MAPE: 2.0572089029888656 %
|
||||
```
|
||||
|
||||
|
||||
|
||||
🏆 Very nice plots, showing a model with good accuracy. Well done!
|
||||
|
||||
---
|
||||
|
||||
## 🚀Challenge
|
||||
|
||||
- Try to tweak the hyperparameters (gamma, C, epsilon) while creating the model and evaluate on the data to see which set of hyperparameters give the best results on the testing data. To know more about these hyperparameters, you can refer to the document [here](https://scikit-learn.org/stable/modules/svm.html#parameters-of-the-rbf-kernel).
|
||||
- Try to use different kernel functions for the model and analyze their performances on the dataset. A helpful document can be found [here](https://scikit-learn.org/stable/modules/svm.html#kernel-functions).
|
||||
- Try using different values for `timesteps` for the model to look back to make prediction.
|
||||
|
||||
## [Post-lecture quiz](https://white-water-09ec41f0f.azurestaticapps.net/quiz/52/)
|
||||
|
||||
## Review & Self Study
|
||||
|
||||
This lesson was to introduce the application of SVR for Time Series Forecasting. To read more about SVR, you can refer to [this blog](https://www.analyticsvidhya.com/blog/2020/03/support-vector-regression-tutorial-for-machine-learning/). This [documentation on scikit-learn](https://scikit-learn.org/stable/modules/svm.html) provides a more comprehensive explanation about SVMs in general, [SVRs](https://scikit-learn.org/stable/modules/svm.html#regression) and also other implementation details such as the different [kernel functions](https://scikit-learn.org/stable/modules/svm.html#kernel-functions) that can be used, and their parameters.
|
||||
|
||||
## Assignment
|
||||
|
||||
[A new SVR model](assignment.md)
|
||||
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
[^1]: The text, code and output in this section was contributed by [@AnirbanMukherjeeXD](https://github.com/AnirbanMukherjeeXD)
|
||||
[^2]: The text, code and output in this section was taken from [ARIMA](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA)
|
@ -0,0 +1,14 @@
|
||||
# A new SVR model
|
||||
|
||||
## Instructions [^1]
|
||||
|
||||
Now that you have built an SVR model, build a new one with fresh data (try one of [these datasets from Duke](http://www2.stat.duke.edu/~mw/ts_data_sets.html). Annotate your work in a notebook, visualize the data and your model, and test its accuracy using appropriate plots and MAPE. Also try tweaking the different hyperparameters and also using different values for the timesteps.
|
||||
## Rubric [^1]
|
||||
|
||||
| Criteria | Exemplary | Adequate | Needs Improvement |
|
||||
| -------- | ------------------------------------------------------------ | --------------------------------------------------------- | ----------------------------------- |
|
||||
| | A notebook is presented with an SVR model built, tested and explained with visualizations and accuracy stated. | The notebook presented is not annotated or contains bugs. | An incomplete notebook is presented |
|
||||
|
||||
|
||||
|
||||
[^1]:The text in this section was based on the [assignment from ARIMA](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA/assignment.md)
|
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 155 KiB |
After Width: | Height: | Size: 120 KiB |
File diff suppressed because one or more lines are too long
@ -0,0 +1,698 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fv9OoQsMFk5A"
|
||||
},
|
||||
"source": [
|
||||
"# Time series prediction using Support Vector Regressor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In this notebook, we demonstrate how to:\n",
|
||||
"\n",
|
||||
"- prepare 2D time series data for training an SVM regressor model\n",
|
||||
"- implement SVR using RBF kernel\n",
|
||||
"- evaluate the model using plots and MAPE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Importing modules"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import sys\n",
|
||||
"sys.path.append('../../')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"id": "M687KNlQFp0-"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import warnings\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import datetime as dt\n",
|
||||
"import math\n",
|
||||
"\n",
|
||||
"from sklearn.svm import SVR\n",
|
||||
"from sklearn.preprocessing import MinMaxScaler\n",
|
||||
"from common.utils import load_data, mape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Cj-kfVdMGjWP"
|
||||
},
|
||||
"source": [
|
||||
"## Preparing data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8fywSjC6GsRz"
|
||||
},
|
||||
"source": [
|
||||
"### Load data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 363
|
||||
},
|
||||
"id": "aBDkEB11Fumg",
|
||||
"outputId": "99cf7987-0509-4b73-8cc2-75d7da0d2740"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>load</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>2012-01-01 00:00:00</th>\n",
|
||||
" <td>2698.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2012-01-01 01:00:00</th>\n",
|
||||
" <td>2558.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2012-01-01 02:00:00</th>\n",
|
||||
" <td>2444.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2012-01-01 03:00:00</th>\n",
|
||||
" <td>2402.0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2012-01-01 04:00:00</th>\n",
|
||||
" <td>2403.0</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" load\n",
|
||||
"2012-01-01 00:00:00 2698.0\n",
|
||||
"2012-01-01 01:00:00 2558.0\n",
|
||||
"2012-01-01 02:00:00 2444.0\n",
|
||||
"2012-01-01 03:00:00 2402.0\n",
|
||||
"2012-01-01 04:00:00 2403.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"energy = load_data('../../data')[['load']]\n",
|
||||
"energy.head(5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "O0BWP13rGnh4"
|
||||
},
|
||||
"source": [
|
||||
"### Plot the data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 486
|
||||
},
|
||||
"id": "hGaNPKu_Gidk",
|
||||
"outputId": "7f89b326-9057-4f49-efbe-cb100ebdf76d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)\n",
|
||||
"plt.xlabel('timestamp', fontsize=12)\n",
|
||||
"plt.ylabel('load', fontsize=12)\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "IPuNor4eGwYY"
|
||||
},
|
||||
"source": [
|
||||
"### Create training and testing data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ysvsNyONGt0Q"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"train_start_dt = '2014-11-01 00:00:00'\n",
|
||||
"test_start_dt = '2014-12-30 00:00:00'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 548
|
||||
},
|
||||
"id": "SsfdLoPyGy9w",
|
||||
"outputId": "d6d6c25b-b1f4-47e5-91d1-707e043237d7"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \\\n",
|
||||
" .join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \\\n",
|
||||
" .plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)\n",
|
||||
"plt.xlabel('timestamp', fontsize=12)\n",
|
||||
"plt.ylabel('load', fontsize=12)\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "XbFTqBw6G1Ch"
|
||||
},
|
||||
"source": [
|
||||
"### Preparing data for training"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now, you need to prepare the data for training by performing filtering and scaling of your data."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "cYivRdQpHDj3",
|
||||
"outputId": "a138f746-461c-4fd6-bfa6-0cee094c4aa1"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]\n",
|
||||
"test = energy.copy()[energy.index >= test_start_dt][['load']]\n",
|
||||
"\n",
|
||||
"print('Training data shape: ', train.shape)\n",
|
||||
"print('Test data shape: ', test.shape)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Scale the data to be in the range (0, 1)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 363
|
||||
},
|
||||
"id": "3DNntGQnZX8G",
|
||||
"outputId": "210046bc-7a66-4ccd-d70d-aa4a7309949c"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"scaler = MinMaxScaler()\n",
|
||||
"train['load'] = scaler.fit_transform(train)\n",
|
||||
"train.head(5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 206
|
||||
},
|
||||
"id": "26Yht-rzZexe",
|
||||
"outputId": "20326077-a38a-4e78-cc5b-6fd7af95d301"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"test['load'] = scaler.transform(test)\n",
|
||||
"test.head(5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "x0n6jqxOQ41Z"
|
||||
},
|
||||
"source": [
|
||||
"### Creating data with time-steps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fdmxTZtOQ8xs"
|
||||
},
|
||||
"source": [
|
||||
" For our SVR, we transform the input data to be of the form `[batch, timesteps]`. So, we reshape the existing `train_data` and `test_data` such that there is a new dimension which refers to the timesteps. For our example, we take `timesteps = 5`. So, the inputs to the model are the data for the first 4 timesteps, and the output will be the data for the 5<sup>th</sup> timestep."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "Rpju-Sc2HFm0"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Converting to numpy arrays\n",
|
||||
"\n",
|
||||
"train_data = train.values\n",
|
||||
"test_data = test.values"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Selecting the timesteps\n",
|
||||
"\n",
|
||||
"timesteps=None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "O-JrsrsVJhUQ",
|
||||
"outputId": "c90dbe71-bacc-4ec4-b452-f82fe5aefaef"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Converting data to 2D tensor\n",
|
||||
"\n",
|
||||
"train_data_timesteps=None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "exJD8AI7KE4g",
|
||||
"outputId": "ce90260c-f327-427d-80f2-77307b5a6318"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Converting test data to 2D tensor\n",
|
||||
"\n",
|
||||
"test_data_timesteps=None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "2u0R2sIsLuq5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x_train, y_train = None\n",
|
||||
"x_test, y_test = None\n",
|
||||
"\n",
|
||||
"print(x_train.shape, y_train.shape)\n",
|
||||
"print(x_test.shape, y_test.shape)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8wIPOtAGLZlh"
|
||||
},
|
||||
"source": [
|
||||
"## Creating SVR model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "EhA403BEPEiD"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Create model using RBF kernel\n",
|
||||
"\n",
|
||||
"model = None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "GS0UA3csMbqp",
|
||||
"outputId": "d86b6f05-5742-4c1d-c2db-c40510bd4f0d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Fit model on training data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Rz_x8S3UrlcF"
|
||||
},
|
||||
"source": [
|
||||
"### Make model prediction"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "XR0gnt3MnuYS",
|
||||
"outputId": "157e40ab-9a23-4b66-a885-0d52a24b2364"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Making predictions\n",
|
||||
"\n",
|
||||
"y_train_pred = None\n",
|
||||
"y_test_pred = None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "_2epncg-SGzr"
|
||||
},
|
||||
"source": [
|
||||
"## Analyzing model performance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Scaling the predictions\n",
|
||||
"\n",
|
||||
"y_train_pred = scaler.inverse_transform(y_train_pred)\n",
|
||||
"y_test_pred = scaler.inverse_transform(y_test_pred)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "xmm_YLXhq7gV",
|
||||
"outputId": "18392f64-4029-49ac-c71a-a4e2411152a1"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Scaling the original values\n",
|
||||
"\n",
|
||||
"y_train = scaler.inverse_transform(y_train)\n",
|
||||
"y_test = scaler.inverse_transform(y_test)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "u3LBj93coHEi",
|
||||
"outputId": "d4fd49e8-8c6e-4bb0-8ef9-ca0b26d725b4"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Extract the timesteps for x-axis\n",
|
||||
"\n",
|
||||
"train_timestamps = None\n",
|
||||
"test_timestamps = None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"plt.figure(figsize=(25,6))\n",
|
||||
"# plot original output\n",
|
||||
"# plot predicted output\n",
|
||||
"plt.legend(['Actual','Predicted'])\n",
|
||||
"plt.xlabel('Timestamp')\n",
|
||||
"plt.title(\"Training data prediction\")\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "LnhzcnYtXHCm",
|
||||
"outputId": "f5f0d711-f18b-4788-ad21-d4470ea2c02b"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 225
|
||||
},
|
||||
"id": "53Q02FoqQH4V",
|
||||
"outputId": "53e2d59b-5075-4765-ad9e-aed56c966583"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"plt.figure(figsize=(10,3))\n",
|
||||
"# plot original output\n",
|
||||
"# plot predicted output\n",
|
||||
"plt.legend(['Actual','Predicted'])\n",
|
||||
"plt.xlabel('Timestamp')\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "clOAUH-SXCJG",
|
||||
"outputId": "a3aa85ff-126a-4a4a-cd9e-90b9cc465ef5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "DHlKvVCId5ue"
|
||||
},
|
||||
"source": [
|
||||
"## Full dataset prediction"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "cOFJ45vreO0N",
|
||||
"outputId": "35628e33-ecf9-4966-8036-f7ea86db6f16"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Extracting load values as numpy array\n",
|
||||
"data = None\n",
|
||||
"\n",
|
||||
"# Scaling\n",
|
||||
"data = None\n",
|
||||
"\n",
|
||||
"# Transforming to 2D tensor as per model input requirement\n",
|
||||
"data_timesteps=None\n",
|
||||
"\n",
|
||||
"# Selecting inputs and outputs from data\n",
|
||||
"X, Y = None, None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ESSAdQgwexIi"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Make model predictions\n",
|
||||
"\n",
|
||||
"# Inverse scale and reshape\n",
|
||||
"Y_pred = None\n",
|
||||
"Y = None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 328
|
||||
},
|
||||
"id": "M_qhihN0RVVX",
|
||||
"outputId": "a89cb23e-1d35-437f-9d63-8b8907e12f80"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"plt.figure(figsize=(30,8))\n",
|
||||
"# plot original output\n",
|
||||
"# plot predicted output\n",
|
||||
"plt.legend(['Actual','Predicted'])\n",
|
||||
"plt.xlabel('Timestamp')\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "AcN7pMYXVGTK",
|
||||
"outputId": "7e1c2161-47ce-496c-9d86-7ad9ae0df770"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print('MAPE: ', mape(Y_pred, Y)*100, '%')"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"accelerator": "GPU",
|
||||
"colab": {
|
||||
"collapsed_sections": [],
|
||||
"name": "Recurrent_Neural_Networks.ipynb",
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import os
|
||||
from collections import UserDict
|
||||
|
||||
def load_data(data_dir):
|
||||
"""Load the GEFCom 2014 energy load data"""
|
||||
|
||||
energy = pd.read_csv(os.path.join(data_dir, 'energy.csv'), parse_dates=['timestamp'])
|
||||
|
||||
# Reindex the dataframe such that the dataframe has a record for every time point
|
||||
# between the minimum and maximum timestamp in the time series. This helps to
|
||||
# identify missing time periods in the data (there are none in this dataset).
|
||||
|
||||
energy.index = energy['timestamp']
|
||||
energy = energy.reindex(pd.date_range(min(energy['timestamp']),
|
||||
max(energy['timestamp']),
|
||||
freq='H'))
|
||||
energy = energy.drop('timestamp', axis=1)
|
||||
|
||||
return energy
|
||||
|
||||
|
||||
def mape(predictions, actuals):
|
||||
"""Mean absolute percentage error"""
|
||||
predictions = np.array(predictions)
|
||||
actuals = np.array(actuals)
|
||||
return (np.absolute(predictions - actuals) / actuals).mean()
|
||||
|
||||
|
||||
def create_evaluation_df(predictions, test_inputs, H, scaler):
|
||||
"""Create a data frame for easy evaluation"""
|
||||
eval_df = pd.DataFrame(predictions, columns=['t+'+str(t) for t in range(1, H+1)])
|
||||
eval_df['timestamp'] = test_inputs.dataframe.index
|
||||
eval_df = pd.melt(eval_df, id_vars='timestamp', value_name='prediction', var_name='h')
|
||||
eval_df['actual'] = np.transpose(test_inputs['target']).ravel()
|
||||
eval_df[['prediction', 'actual']] = scaler.inverse_transform(eval_df[['prediction', 'actual']])
|
||||
return eval_df
|
||||
|
||||
|
||||
class TimeSeriesTensor(UserDict):
|
||||
"""A dictionary of tensors for input into the RNN model.
|
||||
|
||||
Use this class to:
|
||||
1. Shift the values of the time series to create a Pandas dataframe containing all the data
|
||||
for a single training example
|
||||
2. Discard any samples with missing values
|
||||
3. Transform this Pandas dataframe into a numpy array of shape
|
||||
(samples, time steps, features) for input into Keras
|
||||
|
||||
The class takes the following parameters:
|
||||
- **dataset**: original time series
|
||||
- **target** name of the target column
|
||||
- **H**: the forecast horizon
|
||||
- **tensor_structures**: a dictionary describing the tensor structure of the form
|
||||
{ 'tensor_name' : (range(max_backward_shift, max_forward_shift), [feature, feature, ...] ) }
|
||||
if features are non-sequential and should not be shifted, use the form
|
||||
{ 'tensor_name' : (None, [feature, feature, ...])}
|
||||
- **freq**: time series frequency (default 'H' - hourly)
|
||||
- **drop_incomplete**: (Boolean) whether to drop incomplete samples (default True)
|
||||
"""
|
||||
|
||||
def __init__(self, dataset, target, H, tensor_structure, freq='H', drop_incomplete=True):
|
||||
self.dataset = dataset
|
||||
self.target = target
|
||||
self.tensor_structure = tensor_structure
|
||||
self.tensor_names = list(tensor_structure.keys())
|
||||
|
||||
self.dataframe = self._shift_data(H, freq, drop_incomplete)
|
||||
self.data = self._df2tensors(self.dataframe)
|
||||
|
||||
def _shift_data(self, H, freq, drop_incomplete):
|
||||
|
||||
# Use the tensor_structures definitions to shift the features in the original dataset.
|
||||
# The result is a Pandas dataframe with multi-index columns in the hierarchy
|
||||
# tensor - the name of the input tensor
|
||||
# feature - the input feature to be shifted
|
||||
# time step - the time step for the RNN in which the data is input. These labels
|
||||
# are centred on time t. the forecast creation time
|
||||
df = self.dataset.copy()
|
||||
|
||||
idx_tuples = []
|
||||
for t in range(1, H+1):
|
||||
df['t+'+str(t)] = df[self.target].shift(t*-1, freq=freq)
|
||||
idx_tuples.append(('target', 'y', 't+'+str(t)))
|
||||
|
||||
for name, structure in self.tensor_structure.items():
|
||||
rng = structure[0]
|
||||
dataset_cols = structure[1]
|
||||
|
||||
for col in dataset_cols:
|
||||
|
||||
# do not shift non-sequential 'static' features
|
||||
if rng is None:
|
||||
df['context_'+col] = df[col]
|
||||
idx_tuples.append((name, col, 'static'))
|
||||
|
||||
else:
|
||||
for t in rng:
|
||||
sign = '+' if t > 0 else ''
|
||||
shift = str(t) if t != 0 else ''
|
||||
period = 't'+sign+shift
|
||||
shifted_col = name+'_'+col+'_'+period
|
||||
df[shifted_col] = df[col].shift(t*-1, freq=freq)
|
||||
idx_tuples.append((name, col, period))
|
||||
|
||||
df = df.drop(self.dataset.columns, axis=1)
|
||||
idx = pd.MultiIndex.from_tuples(idx_tuples, names=['tensor', 'feature', 'time step'])
|
||||
df.columns = idx
|
||||
|
||||
if drop_incomplete:
|
||||
df = df.dropna(how='any')
|
||||
|
||||
return df
|
||||
|
||||
def _df2tensors(self, dataframe):
|
||||
|
||||
# Transform the shifted Pandas dataframe into the multidimensional numpy arrays. These
|
||||
# arrays can be used to input into the keras model and can be accessed by tensor name.
|
||||
# For example, for a TimeSeriesTensor object named "model_inputs" and a tensor named
|
||||
# "target", the input tensor can be acccessed with model_inputs['target']
|
||||
|
||||
inputs = {}
|
||||
y = dataframe['target']
|
||||
y = y.as_matrix()
|
||||
inputs['target'] = y
|
||||
|
||||
for name, structure in self.tensor_structure.items():
|
||||
rng = structure[0]
|
||||
cols = structure[1]
|
||||
tensor = dataframe[name][cols].as_matrix()
|
||||
if rng is None:
|
||||
tensor = tensor.reshape(tensor.shape[0], len(cols))
|
||||
else:
|
||||
tensor = tensor.reshape(tensor.shape[0], len(cols), len(rng))
|
||||
tensor = np.transpose(tensor, axes=[0, 2, 1])
|
||||
inputs[name] = tensor
|
||||
|
||||
return inputs
|
||||
|
||||
def subset_data(self, new_dataframe):
|
||||
|
||||
# Use this function to recreate the input tensors if the shifted dataframe
|
||||
# has been filtered.
|
||||
|
||||
self.dataframe = new_dataframe
|
||||
self.data = self._df2tensors(self.dataframe)
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,13 @@
|
||||
# Posfácio: Aplicações no mundo real do Machine Learning clássico
|
||||
Nesta seção do currículo, você será apresentado a algumas aplicações do ML clássico. Ao vasculhar publicações e artigos sobre essas aplicações na internet, nós buscamos trazer apenas a ML de modo a evitar, ao máximo, usar as estratégias de redes neurais, deep learning e IA. Aprenda sobre como o ML é usado nos sistemas de negócios, nas aplicações ecológicas, nas finanças, na arte, na cultura e muito mais.
|
||||
|
||||

|
||||
|
||||
> Foto de <a href="https://unsplash.com/@childeye?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Alexis Fauvet</a> disponível em <a href="https://unsplash.com/s/photos/artificial-intelligence?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
|
||||
|
||||
## Aula
|
||||
|
||||
1. [Aplicações práticas do ML no mundo real](https://github.com/microsoft/ML-For-Beginners/blob/main/9-Real-World/1-Applications/README.md)
|
||||
## Créditos
|
||||
|
||||
"Real-World Applications" foi escrito por uma equipe de colegas, dentre eles [Jen Looper](https://twitter.com/jenlooper) e [Ornella Altunyan](https://twitter.com/ornelladotcom).
|
Binary file not shown.
Loading…
Reference in new issue