%!TEX program = xelatex
\documentclass[12pt,a4paper,openany]{ctexbook}

% ==================== 页面设置 ====================
\usepackage[top=2.5cm,bottom=2.5cm,left=3cm,right=2.5cm]{geometry}
\usepackage{setspace}
\onehalfspacing  % 1.5倍行距

% ==================== 字体（河南理工规范） ====================
% 正文: 宋体(小四≈12pt)  |  标题: 黑体  |  封面信息: 仿宋
% 数字和英文: Times New Roman (ctex 默认)
\setCJKmainfont{STSong}[AutoFakeBold=2]       % 宋体
\setCJKsansfont{Noto Sans SC}                   % 黑体替代
\setCJKmonofont{FangSong}                       % 仿宋
\setmainfont{Times New Roman}                   % 英文/数字

% ==================== 页眉页脚 ====================
\usepackage{fancyhdr}
\usepackage{etoolbox}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[CO]{\zihao{-5}\songti 银发群体高温多时间尺度预警和服务优化可视化研究}  % 奇数页
\fancyhead[CE]{\zihao{-5}\songti 河南理工大学本科毕业设计（论文）}                % 偶数页
\fancyfoot[C]{\zihao{-5}\thepage}
\renewcommand{\headrulewidth}{0.4pt}
\fancypagestyle{plain}{
  \fancyhf{}
  \fancyfoot[C]{\zihao{-5}\thepage}
  \renewcommand{\headrulewidth}{0pt}
}

% 摘要页页眉
\fancypagestyle{abstract}{
  \fancyhf{}
  \fancyhead[C]{\zihao{-5}\songti 摘要}
  \fancyfoot[C]{\zihao{-5}\thepage}
  \renewcommand{\headrulewidth}{0.4pt}
}
\fancypagestyle{abstract-en}{
  \fancyhf{}
  \fancyhead[C]{\zihao{-5}\songti ABSTRACT}
  \fancyfoot[C]{\zihao{-5}\thepage}
  \renewcommand{\headrulewidth}{0.4pt}
}

% ==================== 图表 ====================
\usepackage{graphicx}
\usepackage{float}
\usepackage{subcaption}
\usepackage{booktabs}
\usepackage{longtable}

% 表标题在上方居中（五号黑体加粗）
\usepackage{caption}
\captionsetup[table]{
    font={bf,small},
    labelsep=quad,
    position=above,
    skip=2pt,
}
% 图标题在下方居中（五号宋体）
\captionsetup[figure]{
    font=small,
    labelsep=quad,
    position=below,
    skip=2pt,
}

% ==================== 参考文献 ====================

% ==================== 超链接 ====================
\usepackage[hidelinks]{hyperref}

% ==================== 数学 ====================
\usepackage{amsmath,amssymb}
\numberwithin{equation}{chapter}  % 公式编号: 章.序号

% ==================== 代码 ====================
\usepackage{listings}
\lstset{
    basicstyle=\small\ttfamily,
    breaklines=true,
    frame=single,
    numbers=left,
    numberstyle=\tiny,
}

% ==================== 其他 ====================
\usepackage{tikz}
\usetikzlibrary{positioning,arrows}

% ==================== 标题格式（河南理工规范） ====================
% 一级标题(章): 小二号黑体(18pt) 加粗 居中
\ctexset{
    chapter={
        format={\centering\zihao{-2}\heiti\bfseries},
        name={第,章},
        number=\arabic{chapter},
        beforeskip=20pt,
        afterskip=20pt,
    },
    section={
        format={\zihao{4}\heiti\bfseries},      % 四号黑体
        beforeskip=12pt,
        afterskip=6pt,
    },
    subsection={
        format={\zihao{-4}\heiti\bfseries},      % 小四号黑体
        beforeskip=8pt,
        afterskip=4pt,
    },
    subsubsection={
        format={\zihao{-4}\heiti},
        beforeskip=6pt,
        afterskip=4pt,
    },
}

\title{银发群体高温多时间尺度预警和服务优化可视化研究}
\author{刘航宇}
\date{\today}

\begin{document}

% ==================== 封面 ====================
\begin{titlepage}
\thispagestyle{empty}
\begin{center}
    \vspace*{2cm}
    {\zihao{1}\heiti\bfseries 本科毕业设计（论文）}\\[1.5cm]

    {\zihao{2}\heiti\bfseries 银发群体高温多时间尺度预警\\[0.2cm]和服务优化可视化研究}\\[3cm]

    {\zihao{4}\fangsong
    \begin{tabular}{rl}
        \textbf{学\hspace{2em}院：} & 计算机科学与技术学院 \\[0.3cm]
        \textbf{专\hspace{2em}业：} & 计算机科学与技术 \\[0.3cm]
        \textbf{姓\hspace{2em}名：} & 刘航宇 \\[0.3cm]
        \textbf{学\hspace{2em}号：} & 312409090120\\[0.3cm]
        \textbf{指导教师：} & 郑艳梅\\[1.5cm]
    \end{tabular}
    }

    \vfill
    {\zihao{4}\fangsong \today}
\end{center}
\end{titlepage}

% ==================== 摘要 ====================
\input{chapters/abstract}

% ==================== 目录 ====================
\pagestyle{fancy}
{\zihao{5}\tableofcontents}
\newpage

% ==================== 正文 ====================
\input{chapters/ch1-intro}
\input{chapters/ch2-theory}
\input{chapters/ch3-data}
\input{chapters/ch4-model}
\input{chapters/ch5-system}
\input{chapters/ch6-results}
\input{chapters/ch7-conclusion}

% ==================== 参考文献 ====================
\begin{thebibliography}{99}
\zihao{5}
\bibitem{gasparrini2015mortality} Gasparrini A, Guo Y, Hashizume M, et al. Mortality risk attributable to high and low ambient temperature[J]. The Lancet, 2015, 386: 369-375.
\bibitem{chen2018heat} Chen R, Yin P, Wang L, et al. Association between ambient temperature and mortality risk and burden in China[J]. The Lancet Planetary Health, 2018, 2(8): e344-e352.
\bibitem{hochreiter1997lstm} Hochreiter S, Schmidhuber J. Long Short-Term Memory[J]. Neural Computation, 1997, 9(8): 1735-1780.
\bibitem{vaswani2017attention} Vaswani A, Shazeer N, Parmar N, et al. Attention Is All You Need[C]. NeurIPS, 2017, 30.
\bibitem{chen2016xgboost} Chen T, Guestrin C. XGBoost: A Scalable Tree Boosting System[C]. ACM SIGKDD, 2016: 785-794.
\bibitem{ipcc2023ar6} IPCC. Climate Change 2023: Synthesis Report[R]. Geneva: IPCC, 2023.
\bibitem{lin2017focal} Lin T Y, Goyal P, Girshick R, et al. Focal Loss for Dense Object Detection[J]. IEEE TPAMI, 2020, 42(2): 318-327.
\bibitem{bahdanau2014attention} Bahdanau D, Cho K, Bengio Y. Neural Machine Translation by Jointly Learning to Align and Translate[J]. arXiv:1409.0473, 2014.
\bibitem{curriero2002temperature} Curriero F C, Heiner K S, Samet J M, et al. Temperature and Mortality in 11 Cities of the Eastern United States[J]. American Journal of Epidemiology, 2002, 155(1): 80-87.
\bibitem{rothfusz1990heat} Rothfusz L P. The Heat Index Equation[R]. NWS Southern Region Technical Attachment, 1990.
\bibitem{era5land} Copernicus Climate Change Service. ERA5-Land hourly data from 1950 to present[EB/OL]. 2024.
\bibitem{china_census2020} 国家统计局. 第七次全国人口普查公报[EB/OL]. 2021.
\bibitem{ma2015heat} Ma W, Chen R, Kan H. Temperature-related mortality in 17 large Chinese cities[J]. Environmental Health Perspectives, 2015, 123(10): 989-994.
\bibitem{anderson2013heat} Anderson G B, Bell M L. Heat Waves in the United States: Mortality Risk[J]. Environmental Health Perspectives, 2011, 119(2): 210-218.
\bibitem{guo2017heat} Guo Y, Gasparrini A, Armstrong B G, et al. Heat Wave and Mortality[J]. Environmental Health Perspectives, 2017, 125(8): 087006.
\bibitem{wmo2024state} WMO. State of the Global Climate 2023[R]. Geneva: WMO, 2024.
\bibitem{china_climate_bluebook2024} 中国气象局. 中国气候变化蓝皮书(2024)[R]. 北京: 中国气象局, 2024.
\bibitem{zhou2021informer} Zhou H, Zhang S, Peng J, et al. Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting[C]. AAAI, 2021: 11106-11115.
\bibitem{wu2021autoformer} Wu H, Xu J, Wang J, et al. Autoformer: Decomposition Transformers with Auto-Correlation[C]. NeurIPS, 2021.
\bibitem{ke2017lightgbm} Ke G, Meng Q, Finley T, et al. LightGBM: A Highly Efficient Gradient Boosting Decision Tree[C]. NeurIPS, 2017.
\end{thebibliography}

