On Combining Bags to Better Learn from Label Proportions:标签比例学习的组合袋方法复现指南
On Combining Bags to Better Learn from Label Proportions标签比例学习的组合袋方法复现指南【免费下载链接】google-researchGoogle Research项目地址: https://gitcode.com/gh_mirrors/go/google-research本文是 Google Research 开源仓库中 AISTATS22 论文《On Combining Bags to Better Learn from Label Proportions》的完整复现与源码解析指南。该目录On_Combining_Bags_to_Better_Learn_from_Label_Proportions提供了一套端到端的实验代码从 UCI 小规模基准数据集的预处理、袋bag级训练/测试数据生成到多种标签比例学习Learning from Label Proportions, LLP算法的训练、评估与结果汇总并延伸到 Criteo Kaggle 与 MovieLens 20m 两个大规模数据集实验。读完本文你将掌握该论文全部三组实验伪合成数据集、大规模数据集、大规模数据集-2的复现流程、七种袋生成场景与广义袋Generalized Bags方法的底层实现原理。背景从袋比例中学习标签标签比例学习LLP是一类特殊的弱监督学习设定训练阶段无法访问单个样本的标签只能拿到每个袋bag中正例所占的比例。经典做法是 Mean-MapMM估计、LMM 及其变体等。本文档对应的论文进一步研究了如何组合多个袋来更好地学习标签比例核心创新在于引入**广义袋Generalized Bags**框架允许对袋内样本赋予权重如 SDP 求解得到的权重从而把单袋比例约束推广为带权重的线性约束族。仓库代码围绕三类实验展开伪合成数据集实验在 Ionosphere、Australian、Heart 三个 UCI 数据集上按多种分布场景构造袋对比经典基线与广义袋方法大规模数据集实验Criteo Kaggle 展示广告数据集事件级逻辑回归 广义袋大规模数据集-2 实验MovieLens 20m 数据集上的同类实验。仓库结构与实验总体流程以仓库根目录为基准实验目录结构如下On_Combining_Bags_to_Better_Learn_from_Label_Proportions/ ├── Code/ │ ├── GenBagTfCode/ # 广义袋/袋方法 TensorFlow 训练method1~method7 │ ├── ProcessingResults/ # 结果汇总与指标提取 │ ├── PythCode/ # LMMCM 基线的 Python 循环 │ ├── RCode/ # MM/LMM/AMM 基线的 R 脚本method1~method7 │ ├── TrainTestCreation/ # 预处理、五折划分、袋生成 │ └── requirements.txt ├── Large_dataset/ # Criteo 大规模实验 │ ├── Dataset_Preprocessing/ # 特征分桶、划分与袋文件生成 │ ├── SDP_solving/ # 广义袋 SDP 权重求解 │ └── Training_loops/ # 线性逻辑回归与袋训练循环 ├── Large_dataset_2/ # MovieLens 20m 大规模实验 ├── GenBagCode.sh # 运行袋/广义袋方法 1~7 ├── RCode.sh # 运行 R 基线方法 1~7 ├── PythCode.sh # 运行 LMMCM 基线 ├── dataCreation.sh # 预处理 划分 袋生成 ├── resultsProcessing.sh # 汇总原始结果 └── Large_Dataset_expts.sh # Criteo 全流程脚本 └── Large_Dataset_2_expts.sh # MovieLens 20m 全流程脚本顶层脚本 GenBagCode.sh、RCode.sh、PythCode.sh、dataCreation.sh、resultsProcessing.sh 一一对应 README 中的复现步骤是理解整套流程的捷径。实验一伪合成数据集实验Pseudo-synthetic datasets步骤 1收集先前工作的基线代码论文对比了已有 LLP 方法需要先获取两个第三方仓库的代码按 README 要求固定到指定 commitalmostnolabelcommit4de5f54克隆为文件夹almostnolabel-main放置在包含本 README 的目录即On_Combining_Bags_to_Better_Learn_from_Label_Proportions/下Learning-from-Label-Proportions-A-Mutual-Contamination-Frameworkcommitadb57fa将其LMMCM目录内容复制到./Code/PythCode/。前者提供 MM、LMM、AMM 基线后者提供 LMMCM互污染框架基线。复制到Code/PythCode/后PythCode.sh 会依次执行ionosphereloops.py、australianloops.py、heartloops.py三个循环脚本完成 LMMCM 实验。步骤 2创建 Python 虚拟环境伪合成实验使用名为pythenv的 venv 环境Python 版本 3.9.2cd ./Code python -m venv pythenv source pythenv/bin/activate pip install -r requirements.txt deactivate依赖清单见 Code/requirements.txt固定版本如下依赖版本cvxopt1.2.6numpy1.19.5pandas1.2.4scikit-learn0.24.2scipy1.6.3tensorflow2.5.0rc1步骤 3创建 LMMCM 的 conda 环境LMMCM 基线依赖独立的 conda 环境LLP环境搭建方式遵循上述互污染框架仓库commitadb57fa的安装说明。步骤 4下载原始数据并生成袋级训练/测试数据在顶层目录包含 README.md 的目录创建OrigData/并下载三个 UCI 数据集mkdir OrigData cd OrigData wget http://archive.ics.uci.edu/ml/machine-learning-databases/ionosphere/ionosphere.data wget https://archive.ics.uci.edu/ml/machine-learning-databases/statlog/australian/australian.dat wget https://archive.ics.uci.edu/ml/machine-learning-databases/statlog/heart/heart.dat随后从顶层目录创建数据目录结构并运行预处理脚本mkdir -p Data/FullDatasets Data/Australian Data/Ionosphere Data/Heart source Code/pythenv/bin/activate ./dataCreation.sh deactivatedataCreation.sh 内部依次执行三个 Python 脚本preprocessingdata.py见 Code/TrainTestCreation/preprocessingdata.py读取OrigData/中的原始文件将标签映射为{-1, 1}Heart 中 2→1、其余→-1Ionosphere 中g→1、其余→-1Australian 中 1→1、其余→-1插入bag占位列与label列对特征列执行StandardScaler标准化并追加常数特征列constant输出Data/FullDatasets/*-Processed.csvfivefoldsplits.py见 Code/TrainTestCreation/fivefoldsplits.py生成五折训练/测试划分目录结构为Data/Dataset/Fold_k/Split_s/clusteringloopseeded.py见 Code/TrainTestCreation/clusteringloopseeded.py为每个划分生成方法 1~8 对应的袋文件存入ClusterBags_method/目录其中head_bags_i与tail_bags_i为 pickle 序列化的袋索引列表。步骤 5运行 MM / LMM / AMM 基线MM、LMM(v(G,s))、AMM(MM)、AMM(LMM(v(G,s))) 基线使用almostnolabel的 R 代码需要先安装 R。随后从顶层目录执行./RCode.shRCode.sh 会依次运行 Code/RCode/ 下的RCodeMethod1.R~RCodeMethod7.R七个 R 脚本对应方法 1~7 场景每个脚本的输出追加到同名.log文件最终结果写入Data/对应数据集目录。步骤 6运行 LMMCM 基线LMMCM 基线使用互污染框架的代码conda activate LLP ./PythCode.sh conda deactivate步骤 7运行 Bag 与 Generalized Bag 方法这是本论文的核心方法。从顶层目录执行source Code/pythenv/bin/activate ./GenBagCode.sh deactivateGenBagCode.sh 依次运行 Code/GenBagTfCode/ 下 7 个 TensorFlow 脚本覆盖 README 列出的全部方法组合LIN(KL-div, U)均匀权重 KL 散度损失method1~method7 各场景均含LIN(l_2^2, S)SDP/分布权重 平方欧氏距离损失LIN(l_2^2, U)均匀权重 平方欧氏距离损失LIN(l_2^2, R)随机权重 平方欧氏距离损失LIN(l_1, S)、LIN(l_1, U)、LIN(l_1, R)对应的 L1 损失变体。核心实现三种自定义损失以 method1loopseeded.py 为例其三种损失函数代表了广义袋训练的核心机制custom_loss_ell2sq_genbagL2 平方损失对每个广义袋genBag按权重wts加权求和袋内样本的预测与真实标签再对两者加权和计算 MSEcustom_loss_abs_genbagL1 损失同上但以 MAE 度量加权和的差异custom_loss_kld_genbagKL 散度损失先对加权和按总权重归一化得到袋内均值再分别对正类均值与反类均值1-均值计算 KL 散度并求和。数据组织上每个 batch 由META_BATCH_SIZE 32个广义袋组成每个广义袋从 head/tail 袋列表中按不同权重采样策略抽取子袋并打上wt权重与genBagNo袋编号标记模型为单层线性分类器Linearsigmoid 输出SGD 学习率0.0001共训练NUM_BATCHES 1000个批次。S 变体的权重由correlation_matrix见 matricesforgenbag.py 中a0.2, b0.2推导的[[3.125, -3.125], [-3.125, 3.125]]采样的多元正态分布给出U 变体为 one-hot 均匀权重R 变体为标准正态随机权重。方法 1~5 的权重矩阵均可在 matricesforgenbag.py 中直接查看其推导输出例如方法 2/3 的 6×6 对角块矩阵、方法 4 基于 power-lawscipy.stats.powerlaw(1.66)参数的矩阵、方法 5 的非对称 4×4 矩阵。七种袋生成场景对应 README 中 method1~method7 的袋构造方式在 clusteringloopseeded.py 中可查关键参数如下方法袋场景关键参数1单簇 head/tail 袋n_clusters1head/tail 包含概率 0.1/0.1n_head125, n_tail1252三簇 head/tail 袋n_clusters3head/tail 包含概率 0.9/0.1n_head40, n_tail40簇偏置[1,1,1]3三簇非对称偏置袋n_clusters3head/tail 0.9/0.1n_head15, n_tail15簇偏置[1,3,5]4power-law 分布袋head/tail 包含概率 -0.9/-0.1p_law_param1.66optionpowerlaw5多幂律非对称袋head/tail 幂律指数[1.7,1.6,1.9]/[1.1,1.2,1.01]见 bagsformethod5.py6单跨越袋straddlestraddle/tail 包含概率 0.2/0.6n_tail60, n_straddle607单跨越袋另一组参数straddle/tail 包含概率 0.4/0.8 与 0.2/0.28双跨越袋两组 straddle 概率 0.2/0.6 与 tail 0.2见 twostraddlebags.py方法 5/6/7 的袋由 bagsformethod5.py、singlestraddlebag.py、twostraddlebags.py 生成。测试阶段统一使用完整测试集test_df上wt0、genBagNo0以自定义 AUC 指标评估结果按数据集, 方法, split, fold, 各方法AUC的 CSV 行追加写入Data/Dataset/Dataset_TFexpOutputClusterBags_method文件。步骤 8~9结果收集与汇总mkdir -p Results/Raw_Results source Code/pythenv/bin/activate ./resultsProcessing.sh deactivateresultsProcessing.sh 先将Data/Heart、Data/Australian、Data/Ionosphere下的结果复制到Results/Raw_Results/再依次运行 Code/ProcessingResults/ 下的三个汇总脚本processing_r_results.py解析 R 基线输出processing_mutcon_results.py解析 LMMCM 基线输出processing_genbag_results.py解析广义袋方法输出。最终所有指标汇总至./Results/目录。实验二大规模数据集实验Criteo Kaggle数据准备与划分从 Criteo Kaggle 展示广告挑战赛下载数据集在./Large_dataset/Dataset_Preprocessing/Dataset/下放置train.txt在该目录下创建Split_0~Split_4五个子目录。环境搭建使用 Python 3.9.7 创建独立虚拟环境cd ./Large_dataset python -m venv pythenv_large source pythenv_large/bin/activate pip install -r requirements.txt依赖见 Large_dataset/requirements.txt。运行实验./Large_Dataset_expts.sh该脚本串联了三阶段处理预处理feature_bucketing.py完成特征分桶生成含C14_bucket等分桶索引的处理后数据train_test_splits_bags.py见 Large_dataset/Dataset_Preprocessing/train_test_splits_bags.py用KFold(n_splits5, shuffleTrue, random_state4091)划分训练/测试集并生成袋训练文件.ftrSDP 权重求解gen_bag_SDP.py见 Large_dataset/SDP_solving/gen_bag_SDP.py基于读取的corr_matrices_C14_bucket与mean_vecs_C14_bucket用 cvxpy 构造半正定矩阵变量W、Y_upper、Y_lower及W 0等约束求解广义袋的 SDP 权重训练循环lin_loop.py训练事件级线性逻辑回归bag_loop.py训练袋级广义袋模型对应 Large_dataset/Training_loops/。结果读取结果输出在./Large_dataset/Dataset_Preprocessing/Dataset/下各Split_i目录中results_lin_i事件级线性逻辑回归结果重点看val_auc列results_multi_genbags_i后 4 列分别为广义袋 SDP 权重 平方欧氏距离损失同上 L1 损失单袋 平方欧氏距离损失单袋 KL 散度损失。每行对应一个 epoch。实验三大规模数据集-2 实验MovieLens 20m流程与实验二完全平行从 GroupLens 下载 MovieLens 20m 数据集全部文件放入./Large_dataset_2/Dataset_Preprocessing/Dataset/创建Split_0~Split_4五个子目录Python 3.9.7 建环境pythenv_large_2依赖见 Large_dataset_2/requirements.txt从顶层运行./Large_Dataset_2_expts.sh。对应源码位于 Large_dataset_2/ 下的Dataset_Preprocessing/preprocessing_movielens20m.py、train_test_splits_bags_movielens20m.py、SDP_solving/gen_bag_SDP_movielens20m.py与Training_loops/bag_loop_movielens20m.py、lin_loop_movielens20m.py。结果同样落在各Split_i目录results_lin_ival_auc列为事件级线性逻辑回归结果result_multi_genbags_movielensi后 4 列为与实验二相同的四种广义袋/单袋方法组合每行对应一个 epoch。方法矩阵速查方法标识权重来源损失函数LIN(l_2^2, S)SDP/分布权重多元正态采样平方欧氏距离MSELIN(l_2^2, U)均匀权重one-hot平方欧氏距离MSELIN(l_2^2, R)标准正态随机权重平方欧氏距离MSELIN(l_1, S)SDP/分布权重L1MAELIN(l_1, U)均匀权重L1MAELIN(l_1, R)随机权重L1MAELIN(KL-div, U)均匀权重KL 散度复现注意事项环境隔离伪合成实验使用 venvpythenvPython 3.9.2LMMCM 使用 condaLLP两个大规模实验分别使用pythenv_large与pythenv_large_2均要求 Python 3.9.7互不干扰版本固定README 明确要求第三方基线仓库锁定到指定 commitalmostnolabel4de5f54、互污染框架adb57fa以保证实验可复现依赖版本敏感TensorFlow 固定为2.5.0rc1numpy 1.19.5 等版本与 TF 2.5 生态匹配升级依赖可能导致损失函数中tf.gather/tf.cond行为差异数据目录约定所有脚本通过pathlib相对__file__定位Data/、OrigData/等目录因此必须保持 README 规定的目录层级顶层目录执行./*.sh结果输出位置伪合成实验结果在Data/Dataset/与Results/大规模实验结果在各Split_i子目录AUC 为评估指标。总结本文档仓库完整承载了 AISTATS22 论文《On Combining Bags to Better Learn from Label Proportions》的全部复现链路伪合成实验覆盖 3 个 UCI 数据集 × 8 种袋生成场景 × 7 种算法含 3 组外部基线大规模实验验证了方法在 Criteo 与 MovieLens 20m 上的可扩展性。广义袋方法通过在单袋比例约束上叠加 SDP 求解的权重分配将经典 LLP 扩展为更灵活的带权组合优化问题。对于研究 LLP、袋学习或希望复现该论文实验的开发者可按本指南顺序依次执行五个顶层 shell 脚本并借助各源码模块深入理解实现细节。【免费下载链接】google-researchGoogle Research项目地址: https://gitcode.com/gh_mirrors/go/google-research创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

