[My IT : Codes] LSTM 활용 Air Pollution Forecast 데이터셋 예측(1) 데이터셋 소개 ~ 모델링

2026. 3. 25. 16:16·My IT/Codes

Air Pollution Forecasting

데이터셋 : Kaggle의 Air Pollution Forecasting - LSTM Multivariation

 

Air Pollution Forecasting - LSTM Multivariate

Lstm multivariate sample dataset for architecture design and orchestration

www.kaggle.com

 

목표 : LSTM을 활용해 pollution 수치 예측, 시계열 데이터 올바르게 전처리하기

 

!pip install torchmetrics
!pip install optuna
!pip install torchviz
import zipfile
import os
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder
import numpy as np
import optuna
from torchviz import make_dot

 

 

1.파일 압축해제/불러오기

zip_filename = 'air_pollution.zip'
extract_folder = './air_pollution'

os.makedirs(extract_folder, exist_ok=True)

with zipfile.ZipFile(zip_filename, 'r') as zipf:
    zipf.extractall(extract_folder)

 

 

2. 데이터 EDA

압축을 해제해보니, train 데이터와 test 데이터로 보이는 제목의 csv 문서가 2개 있어서 살펴보았다.

train_path = './air_pollution/LSTM-Multivariate_pollution.csv'
test_path = './air_pollution/pollution_test_data1.csv'
#train 데이터 살펴보기
train_df = pd.read_csv(train_path)
train_df.info()

 

 

train_df.head()

train_df.tail()

 

 

2010년 ~ 2014년의 데이터셋인 것을 확인했다.

 

Column 정보 :

 

- date : 날짜

- pollution : 오염 정도(타겟 column)

- dew : 이슬점(공기 중 수증기가 포화되어 응결되기 시작되는 온도)

- temp : 온도

- press : 기압

- wind_dir : 풍향

- wnd_spd : 풍속

- snow : 적설량

- rain : 강우량

 

 

이후 수치형 column(date, win_dir column 제외하고 모든 column)의 형태를 보기 위해 시각화를 진행했다.

 

train_df.hist(bins = 30, figsize = (20, 20))
plt.tight_layout()
plt.show()

 

 

 

EDA를 위해 copy 생성

train_df_eda = train_df.copy()

 

유일한 범주형 column인 wnd_dir column을 보았다.

 

train_df_eda['wnd_dir'].value_counts()

-> CV는 SW방향이라고 판단

 

이후 object 타입의 date column을 시간을 나타내는 datetime type으로 바꿔주어, 시계열 데이터의 형태를 띄도록 했다.

train_df_eda['date'] = pd.to_datetime(train_df_eda['date'], format = '%Y-%m-%d %H:%M:%S')
train_df_eda.sort_values(by = 'date', inplace = True)

 

#시간에 따른 pollution 시각화
df_2010 = train_df_eda[train_df_eda['date'].dt.year == 2010]

plt.figure(figsize = (20, 10))
plt.plot(df_2010['date'], df_2010['pollution'])
plt.xlabel('date')
plt.ylabel('Pollution')
plt.title('Pollution Over Time(2010)')
plt.show()

 

train 데이터만 살펴보았을 때는 여름과 겨울의 pollution 수치가 달라지는 것을 관찰할 수 있어서 계절에 해당하는 column을 추가하려 했지만 test 데이터의 column을 보고 결정하기로 했다.

 

#test 데이터 info
test_df = pd.read_csv(test_path)
test_df.info()

 

test 데이터에는 date데이터가 없어서 test 데이터셋에서는 계절 특성 추출이 불가능하였고, 따라서 특성 일치를 위해서 추가하지 않기로 판단했다.

 

 

 

3. 데이터셋 구축 / 데이터로더 정의

- train 데이터와 validation 데이터의 경우에는 랜덤으로 나누지 않고, 2014년의 데이터를 validation 데이터로 활용하고 2014년 이전의 데이터를 train 데이터로 활용했다.

 

- train/val 데이터셋과 test 데이터셋의 클래스를 따로 정의하여 가독성과 유지보수성을 높였다. 

 

Train/Val Dataset

#Train, Validation 데이터셋 구축
class PollutionDataset_Train_Val(Dataset):
  def __init__(self, csv_path, seq_len, mode = 'train', seq_x_scaler = None, encoder = None, y_scaler = None) :
    self.seq_len = seq_len

    df = pd.read_csv(csv_path)
    #dateTime 타입으로 변경 후 sort
    df['date'] = pd.to_datetime(df['date'], format = '%Y-%m-%d %H:%M:%S')
    df.sort_values(by = 'date', inplace = True)

    seq_x = ['dew', 'temp', 'press', 'wnd_spd', 'snow', 'rain']
    cate_x = ['wnd_dir']
    target = ['pollution']


    if mode == 'train': #Train Dataset
        df_subset = df[df['date'].dt.year < 2014]
    else: #Validation Dataset
        df_subset = df[df['date'].dt.year >= 2014]

    if mode == 'train' :  #Train Dataset
      self.seq_x_scaler = StandardScaler()
      self.encoder = OneHotEncoder(sparse_output = False)
      self.y_scaler = StandardScaler()

      self.seq_x = self.seq_x_scaler.fit_transform(df_subset[seq_x])
      self.cate_x = self.encoder.fit_transform(df_subset[cate_x])

      self.X = np.concatenate([self.seq_x, self.cate_x], axis = 1)

      self.Y = self.y_scaler.fit_transform(df_subset[target])

    else :  #Validation Dataset
      self.seq_x_scaler = seq_x_scaler
      self.encoder = encoder
      self.y_scaler = y_scaler

      self.seq_x = self.seq_x_scaler.transform(df_subset[seq_x])
      self.cate_x = self.encoder.transform(df_subset[cate_x])

      self.X = np.concatenate([self.seq_x, self.cate_x], axis = 1)

      self.Y = self.y_scaler.transform(df_subset[target])


  def __len__(self) :	#슬라이싱 위해 len - seq_len
    return len(self.X) - self.seq_len

  def __getitem__(self, idx) :	#윈도우 슬라이싱
    x = self.X[idx : idx + self.seq_len]
    y = self.Y[idx + self.seq_len]

    return torch.tensor(x, dtype = torch.float32), torch.tensor(y, dtype = torch.float32)

 

Test Dataset

#Test Dataset 구축
class PollutionDataset_Test(Dataset):
  def __init__(self, csv_path, seq_len, seq_x_scaler, encoder, y_scaler) :
    self.seq_len = seq_len

    df = pd.read_csv(csv_path)
   #Date Column이 없으므로 처리 불필요

    seq_x = ['dew', 'temp', 'press', 'wnd_spd', 'snow', 'rain']
    cate_x = ['wnd_dir']
    target = ['pollution']

    self.seq_x_scaler = seq_x_scaler
    self.encoder = encoder
    self.y_scaler = y_scaler

    self.seq_x = self.seq_x_scaler.transform(df[seq_x])
    self.cate_x = self.encoder.transform(df[cate_x])

    self.X = np.concatenate([self.seq_x, self.cate_x], axis = 1)

    self.Y = self.y_scaler.transform(df[target])

  def __len__(self) :
    return len(self.X) - self.seq_len

  def __getitem__(self, idx) :
    x = self.X[idx : idx + self.seq_len]
    y = self.Y[idx + self.seq_len]
    return torch.tensor(x, dtype = torch.float32), torch.tensor(y, dtype = torch.float32)

 

 

Train Dataset / Validation Dataset 가져오기

#1시간마다 기록되어있으므로, 일주일을 하나의 seq로 잡음(24 * 7)
seq_len = 168

train_ds = PollutionDataset_Train_Val(train_path, seq_len)

val_ds = PollutionDataset_Train_Val(train_path, seq_len, mode = 'val',
                                    seq_x_scaler = train_ds.seq_x_scaler,
                                    encoder = train_ds.encoder,
                                    y_scaler = train_ds.y_scaler)

 

Train Dataset / Validation Dataset 데이터로더 생성

#DataLodaer 생성
train_loader = DataLoader(train_ds, batch_size = 128, shuffle = True)
val_loader = DataLoader(val_ds, batch_size = 128, shuffle = False)

#배치의 shape 확인 -> [Batch, seq_len, features]
input_x, target_y = next(iter(train_loader))
print(f"Batch X Shape: {input_x.shape}")
print(f"Batch Y Shape: {target_y.shape}")

 

[배치 크기, seq_len, 특성 개수]로 잘 들어간 것을 확인할 수 있었다.

 

3. 모델링

예측은 LSTM모델을 사용했고, 이후 베이지안 튜닝을 위해서 파라미터들은 따로 상수로 정의하지 않고 변수로 정의해놓았다.

class LSTMModel(nn.Module) :
  def __init__(self, input_size, hidden_size, num_layers, dropout) :
    super(LSTMModel, self).__init__()

    #LSTM 레이어
    self.lstm = nn.LSTM(input_size, hidden_size,
                        num_layers = num_layers,
                        batch_first = True, dropout = dropout)
    #레이어정규화
    self.ln = nn.LayerNorm(hidden_size)

    #ReLU 활성화
    self.relu = nn.ReLU()

    #선형변환 수행(최종 출력)
    self.fc = nn.Linear(hidden_size, 1)

  def forward(self, x) :
    x, _ = self.lstm(x)

    #마지막 타입스템 선택
    x = x[:, -1, :]

    x = self.ln(x)
    x = self.relu(x)
    output = self.fc(x)

    return output

'My IT > Codes' 카테고리의 다른 글

[My IT : Codes] X-ray Image Dataset Classification(1) (시작~ 1차 테스트)  (0) 2026.04.01
[My IT : Codes] LSTM 활용 Air Pollution Forecast 데이터셋 예측(2) 하이퍼파라미터 튜닝 ~ 예측 시각화  (2) 2026.03.25
[My IT : Codes] AutoEncoder 활용 Denoising  (0) 2026.03.23
[My IT : Codes] Bank-Marketing 데이터 분석(2) (모델 비교 학습 ~ 결론 도출)  (1) 2026.03.09
[My IT : Codes]Bank-Marketing 데이터 분석(1) (데이터셋 설명 ~ 데이터 전처리)  (2) 2026.03.07
'My IT/Codes' 카테고리의 다른 글
  • [My IT : Codes] X-ray Image Dataset Classification(1) (시작~ 1차 테스트)
  • [My IT : Codes] LSTM 활용 Air Pollution Forecast 데이터셋 예측(2) 하이퍼파라미터 튜닝 ~ 예측 시각화
  • [My IT : Codes] AutoEncoder 활용 Denoising
  • [My IT : Codes] Bank-Marketing 데이터 분석(2) (모델 비교 학습 ~ 결론 도출)
uj07096
uj07096
개발블로그 시작 !
  • uj07096
    김재헌 님의 블로그
    uj07096
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • Algorithm
      • My IT
        • Article
        • Codes
      • TIL
      • My Projects N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    딥러닝
    python
    GAN
    데이터전처리
    til
    LeetCode
    프로그래머스
    LSTM
    EDA
    convolution
    DeepLearning
    Algorithm
    YOLO
    kaggle
    EfficientNet
    Tensor
    PyTorch
    코딩테스트
    AI
    autoencoder
    머신러닝
    Stack
    Faster R-CNN
    ResNet
    이상치
    DenseNet
    transfer learning
    파이썬
    optuna
    코테
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
uj07096
[My IT : Codes] LSTM 활용 Air Pollution Forecast 데이터셋 예측(1) 데이터셋 소개 ~ 모델링
상단으로

티스토리툴바