Spaces:
Sleeping
Sleeping
| 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() |