用MATLAB复现电力价格风险模型:从均值回归到跳扩散

用MATLAB复现电力价格风险模型:从均值回归到跳扩散

能源价格风险管理,尤其是电力价格的风险建模,是我近期用MATLAB从零复现的一个项目。外行看到“电力价格”会觉得它和普通大宗商品差不多,但实际上电力价格的波动性远远大于传统商品,刚拿到数据时那种日内冲高几倍、隔几天又跌到负…

2026/9/20 4:20:04 阅读更多 →
Filter/Interceptor在HTTPS下的暗坑与实战排查

Filter/Interceptor在HTTPS下的暗坑与实战排查

这个题目放在一起看,有点“跨层”的味道:Filter、Interceptor是Java Web里的经典拦截机制,HTTPS则是网络传输层的东西。但真实项目里,这三者恰恰是纠缠最深的组合。我之前接手过一个服务,请求链路看起来没毛病——登录…

2026/9/20 4:20:04 阅读更多 →
AI辅助编程系统工程:程序员从农耕到魔法的6条避坑指南

AI辅助编程系统工程:程序员从农耕到魔法的6条避坑指南

程序员从“农耕”走向“魔法”的时代:AI辅助编程系统工程,这6条注意事项我踩过坑才明白这两年AI辅助编程的普及速度,比我预想的快得多。去年我还在跟团队强调“AI生成的代码只能当参考”,今年已经有不少同事把Copilot、Cursor、通…

