Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn

Introdução

O algoritmo Random Forest é um dos algoritmos mais flexíveis, poderosos e amplamente utilizados para classificação e regressão, construído como um Conjunto de Árvores de Decisão.

Se você não estiver familiarizado com eles - não se preocupe, abordaremos todos esses conceitos.

Neste guia prático detalhado, criaremos um intuição sobre como funcionam as árvores de decisão, como o agrupamento impulsiona classificadores e regressores individuais, o que são florestas aleatórias e construa um classificador e regressor de floresta aleatória usando Python e Scikit-Learn, por meio de um miniprojeto de ponta a ponta, e responda a uma pergunta de pesquisa.

Considere que você atualmente faz parte de um grupo de pesquisa que está analisando dados sobre mulheres. O grupo coletou 100 registros de dados e quer organizar esses registros iniciais dividindo as mulheres em categorias: estar ou não grávida e morar em áreas rurais ou urbanas. Os pesquisadores querem entender quantas mulheres estariam em cada categoria.

Existe uma estrutura computacional que faz exatamente isso, é o árvore estrutura. Usando uma estrutura de árvore, você poderá representar as diferentes divisões para cada categoria.

Árvores de decisão

Como você preenche os nós de uma árvore? é aqui Árvores de decisão entrar em foco.

Primeiro, podemos dividir os registros por gravidez, depois podemos dividi-los por residir em áreas urbanas ou rurais. Observe que poderíamos fazer isso em uma ordem diferente, dividindo inicialmente por qual área as mulheres vivem e depois por seu estado de gravidez. A partir disso, podemos ver que a árvore tem uma hierarquia inerente. Além de organizar as informações, uma árvore organiza as informações de maneira hierárquica – a ordem em que as informações aparecem é importante e leva a diferentes árvores como resultado.

Abaixo, está um exemplo da árvore que foi descrita:

Na imagem da árvore, há 7 quadrados, o de cima que dá conta do total de 100 mulheres, este quadrado superior está conectado com dois quadrados abaixo, que dividem as mulheres com base em seu número de 78 não grávidas e 22 grávidas, e de ambos os quadrados anteriores há quatro quadrados; dois ligados a cada quadrado acima que dividem as mulheres com base na sua área, para as não grávidas, 45 vivem na zona urbana, 33 na zona rural e para as grávidas, 14 vivem na zona rural e 8 na zona urbana. Só de olhar para a árvore é fácil entender essas divisões e ver como cada “camada” é derivada das anteriores, essas camadas são a árvore níveis, os níveis descrevem o profundidade da árvore:

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Observe na imagem acima que o primeiro nível da árvore é nível 0 onde há apenas um quadrado, seguido por nível 1 onde há dois quadrados, e nível 2 onde há quatro quadrados. Isto é um profundidade 2 árvore.

No nível 0 está o quadrado que dá origem à árvore, o primeiro, chamado nó raiz, esta raiz tem dois nós filhos no nível 1, que são nós pais aos quatro nós no nível 2. Veja que os “quadrados” que mencionamos até agora são, na verdade, chamados nós; e que cada nó anterior é pai dos nós seguintes, que são seus filhos. Os nós filhos de cada nível que têm o mesmo pai são chamados irmãos, como pode ser visto na próxima imagem:

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Na imagem anterior, também exibimos o nível 1 como sendo o nós interiores, uma vez que estão entre a raiz e os últimos nós, que são os nós folha. Os nós das folhas são a última parte de uma árvore, se disséssemos das 100 mulheres iniciais, quantas estão grávidas e morando em áreas rurais, poderíamos fazer isso olhando para as folhas. Portanto, o número nas folhas responderia à primeira pergunta de pesquisa.

Se houvesse novos registros de mulheres, e a árvore que antes era usada para categorizá-las, agora fosse usada para decidir se uma mulher poderia ou não fazer parte da pesquisa, ela ainda funcionaria? A árvore usaria os mesmos critérios, e uma mulher seria elegível para participar se estivesse grávida e vivesse em uma área rural.

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Olhando para a imagem acima, podemos ver que as respostas para as perguntas de cada nó da árvore – “ela é participante?”, “ela está grávida?”, “ela mora em área rural?”- são sim, sim, e sim, então parece que a árvore pode levar a uma decisão, neste caso, que a mulher possa participar da pesquisa.

Este é o essência de árvores de decisão, feito de forma manual. Usando Machine Learning, podemos construir um modelo que construa esta árvore automaticamente para nós, de forma a maximizar a precisão das decisões finais.

Observação: existem vários tipos de árvores em Ciência da Computação, como árvores binárias, árvores gerais, árvores AVL, árvores splay, árvores red black, b-trees, etc. Aqui, estamos nos concentrando em dar uma ideia geral do que é uma árvore de decisão . Se depender da resposta de um sim or não pergunta para cada nó e, portanto, cada nó tem no máximo dois filhos, quando ordenados de modo que os nós “menores” fiquem à esquerda, isso classifica as árvores de decisão como árvores binárias.

Nos exemplos anteriores, observe como a árvore poderia classificar novos dados como participante ou não participante, ou as perguntas também poderiam ser alteradas para – “quantos são participantes?”, “quantos estão grávidas?”, “quantos vivem em uma área rural?”- levando-nos a encontrar o quantidade de participantes gestantes residentes na zona rural.

Quando os dados são classificados, isso significa que a árvore está realizando uma classificação tarefa, e quando a quantidade de dados é encontrada, a árvore está realizando uma regressão tarefa. Isso significa que a árvore de decisão pode ser usada para ambas as tarefas – classificação e regressão.

Agora que entendemos o que é uma árvore de decisão, como ela pode ser usada e qual nomenclatura é usada para descrevê-la, podemos nos perguntar sobre suas limitações.

Entendendo as Florestas Aleatórias

O que acontece com a decisão se algum participante mora na divisão entre áreas urbanas e rurais? A árvore acrescentaria esse registro ao rural ou ao urbano? Parece difícil encaixar esses dados na estrutura que temos atualmente, já que é bastante claro.

Além disso, e se uma mulher que mora em um barco participar da pesquisa, ela seria considerada rural ou urbana? Da mesma forma que no caso anterior, é um ponto de dados desafiador para classificar considerando as opções disponíveis na árvore.

Pensando um pouco mais no exemplo da árvore de decisão, podemos ver que ela pode classificar corretamente novos dados considerando que já segue um padrão que a árvore já possui – mas quando há registros que diferem dos dados iniciais que definiram a árvore, o a estrutura da árvore é muito rígida, tornando os registros não classificáveis.

Isso significa que a árvore de decisão pode ser restrita e limitada em suas possibilidades. Uma árvore de decisão ideal seria mais flexível e capaz de acomodar dados não vistos com mais nuances.

Alternativa? Assim como “dois pares de olhos enxergam melhor do que um”, dois modelos costumam apresentar uma resposta mais precisa do que um. Levando em conta a diversidade nas representações do conhecimento (codificadas na estrutura da árvore), a rigidez das estruturas ligeiramente diferentes entre várias árvores semelhantes não é mais tão limitante, uma vez que as deficiências de uma árvore podem ser “compensadas” por outra. Ao combinar muitos árvores juntos, obtemos um floresta.

Quanto à resposta à pergunta inicial, já sabemos que estará codificada nas folhas das árvores – mas o que muda quando temos muitas árvores em vez de uma?

Se as árvores forem combinadas para uma classificação, o resultado será definido pela maioria das respostas, isso se chama votação por maioria; e no caso de uma regressão, o número dado por cada árvore na floresta será média.

Ensemble Learning e Model Ensembles

Este método é conhecido como aprendizagem em conjunto. Ao aplicar o aprendizado de conjunto, você pode misturar quaisquer algoritmos, desde que possa garantir que a saída possa ser analisada e combinada com outras saídas (manualmente ou usando bibliotecas existentes). Normalmente, você agrupa vários modelos do mesmo tipo, como várias árvores de decisão, mas não está limitado a apenas unir conjuntos do mesmo tipo de modelo.

O agrupamento é uma maneira praticamente garantida de generalizar melhor para um problema e obter um leve aumento de desempenho. Em alguns casos, a combinação de modelos produz uma periodo aumento no poder preditivo e, às vezes, apenas leve. Isso depende do conjunto de dados que você está treinando e avaliando, bem como dos próprios modelos.

Juntar árvores de decisão produz periodo aumentos de desempenho compactados em árvores individuais. Essa abordagem foi popularizada nas comunidades de pesquisa e aprendizado de máquina aplicada e era tão comum que o conjunto de árvores de decisão foi coloquialmente chamado de floresta, e o tipo comum de floresta que estava sendo criado (uma floresta de árvores de decisão em um subconjunto aleatório de recursos) popularizou o nome florestas aleatórias.

Dado o uso em larga escala, bibliotecas como Scikit-Learn implementaram wrappers para RandomForestRegressorareia RandomForestClassifiers, construídos sobre suas próprias implementações de árvore de decisão, para permitir que os pesquisadores evitem construir seus próprios conjuntos.

Vamos mergulhar em florestas aleatórias!

Como funciona o algoritmo Random Forest?

A seguir estão as etapas básicas envolvidas na execução do algoritmo de floresta aleatória:

  1. Escolha um número de registros aleatórios, pode ser qualquer número, como 4, 20, 76, 150 ou até 2.000 do conjunto de dados (chamado N registros). O número dependerá da largura do conjunto de dados, quanto mais largo, maior N pode ser. É aqui que o acaso parte no nome do algoritmo vem!
  2. Construir uma árvore de decisão com base nessas N registros aleatórios;
  3. De acordo com o número de árvores definido para o algoritmo, ou o número de árvores da floresta, repita os passos 1 e 2. Isso gera mais árvores a partir de conjuntos de registros de dados aleatórios;
  4. Após a etapa 3, vem a etapa final, que é prever os resultados:
    • No caso de classificação: cada árvore da floresta irá prever a categoria a que pertence o novo registro. Depois disso, o novo recorde é atribuído à categoria que obtiver a maioria dos votos.
    • No caso de regressão: cada árvore da floresta prevê um valor para o novo registro, e o valor final da previsão será calculado tirando uma média de todos os valores previstos por todas as árvores da floresta.

Cada árvore que se encaixa em um subconjunto aleatório de feições necessariamente não terá conhecimento de algumas outras feições, o que é corrigido por ensemble, mantendo o custo computacional mais baixo.

Conselho: Como a Random Forest usa árvores de decisão como base, é muito útil entender como as árvores de decisão funcionam e praticar um pouco com elas individualmente para construir uma intuição sobre sua estrutura. Ao compor florestas aleatórias, você definirá valores como a profundidade máxima de uma árvore, o número mínimo de amostras necessárias para estar em um nó folha, os critérios para apostar na determinação de divisões internas, etc. conjunto de dados e generalizar para novos pontos. Na prática, você normalmente usará Random Forests, Gradient Boosting ou Extreme Gradient Boosting ou outras metodologias baseadas em árvore, portanto, ter uma boa compreensão dos hiperparâmetros de uma única árvore de decisão ajudará na construção de uma forte intuição para ajustar conjuntos.

Com uma intuição sobre como as árvores funcionam e uma compreensão das Florestas Aleatórias - a única coisa que resta é praticar a construção, treinamento e ajuste delas em dados!

Construindo e treinando modelos de floresta aleatórios com o Scikit-Learn

Havia uma razão para os exemplos usados ​​até agora envolverem gravidez, área de convivência e mulheres.

Em 2020, pesquisadores de Bangladesh perceberam que a mortalidade entre gestantes ainda era muito alta, principalmente considerando as que vivem em áreas rurais. Por isso, eles usaram um sistema de monitoramento IOT para analisar o risco de saúde materna. O sistema IOT coletou dados de diferentes hospitais, clínicas comunitárias e cuidados de saúde materna das áreas rurais de Bangladesh.

Os dados coletados foram organizados em um arquivo de valores separados por vírgula (csv) e enviados para Repositório de aprendizado de máquina da UCI.

Esses são os dados que usaremos para praticar e tentar entender se uma gestante tem um baixo, média or Alto risco de mortalidade.

Note: você pode baixar o conjunto de dados SUA PARTICIPAÇÃO FAZ A DIFERENÇA.

Usando Floresta Aleatória para Classificação

Como queremos saber se a mulher tem um baixo, média or Alto risco de mortalidade, isso significa que faremos uma classificação com três classes. Quando um problema tem mais de duas classes, ele é chamado de multiclasse problema, ao contrário de um binário problema (onde você escolhe entre duas classes, normalmente 0 e 1).

Neste primeiro exemplo, implementaremos um modelo de classificação multiclasse com um classificador Random Forest e o Scikit-Learn do Python.

Seguiremos as etapas usuais de aprendizado de máquina para resolver esse problema, que são carregar bibliotecas, ler os dados, examinar estatísticas resumidas e criar visualizações de dados para melhor entendê-los. Em seguida, pré-processar e dividir os dados seguidos pela geração, treinamento e avaliação de um modelo.

Importando Bibliotecas

Estaremos usando Pandas para ler os dados, Seaborn e Matplotlib para visualizá-los e NumPy para os métodos de grande utilidade:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
Importando o conjunto de dados

O código a seguir importa o conjunto de dados e o carrega em um python DataFrame:

dataset = pd.read_csv("../../datasets/random-forest/maternal_health_risk.csv")

Para ver as cinco primeiras linhas dos dados, executamos o head() comando:

dataset.head()

Isso resulta em:

    Age SystolicBP  DiastolicBP BS      BodyTemp    HeartRate   RiskLevel
0   25  130         80          15.0    98.0        86          high risk
1   35  140         90          13.0    98.0        70          high risk
2   29  90          70          8.0     100.0       80          high risk
3   30  140         85          7.0     98.0        70          high risk
4   35  120         60          6.1     98.0        76          low risk

Aqui podemos ver todos os atributos coletados durante a pesquisa.

  • Idade: idades em anos.
  • PA Sistólica: valor superior da Pressão Arterial em mmHg, atributo significativo durante a gravidez.
  • PA Diastólica: menor valor da Pressão Arterial em mmHg, outro atributo significativo durante a gestação.
  • BS: níveis de glicose no sangue em termos de concentração molar, mmol/L.
  • HeartRate: frequência cardíaca em repouso em batimentos por minuto.
  • RiskLevel: nível de risco durante a gravidez.
  • BodyTemp: a temperatura do corpo.

Agora que entendemos mais sobre o que está sendo medido, podemos olhar para os tipos de dados com info():

dataset.info()

Isto resulta em:


RangeIndex: 1014 entries, 0 to 1013
Data columns (total 7 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   Age          1014 non-null   int64  
 1   SystolicBP   1014 non-null   int64  
 2   DiastolicBP  1014 non-null   int64  
 3   BS           1014 non-null   float64
 4   BodyTemp     1014 non-null   float64
 5   HeartRate    1014 non-null   int64  
 6   RiskLevel    1014 non-null   object 
dtypes: float64(2), int64(4), object(1)
memory usage: 55.6+ KB

De olhar para o RangeIndex linha, podemos ver que são 1014 registros, e a coluna Non-Null Count informa que os dados não possuem nenhum valor ausente. Isso significa que não precisaremos fazer nenhum tratamento para os dados perdidos!

No Dtype coluna, podemos ver o tipo de cada variável. Atualmente, float64 colunas como BS e BodyTemp possuem valores numéricos que podem variar em qualquer faixa, como 15.0, 15.51, 15.76, 17.28, tornando-os numericamente contínuo (você sempre pode adicionar um 0 a um número de ponto flutuante, ad infinitem). Por outro lado, variáveis ​​como Age, SystolicBP, DiastolicBP e HeartRate são do tipo int64, isso significa que os números só mudam por unidade, como 11, 12, 13, 14 – não teremos uma frequência cardíaca de 77.78, é 77 ​​ou 78 – esses são numericamente discreto valores. E também temos RiskLevel com uma object type, isso geralmente indica que a variável é um texto, e provavelmente precisaremos transformá-la em um número. Como o nível de risco cresce de baixo para alto, há uma ordem implícita nas categorias, isso indica que é um categoricamente ordinal variável.

Note: é importante olhar para o tipo de cada dado, e ver se faz sentido de acordo com o seu contexto. Por exemplo, não faz sentido ter metade de uma unidade de frequência cardíaca, então isso significa que o tipo inteiro é adequado para um valor discreto. Quando isso não acontecer, você pode alterar o tipo de dados com o Pandas' astype() propriedade - df['column_name'].astype('type').

Depois de olhar para os tipos de dados, podemos usar describe() para dar uma olhada em algumas estatísticas descritivas, como os valores médios de cada coluna, o desvio padrão, quantis, valores mínimos e máximos de dados:

dataset.describe().T 

O código acima exibe:

            count   mean        std         min     25%     50%     75%     max
Age         1014.0  29.871795   13.474386   10.0    19.0    26.0    39.0    70.0
SystolicBP  1014.0  113.198225  18.403913   70.0    100.0   120.0   120.0   160.0
DiastolicBP 1014.0  76.460552   13.885796   49.0    65.0    80.0    90.0    100.0
BS          1014.0  8.725986    3.293532    6.0     6.9     7.5     8.0     19.0
BodyTemp    1014.0  98.665089   1.371384    98.0    98.0    98.0    98.0    103.0
HeartRate   1014.0  74.301775   8.088702    7.0     70.0    76.0    80.0    90.0
RiskLevel   1014.0  0.867850    0.807353    0.0     0.0     1.0     2.0     2.0

Observe que para a maioria das colunas, o significar os valores estão longe do desvio padrão (std) – isso indica que os dados não seguem necessariamente uma distribuição estatística bem comportada. Se tivesse, teria ajudado o modelo ao prever o risco. O que pode ser feito aqui é pré-processar os dados para torná-los mais representativos como se fossem dados de toda a população mundial, ou mais normalizado. Mas, uma vantagem ao usar modelos Random Forest para classificação, é que a estrutura de árvore inerente pode lidar bem com dados que não foram normalizados, uma vez que os divide pelo valor em cada nível de árvore para cada variável.

Além disso, como estamos usando árvores e a classe resultante será obtida por votação, não estamos comparando inerentemente entre valores diferentes, apenas entre os mesmos tipos de valores, portanto, ajustar os recursos para a mesma escala não é necessário neste caso . Isso significa que o modelo de classificação Random Forest é escala invariante, e você não precisa executar dimensionamento de recurso.

Nesse caso, a etapa de pré-processamento de dados que podemos realizar é transformar o categórico RiskLevel coluna em uma numérica.

Visualizando os dados

Antes de transformar RiskLevel, vamos também visualizar rapidamente os dados observando as combinações de pontos para cada par de recursos com um Scatterplot e como os pontos são distribuídos visualizando a curva do histograma. Para isso, usaremos o Seaborn's pairplot() que combina as duas parcelas. Ele gera ambos os gráficos para cada combinação de recursos e exibe os pontos codificados por cores de acordo com seu nível de risco com o hue propriedade:

g = sns.pairplot(dataset, hue='RiskLevel')
g.fig.suptitle("Scatterplot and histogram of pairs of variables color coded by risk level", 
               fontsize = 14, 
               y=1.05); 

O código acima gera:

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Ao olhar para o gráfico, a situação ideal seria ter uma separação clara entre curvas e pontos. Como podemos observar, os três tipos de classes de risco em sua maioria se misturam, pois as árvores traçam linhas internamente ao delimitar os espaços entre os pontos, podemos supor que mais árvores na floresta poderiam delimitar mais espaços e classificar melhor os pontos.

Com a análise de dados exploratória básica feita, podemos pré-processar o RiskLevel coluna.

Pré-processamento de dados para classificação

Para ter certeza, existem apenas três classes de RiskLevel em nossos dados, e que nenhum outro valor foi adicionado erroneamente, podemos usar unique() para exibir os valores exclusivos da coluna:

dataset['RiskLevel'].unique()

Isso resulta em:

array(['high risk', 'low risk', 'mid risk'], dtype=object)

As classes são verificadas, agora o próximo passo é transformar cada valor em um número. Como existe uma ordem entre as classificações, podemos usar os valores 0, 1 e 2 para significar baixo, média e Alto riscos. Existem muitas maneiras de alterar os valores das colunas, seguindo as instruções do Python simples é melhor que complexo lema, usaremos o .replace() e simplesmente substitua-os por suas representações inteiras:

dataset['RiskLevel'] = dataset['RiskLevel'].replace('low risk', 0).replace('mid risk', 1).replace('high risk', 2)

Depois de substituir os valores, podemos dividir os dados no que será usado para treinar o modelo, o características or X, e o que queremos prever, o Labels or y:

y = dataset['RiskLevel']
X = dataset.drop(['RiskLevel'], axis=1)

Uma vez que o X e y conjuntos estão prontos, podemos usar o Scikit-Learn's train_test_split() método para dividi-los ainda mais nos conjuntos de treinamento e teste:

from sklearn.model_selection import train_test_split

SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=0.2, 
                                                    random_state=SEED)

Conselho: lembre-se de usar uma semente de estado aleatório se quiser tornar o resultado reproduzível. Usamos uma semente de estado aleatório para que você possa reproduzir os mesmos resultados do guia.

Aqui, estamos usando 20% dos dados para teste e 80% para treinamento.

Treinando um RandomForestClassifier

