File size: 3,461 Bytes
0640b0e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import pandas as pd
import torch
import numpy as np
from modules.config import SEQ_LEN
from datetime import datetime, timedelta


def create_sequences(data, seq_len):
    xs = []
    for i in range(seq_len, len(data)):
        x = data[i - seq_len:i]
        xs.append(x)
    return np.array(xs)

def infer_aqi(df, location_id, datetime_str, scaler_list, model_point):
    df_loc = df[(df["ID Vị Trí"] == location_id)].copy()

    # Chuyển đổi thời gian
    df_loc["Datetime"] = pd.to_datetime(df_loc["Datetime"], format="%H:%M %d/%m/%Y", errors='coerce')

    # Lọc theo thời gian <= thời điểm được chọn (lấy dữ liệu trước thời điểm này)
    try:
        target_time = pd.to_datetime(datetime_str, format="%H:%M %d/%m/%Y")
    except Exception as e:
        print(f"❌ Định dạng thời gian sai. Định dạng đúng: HH:MM dd/mm/yyyy\nChi tiết: {e}")
        return 0.0

    df_loc = df_loc[df_loc["Datetime"] <= target_time]
    df_loc = df_loc.sort_values("Datetime")

    if len(df_loc) < SEQ_LEN:
        print("❌ Không đủ dữ liệu trước thời điểm này để dự đoán")
        return 0.0

    # Xử lý dữ liệu tương tự khi train
    df_loc["AQI_PM2.5"] = df_loc["AQI_PM2.5"].astype(str).str.replace(",", ".")
    df_loc["AQI_PM2.5"] = pd.to_numeric(df_loc["AQI_PM2.5"], errors="coerce")

    data_input = df_loc[["AQI_PM2.5", "Vĩ độ", "Kinh độ"]].values
    scaler = scaler_list[location_id]
    data_scaled = scaler.transform(data_input)

    # Tạo chuỗi đầu vào
    seq_input = create_sequences(data_scaled, SEQ_LEN)
    input_tensor = torch.FloatTensor(seq_input[-1:])  # lấy chuỗi gần nhất

    model = model_point[location_id]
    model.eval()
    with torch.no_grad():
        pred_scaled = model(input_tensor).numpy().squeeze()

    # Đảo chuẩn hóa
    pred_extended = np.zeros((1, 3))
    pred_extended[:, 0] = pred_scaled
    pred_original = scaler.inverse_transform(pred_extended)[0, 0]
    
    return pred_original

def infer_and_append_aqi(df, location_id, datetime_str, scaler_list, model_point):
    # Bước 1: Thực hiện dự đoán như cũ
    pred_list = []
    for location_id in range(0, len(scaler_list)):
        pred_original = infer_aqi(df, location_id, datetime_str, scaler_list, model_point)
        
        # Bước 2: Tạo bản ghi mới từ kết quả dự đoán
        original_time = datetime.strptime(datetime_str, "%H:%M %d/%m/%Y")
        one_hour_later = original_time + timedelta(hours=1)
        formatted_time = one_hour_later.strftime("%H:%M %d/%m/%Y")
        new_record = {
            "ID Vị Trí": location_id,
            "Datetime": formatted_time,
            "AQI_PM2.5": pred_original,
            "Tên": df[df["ID Vị Trí"] == location_id]["Tên"].iloc[0],
            "Vĩ độ": df[df["ID Vị Trí"] == location_id]["Vĩ độ"].iloc[0],
            "Kinh độ": df[df["ID Vị Trí"] == location_id]["Kinh độ"].iloc[0],
            "is_predicted": True  # Đánh dấu là dữ liệu dự đoán
        }
        
        # Bước 3: Thêm vào DataFrame
        # Sử dụng biến toàn cục hoặc truyền df vào theo cách khác
        df = pd.concat([df, pd.DataFrame([new_record])], ignore_index=True)
        pred_list.append(pred_original)
    return pred_list, df.copy()