# Principais métricas de avaliação de modelos em Machine Learning - Medium **Título Original:** **Principais métricas de avaliação de modelos em Machine Learning** **Fonte**: Medium **Data de Publicação:** 29.07.2023 **URL:** https://medium.com/data-hackers/principais-m%C3%A9tricas-de-classifica%C3%A7%C3%A3o-de-modelos-em-machine-learning-94eeb4b40ea9 **Autor:** Edson Junior # Resumo gerado por AI Este artigo aborda as principais métricas de avaliação de modelos de Machine Learning, incluindo matriz de confusão, acurácia, precisão, revocação, medida F1, curva ROC e curva precisão-revocação. O objetivo é auxiliar na escolha do modelo mais adequado para um problema específico, considerando o balanceamento dos dados e a importância de falsos positivos e falsos negativos. - Introdução ao problema de classificação binária com dados de pacientes fictícios. - Apresentação da matriz de confusão como ferramenta para avaliar o desempenho do modelo. - Definição e cálculo da acurácia, com ressalvas sobre seu uso em bases de dados desbalanceadas. - Explicação da precisão e sua importância em evitar falsos positivos. - Definição da revocação e sua importância em evitar falsos negativos. - Apresentação da medida F1 como média harmônica entre precisão e revocação. - Introdução à curva ROC e à área sob a curva (AUC) como métricas de avaliação. - Explicação do conceito de limiar de classificação (threshold) e seu impacto nas métricas. - Apresentação da curva precisão-revocação como alternativa à curva ROC em bases desbalanceadas. - Referências para aprofundamento nos temas abordados. # Artigo Original ## Escolhendo as métricas certas para medir o sucesso do seu modelo de Machine Learning ## Sumário **→ Introdução → Matriz de Confusão → Acurácia → Precisão → Revocação → Medida-F1 → Curva ROC → Curva Precisão-Revocação → Referências** ## Introdução Imagine que você possui em mãos alguns dados fictícios de pacientes de uma clínica de saúde, como pressão sanguínea, concentração de glicose, idade e IMC. Além destas variáveis há também uma variável “Target” indicando se o paciente possui ou não diabetes. ![[1*KRlQr8YqPphsJjuxckq1gQ.png]] Fonte: Próprio autor Você decide utilizar alguns modelos de Machine Learning para, com base nos dados dos pacientes, prever quem possui a doença. Mas entre todos os modelos disponíveis, como *Support Vector Machine* (SVM), *Random Forest* (RF), Árvore de Decisão, Regressão Logística, etc), como decidir qual deles funciona melhor para os dados que possui? Para isso, existem algumas métricas para que podem ajudar em uma decisão mais técnica. ## Matriz de Confusão Para medir o desempenho de um modelo e extrair mais informações sobre o quão boa foi a sua performance, é possível a utilização de um recurso chamado **matriz de confusão** (ou *confusion matrix*, do inglês). Trata-se de uma tabela de duas linhas e duas colunas (caso o problema de classificação seja binário), na qual as linhas representam as classes previstas, enquanto que as colunas representam as classes reais e os valores das células são as frequências de ocorrência das combinações previsto-real. Pode ser representada da seguinte maneira: ![[1*gCVmLjgWWpcnOg5NkShxSA.png]] Fonte: Próprio autor Para o caso deste problema, em que tem-se a classe dos diabéticos e dos não diabéticos, a matriz de confusão pode ser adaptada para: ![[1*cWj8vsLpfP2j0p17QMEb_A.png]] Fonte: Próprio autor Neste caso, os significados das células são: Verdadeiro Positivo (**VP**): São os pacientes que o modelo classificou como diabéticos e que realmente são diabéticos; Falso Positivo (**FP**): São os pacientes que o modelo classificou como diabéticos e que na verdade não são diabéticos; Falso Negativo (**FN**): São os pacientes que o modelo classificou como não diabéticos e que na verdade são diabéticos;e Verdadeiro Negativo (**VN**): São os pacientes que o modelo classificou como não diabéticos e que realmente não são diabéticos. Beleza!! Supondo que você já fez a divisão em treino/teste e já treinou os seus algoritmos. Como obter a matriz de confusão em Python? ``` from sklearn.metrics import confusion_matriximport seaborn as snsmatriz_conf = confusion_matrix(y_real, y_pred)sns.heatmap(matriz_conf, annot=True, fmt='d', cmap='Blues')plt.title('Matriz de Confusão')plt.xlabel('Valor Predito')plt.ylabel('Valor Real') ``` Supondo que utilizando o modelo SVM você obteve a seguinte matriz de confusão: ![[1*-9Satr0Nm8l_BWdk5_E6_Q.png]] Fonte: Próprio autor Pode-se interpretar da seguinte maneira: - Houve 243 pacientes com diabetes que o SVM **acertou** em classificar como portadores da doença. São os **VP**; - Houve 465 pacientes sem a doença que o SVM **acertou** em classificar como não portadores da doença. São os **VN**; - Porém o modelo errou em 25 casos, dizendo que estes pacientes não possuem a doença, quando na verdade eles possuem. São os **FN**; e - Errou em outros 34 casos, dizendo que os pacientes possuem a doença, quando na verdade eles não possuem. São os **FP**. Não satisfeito, você decidiu aplicar também o modelo RF. Assim, obteve a seguinte matriz de confusão: ![[1*uVY4Z5cMTg3KXxYlRpE2lg.png]] Fonte: Próprio autor De forma similar, pode-se fazer a mesma interpretação que foi feita para a matriz do algoritmo SVM. Sendo assim, é possível observar que: - o SVM acertou mais ao classificar pacientes como **diabéticos (VP)**, com 243 acertos, contra 213 do RF. Consequentemente também errou menos ao ter 34 classificações (contra 64 do RF) como diabéticos, que na verdade **não eram diabéticos (FP)**. - o SVM acertou mais ao classificar pacientes como **NÃO diabéticos (VN)**, com 465 acertos, contra 435 do RF. Consequentemente também errou menos ao ter 25 classificações (contra 55 do RF) como não diabéticos, que na verdade eram **diabéticos (FN)**. Com estas informações é possível ter uma ideia da performance dos dois modelos. Mas na maioria das vezes somente comparando os parâmetros VP, VN, FP e FN para os diferentes algoritmos não será suficiente. Pensando nisso, são utilizadas outras métricas de classificação para ajudar os usuários a definir o melhor modelo para seus dados, trazendo uma interpretação mais completa. ## Acurácia A acurácia (ou *accuracy*, em inglês) é uma métrica que pode ser resumida em “De todas as classificações que o modelo realizou, o quanto ele acertou?”. Pode ser definida da seguinte maneira: ![[1*b5PlJ_4AMuvEjpcUx1JIoQ.png]] Fonte: Próprio autor Continuando no exemplo dos pacientes da clínica, o modelo SVM gerou: - VP = 243; VN = 465; FN = 25 e FP = 34 Sendo assim, substituindo os valores na fórmula, a acurácia obtida para este modelo seria de 0,92 ou 92%. De forma semelhante, para o caso do modelo RF, com: - VP = 213; VN = 435; FN = 55 e FP = 64 A acurácia seria de 0,84 ou 84%. Mas como fazer este cálculo em Python? ``` from sklearn.metrics import accuracy_scorey_pred = modelo.predict(X_test)accuracy = accuracy_score(y_real, y_pred) ``` De forma geral, a acurácia é uma métrica muita boa quando a base de dados está balanceada, ou seja, a quantidade de registros (instâncias ou linhas) para uma classe é praticamente a mesma para a outra classe. Trazendo para o exemplo do artigo, se a base de pacientes estivesse balanceada, a quantidade de registros de pacientes diabéticos seria bem próxima da quantidade dos não diabéticos. **Beleza! Mas por que isso é bom para a acurácia?** Imagine que de 1000 registros que a base de pacientes possua, 900 deles são não diabéticos e 100 são portadores da doença. O modelo aprenderá com muito mais dados de uma classe do que de outra, assim, tenderá a classificar os pacientes como não diabéticos e terá mais dificuldade para acertar quando receber informações de uma pessoa que de fato tenha a doença. Assim, se de 100 registros para os dados de teste, 90 forem da classe sem diabetes e 10 com diabetes, o modelo terá uma certa facilidade para acertar grande parte das análises (90%), gerando uma acurácia alta, que certamente será **enganosa**. Para bases desbalanceadas, há outras métricas que podem ser exploradas para machine learning, por exemplo a **Precisão e Revocação**. ## Precisão A precisão (ou *precision*, em inglês) é uma métrica que pode ser resumida em “De todas as previsões que o modelo classificou como Positivo, quantas ele acertou?”. É representada da seguinte maneira: ![[1*9I8tXnIQJdxQITtIOdk-4w.png]] Fonte: Próprio autor No exemplo dos pacientes da clínica, o modelo SVM gerou: - VP = 243 e FP = 34 Sendo assim, substituindo os valores na fórmula, a precisão obtida para este modelo seria de aproximadamente 0,88 ou 88%. Mas como fazer este cálculo em Python? ``` from sklearn.metrics import precision_scorey_pred = modelo.predict(X_test)precision = precision_score(y_real, y_pred) ``` Perceba que a métrica leva em consideração os FP, mas os FN ficam de fora. Isso pode ser ruim dependendo do tipo de problema que está sendo analisado. Neste caso, como é uma situação que envolve uma doença, os FN ficando de fora significa que há pacientes que realmente são diabéticos e que não estão fazendo parte da avaliação da métrica. Imagine que você possua uma doença e, depois de todos os exames, você é liberado para casa como se não tivesse nada. Situação **BEM PERIGOSA**. Analisando para um problema de inadimplência, se é priorizada a métrica Precisão, o modelo levará em consideração alguns adimplentes (FP) e deixará inadimplentes de fora (FN), o que pode resultar em prejuízo. Em um outro exemplo, considerando uma análise de sistema prisional para prever se alguém é culpado ou não, utilizar a Precisão pode ser uma boa escolha pois leva em consideração aqueles que são inocentes (FP), mas seria ruim por não considerar muitos que são culpados (FN). Nesses casos sempre há uma análise a se fazer em torno do problema proposto e da melhor métrica possível para avaliar o modelo. Resumindo, **a precisão mede a capacidade do modelo de evitar os FP**. ## **Revocação** Enquanto a precisão leva em consideração os FP, a revocação (ou *recall*, em inglês), que também pode ser chamada de sensitividade (ou *sensitivity*, em inglês), leva em conta os FN, ou seja, “De todos os casos que são realmente positivos, o quanto o modelo acertou?” Pode ser representada da seguinte maneira: ![[1*9DQe47gSjt_nRaGNKaCRHg.png]] Fonte: Próprio autor No exemplo dos pacientes da clínica, o modelo SVM gerou: - VP = 243 e FN = 25 Sendo assim, substituindo os valores na fórmula, a precisão obtida para este modelo seria de aproximadamente 0,91 ou 91%. Mas como fazer isso em Python? ``` from sklearn.metrics import recall_scorey_pred = modelo.predict(X_test)recall = recall_score(y_real, y_pred) ``` Por levar em conta os FP, seria uma boa métrica para se considerar em problemas que envolvem a área de saúde, pois a métrica prefere classificar como doente quem não possui a doença, do que classificar como saudável e deixar o paciente ir embora, sendo que possui a doença. É bem “menos pior” receber um diagnóstico de diabetes e depois perceber que era um engano, do que achar que está tudo bem quando na verdade se está com a doença, não é mesmo?? Resumindo, **a revocação mede a capacidade do modelo de evitar os FN**. ## Medida-F1 A Medida-F1 (ou *F1-Score*, do inglês) nada mais é que uma média harmônica entre a precisão e a revocação, sendo bastante útil quando busca-se avaliar tanto os FP quanto os FN do modelo. Neste caso é utilizada a média harmônica pois, **ao buscar um modelo que equilibre as métricas de revocação e precisão**, a média harmônica acaba privilegiando o valor mais baixo entre as duas. Pode ser representada da seguinte maneira: ![[1*9p2a2HOcM7I1jd8phAbs4A.png]] Fonte: Próprio autor No exemplo dos pacientes da clínica, os valores de precisão e revocação foram respectivamente 0,88 e 0,91. Sendo assim, o valor da métrica F1 para o modelo SVM seria de aproximadamente 0,89 ou 89%. Quando o valor da Medida F1 é alto, quer dizer que a precisão e revocação estão equilibradas entre si e ambas mantendo um bom nível. Caso contrário, se for baixo, será um indicativo de que as duas métricas estão bem distantes entre si, sendo necessário ajustar o modelo (caso ter estas métricas equilibradas seje um requisito). Em Python, para obter esta métrica deve-se seguir: ``` from sklearn.metrics import f1_scorey_pred = modelo.predict(X_test)f1 = f1_score(y_real, y_pred) ``` ## Curva ROC A curva ***Receiver Operating Characteristic*** (ROC) é uma métrica que relaciona a Taxa de Falso Positivo (FPR, do inglês *False Positive Rate*) no “eixo X” com a Taxa de Verdadeiro Positivo (TPR, do inglês *True Positive Rate*) no “eixo Y”. Na imagem a seguir pode-se observar um exemplo de curva ROC. ![[1*ELRlB7bCy00XGqrCxMT-AQ.png]] Fonte: Próprio autor A TPR nada mais é do que a revocação, calculada da mesma maneira. A FPR é conhecida também por ser (1 — Revocação) e pode ser interpretada por “De todas os casos que realmente são negativos, o quanto o modelo acabou classificando como positivo?”, calculada do modo apresentado a seguir: ![[1*DLsDOTSb0B0lkTkK34yQRA.png]] Fonte: Próprio autor O ideal seria o modelo avaliado apresentar TPR = 1, ou seja, de todos as classes realmente positivas o classificador identificou todas corretamente. Outra situação ideal seria o FPR = 0, ou seja, de todas as classes realmente negativas o modelo não identificou nenhuma como positiva. Isso resultaria no par ordenado (0;1) no gráfico da curva ROC a seguir. ![[1*5Z-rnZy0gPNiGjRhT3QFqQ.png]] Fonte: Próprio autor Sendo assim, quanto mais próxima a curva ROC está do ponto (0;1) melhor é o classificador. ![[Imagebalanco.jpeg]]