Confira nosso guia prático e prático para aprender Git, com práticas recomendadas, padrões aceitos pelo setor e folha de dicas incluída. Pare de pesquisar comandos Git no Google e realmente aprender -lo!

Scikit-Learn implementou ensembles sob o sklearn.ensemble módulo. Um conjunto de árvores de decisão usado para classificação, no qual uma maioria de votos é tomada, é implementado como o RandomForestClassifier.

Tendo os conjuntos de treinamento e teste, podemos importar o RandomForestClassifier classe e criar o modelo. Para começar, vamos criar uma floresta com três árvores, definindo n_estimators parâmetro como 3, e com cada árvore tendo três níveis, definindo max_depthpara 2:

from sklearn.ensemble import RandomForestClassifier

rfc = RandomForestClassifier(n_estimators=3, 
                             max_depth=2,
                             random_state=SEED)

Observação: O valor padrão para n_estimators is 100. Isso aumenta o poder preditivo e a generalização do conjunto, mas estamos criando um menor para facilitar sua visualização e inspeção. Com apenas 3 árvores – podemos visualizá-las e inspecioná-las manualmente para construir ainda mais nossa intuição de ambas as árvores individuais e sua co-dependência. O mesmo se aplica para max_depth, o que é None, o que significa que as árvores podem se aprofundar cada vez mais para ajustar os dados conforme necessário.

Para ajustar o modelo em torno dos dados - chamamos o fit() método, passando nos recursos e rótulos de treinamento:


rfc.fit(X_train, y_train)

y_pred = rfc.predict(X_test)

Agora podemos comparar os rótulos previstos com os rótulos reais para avaliar o desempenho do modelo! Antes de avaliar o modelo, vamos dar uma olhada no conjunto.

Para olhar um pouco mais fundo no modelo, podemos visualizar cada uma das árvores e como elas estão dividindo os dados. Isso pode ser feito usando o tree módulo embutido no Scikit-Learn e, em seguida, percorrendo cada um dos estimadores no conjunto:


from sklearn import tree

features = X.columns.values 
classes = ['0', '1', '2'] 



for estimator in rfc.estimators_:
    print(estimator)
    plt.figure(figsize=(12,6))
    tree.plot_tree(estimator,
                   feature_names=features,
                   class_names=classes,
                   fontsize=8, 
                   filled=True, 
                   rounded=True)
    plt.show()

O código acima exibe os gráficos de árvore:

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.
Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Observe como as três árvores são diferentes. A primeira começa com o BS recurso, o segundo com DiastolicBP, e o terceiro com BS novamente. Embora o terceiro olhe para um número diferente de amostras. No ramo direito, as duas primeiras árvores também decidem usando Age no nível da folha, enquanto a terceira árvore termina com BS característica. Com apenas três estimadores, fica claro como o aumento de escala fornece uma representação rica e diversificada do conhecimento que pode ser agrupado com sucesso em um modelo altamente preciso.

Quanto mais árvores na floresta, mais diversificado pode ser o modelo. Há um ponto de retornos decrescentes, porém, como com muitas árvores ajustadas em um subconjunto aleatório de recursos, haverá um bom número de árvores semelhantes que não oferecem muita diversidade no conjunto e que começarão a ter muito poder de voto e distorcer o conjunto para ser superajustado no conjunto de dados de treinamento, prejudicando a generalização para o conjunto de validação.

Houve uma hipótese feita anteriormente sobre ter mais árvores e como isso poderia melhorar os resultados do modelo. Vamos dar uma olhada nos resultados, gerar um novo modelo e ver se a hipótese se sustenta!

Avaliando o RandomForestClassifier

O Scikit-Learn facilita a criação de linhas de base, fornecendo uma DummyClassifier, que gera previsões sem usar os recursos de entrada (saídas totalmente aleatórias). Se o seu modelo for melhor que o DummyClassifier, alguns aprendizagem está acontecendo! Para maximizar o aprendizado - você pode testar vários hiperparâmetros automaticamente usando um RandomizedSearchCV or GridSearchCV. Além de ter uma linha de base, você pode avaliar o desempenho do seu modelo pelas lentes de diversas métricas.

Algumas métricas de classificação tradicionais que podem ser usadas para avaliar o algoritmo são precisão, recall, pontuação f1, precisão e matriz de confusão. Segue uma breve explicação sobre cada um deles:

  1. Precisão: quando nosso objetivo é entender quais valores de predição corretos foram considerados corretos por nosso classificador. A precisão dividirá esses valores positivos verdadeiros pelas amostras que foram previstas como positivas;

$$
precisão = frac{texto{verdadeiros positivos}}{texto{verdadeiros positivos} + texto{falsos positivos}}
$$

  1. Recordar: comumente calculado com precisão para entender quantos dos verdadeiros positivos foram identificados pelo nosso classificador. O recall é calculado dividindo os verdadeiros positivos por qualquer coisa que deveria ter sido prevista como positiva.

$$
recall = frac{texto{verdadeiros positivos}}{texto{verdadeiros positivos} + texto{falsos negativos}}
$$

  1. Pontuação F1: é o balanceado ou média harmônica de precisão e revocação. O valor mais baixo é 0 e o mais alto é 1. Quando f1-score é igual a 1, significa que todas as classes foram previstas corretamente – esta é uma pontuação muito difícil de obter com dados reais (exceções quase sempre existem).

$$
text{f1-score} = 2* frac{text{precisão} * text{recall}}{text{precisão} + text{recall}}
$$

  1. Matriz de Confusão: quando precisamos saber quantas amostras acertamos ou erramos cada aula. Os valores que foram corretos e corretamente previstos são chamados verdadeiros positivos, aqueles que foram previstos como positivos, mas não foram positivos, são chamados falso-positivo. A mesma nomenclatura de verdadeiros negativos e falsos negativos é usado para valores negativos;

  2. Precisão: descreve quantas previsões nosso classificador acertou. O valor de precisão mais baixo é 0 e o mais alto é 1. Esse valor geralmente é multiplicado por 100 para obter uma porcentagem:

$$
precisão = frac{text{número de previsões corretas}}{text{número total de previsões}}
$$

Observação: É praticamente impossível obter 100% de precisão em quaisquer dados reais aos quais você deseja aplicar o aprendizado de máquina. Se você vir um classificador de precisão de 100% ou mesmo um resultado próximo a 100%, seja cético e faça uma avaliação. Uma causa comum para esses problemas é o vazamento de dados (vazamento de parte do teste de treinamento em um conjunto de teste, direta ou indiretamente). Não há consenso sobre o que é “uma boa precisão”, principalmente porque depende dos seus dados – às vezes, uma precisão de 70% será alta! Às vezes, essa será uma precisão muito baixa. Geralmente, mais de 70% é suficiente para muitos modelos, mas isso cabe ao pesquisador de domínio determinar.

Você pode executar o seguinte script para importar as bibliotecas necessárias e ver os resultados:

from sklearn.metrics import classification_report, confusion_matrix

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d').set_title('Maternal risks confusion matrix (0 = low risk, 1 = medium risk, 2 = high risk)')

print(classification_report(y_test,y_pred))

O resultado será mais ou menos assim:

                precision    recall  f1-score   support

           0       0.53      0.89      0.66        80
           1       0.57      0.17      0.26        76
           2       0.74      0.72      0.73        47

    accuracy                           0.58       203
   macro avg       0.61      0.59      0.55       203
weighted avg       0.59      0.58      0.53       203

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

No relatório de classificação, observe que o recall é alto, 0.89 para a classe 0, tanto a precisão quanto o recall são altos para a classe 2, 0.74, 0.72 – e para a classe 1, são baixos, principalmente o recall de 0.17 e uma precisão de 0.57 . A relação entre o recall e a precisão para todas as três classes individualmente é capturada no F1 pontuação, que é a média harmônica entre recall e precisão - o modelo está fazendo ok para a classe 0, bastante ruim para a classe 1 e decente para a classe 2.

O modelo está tendo muita dificuldade em identificar o casos de médio risco.

A precisão alcançada pelo nosso classificador de floresta aleatória com apenas 3 árvores é de 0.58 (58%) – isso significa que está acertando um pouco mais da metade dos resultados. Esta é uma precisão baixa e talvez possa ser melhorada adicionando mais árvores.

Observando a matriz de confusão, podemos ver que a maioria dos erros ocorre ao classificar 52 prontuários de médio risco como baixo risco, o que dá uma visão mais aprofundada da baixa recordação da classe 1. Ela é tendenciosa para classificar pacientes de médio risco como baixo pacientes de risco.

Outra coisa que pode ser verificada para gerar ainda mais insights é quais recursos são mais levados em consideração pelo classificador ao prever. Este é um passo importante a ser dado para sistemas de aprendizado de máquina explicáveis, e ajuda a identificar e atenuar o viés nos modelos.

Para ver isso, podemos acessar o feature_importances_ propriedade do classificador. Isso nos dará uma lista de porcentagens, para que também possamos acessar o feature_names_in_ propriedade para obter o nome de cada recurso, organizá-los em um dataframe, classificá-los do maior para o menor e plotar o resultado:


features_df = pd.DataFrame({'features': rfc.feature_names_in_, 'importances': rfc.feature_importances_ })


features_df_sorted = features_df.sort_values(by='importances', ascending=False)


g = sns.barplot(data=features_df_sorted, x='importances', y ='features', palette="rocket")
sns.despine(bottom = True, left = True)
g.set_title('Feature importances')
g.set(xlabel=None)
g.set(ylabel=None)
g.set(xticks=[])
for value in g.containers:
    g.bar_label(value, padding=2)

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Observe como o classificador está considerando principalmente o açúcar sanguíneo, então um pouco da pressão diastólica, temperatura corporal e um pouco da idade para tomar uma decisão, isso também pode ter a ver com a baixa recordação na classe 1, talvez os dados de risco médio tenham a ver com recursos que não estão sendo levado em consideração pelo modelo. Você pode tentar brincar mais com as importâncias dos recursos para investigar isso e ver se as alterações no modelo afetam os recursos que estão sendo usados, também se há uma relação significativa entre alguns dos recursos e as classes previstas.

Finalmente é hora de gerar um novo modelo com mais árvores para ver como isso afeta os resultados. Vamos criar o rfc_ floresta com 900 árvores, 8 níveis e a mesma semente. Os resultados vão melhorar?

rfc_ = RandomForestClassifier(n_estimators=900, 
                             max_depth=7,
                             random_state=SEED)
rfc_.fit(X_train, y_train)
y_pred = rfc_.predict(X_test)

Calculando e exibindo as métricas:

cm_ = confusion_matrix(y_test, y_pred)
sns.heatmap(cm_, annot=True, fmt='d').set_title('Maternal risks confusion matrix (0 = low risk, 1 = medium risk, 2 = high risk) for 900 trees with 8 levels')

