Previsão do tempo de Natal-RN utilizando machine learning
A previsão do tempo é algo que esta relacionado ao nosso dia-a-dia. Por exemplo: se sabemos que vai chover, levamos o guarda-chuva quando saímos de casa. Além disso, se fossemos agricultores, saber quando irá chover influencia diretamente quando começaremos o nosso plantio, visto que as sementes precisam de água para germinar e isso pode evitar-nos alguns gastos.
Sabendo dessa influência do tempo no nosso dia-a-dia, esse artigo propõe apresentar um rápido estudo inicial sobre algoritmos de machine learning na previsão do tempo, por isso optamos por realizar a previsão do tempo apenas em Natal-RN.
Lembrando que é comum abordar esse problema usando modelos seriais, sendo que optamos por, primeiramente, usarmos modelos mais gerais de machine learning. Iremos criar modelos para problemas específicos e, por fim, ter um conjunto de modelos que possam trabalhar em conjunto na previsão do tempo.
Tempo e Clima
É comum as confundirem os termos tempo e clima, sendo que para o prosseguir desse artigo é interessante termos em mente o significado desses termos:
- Tempo: corresponde a situação de momento. Hoje pode chover, mas amanhã pode fazer sol, como em outro dia pode estar nublado, etc.
- Clima: corresponde ao conjunto de condições atmosféricas que predominam em uma determinada região. Por exemplo: a caatinga é caracterizada pelo clima quente e seco, podendo ocorrer chuvas.
Dados
Os dados foram coletados do portal do Instituto Nacional de Meteorologia (INMET), instituto do Ministério da Agricultura, Pecuária e Abastecimento (MAPA) responsável por prover informações meteorológicas. Foram coletados dados da seguinte estação:
- Estação: Natal-RN ;
- Código OMM: 82598;
- Categoria: estação convencional;
- Aberta em: 01/01/1911;
- Latitude: -5.837222º;
- Longitude: -35.207778º;
- Altitude: 47.68 metros.
Foram coletados os dados de 01/01/1961 até 09/10/19, sendo realizado 3 coletas de dados atmosféricos pela estação nos horários: 00:00, 12:00 e 18:00. As informações sobre o nosso dataset:
Podemos observar que há vários dados faltantes. A quantidade e porcentagem em cada coluna:
Podemos dividir essas colunas em 2 grupos:
- > 10% NaN: Precipitacao, TempMaxima, TempMinima, PressaoAtmMar, Insolação, Evaporacao Piche, Temp Comp Media, Umidade Relativa Media, Velocidade do Vento Media. (9 colunas)
- ≤ 10% NaN: Estacao, Data, Hora, TempBulboSeco, TempBulboUmido, UmidadeRelativa, PressaoAtmEstacao, DirecaoVento, VelocidadeVento, Nebulosidade. (10 colunas)
Modelos
Aqui apresentaremos os modelos criados e resultados obtidos em cada um. Será apresentados os modelos para previsão de:
- Velocidade do vento;
- Precipitação;
- Pressão;
- Umidade;
- Temperatura.
Velocidade do vento
Primeiro foi analisado a correlação das outras colunas sobre VelocidadeVento. Tomando como base a correlação e a quantidade de valores faltantes, decidiu-se usar as seguintes colunas (com suas respectivas correlações):
- UmidadeRelativa: -0.442596;
- DirecaoVento: 0.225644;
- TempBulboSeco: 0.313335;
- Hora: 0.330918.
Foi realizado o processo de EDA (Exploratory Data Analysis), destacando o processo sobre a coluna DirecaoVento, pois trata-se de uma coluna categórica, visto que cada valor do tipo float
nela representa uma direção que o vento pode seguir, esses valores estão presentes clicando aqui.
Na divisão dos conjuntos de dados para o treinamento, validação e teste, dividiu-se:
- Treino e validação: 80% dos dados totais;
- Teste: 20% dos dados totais.
Para a previsão da velocidade do vento, foram criados 3 modelos: um de regressão linear, outro de regressão por KNN e outro de XGBoost. Os resultados foram:
- Regressão Linear: obteve MSE de ~3.4;
- Regressão por KNN: obteve MSE de ~3.68;
- XGBoost: obteve MSE de ~2.87.
Por mais que o XGBoost tenha obtido omelhor resultado, ainda é um valor muito alto de MSE para essa variável.
Nota: infelizmente algumas colunas com alta correlação foram desconsideradas por possuir mais de 10% de valores faltantes, no caso: Evaporação Piche possui 0.514841 de correlação e Velocidade do Vento Media possui 0.547886 de correlação, sendo que faltam, respectivamente, ~67.87% e ~67.09 dos dados.
Precipitação
Primeiro criou-se 5 novas colunas a partir da coluna Data:
- Day: dia do registro;
- Month: mês do registro;
- Year: ano do registro;
- Week: semana do registro;
- DayOfWeek: dia de semana do registro.
Após isso, converteu-se a coluna Precipitacao de uma variável contínua para uma categórica: true
(caso tenha tido precipitação) ou false
(caso não tenha tido precipitação). Em seguida, explorou-se a correlação das outras variáveis sobre ela. Tomando como base a correlação, decidiu-se usar as seguintes colunas (com suas respectivas correlações):
- TempBulboSeco: -0.433996;
- VelocidadeVento: -0.223792;
- TempMinima: -0.199019;
- Month: -0.099470;
- Week: -0.098879;
- TempBulboUmido: -0.028171;
- DayOfWeek: 0.001953;
- Day: 0.005201;
- PressaoAtmEstacao: 0.035965;
- Year: 0.067590;
- DirecaoVento: 0.112756;
- Nebulosidade: 0.310884;
- UmidadeRelativa: 0.533668.
Na divisão dos conjuntos de dados para o treinamento, validação e teste, dividiu-se:
- Treino e validação: 70% dos dados totais;
- Teste: 30% dos dados totais.
Para a previsão de precipitação, criou-se dois modelos usando XGBoost: XGBClassifier e RandomForestClassifier. O melhor resultado foi:
Best: 0.7649 using {
'clf': XGBClassifier(
base_score=0.5,
booster='gbtree',
colsample_bylevel=1,
colsample_bynode=1,
colsample_bytree=1,
gamma=0,
learning_rate=0.3,
max_delta_step=0,
max_depth=2,
min_child_weight=1,
missing=None,
n_estimators=200,
n_jobs=-1,
nthread=None,
nthread =-1,
objective='binary:logistic',
random_state=0,
reg_alpha=0,
reg_lambda=1,
scale_pos_weight=1,
seed=None,
silent=None,
subsample=1,
verbosity=1
),
'clf__learning_rate': 0.3,
'clf__max_depth': 2,
'clf__n_estimators': 200,
'clf__n_jobs': -1,
'clf__nthread ': -1,
'clf__objective': 'binary:logistic',
'clf__verbosity': 1
}Accuracy
0.7640172520024646
Para o XGBClassifier a feature mais impactante de longe foi a Umidade relativa com ~0.52, seguida pela Nebulosidade com ~0.1. A Random Forest teve um resultado diferente, onde a Umidade relativa pontuava 0.2 em media e em seguida TempBulboSeco com 0.1.
Na média das importâncias, temos a UmidadeRelativa com 0.53, seguido por TempBulboSeco com 0.21. Uma diferença bem grande no valor da importância entre as features.
Segundo a correlação obtida no inicio, a Umidade realmente deveria ser uma boa feature, assim como a TempBulboSeco com sua correlação negativa.
Pressão
Primeiro criou-se 5 novas colunas a partir da coluna Data:
- Day: dia do registro;
- Month: mês do registro;
- Year: ano do registro;
- Week: semana do registro;
- DayOfWeek: dia de semana do registro.
Após isso, verificou-se a correlação das variáveis sobre PressaoAtmEstacao. Tomando como base a correlação e a quantidade de valores faltantes, decidiu-se usar as seguintes colunas (com suas respectivas correlações):
- TempMaxima: -0.514731;
- TempBulboUmido: -0.460017;
- TempBulboSeco: -0.399891;
- Temp Comp Media: -0.342477;
- TempMinima: -0.216913;
- Umidade Relativa Media: -0.168751;
- Nebulosidade: -0.082016;
- Insolação: -0.010053;
- Velocidade do Vento Media: -0.004262;
- Evaporacao Piche: 0.002001;
- Precipitacao: 0.033079;
- UmidadeRelativa: 0.047514.
- VelocidadeVento: 0.151287;
- DirecaoVento: 0.182315;
- PressaoAtmMar: 0.963394.
Na divisão dos conjuntos de dados para o treinamento, validação e teste, dividiu-se:
- Treino e validação: 70% dos dados totais;
- Teste: 30% dos dados totais.
Para a previsão de pressão, criou-se dois modelos usando XGBoost: XGBRegressor e RandomForestRegressor. O melhor resultado foi:
Best: 0.6734 using {
'clf': XGBRegressor(
base_score=0.5,
booster='gbtree',
colsample_bylevel=1,
colsample_bynode=1,
colsample_bytree=1,
gamma=0,
importance_type='gain',
learning_rate=0.25,
max_delta_step=0,
max_depth=6,
min_child_weight=1,
missing=None,
n_estimators=200,
n_jobs=-1,
nthread=None,
nthread =-1,
objective='reg:squarederror',
random_state=0,
reg_alpha=0,
reg_lambda=1,
scale_pos_weight=1,
seed=None,
silent=None,
subsample=1,
verbosity=1
),
'clf__learning_rate': 0.25,
'clf__max_depth': 6,
'clf__n_estimators': 200,
'clf__n_jobs': -1,
'clf__nthread ': -1,
'clf__objective':
'reg:squarederror',
'clf__verbosity': 1
}MSE
2.473312797831465
R2
0.6737104685942408
Para o XGBoost a feature mais impactante de longe foi a PressaoAtmMar com 0.26, seguida pelo VelocidadeVento e TempBulboUmido, com 0.08 e 0.077 de importância respectivamente.
A Random Forest teve um resultado diferente, com o PressaoAtmMar pontuando 0.2 seguido pela TempBulboUmido também com 0.2, aproximadamente, e TempBulboSeco em terceiro lugar com 0.11.
Lembrando da correlação obtida no inicio, podemos ver que a PressaoAtmMar realmente era uma boa feature, enquanto a temperatura máxima nem tanto, ficando com uma importância relevante, porém ainda não tanto quanto era esperado.
Umidade
Primeiro criou-se 5 novas colunas a partir da coluna Data:
- Day: dia do registro;
- Month: mês do registro;
- Year: ano do registro;
- Week: semana do registro;
- DayOfWeek: dia de semana do registro.
Após isso, explorou-se a correlação das outras variáveis sobre a coluna UmidadeRelativa. Tomando como base a correlação, decidiu-se usar as seguintes colunas (com suas respectivas correlações):
- TempBulboSeco: -0.658902;
- Hora: -0.430898;
- VelocidadeVento: -0.427727;
- Nebulosidade: 0.208243.
Na divisão dos conjuntos de dados para o treinamento, validação e teste, dividiu-se:
- Treino e validação: 70% dos dados totais;
- Teste: 30% dos dados totais.
Para a previsão de umidade, criou-se dois modelos usando XGBoost: XGBRegressor e RandomForestRegressor. O melhor resultado foi:
Best: 0.7910 using {
'clf': XGBRegressor(
base_score=0.5,
booster='gbtree',
colsample_bylevel=1,
colsample_bynode=1,
colsample_bytree=1,
gamma=0,
importance_type='gain',
learning_rate=0.2,
max_delta_step=0,
max_depth=8,
min_child_weight=1,
missing=None,
n_estimators=100,
n_jobs=-1,
nthread=None,
nthread =-1,
objective='reg:linear',
random_state=0,
reg_alpha=0,
reg_lambda=1,
scale_pos_weight=1,
seed=None,
silent=None,
subsample=1,
verbosity=1
),
'clf__learning_rate': 0.2,
'clf__max_depth': 8,
'clf__n_estimators': 100,
'clf__n_jobs': -1,
'clf__nthread ': -1,
'clf__verbosity': 1
}MSE
15.004844196842544
R2
0.7853850716993197
Temperatura mínima
Primeiro criou-se 5 novas colunas a partir da coluna Data:
- Day: dia do registro;
- Month: mês do registro;
- Year: ano do registro;
- Week: semana do registro;
- DayOfWeek: dia de semana do registro.
Após isso, explorou-se a correlação das outras variáveis sobre a coluna TempMinima. Tomando como base a correlação, decidiu-se usar as seguintes colunas (com suas respectivas correlações):
- PressaoAtmMar: -0.494567;
- DirecaoVento: -0.230771;
- UmidadeRelativa: -0.228789;
- PressaoAtmEstacao: -0.216913;
- TempBulboUmido: 0.450186;
- TempBulboSeco: 0.547944.
Na divisão dos conjuntos de dados para o treinamento, validação e teste, dividiu-se:
- Treino e validação: 70% dos dados totais;
- Teste: 30% dos dados totais.
Para a previsão de umidade, criou-se dois modelos usando XGBoost: XGBRegressor e RandomForestRegressor. O melhor resultado foi:
Best: 0.7464 using {
'clf': XGBRegressor(
base_score=0.5,
booster='gbtree',
colsample_bylevel=1,
colsample_bynode=1,
colsample_bytree=1,
gamma=0,
importance_type='gain',
learning_rate=0.2,
max_delta_step=0,
max_depth=6,
min_child_weight=1,
missing=None,
n_estimators=100,
n_jobs=-1,
nthread=None,
nthread =-1,
objective='reg:linear',
random_state=0,
reg_alpha=0,
reg_lambda=1,
scale_pos_weight=1,
seed=None,
silent=None,
subsample=1,
verbosity=1
),
'clf__learning_rate': 0.2,
'clf__max_depth': 6,
'clf__n_estimators': 100,
'clf__n_jobs': -1,
'clf__nthread ': -1,
'clf__verbosity': 1
}MSE
1.0841623072454543
R2
0.7491426293605026
Temperatura máxima
Primeiro criou-se 5 novas colunas a partir da coluna Data:
- Day: dia do registro;
- Month: mês do registro;
- Year: ano do registro;
- Week: semana do registro;
- DayOfWeek: dia de semana do registro.
Após isso, explorou-se a correlação das outras variáveis sobre a coluna TempMaxima. Tomando como base a correlação, decidiu-se usar as seguintes colunas (com suas respectivas correlações):
- PressaoAtmEstacao: -0.514731;
- Umidade Relativa Media: -0.326146;
- Evaporacao Piche: 0.257788;
- Insolação: 0.463361;
- TempBulboUmido: 0.511474;
- TempBulboSeco: 0.551195;
- Temp Comp Media: 0.802392.
Na divisão dos conjuntos de dados para o treinamento, validação e teste, dividiu-se:
- Treino e validação: 70% dos dados totais;
- Teste: 30% dos dados totais.
Para a previsão de umidade, criou-se dois modelos usando XGBoost: XGBRegressor e RandomForestRegressor. O melhor resultado foi:
Best: 0.8072 using {
'clf': RandomForestRegressor(
bootstrap=True,
criterion='mse',
max_depth=20,
max_features=0.5,
max_leaf_nodes=None,
min_impurity_decrease=0.0,
min_impurity_split=None,
min_samples_leaf=1,
min_samples_split=2,
min_weight_fraction_leaf=0.0,
n_estimators=100,
n_jobs=-1,
oob_score=False,
random_state=None,
verbose=0,
warm_start=False
),
'clf__bootstrap': True,
'clf__max_depth': 20,
'clf__max_features': 0.5,
'clf__n_estimators': 100,
'clf__n_jobs': -1
}MSE
0.30730927799894037
R2
0.8001812550776142
Conclusão
Após analisarmos os resultados, concluímos que os modelos não possuíram o desempenho desejado, independente da técnicas ser simples, como regressão linear, ou mais complexa, como XGBoost.
Trabalhos futuros
O uso de modelos seriais é bastante utilizado na previsão do tempo. Como esse trabalho usou apenas modelos mais gerais, seria interessante aplicar os modelos seriais nos mesmos dados e realizar um comparativo de eficiência entre os grupos de modelos. Um exemplo de modelo de série bom de ser usar seria usando cadeia de Markov.
Esse artigo foi escrito para a disciplina de Aprendizado de Máquina, no curso de Bacharelado em Tecnologia da Informação (BTI) da Universidade Federal do Rio Grande do Norte (UFRN), possuindo Ivanovitch Silva como professor. Grupo: