본문 바로가기

Data-science/deep learning

dacon - Rainnet기반 강수량 예측시 CSI, MAE 계산

728x90

CSI 계산법 예)

import numpy as np
true = np.array([0.2, 0.3, 0.4, 0.05, 0.03])
pred = np.array([0.05, 0.2, 0.3, 0.01, 0.5])
true_ok = true >= 0.1
pred_ok = pred >= 0.1
num_true_ok = np.sum(true_ok)
num_pred_ok = np.sum(pred_ok)
num_H = np.sum(true_ok & pred_ok)
num_total = np.sum(true_ok | pred_ok)
print(f'true_ok : {num_true_ok}, pred_ok : {num_pred_ok} ==== \ntrue_ok : {true_ok},\npred_ok : {pred_ok}')
print(f'Hits # : {num_H} ==== Hits : {true_ok & pred_ok}')
print(f'num_total # : {num_total} ==== Totals : {true_ok | pred_ok}')

from sklearn.metrics import mean_absolute_error

def cal_rain(pred):
    '''
        120x120 pixel (0~255사이의 uint 값 )
        이미지에서 강우량으로 변환
    '''
    pred = ((pred - 0.5) / 255.) * 70 - 10
    DBZ = np.reshape(pred, (-1, 14400))
    Z = pow(10.0, DBZ/10.0)
    R = pow(Z/200.0, 1.0/1.6)
    return R

def cal_mae(true, pred):
    '''
        keypoints에 해당하는 강우량 부분의 mae 계산
    '''
    pred = cal_rain(pred)
    keypoints = [6071, 6304, 7026, 7629, 7767, 8944, 11107]
    true = np.reshape(true, (-1, 14400))
    pred_key = pred[:, keypoints]
    true_key = true[:, keypoints]
    mae = mean_absolute_error(true_key, pred_key)
    return mae

def cal_csi(true, pred):
    '''
        120x120 pixel (0~255사이의 uint 값 )
        전체 이미지에서 강우량이 0.1 이상일 경우 비가온다고 예측 혹은 관찰 (TH = 0.1)
        CSI = 관찰&예측 성공한 픽셀 수 / 비가 온다고 관찰 혹은 예측한 전체 픽셀 수
    '''
    pred = cal_rain(pred)
    true = np.reshape(ture, (-1, 14400))
    forecast_rain = pred >= 0.1
    observed_rain = true >= 0.1
    hit_mask = forecast_rain & observed_rain
    total_mask = forecast_rain | observed_rain
    CSI = np.sum(hit_mask) / np.sum(total_mask)
    return CSI
mae = cal_mae(trues, preds)
csi = cal_csi(trues, preds)
lb = mae/csi
print(f'mae : {mae}, csi : {csi}, lb : {mae/csi}')