print(classification_report(y_test,y_pred))

Isso resulta em:

                precision    recall  f1-score   support

           0       0.68      0.86      0.76        80
           1       0.75      0.58      0.65        76
           2       0.90      0.81      0.85        47

    accuracy                           0.74       203
   macro avg       0.78      0.75      0.75       203
weighted avg       0.76      0.74      0.74       203

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Isso mostra como adicionar mais árvores e mais árvores especializadas (níveis mais altos) melhorou nossas métricas. Ainda temos um recall baixo para a classe 1, mas a precisão agora é de 74%. O F1-score ao classificar casos de alto risco é de 0.85, o que significa que os casos de alto risco agora são mais facilmente identificados quando comparado a 0.73 no modelo anterior!

Em um projeto do dia a dia, pode ser mais importante identificar casos de alto risco, por exemplo, com uma métrica semelhante à precisão, também conhecida como sensibilidade nas estatísticas. Tente ajustar alguns dos parâmetros do modelo e observe os resultados.

Até agora, obtivemos uma compreensão geral de como o Random Forest pode ser usado para classificar dados – na próxima seção, podemos usar o mesmo conjunto de dados de uma maneira diferente para ver como o mesmo modelo prevê valores com regressão.

Usando florestas aleatórias para regressão

Nesta seção, estudaremos como um algoritmo Random Forest pode ser usado para resolver problemas de regressão usando o Scikit-Learn. Os passos seguidos para implementar este algoritmo são quase idênticos aos passos realizados para classificação, além do tipo de modelo, e tipo de dados previstos – que agora serão valores contínuos – há apenas uma diferença na preparação dos dados.

Como a regressão é feita para valores numéricos – vamos escolher um valor numérico do conjunto de dados. Vimos que o açúcar no sangue era importante na classificação, por isso deveria ser previsível com base em outras características (já que se correlaciona com alguma característica, essa característica também se correlaciona com ela).

Seguindo o que fizemos para a classificação, vamos primeiro importar as bibliotecas e o mesmo conjunto de dados. Se você já fez isso para o modelo de classificação, pode pular esta parte e ir diretamente para a preparação de dados para treinamento.

Importando bibliotecas e dados
import pandas as pd
import numpy as np
import maplotlib.pyplot as plt
import seaborn as sns

dataset = pd.read_csv("../../datasets/random-forest/maternal_health_risk.csv")
Pré-processamento de dados para regressão

Esta é uma tarefa de regressão, portanto, em vez de prever classes, podemos prever uma das colunas numéricas do conjunto de dados. Neste exemplo, o BS coluna será prevista. Isso significa que y os dados irão conter dados de açúcar no sangue e X os dados conterão todos os recursos além do açúcar no sangue. Depois de separar o X e y dados, podemos dividir os conjuntos de treinamento e teste:

from sklearn.model_selection import train_test_split

SEED = 42

y = dataset['BS']
X = dataset.drop(['BS'], axis=1) 

X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=0.2, 
                                                    random_state=SEED)
Treinando um RandomForestRegressor

Agora que escalamos nosso conjunto de dados, é hora de treinar nosso algoritmo para resolver esse problema de regressão, para mudar um pouco – vamos criar um modelo com 20 árvores na floresta e cada uma com 4 níveis. Para fazer isso, você pode executar o seguinte código:

from sklearn.ensemble import RandomForestRegressor

rfr = RandomForestRegressor(n_estimators=20, 
                            max_depth=3, 
                            random_state=SEED)

rfr.fit(X_train, y_train)
y_pred = rfr.predict(X_test)

Você pode encontrar detalhes para todos os parâmetros de RandomForestRegressor na documentação oficial.

Como plotar e olhar para 20 árvores exigiria algum tempo e dedicação, podemos plotar apenas a primeira para dar uma olhada em como ela é diferente da árvore de classificação:

from sklearn import tree

features = X.columns

first_tree = rfr.estimators_[0]

plt.figure(figsize=(15,6))
tree.plot_tree(first_tree,
               feature_names=features,
               fontsize=8, 
               filled=True, 
               rounded=True);

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Observe que a árvore de regressão já possui um valor atribuído aos dados que caem em cada nó. Esses são os valores que serão calculados ao combinar as 20 árvores. Seguindo o que fizemos com a classificação, você também pode plotar as importâncias dos recursos para ver quais variáveis ​​o modelo de regressão está levando mais em consideração ao calcular os valores.

É hora de prosseguir para a última e última etapa ao resolver um problema de aprendizado de máquina e avaliar o desempenho do algoritmo!

Avaliando um RandomForestRegressor

Para problemas de regressão, as métricas usadas para avaliar um algoritmo são o erro médio absoluto (MAE), o erro médio quadrático (MSE) e a raiz do erro quadrático médio (RMSE).

  1. Erro Médio Absoluto (MAE): quando subtraímos os valores previstos dos valores reais, obtendo os erros, somamos os valores absolutos desses erros e obtemos sua média. Essa métrica dá uma noção do erro geral para cada previsão do modelo, quanto menor (mais próximo de 0) melhor.

$$
mae = (frac{1}{n})sum_{i=1}^{n}esquerda | Real – Previsto certo |
$$

Observação: Você também pode encontrar o y e ŷ notação nas equações. o y refere-se aos valores reais e a ŷ aos valores previstos.

  1. Erro médio quadrático (MSE): é semelhante à métrica MAE, mas eleva ao quadrado os valores absolutos dos erros. Além disso, como no MAE, quanto menor ou mais próximo de 0, melhor. O valor MSE é elevado ao quadrado para tornar os erros ainda maiores. Uma coisa a ter bastante atenção é que costuma ser uma métrica difícil de interpretar devido ao tamanho de seus valores e ao fato de não estarem na mesma escala dos dados.

$$
mse = soma_{i=1}^{D}(Real – Previsto)^2
$$

  1. Erro quadrático médio (RMSE): tenta resolver o problema de interpretação levantado com o MSE obtendo a raiz quadrada de seu valor final, de modo a redimensioná-lo para as mesmas unidades dos dados. É mais fácil de interpretar e bom quando precisamos exibir ou mostrar o valor real dos dados com o erro. Ele mostra o quanto os dados podem variar, portanto, se tivermos um RMSE de 4.35, nosso modelo pode cometer um erro porque adicionou 4.35 ao valor real ou precisou de 4.35 para chegar ao valor real. Quanto mais próximo de 0, melhor também.

$$
rmse = sqrt{ soma_{i=1}^{D}(Real – Previsto)^2}
$$

Podemos usar qualquer uma dessas três métricas para comparar modelos (se precisarmos escolher um). Também podemos comparar o mesmo modelo de regressão com valores de argumentos diferentes ou com dados diferentes e então considerar as métricas de avaliação. Isso é conhecido como ajuste de hiperparâmetro – ajustar os hiperparâmetros que influenciam um algoritmo de aprendizado e observar os resultados.

Ao escolher entre os modelos, os que apresentam os menores erros costumam ter melhor desempenho. Ao monitorar modelos, se as métricas pioraram, uma versão anterior do modelo foi melhor ou houve alguma alteração significativa nos dados para que o modelo tenha um desempenho pior do que estava.

Você pode usar o código a seguir para encontrar esses valores:

from sklearn.metrics import mean_absolute_error, mean_squared_error

print('Mean Absolute Error:', mean_absolute_error(y_test, y_pred))
print('Mean Squared Error:', mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error:', np.sqrt(mean_squared_error(y_test, y_pred)))

A saída deve ser:

Mean Absolute Error: 1.127893702896059
Mean Squared Error: 3.0802988503933326
Root Mean Squared Error: 1.755078018320933

Com 20 árvores, a raiz do erro quadrático médio é de 1.75, o que é baixo, mas mesmo assim – aumentando o número de árvores e experimentando os outros parâmetros, esse erro provavelmente pode ficar ainda menor.

Vantagens de usar Random Forest

Como acontece com qualquer algoritmo, há vantagens e desvantagens em usá-lo. Nas próximas duas seções, veremos os prós e contras do uso da floresta aleatória para classificação e regressão.

  1. O algoritmo de floresta aleatória não é tendencioso, pois existem várias árvores e cada árvore é treinada em um subconjunto aleatório de dados. Basicamente, o algoritmo da floresta aleatória depende do poder da “multidão”; portanto, o grau geral de viés do algoritmo é reduzido.
  2. Este algoritmo é muito estável. Mesmo que um novo ponto de dados seja introduzido no conjunto de dados, o algoritmo geral não é muito afetado, pois novos dados podem afetar uma árvore, mas é muito difícil impactar todas as árvores.
  3. O algoritmo de floresta aleatória funciona bem quando você tem recursos categóricos e numéricos.
  4. O algoritmo de floresta aleatória também funciona bem quando os dados têm valores ausentes ou não foram dimensionados.

Desvantagens de usar Random Forest

  1. A principal desvantagem das florestas aleatórias está em sua complexidade. Eles exigem muito mais recursos computacionais, devido ao grande número de árvores de decisão reunidas, ao treinar grandes ensembles. Embora - com hardware moderno, treinar até mesmo uma grande floresta aleatória não leva muito tempo.

Indo além - Projeto portátil de ponta a ponta

Sua natureza curiosa faz você querer ir mais longe? Recomendamos verificar nosso Projeto Guiado: “Previsão de preço de casa prática – Aprendizado de máquina em Python”.

Guia definitivo para o algoritmo Random Forest com Python e Scikit-Learn PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Neste projeto guiado, você aprenderá a construir modelos tradicionais poderosos de aprendizado de máquina, bem como modelos de aprendizado profundo, utilizar o Ensemble Learning e treinar meta-aprendizes para prever preços de imóveis a partir de uma série de modelos Scikit-Learn e Keras.

Usando Keras, a API de aprendizado profundo criada com base no Tensorflow, vamos experimentar arquiteturas, construir um conjunto de modelos empilhados e treinar um meta-aprendiz rede neural (modelo de nível 1) para descobrir o preço de uma casa.

O aprendizado profundo é incrível – mas antes de recorrer a ele, é aconselhável tentar também resolver o problema com técnicas mais simples, como aprendizagem superficial algoritmos. Nosso desempenho de linha de base será baseado em um Regressão da Floresta Aleatória algoritmo. Além disso, exploraremos a criação de conjuntos de modelos por meio do Scikit-Learn por meio de técnicas como ensacamento e votação.

Este é um projeto de ponta a ponta e, como todos os projetos de Machine Learning, começaremos com – com Análise exploratória de dados, Seguido por Pré-processamento de dados e finalmente Edifício Raso e Modelos de aprendizado profundo para ajustar os dados que exploramos e limpamos anteriormente.

Carimbo de hora:

Mais de Abuso de pilha