Algoritmos de Machine Learning com Python
O Machine Learning, também conhecido como aprendizado de máquina, é um subcampo da inteligência artificial que emprega algoritmos estatísticos para fazer com que os computadores aprendam a partir dos dados e, então, façam previsões ou tomem decisões. Python se tornou uma das linguagens mais populares para o Machine Learning devido à sua simplicidade e à extensa coleção de bibliotecas, como NumPy, pandas e scikit-learn, que tornam a implementação de algoritmos de Machine Learning relativamente direta.
O que é Regressão?
A regressão é uma técnica que tenta prever um valor contínuo (por exemplo, o preço de uma casa) com base em um ou mais valores de entrada (por exemplo, o tamanho da casa, a localização, o número de quartos, etc.). Em outras palavras, ela tenta estabelecer uma relação entre variáveis independentes (entrada) e uma variável dependente (saída).
Regressão Linear: Conceitos fundamentais
A regressão linear é uma das técnicas mais básicas e comumente usadas em Machine Learning e estatística. Na regressão linear, assumimos que a saída depende linearmente das variáveis de entrada.
Podemos expressar essa relação na forma:
1 |
y = a0 + a1x1 + a2x2 + a3x3 + … + anxn |
Aqui, y é a variável alvo e x1, x2, …, xn são as variáveis preditoras ou características. A regressão linear envolvendo apenas uma característica é conhecida como regressão linear simples, enquanto a que envolve múltiplas características é conhecida como regressão linear múltipla. Os parâmetros a0, a1, a2, …, an (também conhecidos como coeficientes ou pesos) do modelo são o que queremos determinar com o algoritmo de regressão linear.
Imagine que você está jogando dardos e tem como alvo um conjunto de números que seguem uma linha reta. Cada vez que joga um dardo, ele se aproxima mais ou menos dessa linha reta. A Regressão Linear é como esse jogo de dardos – só que, em vez de jogar dardos, ela tenta encontrar uma linha que se encaixe da melhor maneira possível em um conjunto de pontos.
Para entendermos melhor, vamos trabalhar com um exemplo simples. Vamos supor que temos os seguintes dados de entrada (peso em kg) e saída (altura em cm):
1 2 |
Peso: [50, 60, 70, 80, 90] Altura: [152, 167, 170, 175, 192] |
O que queremos é encontrar uma relação entre esses dois conjuntos de dados. Nosso objetivo é descobrir como o peso de uma pessoa pode influenciar na sua altura. Esse é o principal objetivo da Regressão Linear – encontrar uma relação entre os dados que temos e os que queremos prever.
A Regressão Linear faz isso através de uma equação matemática. No nosso caso, a equação seria assim:
1 |
Altura = a0 + a1*Peso + 𝜖 |
Na equação, “a0” e “a1” são os chamados coeficientes. Eles são os números que queremos descobrir para que a nossa equação possa prever a altura de uma pessoa baseada apenas no seu peso.
Substituindo o peso e a altura de cada pessoa em nossa equação de regressão linear, teríamos as seguintes cinco equações (uma para cada observação):
1 |
152 = a0 + a150 + 𝜖1 167 = a0 + a160 + 𝜖2 170 = a0 + a170 + 𝜖3 175 = a0 + a180 + 𝜖4 192 = a0 + a1*90 + 𝜖5 |
As incógnitas em nosso sistema de equações são os coeficientes a0 (o intercepto) e a1 (a inclinação). O objetivo do algoritmo de regressão linear é encontrar os valores de a0 e a1 que minimizam a soma dos quadrados dos erros (𝜖). Este é um problema de otimização que pode ser resolvido com várias técnicas, incluindo gradientes descendentes e equações normais.
Mas como encontrar os valores de “a0” e “a1” que fazem a nossa equação funcionar da melhor maneira possível?
É aqui que entra o chamado “Erro Quadrático Médio” (MSE, do inglês “Mean Squared Error”). O MSE é uma maneira de calcular o quão errada está a nossa equação. Ele faz isso comparando os valores que nossa equação prevê com os valores reais que temos (no nosso caso, as alturas das pessoas). Quanto menor for o MSE, melhor é a nossa equação.
Então, o que a Regressão Linear faz é testar muitos valores diferentes para “a0” e “a1” e escolher os que fazem o MSE ser o menor possível. Em outras palavras, ela escolhe os valores que fazem a nossa equação prever as alturas das pessoas da maneira mais precisa possível.
Essas técnicas incluem resolver uma equação matricial conhecida como equação normal ou usar uma técnica chamada gradiente descendente para testar diferentes conjuntos de parâmetros iterativamente. Felizmente, não precisamos realizar esses cálculos nós mesmos; podemos usar a classe LinearRegression do sklearn para isso.
Regressão Linear com Scikit-Learn
Para implementar a regressão linear em Python, uma das bibliotecas mais populares é o scikit-learn. Além disso, usaremos outras bibliotecas auxiliares como a matplotlib, para manipulação de dados e visualização.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
from sklearn.datasets import load_diabetes from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt # Carregando o conjunto de dados diabetes diabetes = load_diabetes() # Separando as variáveis independentes (X) e a variável alvo (y) X = diabetes.data[:, 2] # Usando apenas uma característica para fins de visualização y = diabetes.target # Dividindo os dados em conjuntos de treinamento e teste X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # Criando o modelo de regressão linear model = LinearRegression() # Treinando o modelo com os dados de treinamento model.fit(X_train.reshape(-1, 1), y_train) # Fazendo previsões com os dados de teste y_pred = model.predict(X_test.reshape(-1, 1)) # Plotando o gráfico de dispersão dos dados de teste plt.scatter(X_test, y_test, color='blue', label='Dados de Teste') # Plotando a linha de regressão plt.plot(X_test, y_pred, color='red', linewidth=2, label='Linha de Regressão') # Adicionando rótulos e título ao gráfico plt.xlabel('Característica') plt.ylabel('Progressão da Doença') plt.title('Regressão Linear - Diabetes') plt.legend() # Exibindo o gráfico plt.show() |
Explicação do código:
- Importamos as bibliotecas necessárias, incluindo
matplotlib.pyplot
para criar o gráfico. - Carregamos o conjunto de dados “diabetes” usando a função
load_diabetes()
. - Separamos apenas uma característica (feature) para a variável independente (X) usando
diabetes.data[:, 2]
. Isso é feito apenas para fins de visualização, já que é mais fácil plotar um gráfico bidimensional. A variável alvo (y) permanece a mesma. - Dividimos os dados em conjuntos de treinamento e teste usando a função
train_test_split()
. - Criamos uma instância do modelo de regressão linear usando a classe
LinearRegression()
. - Treinamos o modelo com os dados de treinamento usando o método
fit()
. Como estamos usando apenas uma característica, precisamos reformatar os dados usandoX_train.reshape(-1, 1)
para que tenham a forma adequada. - Fazemos previsões com os dados de teste usando o método
predict()
, também reformatando os dados comX_test.reshape(-1, 1)
. - Plotamos o gráfico de dispersão dos dados de teste usando a função
plt.scatter()
, especificando as coordenadas X e y, a cor dos pontos e o rótulo da legenda. - Plotamos a linha de regressão usando a função
plt.plot()
, especificando as coordenadas X e y (previsões), a cor da linha, a espessura da linha e o rótulo da legenda. - Adicionamos rótulos aos eixos X e Y usando
plt.xlabel()
eplt.ylabel()
, respectivamente, e um título ao gráfico usandoplt.title()
. - Adicionamos uma legenda ao gráfico usando
plt.legend()
. - Por fim, exibimos o gráfico usando
plt.show()
.
O gráfico resultante mostrará os pontos de dados de teste como pontos azuis e a linha de regressão como uma linha vermelha. A linha de regressão representa a relação linear entre a característica selecionada e a progressão da doença, conforme aprendido pelo modelo de regressão linear.
A interpretação do gráfico é que a linha de regressão tenta capturar a tendência geral dos dados, mostrando como a progressão da doença varia em relação à característica selecionada. Quanto mais próximos os pontos estiverem da linha de regressão, melhor o modelo se ajusta aos dados.
Regressão Polinomial: Conceitos Fundamentais
Embora a regressão linear seja eficiente para muitos casos, às vezes a relação entre as variáveis de entrada e saída não é linear. Nesses casos, a regressão polinomial pode ser uma melhor opção. A regressão polinomial tenta encontrar a melhor curva, e não uma linha reta, que se ajusta aos dados.
Regressão Polinomial: Conceitos Fundamentais
A regressão polinomial é uma extensão da regressão linear que pode ajudar quando a relação entre as variáveis de entrada e saída não é linear. Em vez de ajustar uma linha reta, como na regressão linear, a regressão polinomial tenta encontrar a melhor curva que se ajusta aos dados.
Vamos usar um exemplo para ilustrar esse conceito de forma simples e prática. Imaginemos que estamos tentando prever a velocidade de um carro com base no tempo desde que ele foi ligado. Aqui estão os dados:
Tempo (em minutos): [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Velocidade (em km/h): [10, 20, 30, 40, 50, 60, 65, 70, 70, 70]
Se plotarmos esses pontos em um gráfico, veremos que a relação não é linear. Nos primeiros minutos, a velocidade do carro aumenta rapidamente. Mas depois de algum tempo, a velocidade começa a se estabilizar. Isso não é surpreendente – afinal, devido às limitações físicas, um carro não pode aumentar sua velocidade indefinidamente.
Aqui, uma linha reta (como a usada na regressão linear) não seria a melhor maneira de representar essa relação. Em vez disso, uma curva seria mais adequada – é aí que a regressão polinomial se torna útil.
Na regressão polinomial, a equação não é uma linha reta, mas uma curva. A equação se parece com isto:
Velocidade = a0 + a1Tempo + a2Tempo^2 + … + an*Tempo^n + 𝜖
Aqui, “a0” é o termo constante, “a1” é o coeficiente do tempo, “a2” é o coeficiente do tempo ao quadrado, e assim por diante, até “an”, que é o coeficiente do tempo elevado à potência “n”. O termo “𝜖” é o erro, que é a diferença entre o valor real da velocidade e o valor previsto pela nossa equação.
Assim como na regressão linear, o objetivo do algoritmo de regressão polinomial é encontrar os valores de “a0”, “a1”, “a2”, …, “an” que fazem a nossa equação prever as velocidades de forma mais precisa possível.
Podemos usar o exemplo de dados fornecido para criar um modelo de regressão polinomial com o scikit-learn. Eis um código em Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# Importando as bibliotecas necessárias from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression import numpy as np import matplotlib.pyplot as plt # Nosso conjunto de dados Tempo = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).reshape(-1, 1) Velocidade = np.array([10, 20, 30, 40, 50, 60, 65, 70, 70, 70]) # Transformando os dados para um formato polinomial poly = PolynomialFeatures(degree = 2) # Vamos considerar um polinômio de grau 2 Tempo_poly = poly.fit_transform(Tempo) # Criando o modelo de regressão polinomial model = LinearRegression() # Treinando o modelo model.fit(Tempo_poly, Velocidade) # Agora vamos criar um gráfico plt.scatter(Tempo, Velocidade, color = 'blue') # Pontos originais plt.plot(Tempo, model.predict(Tempo_poly), color = 'red') # Linha da regressão plt.title('Regressão Polinomial') plt.xlabel('Tempo') plt.ylabel('Velocidade') plt.show() |
Este script primeiro importa as bibliotecas necessárias e define os dados. Em seguida, ele transforma os dados para um formato polinomial usando a classe PolynomialFeatures do scikit-learn. Depois, ele cria e treina um modelo de regressão linear com os dados polinomiais. Finalmente, o modelo é usado para prever a velocidade em um novo ponto no tempo.
Por favor, note que esse é um exemplo simplificado. Em um cenário real, você precisaria dividir seus dados em conjuntos de treinamento e teste, ajustar os hiperparâmetros do modelo, avaliar o desempenho do modelo, etc.
Embora a regressão polinomial possa parecer complicada, não precisamos nos preocupar em fazer todos esses cálculos à mão. Assim como na regressão linear, também podemos usar a biblioteca scikit-learn do Python para fazer regressão polinomial com apenas algumas linhas de código.
Regressão Polinomial com Scikit-Learn
Com o scikit-learn, é fácil implementar a regressão polinomial. No exemplo abaixo vamos usar o mesmo conjunto de dados de diabetes para ilustrar a aplicação da Regressão Polinomial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# Importando as bibliotecas necessárias from sklearn import datasets from sklearn.preprocessing import PolynomialFeatures from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error import matplotlib.pyplot as plt import numpy as np # Carregando o conjunto de dados de diabetes diabetes = datasets.load_diabetes() # Vamos usar apenas uma característica para simplificar X = diabetes.data[:, np.newaxis, 2] y = diabetes.target # Dividindo os dados em conjunto de treinamento e teste X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # Transformando os dados para um formato polinomial poly = PolynomialFeatures(degree=2) X_train_poly = poly.fit_transform(X_train) X_test_poly = poly.transform(X_test) # Criando o modelo de regressão polinomial model = LinearRegression() # Treinando o modelo model.fit(X_train_poly, y_train) # Fazendo previsões y_pred = model.predict(X_test_poly) # Calculando o erro quadrático médio mse = mean_squared_error(y_test, y_pred) print('Erro Quadrático Médio: ', mse) # Agora vamos criar um gráfico plt.scatter(X_test, y_test, color='blue') # Pontos de teste plt.scatter(X_test, y_pred, color='red') # Pontos previstos plt.title('Regressão Polinomial com Scikit-Learn') plt.xlabel('Medição de índice de massa corporal') plt.ylabel('Progressão da doença') plt.show() |
Pipeline em Machine Learning
Em um projeto de Machine Learning, muitas vezes precisamos executar várias etapas de processamento de dados em uma ordem específica. O conceito de um pipeline em Machine Learning é uma maneira de automatizar esse fluxo de trabalho, facilitando a experimentação e a manutenção do código.
Aqui está um exemplo de como você pode criar um pipeline para um projeto de regressão:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
from sklearn.datasets import load_diabetes from sklearn.model_selection import train_test_split from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler, PolynomialFeatures from sklearn.linear_model import LinearRegression # Carregando os dados de diabetes diabetes = load_diabetes() # Separando as variáveis independentes (X) e a variável dependente (y) X = diabetes.data y = diabetes.target # Dividindo os dados em conjuntos de treinamento e teste X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # Criando o pipeline pipeline = Pipeline([ ("scaler", StandardScaler()), ("poly_features", PolynomialFeatures(degree=2)), ("regressor", LinearRegression()) ]) # Treinando o pipeline com os dados de treinamento pipeline.fit(X_train, y_train) # Fazendo previsões com os dados de teste predictions = pipeline.predict(X_test) |
Neste exemplo, o pipeline consiste em três etapas:
StandardScaler
: Esta etapa padroniza os dados, subtraindo a média e dividindo pelo desvio padrão de cada característica. Isso é importante para garantir que todas as características tenham a mesma escala e evitar que características com valores maiores dominem o modelo.PolynomialFeatures
: Esta etapa aplica uma transformação polinomial nos dados, criando novas características com combinações polinomiais das características originais. Neste exemplo, estamos usando um grau polinomial de 2, o que significa que serão criadas características quadráticas.LinearRegression
: Esta é a etapa final, onde um modelo de regressão linear é treinado usando os dados transformados.
Depois de criar o pipeline, usamos o método fit()
para treinar o pipeline com os dados de treinamento (X_train
e y_train
). Isso executa todas as etapas do pipeline em sequência, passando os dados de uma etapa para a próxima.
Por fim, usamos o método predict()
para fazer previsões com os dados de teste (X_test
). O pipeline aplica automaticamente as mesmas transformações nos dados de teste antes de fazer as previsões.
O uso de um pipeline torna o código mais organizado e modular, permitindo que você experimente facilmente diferentes combinações de etapas de pré-processamento e modelos. Além disso, o pipeline garante que as mesmas transformações sejam aplicadas consistentemente aos dados de treinamento e teste, evitando vazamento de informações e garantindo a integridade do processo de avaliação do modelo.
O uso de um pipeline torna o código mais organizado e modular, permitindo que você experimente facilmente diferentes combinações de etapas de pré-processamento e modelos. Além disso, o pipeline garante que as mesmas transformações sejam aplicadas consistentemente aos dados de treinamento e teste, evitando vazamento de informações e garantindo a integridade do processo de avaliação do modelo.
Validação Cruzada com Pipelines e Scikit-Learn Python
A validação cruzada é uma técnica essencial em aprendizado de máquina que nos permite avaliar o desempenho de um modelo de forma mais robusta e confiável. Ela envolve dividir o conjunto de dados em subconjuntos menores, treinar e testar o modelo em cada subconjunto e, em seguida, combinar os resultados para obter uma estimativa mais precisa do desempenho do modelo.
Considere o seguinte exemplo em Python, onde usamos a biblioteca scikit-learn para realizar a validação cruzada em um modelo de regressão polinomial:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
from sklearn import datasets from sklearn.preprocessing import PolynomialFeatures from sklearn.model_selection import train_test_split, cross_val_score from sklearn.linear_model import LinearRegression from sklearn.pipeline import make_pipeline import numpy as np # Carregando o conjunto de dados de diabetes diabetes = datasets.load_diabetes() # Vamos usar apenas uma característica para simplificar X = diabetes.data[:, np.newaxis, 2] y = diabetes.target # Dividindo os dados em conjunto de treinamento e teste X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # Criando o pipeline para a regressão polinomial model = make_pipeline(PolynomialFeatures(degree=2), LinearRegression()) # Treinando o modelo com validação cruzada scores = cross_val_score(model, X_train, y_train, cv=5) print("Scores da validação cruzada: ", scores) |
Neste exemplo, estamos usando o conjunto de dados de diabetes disponível no scikit-learn. Primeiro, dividimos os dados em conjuntos de treinamento e teste usando a função train_test_split()
. Em seguida, criamos um pipeline que combina a transformação polinomial (PolynomialFeatures
) e o modelo de regressão linear (LinearRegression
).
A parte mais importante deste exemplo é o uso da função cross_val_score()
para realizar a validação cruzada. Passamos o modelo (pipeline), os dados de treinamento (X_train
e y_train
) e o parâmetro cv=5
, que especifica o número de subconjuntos (folds) a serem usados na validação cruzada. Neste caso, estamos usando a validação cruzada k-fold com k=5.
A função cross_val_score()
divide internamente os dados de treinamento em 5 subconjuntos, treina o modelo em 4 subconjuntos e o testa no subconjunto restante. Esse processo é repetido 5 vezes, de modo que cada subconjunto seja usado uma vez como conjunto de teste. No final, obtemos uma lista de 5 scores, representando o desempenho do modelo em cada iteração da validação cruzada.
Ao executar o código fonte acima, você obterá o seguinte resultado:
Scores da validação cruzada: [0.34951055 0.20118732 0.37641365 0.48463914 0.18011347]
Os números impressos são os escores R² para cada uma das 5 divisões (folds) da validação cruzada. A métrica R² (também conhecida como coeficiente de determinação) é uma medida de quão bem as previsões do nosso modelo de regressão se ajustam aos dados reais. O R² varia de 0 a 1, onde 1 significa que nosso modelo explica completamente a variância dos dados alvo.
Analisando os escores, parece que o desempenho do modelo varia um pouco dependendo do subconjunto de dados usado para treinamento. A variação nos escores vai de aproximadamente 0.18 a 0.48. Isso é um indicativo de que nosso modelo está sofrendo de algum grau de variância, pois seu desempenho muda dependendo do subconjunto específico de dados usado para treiná-lo. Pode ser útil experimentar ajustar os hiperparâmetros do modelo, utilizar mais recursos dos dados, ou tentar uma técnica diferente de pré-processamento dos dados para melhorar o desempenho do modelo.
É importante notar que, embora esses escores sejam úteis para avaliar a capacidade de nosso modelo de generalizar para novos dados, eles não nos fornecem a imagem completa. Para uma análise mais completa, você poderia considerar a visualização das previsões reais vs esperadas, ou a verificação de outras métricas de desempenho, como erro médio absoluto ou erro médio quadrático.
A validação cruzada é importante porque nos fornece uma estimativa mais confiável do desempenho do modelo em dados não vistos. Ao treinar e testar o modelo em diferentes subconjuntos dos dados, podemos avaliar sua capacidade de generalização e identificar possíveis problemas de overfitting (quando o modelo se ajusta bem demais aos dados de treinamento, mas tem desempenho ruim em novos dados).
Além disso, a validação cruzada nos permite comparar diferentes modelos ou configurações de hiperparâmetros de maneira justa. Podemos executar a validação cruzada para cada modelo ou configuração e selecionar aquele que apresenta o melhor desempenho médio nos diferentes subconjuntos.
Em resumo, a validação cruzada é uma técnica poderosa para avaliar e comparar modelos de aprendizado de máquina. Ela nos fornece uma estimativa mais robusta do desempenho do modelo, ajuda a identificar problemas de overfitting e permite uma comparação justa entre diferentes modelos. Ao utilizar a validação cruzada, podemos ter mais confiança na capacidade do modelo de generalizar para dados não vistos e tomar decisões mais informadas sobre qual modelo usar em um determinado problema.
Espero que este tutorial tenha sido útil para entender os conceitos e práticas de regressão em Machine Learning utilizando Python. Lembre-se, a chave para se tornar proficiente em Machine Learning é a prática. Então, não se esqueça de experimentar o que você aprendeu aqui em seus próprios projetos!