2026/9/20 4:19:04 阅读更多 →

最新新闻

Claude Code配置指南:API兼容性与VSCode插件调试实战

Claude Code配置指南:API兼容性与VSCode插件调试实战

1. 这不是“又一个AI插件”:Claude Code 的真实定位与能力边界很多人点开这个标题,第一反应是:“哦,又一个让VSCode变聪明的插件”。但如果你真这么想,安装完立刻就会卡在第一步——连基础对话都触发不了,控…

2026/9/20 5:11:26 阅读更多 →
超声波探伤A扫描信号处理与C扫描成像:Python仿真及论文可复现

超声波探伤A扫描信号处理与C扫描成像:Python仿真及论文可复现

简介:这是一份超声波探伤方向的毕业论文文档,面向测控、电子、无损检测等专业的本科或研究生读者,适合作为毕业设计选题参考与课程论文写作范本。论文围绕脉冲反射式超声波检测技术展开,从课题背景与意义入手,先梳理国…

2026/9/20 5:11:26 阅读更多 →
ONNX 6 位浮点格式详解:FLOAT6E2M3 与 FLOAT6E3M2 的位布局、Cast 语义与打包实现

ONNX 6 位浮点格式详解:FLOAT6E2M3 与 FLOAT6E3M2 的位布局、Cast 语义与打包实现