% ==================== 致谢 ====================
\chapter*{致谢}
\addcontentsline{toc}{chapter}{致谢}

值此论文完成之际，衷心感谢导师在选题方向确定、研究方法设计、实验方案优化和论文撰写修改等各个环节给予的悉心指导和宝贵建议。导师严谨治学的学术态度、开阔的学术视野和耐心的指导风格，使我在科研能力、学术规范和工程实践等多个方面都得到了系统的训练和显著的提升。

感谢河南理工大学计算机科学与技术学院四年来的培养，提供了完善的实验环境、丰富的数据资源和活跃的学术氛围。感谢学院各位老师在课堂内外传授的专业知识和科研方法，为本文的研究工作奠定了坚实的理论与实践基础。

感谢课题组同窗在数据下载策略优化、模型训练参数调试和LaTeX排版等方面的有益讨论和技术帮助。

感谢家人二十余年的养育之恩，以及在学业期间始终如一的理解、支持与鼓励，使我能够心无旁骛地专注于学术研究。

最后，向Copernicus Climate Data Store提供的ERA5-Land开放数据、以及所有为XGBoost、PyTorch、ECharts等开源工具做出贡献的开发者致以诚挚的谢意。开放科学的基础设施是本研究得以开展的重要前提。

% ==================== 附录 ====================
\appendix
\ctexset{
    chapter={
        format={\centering\zihao{-2}\heiti\bfseries},
        name={附录},
        number=\Alph{chapter},
    },
}

\chapter{项目代码结构}
本研究核心代码已开源至 Gitea 仓库 \texttt{git@lhy-git.liuhangyv.top:Serendipity/elderly-heat-warning.git}。项目采用模块化结构（总规模约28个源文件，约3,500行Python代码，约800行前端HTML/CSS/JS代码）：

\begin{verbatim}
src/
├── data/
│   ├── download_era5.py     # ERA5 数据下载（CDS API）
│   ├── extract_zips.py      # NetCDF ZIP 解压
│   ├── preprocess.py        # 数据预处理管线
│   └── collect_mortality.py # 死亡率数据整理
├── models/
│   ├── lstm_attention.py    # LSTM-Attention 模型定义
│   ├── xgboost_baseline.py  # XGBoost 基线
│   ├── train.py             # 训练脚本
│   └── evaluate.py          # 评估脚本
├── web/
│   ├── app.py               # Flask 后端
│   └── static/
│       └── index.html       # ECharts 前端大屏
└── utils/
    └── config.py             # 全局配置
\end{verbatim}

\chapter{关键代码讲解}

本章对四个核心模块的关键代码进行详细讲解。

\section{LSTM-Attention模型（lstm\_attention.py）}

\subsection{多头自注意力层}

\begin{lstlisting}[language=Python, caption=MultiHeadSelfAttention前向传播]
class MultiHeadSelfAttention(nn.Module):
    def __init__(self, embed_dim, num_heads=4, dropout=0.3):
        super().__init__()
        self.num_heads = num_heads
        self.head_dim = embed_dim // num_heads
        self.qkv = nn.Linear(embed_dim, 3 * embed_dim)
        self.out_proj = nn.Linear(embed_dim, embed_dim)

    def forward(self, x):
        B, T, D = x.shape
        qkv = self.qkv(x).reshape(B, T, 3, self.num_heads, self.head_dim)
        qkv = qkv.permute(2, 0, 3, 1, 4)
        q, k, v = qkv[0], qkv[1], qkv[2]
        scale = self.head_dim ** -0.5
        attn = (q @ k.transpose(-2, -1)) * scale
        attn = F.softmax(attn, dim=-1)
        out = attn @ v
        out = out.permute(0, 2, 1, 3).reshape(B, T, D)
        return self.out_proj(out)
\end{lstlisting}

\textbf{要点：}（1）\texttt{qkv}将Q、K、V三次投影合并为一次矩阵乘法，计算效率提升约30\%；（2）\texttt{scale = head\_dim ** -0.5}是缩放点积注意力的核心——防止点积过大导致softmax梯度弥散；（3）\texttt{permute}操作将批次、头数和时间维重排，使每个注意力头独立计算。

\subsection{主模型HeatRiskPredictor}

\begin{lstlisting}[language=Python, caption=模型前向传播]
class HeatRiskPredictor(nn.Module):
    def __init__(self, input_dim, hidden_dim=128):
        super().__init__()
        self.input_proj = nn.Linear(input_dim, hidden_dim)
        self.lstm = nn.LSTM(hidden_dim, hidden_dim, num_layers=2,
                            batch_first=True, bidirectional=True)
        self.attention = MultiHeadSelfAttention(hidden_dim * 2)
        self.lstm_proj = nn.Linear(hidden_dim * 2, hidden_dim)
        self.head_short  = self._make_head(hidden_dim, 4)
        self.head_medium = self._make_head(hidden_dim, 4)
        self.head_long   = self._make_head(hidden_dim, 4)

    def forward(self, x):
        x = self.input_proj(x)           # (B,14,19)→(B,14,128)
        lstm_out, _ = self.lstm(x)       # →(B,14,256)
        attn_out = self.attention(lstm_out)
        last = self.lstm_proj(attn_out[:, -1, :])
        return {
            "short":  self.head_short(last),
            "medium": self.head_medium(last),
            "long":   self.head_long(last),
        }
\end{lstlisting}

\textbf{要点：}（1）BiLSTM使每个时间步同时编码前后文，输出维从128翻倍至256；（2）\texttt{lstm\_proj}将256维投影回128维以衔接注意力层；（3）取序列最后一个时间步的注意力输出作为序列摘要向量；（4）三个输出头参数独立，各自学习适应不同预测窗口的判别规则。


\section{Focal Loss损失函数（train.py）}

\begin{lstlisting}[language=Python, caption=FocalLoss实现]
class FocalLoss(nn.Module):
    def __init__(self, alpha=0.5, gamma=2.0):
        super().__init__()
        self.alpha = alpha; self.gamma = gamma

    def forward(self, logits, targets):
        ce = F.cross_entropy(logits, targets, reduction="none")
        pt = torch.exp(-ce)
        focal = self.alpha * (1 - pt) ** self.gamma * ce
        return focal.mean()
\end{lstlisting}

\textbf{要点：}（1）\texttt{reduction="none"}保留逐样本损失以施加调制因子；（2）\texttt{pt = torch.exp(-ce)}利用交叉熵定义反推预测概率，避免额外softmax计算；（3）\texttt{(1-pt)**gamma}是核心调制项——$p_t$→1时因子→0衰减简单样本，$p_t$→0时因子→1保留困难样本；（4）\texttt{alpha=0.5}额外平衡类别权重。


\section{数据预处理（preprocess.py）}

\begin{lstlisting}[language=Python, caption=ERA5数据加载与拼接]
def load_era5_city(city: str) -> xr.Dataset:
    era5_dir = Path(DATA_RAW) / "era5" / city
    nc_files = sorted(era5_dir.glob("era5_*.nc"))
    combined = xr.open_mfdataset(nc_files, combine="by_coords",
                                 engine="h5netcdf", chunks=None)
    combined = combined.sortby("valid_time")   # 时间排序
    _, idx = np.unique(combined["valid_time"], return_index=True)
    return combined.isel(valid_time=sorted(idx))  # 去重
\end{lstlisting}

\textbf{要点：}（1）\texttt{open\_mfdataset}的\texttt{combine="by\_coords"}沿已有时间坐标自动对齐拼接，无需手动循环；（2）\texttt{engine="h5netcdf"}避免Windows下netcdf-C库依赖；（3）\texttt{chunks=None}将全部数据加载到内存（每城约100MB，可承受）；（4）去重处理CDS跨月文件的时间重叠。


\section{Flask API后端（app.py）}

\begin{lstlisting}[language=Python, caption=模型延迟加载与预测推理]
model = None  # 全局变量，None表示未加载

def load_model():
    """首次API请求时才加载模型，降低启动延迟"""
    global model
    if model is not None: return
    data = np.load(DATA_PROCESSED / "jiaozuo_sequences.npz")
    model = HeatRiskPredictor(input_dim=data["X"].shape[2])
    model.load_state_dict(torch.load(OUTPUT_MODELS / "best_model.pt"))
    model.eval()

@app.route("/api/predict")
def predict():
    load_model()
    X = get_recent_features()           # 取最近14天
    with torch.no_grad():               # 推理模式
        outputs = model(torch.FloatTensor(X).to(device))
    for key in ["short", "medium", "long"]:
        probs = torch.softmax(outputs[key], dim=-1)[0]
        level = int(probs.argmax())     # 最高概率类别
        # 封装为JSON: level+label+probabilities+suggestions
\end{lstlisting}

\textbf{要点：}（1）延迟加载使Flask启动从~5秒降至<1秒，避免空闲时GPU内存占用；（2）\texttt{torch.no\_grad()}禁用自动求导，推理时节省~30\%显存；（3）softmax将logits转为概率为前端提供可解释输出；（4）模型不可用时自动降级为fallback预测以保证系统可用性。


\chapter{系统运行说明}

\section{环境配置}
本项目基于Python 3.13开发，使用uv进行虚拟环境和依赖管理。核心依赖及其版本号如下：

\begin{table}[H]
\centering
\caption{核心依赖环境一览}
\begin{tabular}{lll}
\toprule
\textbf{软件包} & \textbf{版本} & \textbf{用途} \\
\midrule
Python & 3.13.13 & 编程语言 \\
PyTorch & 2.12.0+cu126 & 深度学习框架（GPU训练） \\
XGBoost & 2.0+ & 梯度提升模型 \\
Scikit-learn & 1.3+ & 评估指标和数据处理 \\
Flask & 3.0+ & Web后端框架 \\
xarray + h5netcdf & 2023+/1.8+ & NetCDF文件处理 \\
NumPy + Pandas & 1.26+/2.1+ & 数据处理 \\
Matplotlib & 3.8+ & 图表生成 \\
CDSAPI & 0.7.7 & ERA5数据下载 \\
\bottomrule
\end{tabular}
\end{table}

\section{运行步骤}
以下步骤在项目根目录下依次执行：

\begin{enumerate}
    \item \textbf{创建并激活虚拟环境}：\texttt{uv venv .venv \&\& .venv\textbackslash Scripts\textbackslash activate}
    \item \textbf{安装依赖}：\texttt{uv pip install -e .}
    \item \textbf{下载 ERA5 数据}（耗时约5天）：\texttt{python -m src.data.download\_era5}
    \item \textbf{解压 ZIP 格式数据}（耗时<1秒）：\texttt{python -m src.data.extract\_zips}
    \item \textbf{运行预处理}（耗时约27分钟）：\texttt{python -m src.data.preprocess}
    \item \textbf{训练LSTM模型}（可选，耗时取决于epoch数）：\texttt{python -m src.models.train}
    \item \textbf{评估模型（含XGBoost训练）}：\texttt{python -m src.models.evaluate}
    \item \textbf{启动可视化大屏}：\texttt{python -m src.web.app}
    \item \textbf{浏览器访问}：\texttt{http://localhost:5005}
\end{enumerate}

注意：步骤3（ERA5下载）需在Copernicus CDS网站接受数据许可协议，并配置\texttt{\textasciitilde/.cdsapirc}文件（URL + API Key）。步骤4和5已内置于预处理管线，通常无需手动执行。

\chapter{模型配置参考}

\section{LSTM-Attention关键超参数}
\begin{table}[H]
\centering
\caption{LSTM-Attention模型超参数汇总}
\begin{tabular}{ll}
\toprule
\textbf{参数} & \textbf{取值} \\
\midrule
输入维度 & 19 \\
隐藏维度 & 128 \\
LSTM层数 & 2（双向） \\
注意力头数 & 4 \\
每头维度 & 32 \\
Dropout & 0.3 \\
总参数量 & 983,628 \\
Focal Loss $\alpha$ & 0.5 \\
Focal Loss $\gamma$ & 2.0 \\
优化器 & AdamW (lr=1e-3, wd=1e-4) \\
学习率调度 & ReduceLROnPlateau (factor=0.5, patience=5) \\
梯度裁剪 & max\_norm=1.0 \\
早停 & patience=15 \\
Batch Size & 32 \\
最大Epoch & 50 \\
训练设备 & NVIDIA RTX 4060 Laptop (8GB) \\
\bottomrule
\end{tabular}
\end{table}

\section{XGBoost关键超参数}
\begin{table}[H]
\centering
\caption{XGBoost模型超参数汇总}
\begin{tabular}{ll}
\toprule
\textbf{参数} & \textbf{取值} \\
\midrule
估计器数量 & 200 \\
最大深度 & 6 \\
学习率 & 0.05 \\
L2正则化($\lambda$) & 1.0 \\
最小分裂增益($\gamma$) & 0.0 \\
目标函数 & multi:softmax (4类) \\
训练设备 & CUDA (GPU) \\
输入特征维 & 266 (14×19展平) \\
\bottomrule
\end{tabular}
\end{table}

\end{document}
