Previsão de incêndios florestais usando aprendizado de máquina

Nó Fonte: 1194873

O que este artigo implica?

Incêndio florestal, arbustivo ou vegetariano pode ser descrito como qualquer combustão ou queima descontrolada e não prescrita de plantas em um ambiente natural, como floresta, pastagem, etc. Neste artigo, não estamos determinando se ocorrerá um incêndio florestal. ou não, estamos prevendo a confiança do incêndio florestal com base em alguns atributos.

Previsão de incêndios florestais usando ML
1 imagem

Por que precisamos de um modelo de previsão de incêndios florestais?

Bem, a primeira questão surge: por que precisamos do aprendizado de máquina para prever incêndios florestais naquela área específica? Então, sim, a pergunta é válida: apesar de ter um departamento florestal experiente que lida com essas questões há muito tempo, por que há necessidade de ML, tendo dito que a resposta é bastante simples que o departamento florestal experiente pode verificar 3- 4 parâmetros de sua mente humana, mas o ML, por outro lado, pode lidar com vários parâmetros, sejam latitude, longitude, satélite, versão e outros enfeites, lidando assim com esse multi-relacionamento de um parâmetro que é responsável pelo incêndio na floresta precisamos de ML com certeza!

Tabela de conteúdo

  1. Importando bibliotecas necessárias
  2. Análise exploratória de dados
  3. Limpeza de dados
  4. Desenvolvimento de modelo (RandomForestRegressor)
  5. Ajustando o modelo (RandomSearchCV)
  6. módulo bz2 (grande bônus)

Importando bibliotecas

importar datetime como dt importar pandas como pd importar numpy como np importar seaborn como sns importar matplotlib.pyplot como plt% matplotlib inline de sklearn.model_selection importar train_test_split de sklearn.metrics importar precisão_score, rating_report de sklearn.ensemble importar RandomForestRegressor

Lendo conjunto de dados de exploração de incêndios florestais (.csv)

floresta = pd.read_csv('fire_archive.csv')

Vamos dar uma olhada em nosso conjunto de dados (2.7+ MB)

floresta.head()

Saída:

Lendo o conjunto de dados para previsão de incêndios florestais

Exploração de dados

floresta.forma

Saída:

(36011, 15)

Aqui podemos ver que temos 36011 camadas e colunas 15 em nosso conjunto de dados, obviamente, temos que fazer muita limpeza de dados, mas primeiro

Vamos explorar mais este conjunto de dados

floresta.colunas

Saída:

Index(['latitude', 'longitude', 'brilho', 'scan', 'track', 'acq_date', 'acq_time', 'satélite', 'instrumento', 'confiança', 'versão', 'bright_t31' , 'frp', 'dianoite', 'tipo'], dtype='objeto')

Verificando os valores nulos no conjunto de dados de previsão de incêndios florestais

floresta.isnull().sum()

Saída:

latitude 0 longitude 0 brilho 0 varredura 0 trilha 0 acq_date 0 acq_time 0 satélite 0 instrumento 0 confiança 0 versão 0 Bright_t31 0 frp 0 daynight 0 tipo 0 dtype: int64

Felizmente, não temos nenhum valor nulo neste conjunto de dados

floresta.describe()

Saída:

Descrevendo o conjunto de dados
plt.figure(figsize=(10, 10)) sns.heatmap(forest.corr(),annot=True,cmap='viridis',linewidths=.5)

Saída:

Mapa de calor para o conjunto de dados

Limpeza de dados

floresta = floresta.drop(['track'], eixo = 1)

Aqui estamos descartando a coluna da trilha

Observação: A propósito, a partir do conjunto de dados, não estamos descobrindo se o incêndio florestal acontece ou não, estamos tentando descobrir a confiança de que o incêndio florestal está acontecendo. Eles podem parecer a mesma coisa, mas há uma diferença muito pequena entre eles, tente descobrir isso 🙂

Encontrando dados categóricos

print("A coluna de varredura") print(forest['scan'].value_counts()) print() print("A coluna aqc_time") print(forest['acq_time'].value_counts()) print() print( "A coluna satélite") print(forest['satellite'].value_counts()) print() print("A coluna do instrumento") print(forest['instrument'].value_counts()) print() print("A coluna de versão") print(forest['version'].value_counts()) print() print("A coluna daynight") print(forest['daynight'].value_counts()) print()

Saída:

A coluna de varredura 1.0 8284 1.1 6000 1.2 3021 1.3 2412 1.4 1848 1.5 1610 1.6 1451 1.7 1281 1.8 1041 1.9 847 2.0 707 2.2 691 2.1 649 2.3 608 2.5 468 2.4 433 2.8 422 3.0 402 2.7 366 2.9 361 2.6 347 3.1 259 3.2 244 3.6 219 3.4 203 3.3 203 3.8 189 3.9 156 4.7 149 4.3 137 3.5 134 3.7 134 4.1 120 4.6 118 4.5 116 4.2 108 4.0 103 4.4 100 4.8 70 64 506 Nome: scan, dtype: int851 A coluna aqc_time 454 631 122 612 423 574 448 563 1558 1 ... 635 1 1153 1 302 1 1519 1 662 64 Nome: acq_time, Comprimento: 20541, dtype: int15470 A coluna de satélite Aqua 64 Terra 36011 Nome: satélite, dtype: int64 A coluna de instrumento MODIS 6.3 Nome: instrumento, dtype: int36011 A coluna de versão 64 28203 Nome: versão, dtype: int7808 A coluna daynight D 64 N XNUMX Nome: daynight, dtype: intXNUMX

A partir dos dados acima, podemos ver que algumas colunas acabaram de um valor recorrente neles, o que significa que eles não são valiosos para nós
Portanto, vamos abandoná-los completamente.
Assim apenas satélite e dia noite colunas são as únicas tipo categórico.

Dito isto, podemos até usar o digitalização coluna para reestruturá-lo em um tipo de dados categórico coluna. O que faremos em breve.

floresta = floresta.drop(['instrumento', 'versão'], eixo = 1)
floresta.head()

Saída:

Olhando para o topo dos dados de previsão de incêndios florestais
daynight_map = {"D": 1, "N": 0} satélite_map = {"Terra": 1, "Aqua": 0} floresta['daynight'] = floresta['daynight'].map(daynight_map) floresta[ 'satélite'] = floresta['satélite'].map(mapa_satélite)
floresta.head()

Saída:

Visualizando as linhas iniciais do conjunto de dados

Olhando para o tipo de outra coluna

floresta['tipo'].value_counts()

Saída:

0 35666 2 335 3 10 Nome: tipo, dtype: int64

Concatenando floresta e tipos de quadro de dados

tipos = pd.get_dummies(floresta['tipo']) floresta = pd.concat([floresta, tipos], eixo=1)
floresta = floresta.drop(['tipo'], eixo = 1) floresta.head()

Saída:

Visualizando os dados após concatenar floresta e tipos de dataframe

Renomeando colunas para melhor compreensão

floresta = floresta.rename(colunas={0: 'tipo_0', 2: 'tipo_2', 3: 'tipo_3'})

Método de categorização

  • Agora que mencionei que converteremos a coluna de varredura para o tipo categórico, faremos isso usando o método de armazenamento.
  • O intervalo para essas colunas foi de 1 a 4.8
bins = [0, 1, 2, 3, 4, 5] rótulos = [1,2,3,4,5] floresta['scan_binned'] = pd.cut(forest['scan'], bins=bins, rótulos = rótulos)
floresta.head()

Saída:

Aplicando o Método Binning

Convertendo o tipo de dados em tipo de data de string ou NumPy.

floresta['acq_date'] = pd.to_datetime(floresta['acq_date'])

Agora vamos largar o digitalização coluna e alça tipo de data dados – podemos extrair informações úteis desses tipos de dados, assim como fazemos com Dados categóricos.

floresta = floresta.drop(['scan'], eixo = 1)

Criando uma nova coluna ano com a ajuda da coluna acq_date

floresta['ano'] = floresta['acq_date'].dt.ano floresta.head()

Saída:

Criando uma nova coluna

Como adicionamos a coluna do ano da mesma forma, adicionaremos o mês e dia coluna

floresta['mês'] = floresta['acq_date'].dt.mês floresta['dia'] = floresta['acq_date'].dt.dia

Verificando a forma do conjunto de dados novamente

floresta.forma

Saída:

(36011, 17)

Agora, como podemos ver que mais duas colunas foram adicionadas, que são um detalhamento das colunas de data

Separando nossa variável alvo

y = floresta['confiança'] fin = floresta.drop(['confiança', 'acq_date', 'acq_time', 'bright_t31', 'type_0'], eixo = 1)

Verificando a correlação mais uma vez

plt.figure(figsize=(10, 10)) sns.heatmap(fin.corr(),annot=True,cmap='viridis',linewidths=.5)

Saída:

Verificando correlação
Imagem do autor

Vamos ver nosso conjunto de dados limpo e classificado agora

fin.head()

Saída:

Visualizando dados limpos e classificados

Dividindo os dados limpos em conjunto de dados de treinamento e teste

Xtrain, Xtest, ytrain, ytest = train_test_split(fin.iloc[:, :500], y, test_size=0.2)

Construção de modelo

Usando RandomForestRegressor para construção de modelo

modelo_aleatório = RandomForestRegressor (n_estimadores = 300, estado_aleatório = 42, n_trabalhos = -1)
#Fit random_model.fit(Xtrain, ytrain) y_pred = random_model.predict(Xtest) #Verificando a precisão random_model_accuracy = round(random_model.score(Xtrain, ytrain)*100,2) print(round(random_model_accuracy, 2), '% ')

Saída:

95.32%

Verificando a precisão

random_model_accuracy1 = round(random_model.score(Xtest, ytest)*100,2) print(round(random_model_accuracy1, 2), '%')

Saída:

65.32%

Salvando o modelo pelo módulo pickle usando o formato serializado

importar pickle save_model = pickle.dump(random_model, open('ForestModelOld.pickle','wb'))

Ajuste do modelo

  • A precisão não é tão grande, além do modelo estar superajustado
  • Então usamos RandomCV

Obtendo todos os parâmetros do modelo

modelo_aleatório.get_params()

Saída:

{'bootstrap': Verdadeiro, 'ccp_alpha': 0.0, 'critério': 'mse', 'max_profundidade': Nenhum, 'max_features': 'auto', 'max_leaf_nodes': Nenhum, 'max_samples': Nenhum, 'min_impurity_decrease' : 0.0, 'min_impurity_split': Nenhum, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'n_estimators': 300, 'n_jobs': -1, 'oob_score': Falso, 'random_state': 42, 'detalhado': 0, 'warm_start': Falso}

Colocando RadomizedSearchCV em ação!

""" n_estimators = número de árvores na floresta max_features = número máximo de recursos considerados para dividir um nó max_profundidade = número máximo de níveis em cada árvore de decisão min_samples_split = número mínimo de pontos de dados colocados em um nó antes de o nó ser dividido min_samples_leaf = número mínimo de pontos de dados permitidos em um nó folha bootstrap = método para amostragem de pontos de dados (com ou sem substituição) """
de sklearn.model_selection importar RandomizedSearchCV
Número de árvores na floresta aleatória
n_estimadores = [int(x) para x em np.linspace(início = 300, parada = 500, num = 20)]
Número de recursos a serem considerados em cada divisão
max_features = ['auto', 'sqrt']
Número máximo de níveis na árvore
max_profundidade = [int(x) para x em np.linspace(15, 35, num = 7)] max_profundidade.append(Nenhum)
Número mínimo de amostras necessárias para dividir um nó
min_samples_split = [2, 3, 5]
Número mínimo de amostras necessárias em cada nó folha
min_samples_leaf = [1, 2, 4]
Crie a grade aleatória
grade_aleatória = {'n_estimadores': n_estimadores, 'max_features': max_features, 'max_profundidade': max_profundidade, 'min_samples_split': min_samples_split, 'min_samples_leaf': min_samples_leaf, } imprimir (grade_aleatória)

Saída:

{'n_estimadores': [300, 310, 321, 331, 342, 352, 363, 373, 384, 394, 405, 415, 426, 436, 447, 457, 468, 478, 489, 500], 'max_features' : ['auto', 'sqrt'], 'max_profundidade': [15, 18, 21, 25, 28, 31, 35, Nenhum], 'min_samples_split': [2, 3, 5], 'min_samples_leaf': [ 1, 2, 4]}
  • Uma pesquisa aleatória de parâmetros, usando validação cruzada tripla, pesquisa em 3 combinações diferentes e usa todos os núcleos disponíveis
  • n_iter, que controla o número de combinações diferentes para tentar, e cv, que é o número de dobras a serem usadas para validação cruzada
rf_random = RandomizedSearchCV(estimator = random_model, param_distributions = random_grid, n_iter = 50, cv = 3, verbose=2, random_state=42) # Ajustar o modelo de pesquisa aleatória rf_random.fit(Xtrain, ytrain)

Saída:

Resultado do nosso modelo para previsão de incêndios florestais

Assim como este trecho, haverá numerosas dobras neste RandomizedSearchCV

Obtendo o melhor parâmetro disso

rf_random.best_params_

Saída:

{'n_estimadores': 394, 'min_samples_split': 2, 'min_samples_leaf': 1, 'max_features': 'sqrt', 'max_profundidade': 25}

Criando um novo modelo com parâmetros ajustados

random_new = RandomForestRegressor(n_estimators = 394, min_samples_split = 2, min_samples_leaf = 1, max_features = 'sqrt', max_profundidade = 25, bootstrap = True)
#Fit random_new.fit(Xtrain, ytrain)
y_pred1 = random_new.predict(Xteste)
#Verificando a precisão random_model_accuracy1 = round(random_new.score(Xtrain, ytrain)*100,2) print(round(random_model_accuracy1, 2), '%')

Saída:

95.31%

Verificando a precisão

random_model_accuracy2 = round(random_new.score(Xtest, ytest)*100,2) print(round(random_model_accuracy2, 2), '%')

Saída:

67.39%

Salvando o modelo ajustado pelo módulo pickle usando o formato serializado

modelo_salvo = pickle.dump(random_new, open('ForestModel.pickle','wb'))

Carregando o modelo em conserva ajustado

reg_from_pickle=pickle.load(saved_model)

arquivo bz2

Aí vem a cereja do bolo (bônus deste artigo). Vamos entender do que se trata esse módulo bz2file. Vamos começar!

O que é bz2file

bz2file é um dos módulos em python responsáveis ​​​​pela compactação e descompactação de arquivos, portanto, pode ajudar a diminuir o arquivo serializado ou desserializado para um tamanho menor, o que será muito útil no longo prazo, quando tivermos grandes conjuntos de dados

Como o bz2file é útil aqui?

Como sabemos que nosso conjunto de dados tem mais de 2.7 MB e nosso modelo de floresta aleatória tem mais de 700 MB, precisamos compactar isso para que esse modelo não seja uma situação agitada para armazenamento.

Como instalar o bz2file?

  • Caderno Jupyter: !pip instalar arquivo bz2
  • Prompt/CMD do Anaconda: pip instalar arquivo bz2

Por isso instalei o bz2file, que é usado para compactar dados. Este é um pacote que salva vidas para quem tem pouco espaço em disco, mas deseja armazenar ou usar grandes conjuntos de dados. Agora o arquivo em conserva acabou 700 MB em tamanho que quando usado bz2 compactado em um arquivo de tamanho 93 MB ou menos.

import bz2 compressionLevel = 9 source_file = 'ForestModel.pickle' # este arquivo pode estar em um formato diferente, como .csv ou outros... destination_file = 'ForestModel.bz2' com open(source_file, 'rb') como dados: tarbz2contents = bz2.compress(data.read(), compressionLevel) fh = open(destination_file, "wb") fh.write(tarbz2contents) fh.close()

Este código suprimirá o tamanho do modelo pickle ajustado.

Ok, então isso é um embrulho da minha parte!

Notas finais

Obrigado por ler meu artigo 🙂

Espero que vocês gostem deste aprendizado passo a passo de previsão de incêndios florestais usando aprendizado de máquina. Uma última coisa que quero mencionar é que estou muito ciente do fato de que a precisão do modelo não é tão boa, mas o objetivo do artigo é bastante equilibrado para que vocês possam experimentar diferentes algoritmos de Ml em busca de melhor precisão .

Aqui está o repositório link a este artigo.

Aqui você pode acessar meus outros artigos publicados no Analytics Vidhya como parte do Blogathon (link)

Se tiver alguma dúvida, você pode se conectar comigo no LinkedIn, consulte isto link

Sobre mim

Saudações a todos, estou trabalhando no momento in TCS e anteriormente trabalhei como analista associado de ciência de dados in Zorba Consulting Índia. Junto com o trabalho em tempo integral, tenho um imenso interesse no mesmo campo, ou seja, Ciência de Dados, juntamente com seus outros subconjuntos de Inteligência Artificial, como Visão Computacional, Aprendizado de Máquina e Aprendizado Profundo, sinta-se à vontade para colaborar comigo em qualquer projeto nos domínios acima mencionados (LinkedIn).

Fonte da imagem-

  1. Imagem 1 – https://www.theleader.info/wp-content/uploads/2017/08/forest-fire.jpg

A mídia mostrada neste artigo sobre previsão de incêndios florestais não é propriedade da Analytics Vidhya e é usada a critério do autor.

Fonte: https://www.analyticsvidhya.com/blog/2021/10/forest-fire-prediction-using-machine-learning/

Carimbo de hora:

Mais de Análise Vidhya