ONNX 6 位浮点格式详解:FLOAT6E2M3 与 FLOAT6E3M2 的位布局、Cast 语义与打包实现 【免费下载链接】onnx Open standard for machine learning interoperability 项目地址: https://gitcode.com/gh_mirrors/onn/onnx 本指南围绕 ONNX 在 onnx1.23.0 引入的两…

2026/9/20 5:11:26 阅读更多 →
网站连通性检测实战:python-mini-projects 的 Check Website Connectivity 工具全解析

网站连通性检测实战:python-mini-projects 的 Check Website Connectivity 工具全解析

示例工程 【免费下载链接】python-mini-projects A collection of simple python mini projects to enhance your python skills 项目地址: https://gitcode.com/gh_mirrors/py/python-mini-projects 点击查看 免费下载 本篇技术指南围绕 python-mini-projects 仓库…

2026/9/20 5:11:26 阅读更多 →
Slang IR Type 家族参考文档的评审与修复:生成式设计文档 QA 闭环实战解析

Slang IR Type 家族参考文档的评审与修复:生成式设计文档 QA 闭环实战解析

编译器图形学编程语言 【免费下载链接】slang Making it easier to work with shaders 项目地址: https://gitcode.com/GitHub_Trending/sl/slang 点击查看 免费下载 本篇技术指南以仓库中 docs/generated/design/_meta/remediations/ir-reference/types.md.remedi…

2026/9/20 5:11:26 阅读更多 →
VoiceStudio 混合架构实战:Electron 与 Python 子进程通信及 Linux 打包优化

VoiceStudio 混合架构实战:Electron 与 Python 子进程通信及 Linux 打包优化

1. 从零搭建 VoiceStudio:为什么我选 Electron 而不是 PySideVoiceStudio 这个项目,从名字就能看出来,核心是围绕“声音”做文章的工作台。我最初的需求很明确:做一个桌面端的语音处理工具,能录音、能管理音频素材、能…

2026/9/20 5:10:25 阅读更多 →

日新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →