Neste tutorial, você vai conhecer o mundo do machine learning (ML) com Python. Para entender ML na prática, usaremos o algoritmo K-Nearest Neighbor (KNN) em Python.
Você vai implementar KNN no famoso conjunto de dados Iris.
Observação: vale a pena fazer o curso Machine Learning with Python ou, para entender o contexto da evolução do ML e muito mais, ler este post.
Introdução
Machine learning surgiu da ciência da computação e estuda principalmente o design de algoritmos que aprendem com a experiência. Para aprender, eles precisam de dados com certos atributos, a partir dos quais os algoritmos buscam padrões preditivos relevantes. De forma geral, as tarefas de ML podem ser categorizadas em aprendizagem de conceitos, clusterização, modelagem preditiva etc. O objetivo final dos algoritmos de ML é tomar decisões corretas sem intervenção humana. Prever preços de ações ou o clima são alguns exemplos de aplicação.
Existem vários algoritmos de machine learning, como árvores de decisão, Naive Bayes, random forest, support vector machine, K-nearest neighbor, k-means clustering, entre outros.
Do conjunto de algoritmos de ML, o que você vai usar hoje é o k-nearest neighbor.
Agora, o que exatamente é o algoritmo K-Nearest Neighbor? Vamos descobrir!
O que é o k-nearest neighbor?
O KNN, ou k-nearest neighbor, é um algoritmo de aprendizagem supervisionada — “supervisionada” porque ele usa os rótulos de classe dos dados de treinamento durante a fase de aprendizagem. É um algoritmo baseado em instâncias: novos pontos são classificados com base em instâncias rotuladas já armazenadas. KNN pode ser usado tanto para classificação quanto para regressão; porém, é mais comum em tarefas de classificação.
O k no KNN é uma variável crucial, também chamada de hiperparâmetro, que ajuda a classificar um ponto de dados com precisão. Em termos práticos, k é o número de vizinhos mais próximos dos quais você quer “pegar o voto” ao classificar um novo ponto.
Perceba que, à medida que o valor de k aumenta de 1 para 7, a fronteira de decisão entre duas classes se torna mais suave.
Como essa “mágica” acontece? Como todo novo ponto é classificado com base nos pontos armazenados?
Vamos entender rapidamente, passo a passo:
Primeiro, você carrega todos os dados e define o valor de k;
Depois, calcula a distância entre os pontos armazenados e o novo ponto que deseja classificar, usando métricas como distância Manhattan (L1), distância Euclidiana (L2), similaridade do cosseno, distância Bhattacharyya, distância Chebyshev, etc.;
Em seguida, ordena os valores de distância em ordem crescente ou decrescente e determina os k vizinhos mais próximos (maiores ou menores, conforme a métrica);
Coleta os rótulos desses k vizinhos e usa uma votação majoritária ou ponderada para classificar o novo ponto. O rótulo atribuído é o da classe com maior pontuação;
Por fim, retorna a classe prevista para a nova instância.
A previsão pode ser de dois tipos: classificação, na qual é atribuído um rótulo de classe, ou regressão, na qual é atribuído um valor numérico. Diferente da classificação, na regressão costuma-se atribuir ao novo ponto a média dos valores dos k vizinhos.
Desvantagens do KNN: primeiro, a complexidade de buscar os vizinhos mais próximos para cada novo ponto. Segundo, escolher o valor de k pode ser trabalhoso. Por fim, nem sempre é claro qual métrica de distância usar.
Chega de teoria, certo? Vamos carregar, analisar e entender os dados que você vai usar neste tutorial.
Carregando os dados do Iris
O conjunto Iris tem 150 amostras de três classes: Iris-Setosa, Iris-Versicolor e Iris-Virginica. Quatro atributos usados para identificar cada uma das três classes são sepal-length, sepal-width, petal-length e petal-width.
Fique à vontade para usar outro dataset público ou um conjunto de dados próprio.
Sklearn é uma biblioteca de machine learning em Python amplamente usada em tarefas de data science. Ela oferece diversos algoritmos de classificação, regressão e clusterização, incluindo support vector machines, random forests, gradient boosting, k-means, KNN etc. Dentro do sklearn há o módulo datasets com vários conjuntos prontos para uso, incluindo o Iris. É bem intuitivo. Vamos carregar o iris.
Agora você vai combinar dados e rótulos usando a excelente biblioteca NumPy. O NumPy oferece suporte a arrays e matrizes multidimensionais, além de uma coleção extensa de funções matemáticas de alto nível para operar nesses arrays. Vamos importar:
Em seguida, importe a biblioteca de análise de dados pandas, útil para organizar dados em formato tabular e fazer operações e manipulações. Em especial, ela oferece estruturas de dados e operações para trabalhar com tabelas numéricas e séries temporais.
Pronto: o data frame dataset agora tem os dados e os rótulos de classe que você precisa!
Antes de avançar, lembre que a variável labels tem rótulos numéricos. Vamos convertê-los para os nomes das flores (espécies).
Para isso, selecione apenas a coluna class e substitua os três valores numéricos pelas espécies correspondentes. Use inplace=True para modificar o data frame dataset diretamente.
Agora, vamos visualizar os dados carregados acima com um scatterplot para entender quanto uma variável influencia a outra — ou seja, qual é a correlação entre elas.
Você vai usar a biblioteca matplotlib para criar o scatterplot.
Pelo gráfico acima, fica claro que há alta correlação para as flores Iris setosa em relação ao comprimento e à largura da sépala. Por outro lado, há menor correlação entre Iris versicolor e Iris virginica. Os pontos de versicolor e virginica estão mais espalhados, enquanto os de setosa são mais densos.
Vamos também plotar o gráfico para petal-length e petal-width.
Pelas três tabelas, fica claro que a correlação entre petal-length e petal-width é de 0.33 para setosa e 0.32 para virginica, enquanto para versicolor é 0.78.
Agora, vamos visualizar a distribuição das features com histogramas:
petal-length, petal-width e sepal-length mostram distribuição unimodal, enquanto sepal-width se aproxima de uma distribuição Gaussiana. Tudo isso ajuda a escolher um algoritmo que funcione bem com essas distribuições.
Em seguida, vamos analisar se os quatro atributos estão na mesma escala — algo essencial em ML. O data frame do pandas tem a função describe, que retorna count, mean, max, min etc. em formato tabular.
Perceba que os quatro atributos têm escala semelhante entre 0 e 8, em centímetros. Se quiser, você ainda pode reescalá-los para o intervalo entre 0 e 1.
Embora saibamos que há 50 amostras por classe (cerca de 33,3% do total), vamos confirmar:
species
Iris-setosa 50
Iris-versicolor 50
Iris-virginica 50dtype: int64
Tecnologia
Pré-processando seus dados
Depois de carregar e analisar bem os dados, é hora de prepará-los para alimentar seu modelo de ML. Nesta etapa, você vai normalizar os dados e dividir em conjuntos de treino e teste.
Normalizando seus dados
Existem duas formas comuns de normalização:
Normalização por exemplo, em que você normaliza cada amostra individualmente;
Normalização por feature, em que você normaliza cada atributo de forma consistente em todas as amostras.
Por que e quando normalizar? E é necessário padronizar o Iris?
De modo geral, quase sempre é uma boa prática. Normalizar coloca tudo na mesma escala e faixa, o que é crucial quando os dados não são consistentes. Você pode checar inconsistências com describe(), que mostra max e min. Se uma feature tem faixas muito maiores que outra, normalizar ambas é importante.
Imagine X com faixa maior e Y com faixa menor: a influência de Y pode ser ofuscada pela de X. Nesses casos, normalize X e Y.
No Iris, a normalização não é necessária.
Vamos imprimir novamente describe() para ver por que não precisamos normalizar.
O atributo sepal-length varia de 4,3 a 7,9; sepal-width, de 2 a 4,4; petal-length, de 1 a 6,9; e petal-width, de 0,1 a 2,5. Todas as features ficam entre 0,1 e 7,9 — aceitável. Logo, não é necessário normalizar o Iris.
Dividindo os dados
Este é outro ponto importante em ML: seu objetivo é treinar um modelo capaz de tomar decisões ou classificar dados em ambiente de teste sem intervenção humana. Antes de colocar o modelo em produção, garanta que ele generaliza bem nos dados de teste.
Para isso, você precisa de conjunto de treino e de teste. No Iris, com 150 amostras, vamos treinar em 80% e testar nos 20% restantes.
Em data science, você vai ouvir muito sobre overfitting: quando o modelo aprende muito bem os dados de treino, mas vai mal nos de teste. Dividir em treino e teste (ou validação) ajuda a detectar esse problema.
Para fazer o split, use a função train_test_split da biblioteca sklearn. Vamos dividir:
Note que random_state é uma semente. Se você mudar o número, a divisão muda. Mantendo o mesmo random_state, a divisão permanece igual em execuções repetidas.
Vamos imprimir o shape dos conjuntos de treino e teste e seus rótulos.
Agora sim: é hora de alimentar o algoritmo k-nearest neighbor!
O modelo KNN
Depois de carregar, analisar e pré-processar os dados, vamos alimentar o modelo KNN. Para isso, use a função neighbors do sklearn, que tem a classe KNeigborsClassifier.
Comece importando o classificador.
from sklearn.neighbors import KNeighborsClassifier
Tecnologia
Observação: o parâmetro k (n_neighbors) costuma ser ímpar para evitar empates na votação.
Para escolher o melhor k, vamos fazer um grid-search simples: treinar e testar o modelo com 10 valores diferentes de k e ficar com o que tiver melhor desempenho.
Vamos inicializar neighbors(k) com valores de 1 a 9 e duas matrizes de zeros do numpy, train_accuracy e test_accuracy, para armazenar as acurácias de treino e teste. Depois, vamos plotar um gráfico e escolher o melhor neighbor.
No próximo trecho acontece a mágica: vamos enumerate sobre os nove valores de vizinhos e, para cada um, prever em treino e teste. Por fim, armazenar as acurácias em train_accuracy e test_accuracy.
for i,k inenumerate(neighbors):
knn = KNeighborsClassifier(n_neighbors=k)#Fit the model
knn.fit(train_data, train_label)#Compute accuracy on the training set
train_accuracy[i]= knn.score(train_data, train_label)#Compute accuracy on the test set
test_accuracy[i]= knn.score(test_data, test_label)Tecnologia
Agora vamos plotar as acurácias de treino e teste com matplotlib. Com o gráfico de accuracy vs. número de vizinhos, você escolhe o melhor valor de k.
plt.figure(figsize=(10,6))
plt.title('KNN accuracy with varying number of neighbors',fontsize=20)
plt.plot(neighbors, test_accuracy, label='Testing Accuracy')
plt.plot(neighbors, train_accuracy, label='Training accuracy')
plt.legend(prop={'size':20})
plt.xlabel('Number of neighbors',fontsize=20)
plt.ylabel('Accuracy',fontsize=20)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.show()Tecnologia
Olhando o gráfico, parece que com n_neighbors=3 o modelo tem o melhor desempenho. Vamos usar n_neighbors=3 e treinar novamente.
knn = KNeighborsClassifier(n_neighbors=3)#Fit the model
knn.fit(train_data, train_label)#Compute accuracy on the training set
train_accuracy = knn.score(train_data, train_label)#Compute accuracy on the test set
test_accuracy = knn.score(test_data, test_label)Tecnologia
Avaliando seu modelo
No último trecho do tutorial, vamos avaliar o modelo nos dados de teste usando técnicas como confusion_matrix e classification_report.
Primeiro, verifique a acurácia no conjunto de teste.
Uau! Parece que o modelo classificou corretamente 96,66% dos dados de teste. Incrível, né? Com poucas linhas de código, você treinou um modelo que consegue dizer o nome da flor usando apenas quatro atributos, com 96,66% de acerto. Quem sabe ele até supera um humano nessa tarefa.
Matriz de confusão
A matriz de confusão descreve o desempenho do modelo no conjunto de teste, para o qual os rótulos verdadeiros são conhecidos.
O Scikit-learn fornece uma função que calcula a matriz de confusão para você.
Pela confusion_matrix acima, dá para ver que o modelo classificou todas corretamente, exceto uma virginica, que foi prevista como versicolor.
Relatório de classificação
O classification report ajuda a identificar classes mal classificadas com mais detalhes, fornecendo precision, recall e F1 score por classe. Vamos usar o sklearn para visualizar o relatório.
from sklearn.metrics import classification_report
Tecnologia
Parabéns a quem chegou até aqui! Mas isso é só o começo — ainda tem muita estrada pela frente.
Este tutorial tratou dos fundamentos de machine learning e da implementação de um algoritmo, o KNN, em Python. O dataset Iris é pequeno e relativamente simples.
Se este conteúdo despertou seu interesse, experimente outros conjuntos de dados ou estude mais algoritmos de ML e aplique no Iris para observar o impacto na acurácia. Dessa forma, você aprende muito mais do que apenas a teoria!
Se você já praticou bastante com o que foi apresentado aqui e com outros algoritmos de ML, talvez seja hora de se aprofundar em Python e análise de dados.
Você vai implementar KNN no famoso conjunto de dados Iris.
Observação: vale a pena fazer o curso Machine Learning with Python ou, para entender o contexto da evolução do ML e muito mais, ler este post.
Introdução
Machine learning surgiu da ciência da computação e estuda principalmente o design de algoritmos que aprendem com a experiência. Para aprender, eles precisam de dados com certos atributos, a partir dos quais os algoritmos buscam padrões preditivos relevantes. De forma geral, as tarefas de ML podem ser categorizadas em aprendizagem de conceitos, clusterização, modelagem preditiva etc. O objetivo final dos algoritmos de ML é tomar decisões corretas sem intervenção humana. Prever preços de ações ou o clima são alguns exemplos de aplicação.
Existem vários algoritmos de machine learning, como árvores de decisão, Naive Bayes, random forest, support vector machine, K-nearest neighbor, k-means clustering, entre outros.
Do conjunto de algoritmos de ML, o que você vai usar hoje é o k-nearest neighbor.
Agora, o que exatamente é o algoritmo K-Nearest Neighbor? Vamos descobrir!
O que é o k-nearest neighbor?
O KNN, ou k-nearest neighbor, é um algoritmo de aprendizagem supervisionada — “supervisionada” porque ele usa os rótulos de classe dos dados de treinamento durante a fase de aprendizagem. É um algoritmo baseado em instâncias: novos pontos são classificados com base em instâncias rotuladas já armazenadas. KNN pode ser usado tanto para classificação quanto para regressão; porém, é mais comum em tarefas de classificação.
O k no KNN é uma variável crucial, também chamada de hiperparâmetro, que ajuda a classificar um ponto de dados com precisão. Em termos práticos, k é o número de vizinhos mais próximos dos quais você quer “pegar o voto” ao classificar um novo ponto.
Perceba que, à medida que o valor de k aumenta de 1 para 7, a fronteira de decisão entre duas classes se torna mais suave.
Como essa “mágica” acontece? Como todo novo ponto é classificado com base nos pontos armazenados?
Vamos entender rapidamente, passo a passo:
A previsão pode ser de dois tipos: classificação, na qual é atribuído um rótulo de classe, ou regressão, na qual é atribuído um valor numérico. Diferente da classificação, na regressão costuma-se atribuir ao novo ponto a média dos valores dos k vizinhos.
Desvantagens do KNN: primeiro, a complexidade de buscar os vizinhos mais próximos para cada novo ponto. Segundo, escolher o valor de k pode ser trabalhoso. Por fim, nem sempre é claro qual métrica de distância usar.
Chega de teoria, certo? Vamos carregar, analisar e entender os dados que você vai usar neste tutorial.
Carregando os dados do Iris
O conjunto Iris tem 150 amostras de três classes:
Iris-Setosa,Iris-VersicoloreIris-Virginica. Quatro atributos usados para identificar cada uma das três classes sãosepal-length,sepal-width,petal-lengthepetal-width.Fique à vontade para usar outro dataset público ou um conjunto de dados próprio.
Sklearné uma biblioteca de machine learning em Python amplamente usada em tarefas de data science. Ela oferece diversos algoritmos de classificação, regressão e clusterização, incluindosupport vector machines,random forests,gradient boosting,k-means,KNNetc. Dentro dosklearnhá o módulodatasetscom vários conjuntos prontos para uso, incluindo oIris. É bem intuitivo. Vamos carregar oiris.O
load_iristraz os dados e os rótulos de classe de cada amostra. Vamos extrair tudo rapidamente.A variável
dataserá um array numpy de shape (150,4), com 150 amostras e quatro atributos cada. Cada classe tem 50 amostras.Vamos extrair os rótulos de classe.
Agora você vai combinar dados e rótulos usando a excelente biblioteca
NumPy. ONumPyoferece suporte a arrays e matrizes multidimensionais, além de uma coleção extensa de funções matemáticas de alto nível para operar nesses arrays. Vamos importar:Como
dataé um array 2D, você também precisa reshaparlabelspara 2D.Agora use a função
concatenatedonumpy, comaxis=-1, para concatenar pela segunda dimensão.Em seguida, importe a biblioteca de análise de dados
pandas, útil para organizar dados em formato tabular e fazer operações e manipulações. Em especial, ela oferece estruturas de dados e operações para trabalhar com tabelas numéricas e séries temporais.Neste tutorial, você vai usar bastante o
pandas.Pronto: o data frame
datasetagora tem os dados e os rótulos de classe que você precisa!Antes de avançar, lembre que a variável
labelstem rótulos numéricos. Vamos convertê-los para os nomes das flores (espécies).Para isso, selecione apenas a coluna
classe substitua os três valores numéricos pelas espécies correspondentes. Useinplace=Truepara modificar o data framedatasetdiretamente.Vamos imprimir as cinco primeiras linhas de
datasetpara ver o resultado:Analise seus dados
Vamos ver como as três flores ficam quando visualizadas e quão diferentes são entre si — não só em números, mas também na prática!
Agora, vamos visualizar os dados carregados acima com um
scatterplotpara entender quanto uma variável influencia a outra — ou seja, qual é a correlação entre elas.Você vai usar a biblioteca
matplotlibpara criar o scatterplot.Dica: quer aprender diferentes formas de visualizar dados em Python? Então confira o curso Introduction to data visualization with matplotlib.
Pelo gráfico acima, fica claro que há alta correlação para as flores Iris setosa em relação ao comprimento e à largura da sépala. Por outro lado, há menor correlação entre Iris versicolor e Iris virginica. Os pontos de versicolor e virginica estão mais espalhados, enquanto os de setosa são mais densos.
Vamos também plotar o gráfico para
petal-lengthepetal-width.Também para
petal-lengthepetal-width, o gráfico indica uma forte correlação para as flores setosa, que ficam densamente agrupadas.Para reforçar como
petal-lengthepetal-widthse correlacionam, vamos plotar uma matriz de correlação.A tabela acima mostra uma forte correlação de
0.96entrepetal-lengthepetal-widthquando combinamos as três espécies.Vamos analisar a correlação separadamente por espécie.
Pelas três tabelas, fica claro que a correlação entre
petal-lengthepetal-widthé de0.33parasetosae0.32paravirginica, enquanto paraversicoloré0.78.Agora, vamos visualizar a distribuição das features com histogramas:
petal-length,petal-widthesepal-lengthmostram distribuição unimodal, enquantosepal-widthse aproxima de uma distribuição Gaussiana. Tudo isso ajuda a escolher um algoritmo que funcione bem com essas distribuições.Em seguida, vamos analisar se os quatro atributos estão na mesma escala — algo essencial em ML. O data frame do
pandastem a funçãodescribe, que retornacount,mean,max,minetc. em formato tabular.Perceba que os quatro atributos têm escala semelhante entre 0 e 8, em centímetros. Se quiser, você ainda pode reescalá-los para o intervalo entre 0 e 1.
Embora saibamos que há 50 amostras por classe (cerca de 33,3% do total), vamos confirmar:
Pré-processando seus dados
Depois de carregar e analisar bem os dados, é hora de prepará-los para alimentar seu modelo de ML. Nesta etapa, você vai normalizar os dados e dividir em conjuntos de treino e teste.
Normalizando seus dados
Existem duas formas comuns de normalização:
Por que e quando normalizar? E é necessário padronizar o
Iris?De modo geral, quase sempre é uma boa prática. Normalizar coloca tudo na mesma escala e faixa, o que é crucial quando os dados não são consistentes. Você pode checar inconsistências com
describe(), que mostramaxemin. Se uma feature tem faixas muito maiores que outra, normalizar ambas é importante.Imagine X com faixa maior e Y com faixa menor: a influência de Y pode ser ofuscada pela de X. Nesses casos, normalize X e Y.
No
Iris, a normalização não é necessária.Vamos imprimir novamente
describe()para ver por que não precisamos normalizar.O atributo
sepal-lengthvaria de 4,3 a 7,9;sepal-width, de 2 a 4,4;petal-length, de 1 a 6,9; epetal-width, de 0,1 a 2,5. Todas as features ficam entre 0,1 e 7,9 — aceitável. Logo, não é necessário normalizar oIris.Dividindo os dados
Este é outro ponto importante em ML: seu objetivo é treinar um modelo capaz de tomar decisões ou classificar dados em ambiente de teste sem intervenção humana. Antes de colocar o modelo em produção, garanta que ele generaliza bem nos dados de teste.
Para isso, você precisa de conjunto de treino e de teste. No
Iris, com 150 amostras, vamos treinar em 80% e testar nos 20% restantes.Em data science, você vai ouvir muito sobre
overfitting: quando o modelo aprende muito bem os dados de treino, mas vai mal nos de teste. Dividir em treino e teste (ou validação) ajuda a detectar esse problema.Para fazer o split, use a função
train_test_splitda bibliotecasklearn. Vamos dividir:Note que
random_stateé uma semente. Se você mudar o número, a divisão muda. Mantendo o mesmorandom_state, a divisão permanece igual em execuções repetidas.Vamos imprimir o shape dos conjuntos de treino e teste e seus rótulos.
Agora sim: é hora de alimentar o algoritmo k-nearest neighbor!
O modelo KNN
Depois de carregar, analisar e pré-processar os dados, vamos alimentar o modelo KNN. Para isso, use a função
neighborsdosklearn, que tem a classeKNeigborsClassifier.Comece importando o classificador.
Observação: o parâmetro k (n_neighbors) costuma ser ímpar para evitar empates na votação.
Para escolher o melhor k, vamos fazer um
grid-searchsimples: treinar e testar o modelo com 10 valores diferentes de k e ficar com o que tiver melhor desempenho.Vamos inicializar
neighbors(k)com valores de 1 a 9 e duas matrizes de zeros do numpy,train_accuracyetest_accuracy, para armazenar as acurácias de treino e teste. Depois, vamos plotar um gráfico e escolher o melhorneighbor.No próximo trecho acontece a mágica: vamos
enumeratesobre os nove valores de vizinhos e, para cada um, prever em treino e teste. Por fim, armazenar as acurácias emtrain_accuracyetest_accuracy.Agora vamos plotar as acurácias de treino e teste com
matplotlib. Com o gráfico deaccuracy vs. número de vizinhos, você escolhe o melhor valor de k.Olhando o gráfico, parece que com
n_neighbors=3o modelo tem o melhor desempenho. Vamos usarn_neighbors=3e treinar novamente.Avaliando seu modelo
No último trecho do tutorial, vamos avaliar o modelo nos dados de teste usando técnicas como
confusion_matrixeclassification_report.Primeiro, verifique a acurácia no conjunto de teste.
Uau! Parece que o modelo classificou corretamente 96,66% dos dados de teste. Incrível, né? Com poucas linhas de código, você treinou um modelo que consegue dizer o nome da flor usando apenas quatro atributos, com 96,66% de acerto. Quem sabe ele até supera um humano nessa tarefa.
Matriz de confusão
A matriz de confusão descreve o desempenho do modelo no conjunto de teste, para o qual os rótulos verdadeiros são conhecidos.
O
Scikit-learnfornece uma função que calcula a matriz de confusão para você.A função
plot_confusion_matrix()abaixo foi adaptada desta fonte.Pela
confusion_matrixacima, dá para ver que o modelo classificou todas corretamente, exceto uma virginica, que foi prevista como versicolor.Relatório de classificação
O classification report ajuda a identificar classes mal classificadas com mais detalhes, fornecendo
precision,recalleF1 scorepor classe. Vamos usar osklearnpara visualizar o relatório.Vá além!
Parabéns a quem chegou até aqui! Mas isso é só o começo — ainda tem muita estrada pela frente.
Este tutorial tratou dos fundamentos de machine learning e da implementação de um algoritmo, o KNN, em Python. O dataset Iris é pequeno e relativamente simples.
Se este conteúdo despertou seu interesse, experimente outros conjuntos de dados ou estude mais algoritmos de ML e aplique no Iris para observar o impacto na acurácia. Dessa forma, você aprende muito mais do que apenas a teoria!
Se você já praticou bastante com o que foi apresentado aqui e com outros algoritmos de ML, talvez seja hora de se aprofundar em Python e análise de dados.