Blisky-li commited on
Commit
724d130
·
verified ·
1 Parent(s): 96b8d9e

Upload 28 files

Browse files
Files changed (3) hide show
  1. app.py +449 -449
  2. src/__pycache__/language.cpython-39.pyc +0 -0
  3. src/language.py +128 -128
app.py CHANGED
@@ -1,450 +1,450 @@
1
- import os
2
- import gradio as gr
3
- import pandas as pd
4
- from src.populate import get_leaderboard_df, get_filtered_leaderboard
5
- from src.display.filters import get_model_type_choices, get_strategy_choices, get_metric_categories
6
- from src.language import lang
7
- import logging
8
- import traceback
9
-
10
- # 配置路径
11
- RESULTS_PATH = os.path.join(os.path.dirname(__file__), "results")
12
-
13
- # 确保结果目录存在
14
- os.makedirs(RESULTS_PATH, exist_ok=True)
15
-
16
- # 配置日志
17
- logging.basicConfig(
18
- level=logging.INFO,
19
- format="%(asctime)s - %(levelname)s - %(message)s"
20
- )
21
- logger = logging.getLogger(__name__)
22
-
23
-
24
- def get_category_columns(df, category):
25
- """获取特定类别的指标列,根据类别应用不同的命名规则"""
26
- if df.empty:
27
- return [], {}
28
-
29
- category_name = category["name"]
30
- prefixes = category["prefix"]
31
- if not isinstance(prefixes, list):
32
- prefixes = [prefixes]
33
-
34
- # 确保model_name和model_type在前面
35
- columns = []
36
- if 'model_name' in df.columns:
37
- columns.append('model_name')
38
- if 'model_type' in df.columns and 'model_type' not in columns:
39
- columns.append('model_type')
40
-
41
- # 收集并处理指标列
42
- metric_columns = []
43
- for col in df.columns:
44
- for p in prefixes:
45
- if col.startswith(f"MAE_{p}") or col.startswith(f"MSE_{p}"):
46
- # 不同类别使用不同的重命名规则
47
- if category_name == "平稳性/非平稳性":
48
- simplified_col = col
49
- elif category_name == "方差特性":
50
- if "Homo-Scedasticity" in p:
51
- simplified_col = col.replace(p, "Homo_", 1)
52
- elif "Hetero-Scedasticity" in p:
53
- simplified_col = col.replace(p, "Hetero_", 1)
54
- else:
55
- simplified_col = col
56
- elif category_name == "季节数":
57
- if "Seasonality_Count" in p:
58
- simplified_col = col.replace(p, "Count", 1)
59
- else:
60
- simplified_col = col
61
- else:
62
- simplified_col = col.replace(p, "", 1)
63
- metric_columns.append((col, simplified_col))
64
- break
65
-
66
- # 去重并保持顺序
67
- seen = set()
68
- unique_metrics = []
69
- for col, simplified in metric_columns:
70
- if col not in seen:
71
- seen.add(col)
72
- unique_metrics.append((col, simplified))
73
-
74
- # 过滤存在的列
75
- existing_columns = [col for col in columns + [col for col, _ in unique_metrics] if col in df.columns]
76
-
77
- # 创建重命名字典
78
- rename_dict = {col: simplified for col, simplified in unique_metrics if col in existing_columns}
79
-
80
- return existing_columns, rename_dict
81
-
82
-
83
- def refresh_leaderboard():
84
- """刷新排行榜数据,返回原始DataFrame和错误信息"""
85
- logger.info("开始刷新排行榜数据")
86
- try:
87
- if not os.path.exists(RESULTS_PATH):
88
- error_msg = f"❌ 结果目录不存在: {RESULTS_PATH}"
89
- logger.error(error_msg)
90
- categories = get_metric_categories()
91
- return [pd.DataFrame() for _ in categories] + [error_msg]
92
-
93
- if not os.path.isdir(RESULTS_PATH):
94
- error_msg = f"❌ {RESULTS_PATH} 不是一个目录"
95
- logger.error(error_msg)
96
- categories = get_metric_categories()
97
- return [pd.DataFrame() for _ in categories] + [error_msg]
98
-
99
- # 加载数据
100
- df = get_leaderboard_df(RESULTS_PATH)
101
- logger.info(f"成功加载数据,共 {len(df)} 条记录")
102
-
103
- categories = get_metric_categories()
104
- data_outputs = []
105
-
106
- for category in categories:
107
- if df.empty:
108
- data_outputs.append(pd.DataFrame())
109
- else:
110
- category_cols, rename_dict = get_category_columns(df, category)
111
- logger.info(f"类别 {category['name']} 的列: {category_cols}")
112
-
113
- display_df = df[category_cols].copy()
114
- display_df = display_df.rename(columns=rename_dict)
115
-
116
- if 'model_name' in display_df.columns:
117
- display_df['model_name'] = display_df['model_name'].str.slice(0, 25) + \
118
- (display_df['model_name'].str.len() > 25).map({True: '...', False: ''})
119
-
120
- data_outputs.append(display_df)
121
-
122
- # 处理空状态信息
123
- if df.empty:
124
- model_folders = [f for f in os.listdir(RESULTS_PATH) if os.path.isdir(os.path.join(RESULTS_PATH, f))]
125
- error_msg = "⚠️ 找到模型文件夹,但无法加载数据" if model_folders else f"⚠️ 未在 {RESULTS_PATH} 中找到模型"
126
- logger.warning(error_msg)
127
- else:
128
- error_msg = ""
129
-
130
- data_outputs.append(error_msg)
131
- logger.info("刷新排行榜完成")
132
- return data_outputs
133
-
134
- except Exception as e:
135
- error_msg = f"❌ 刷新失败: {str(e)}"
136
- logger.error(f"刷新数据失败: {str(e)}\n{traceback.format_exc()}")
137
- categories = get_metric_categories()
138
- return [pd.DataFrame() for _ in categories] + [error_msg]
139
-
140
-
141
- def apply_filters(model_type, strategies, filter_mode):
142
- """应用筛选条件,返回原始DataFrame和提示信息"""
143
- logger.info(f"开始应用筛选: 模型类型={model_type}, 策略={strategies}, 模式={filter_mode}")
144
- try:
145
- filtered_df = get_filtered_leaderboard(
146
- RESULTS_PATH,
147
- model_type=model_type,
148
- strategies=strategies,
149
- filter_mode=filter_mode
150
- )
151
- logger.info(f"筛选完成,得到 {len(filtered_df)} 条记录")
152
-
153
- categories = get_metric_categories()
154
- data_outputs = []
155
-
156
- for category in categories:
157
- if filtered_df.empty:
158
- data_outputs.append(pd.DataFrame())
159
- else:
160
- category_cols, rename_dict = get_category_columns(filtered_df, category)
161
- logger.info(f"筛选后类别 {category['name']} 的列: {category_cols}")
162
-
163
- display_df = filtered_df[category_cols].copy()
164
- display_df = display_df.rename(columns=rename_dict)
165
-
166
- if 'model_name' in display_df.columns:
167
- display_df['model_name'] = display_df['model_name'].str.slice(0, 25) + \
168
- (display_df['model_name'].str.len() > 25).map({True: '...', False: ''})
169
-
170
- data_outputs.append(display_df)
171
-
172
- empty_msg = "⚠️ 没有找到符合筛选条件的模型。" if filtered_df.empty else ""
173
- data_outputs.append(empty_msg)
174
- logger.info("筛选应用完成")
175
- return data_outputs
176
-
177
- except Exception as e:
178
- error_msg = f"❌ 筛选失败: {str(e)}"
179
- logger.error(f"筛选失败: {str(e)}\n{traceback.format_exc()}")
180
- categories = get_metric_categories()
181
- return [pd.DataFrame() for _ in categories] + [error_msg]
182
-
183
-
184
- def create_interface():
185
- """创建Gradio界面,实现多语言切换及固定列功能"""
186
- try:
187
- model_type_choices = get_model_type_choices()
188
- except Exception as e:
189
- model_type_choices = ["All"]
190
- print(f"获取模型类型选项时出错: {str(e)}")
191
-
192
- try:
193
- strategy_choices = get_strategy_choices(RESULTS_PATH)
194
- except Exception as e:
195
- strategy_choices = []
196
- print(f"获取策略选项时出错: {str(e)}")
197
-
198
- categories = get_metric_categories()
199
-
200
- with gr.Blocks(title="Aries 模型评估排行榜") as demo:
201
- # 添加CSS确保model_name列固定
202
- gr.HTML("""
203
- <style>
204
- .fixed-column-table {
205
- overflow: visible !important;
206
- position: relative !important;
207
- max-height: 90vh !important;
208
- height: auto !important;
209
- }
210
-
211
- .fixed-column-table td,
212
- .fixed-column-table th {
213
- padding: 0.2rem 0.3rem !important;
214
- }
215
-
216
- .fixed-column-table table th:first-child,
217
- .fixed-column-table table td:first-child {
218
- position: sticky !important;
219
- left: 0 !important;
220
- z-index: 2 !important;
221
- background-color: white !important;
222
- color: #333 !important;
223
- min-width: 150px !important;
224
- max-width: 150px !important;
225
- font-weight: bold !important;
226
- box-shadow: 1px 0 2px rgba(0,0,0,0.1) !important;
227
- }
228
-
229
- .fixed-column-table table thead th {
230
- position: sticky !important;
231
- top: 0 !important;
232
- z-index: 1 !important;
233
- background-color: white !important;
234
- color: #333 !important;
235
- }
236
-
237
- .fixed-column-table table thead th:first-child {
238
- z-index: 3 !important;
239
- }
240
-
241
- /* 修改这里:允许第二列及其他列自动换行 */
242
- .fixed-column-table table th:nth-child(2),
243
- .fixed-column-table table td:nth-child(2) {
244
- min-width: 215px !important;
245
- /* 移除固定最大宽度限制 */
246
- /* max-width: 215px !important; */
247
- /* 允许文本换行 */
248
- white-space: normal !important;
249
- /* 移除溢出隐藏和省略号 */
250
- overflow: visible !important;
251
- text-overflow: clip !important;
252
- }
253
-
254
- /* 为其他可能的指标列添加样式 */
255
- .fixed-column-table table th:not(:first-child):not(:nth-child(2)),
256
- .fixed-column-table table td:not(:first-child):not(:nth-child(2)) {
257
- white-space: normal !important;
258
- overflow: visible !important;
259
- text-overflow: clip !important;
260
- }
261
-
262
- .fixed-column-table .dataframe-container {
263
- overflow: visible !important;
264
- }
265
-
266
- @media (prefers-color-scheme: dark) {
267
- .fixed-column-table table th:first-child,
268
- .fixed-column-table table td:first-child {
269
- background-color: #333 !important;
270
- color: #fff !important;
271
- box-shadow: 1px 0 2px rgba(0,0,0,0.3) !important;
272
- }
273
-
274
- .fixed-column-table table thead th {
275
- background-color: #333 !important;
276
- color: #fff !important;
277
- }
278
- }
279
- </style>
280
- """)
281
-
282
- # 保存标题组件引用
283
- title_markdown = gr.Markdown(f"# {lang.get('title')}")
284
-
285
- # 添加语言切换按钮
286
- with gr.Row():
287
- lang_btn = gr.Button(f"Switch to English" if lang.current_lang == "zh" else f"切换至中文")
288
-
289
- with gr.Tabs() as main_tabs:
290
- # 模型排行榜标签页
291
- with gr.Tab(lang.get("model_leaderboard")) as leaderboard_tab:
292
- # 保存筛选条件标题引用
293
- filter_conditions = gr.Markdown(f"### {lang.get('filter_conditions')}")
294
-
295
- with gr.Row():
296
- with gr.Column(scale=1):
297
- model_type = gr.Dropdown(
298
- choices=model_type_choices,
299
- label=lang.get("model_type"),
300
- value="All"
301
- )
302
-
303
- strategies = gr.CheckboxGroup(
304
- choices=strategy_choices,
305
- label=lang.get("strategies"),
306
- value=[]
307
- )
308
-
309
- filter_mode = gr.Radio(
310
- choices=[lang.get("intersection"), lang.get("union")],
311
- label=lang.get("filter_mode"),
312
- value=lang.get("intersection")
313
- )
314
-
315
- with gr.Row():
316
- refresh_btn = gr.Button(lang.get("refresh"))
317
- apply_btn = gr.Button(lang.get("apply_filters"))
318
-
319
- with gr.Column(scale=3):
320
- empty_state = gr.Markdown(visible=False)
321
-
322
- with gr.Tabs() as category_tabs:
323
- category_dataframes = []
324
- category_tabs_list = []
325
- for category in categories:
326
- tab = gr.Tab(category["name"])
327
- category_tabs_list.append(tab)
328
- with tab:
329
- df_component = gr.Dataframe(
330
- interactive=False,
331
- wrap=True,
332
- label=category["description"],
333
- elem_classes="fixed-column-table"
334
- )
335
- category_dataframes.append(df_component)
336
-
337
- # 关于标签页 - 支持多语言切换
338
- about_tab = gr.Tab(lang.get("about_tab"))
339
- with about_tab:
340
- about_markdown = gr.Markdown(
341
- f"## {lang.get('about_title')}\n{lang.get('about_content')}"
342
- )
343
-
344
- # 事件处理
345
- apply_btn.click(
346
- fn=apply_filters,
347
- inputs=[model_type, strategies, filter_mode],
348
- outputs=category_dataframes + [empty_state]
349
- )
350
-
351
- refresh_btn.click(
352
- fn=refresh_leaderboard,
353
- outputs=category_dataframes + [empty_state]
354
- )
355
-
356
- demo.load(
357
- fn=refresh_leaderboard,
358
- outputs=category_dataframes + [empty_state]
359
- )
360
-
361
- def toggle_language():
362
- new_lang = lang.switch_language()
363
- btn_text = "切换至中文" if new_lang == "en" else "Switch to English"
364
-
365
- # 更新标题
366
- new_title = gr.update(value=f"# {lang.get('title')}")
367
-
368
- # 更新标签页标题
369
- leaderboard_tab_title = gr.update(label=lang.get("model_leaderboard"))
370
-
371
- # 更新筛选条件标题
372
- new_filter_conditions = gr.update(value=f"### {lang.get('filter_conditions')}")
373
-
374
- # 更新各种组件的标签
375
- new_model_type_label = gr.update(label=lang.get("model_type"))
376
- new_strategies_label = gr.update(label=lang.get("strategies"))
377
- new_filter_mode_label = gr.update(label=lang.get("filter_mode"))
378
- new_refresh_label = gr.update(value=lang.get("refresh"))
379
- new_apply_label = gr.update(value=lang.get("apply_filters"))
380
- new_filter_mode_choices = [lang.get("intersection"), lang.get("union")]
381
- new_filter_mode = gr.update(
382
- choices=new_filter_mode_choices,
383
- value=lang.get("intersection")
384
- )
385
-
386
- # 重新获取多语言配置
387
- new_categories = get_metric_categories()
388
- refreshed_data = refresh_leaderboard()
389
- dataframes = refreshed_data[:-1]
390
- empty_state_msg = refreshed_data[-1]
391
-
392
- # 准备更新列表
393
- updates = [
394
- btn_text,
395
- new_title,
396
- leaderboard_tab_title,
397
- new_filter_conditions,
398
- new_model_type_label,
399
- new_strategies_label,
400
- new_filter_mode,
401
- new_refresh_label,
402
- new_apply_label
403
- ]
404
-
405
-
406
-
407
- # 更新指标类别标签页
408
- for tab, new_cat in zip(category_tabs_list, new_categories):
409
- updates.append(gr.update(label=new_cat["name"]))
410
-
411
-
412
- # 更新指标表格
413
- for df_comp, new_cat, df in zip(category_dataframes, new_categories, dataframes):
414
- updates.append(gr.update(
415
- label=new_cat["description"],
416
- value=df,
417
- visible=True
418
- ))
419
-
420
- # 更新空状态提示
421
- updates.append(gr.update(value=empty_state_msg, visible=bool(empty_state_msg)))
422
- updates.append(gr.update(label=lang.get("about_tab")))
423
- updates.append(gr.update(value=f"## {lang.get('about_title')}\n{lang.get('about_content')}"))
424
-
425
- return updates
426
-
427
- # 语言切换按钮绑定
428
- lang_btn.click(
429
- fn=toggle_language,
430
- inputs=[],
431
- outputs=[
432
- lang_btn,
433
- title_markdown,
434
- leaderboard_tab,
435
- filter_conditions,
436
- model_type,
437
- strategies,
438
- filter_mode,
439
- refresh_btn,
440
- apply_btn
441
- ] + category_tabs_list + category_dataframes + [empty_state, about_tab, about_markdown]
442
- )
443
-
444
- return demo
445
-
446
-
447
- if __name__ == "__main__":
448
- print(f"正在启动Aries模型评估排行榜,结果目录: {RESULTS_PATH}")
449
- demo = create_interface()
450
  demo.launch()
 
1
+ import os
2
+ import gradio as gr
3
+ import pandas as pd
4
+ from src.populate import get_leaderboard_df, get_filtered_leaderboard
5
+ from src.display.filters import get_model_type_choices, get_strategy_choices, get_metric_categories
6
+ from src.language import lang
7
+ import logging
8
+ import traceback
9
+
10
+ # 配置路径
11
+ RESULTS_PATH = os.path.join(os.path.dirname(__file__), "results")
12
+
13
+ # 确保结果目录存在
14
+ os.makedirs(RESULTS_PATH, exist_ok=True)
15
+
16
+ # 配置日志
17
+ logging.basicConfig(
18
+ level=logging.INFO,
19
+ format="%(asctime)s - %(levelname)s - %(message)s"
20
+ )
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ def get_category_columns(df, category):
25
+ """获取特定类别的指标列,根据类别应用不同的命名规则"""
26
+ if df.empty:
27
+ return [], {}
28
+
29
+ category_name = category["name"]
30
+ prefixes = category["prefix"]
31
+ if not isinstance(prefixes, list):
32
+ prefixes = [prefixes]
33
+
34
+ # 确保model_name和model_type在前面
35
+ columns = []
36
+ if 'model_name' in df.columns:
37
+ columns.append('model_name')
38
+ if 'model_type' in df.columns and 'model_type' not in columns:
39
+ columns.append('model_type')
40
+
41
+ # 收集并处理指标列
42
+ metric_columns = []
43
+ for col in df.columns:
44
+ for p in prefixes:
45
+ if col.startswith(f"MAE_{p}") or col.startswith(f"MSE_{p}"):
46
+ # 不同类别使用不同的重命名规则
47
+ if category_name == "平稳性" or category_name == "Stationarity":
48
+ simplified_col = col
49
+ elif category_name == "方差特性" or category_name == "Scadasticity":
50
+ if "Homo-Scedasticity" in p:
51
+ simplified_col = col.replace(p, "Homo_", 1)
52
+ elif "Hetero-Scedasticity" in p:
53
+ simplified_col = col.replace(p, "Hetero_", 1)
54
+ else:
55
+ simplified_col = col
56
+ elif category_name == "季节数" or category_name == "Seasonality Count":
57
+ if "Seasonality_Count" in p:
58
+ simplified_col = col.replace(p, "Count", 1)
59
+ else:
60
+ simplified_col = col
61
+ else:
62
+ simplified_col = col.replace(p, "", 1)
63
+ metric_columns.append((col, simplified_col))
64
+ break
65
+
66
+ # 去重并保持顺序
67
+ seen = set()
68
+ unique_metrics = []
69
+ for col, simplified in metric_columns:
70
+ if col not in seen:
71
+ seen.add(col)
72
+ unique_metrics.append((col, simplified))
73
+
74
+ # 过滤存在的列
75
+ existing_columns = [col for col in columns + [col for col, _ in unique_metrics] if col in df.columns]
76
+
77
+ # 创建重命名字典
78
+ rename_dict = {col: simplified for col, simplified in unique_metrics if col in existing_columns}
79
+
80
+ return existing_columns, rename_dict
81
+
82
+
83
+ def refresh_leaderboard():
84
+ """刷新排行榜数据,返回原始DataFrame和错误信息"""
85
+ logger.info("开始刷新排行榜数据")
86
+ try:
87
+ if not os.path.exists(RESULTS_PATH):
88
+ error_msg = f"❌ 结果目录不存在: {RESULTS_PATH}"
89
+ logger.error(error_msg)
90
+ categories = get_metric_categories()
91
+ return [pd.DataFrame() for _ in categories] + [error_msg]
92
+
93
+ if not os.path.isdir(RESULTS_PATH):
94
+ error_msg = f"❌ {RESULTS_PATH} 不是一个目录"
95
+ logger.error(error_msg)
96
+ categories = get_metric_categories()
97
+ return [pd.DataFrame() for _ in categories] + [error_msg]
98
+
99
+ # 加载数据
100
+ df = get_leaderboard_df(RESULTS_PATH)
101
+ logger.info(f"成功加载数据,共 {len(df)} 条记录")
102
+
103
+ categories = get_metric_categories()
104
+ data_outputs = []
105
+
106
+ for category in categories:
107
+ if df.empty:
108
+ data_outputs.append(pd.DataFrame())
109
+ else:
110
+ category_cols, rename_dict = get_category_columns(df, category)
111
+ logger.info(f"类别 {category['name']} 的列: {category_cols}")
112
+
113
+ display_df = df[category_cols].copy()
114
+ display_df = display_df.rename(columns=rename_dict)
115
+
116
+ if 'model_name' in display_df.columns:
117
+ display_df['model_name'] = display_df['model_name'].str.slice(0, 25) + \
118
+ (display_df['model_name'].str.len() > 25).map({True: '...', False: ''})
119
+
120
+ data_outputs.append(display_df)
121
+
122
+ # 处理空状态信息
123
+ if df.empty:
124
+ model_folders = [f for f in os.listdir(RESULTS_PATH) if os.path.isdir(os.path.join(RESULTS_PATH, f))]
125
+ error_msg = "⚠️ 找到模型文件夹,但无法加载数据" if model_folders else f"⚠️ 未在 {RESULTS_PATH} 中找到模型"
126
+ logger.warning(error_msg)
127
+ else:
128
+ error_msg = ""
129
+
130
+ data_outputs.append(error_msg)
131
+ logger.info("刷新排行榜完成")
132
+ return data_outputs
133
+
134
+ except Exception as e:
135
+ error_msg = f"❌ 刷新失败: {str(e)}"
136
+ logger.error(f"刷新数据失败: {str(e)}\n{traceback.format_exc()}")
137
+ categories = get_metric_categories()
138
+ return [pd.DataFrame() for _ in categories] + [error_msg]
139
+
140
+
141
+ def apply_filters(model_type, strategies, filter_mode):
142
+ """应用筛选条件,返回原始DataFrame和提示信息"""
143
+ logger.info(f"开始应用筛选: 模型类型={model_type}, 策略={strategies}, 模式={filter_mode}")
144
+ try:
145
+ filtered_df = get_filtered_leaderboard(
146
+ RESULTS_PATH,
147
+ model_type=model_type,
148
+ strategies=strategies,
149
+ filter_mode=filter_mode
150
+ )
151
+ logger.info(f"筛选完成,得到 {len(filtered_df)} 条记录")
152
+
153
+ categories = get_metric_categories()
154
+ data_outputs = []
155
+
156
+ for category in categories:
157
+ if filtered_df.empty:
158
+ data_outputs.append(pd.DataFrame())
159
+ else:
160
+ category_cols, rename_dict = get_category_columns(filtered_df, category)
161
+ logger.info(f"筛选后类别 {category['name']} 的列: {category_cols}")
162
+
163
+ display_df = filtered_df[category_cols].copy()
164
+ display_df = display_df.rename(columns=rename_dict)
165
+
166
+ if 'model_name' in display_df.columns:
167
+ display_df['model_name'] = display_df['model_name'].str.slice(0, 25) + \
168
+ (display_df['model_name'].str.len() > 25).map({True: '...', False: ''})
169
+
170
+ data_outputs.append(display_df)
171
+
172
+ empty_msg = "⚠️ 没有找到符合筛选条件的模型。" if filtered_df.empty else ""
173
+ data_outputs.append(empty_msg)
174
+ logger.info("筛选应用完成")
175
+ return data_outputs
176
+
177
+ except Exception as e:
178
+ error_msg = f"❌ 筛选失败: {str(e)}"
179
+ logger.error(f"筛选失败: {str(e)}\n{traceback.format_exc()}")
180
+ categories = get_metric_categories()
181
+ return [pd.DataFrame() for _ in categories] + [error_msg]
182
+
183
+
184
+ def create_interface():
185
+ """创建Gradio界面,实现多语言切换及固定列功能"""
186
+ try:
187
+ model_type_choices = get_model_type_choices()
188
+ except Exception as e:
189
+ model_type_choices = ["All"]
190
+ print(f"获取模型类型选项时出错: {str(e)}")
191
+
192
+ try:
193
+ strategy_choices = get_strategy_choices(RESULTS_PATH)
194
+ except Exception as e:
195
+ strategy_choices = []
196
+ print(f"获取策略选项时出错: {str(e)}")
197
+
198
+ categories = get_metric_categories()
199
+
200
+ with gr.Blocks(title="Aries 模型评估排行榜") as demo:
201
+ # 添加CSS确保model_name列固定
202
+ gr.HTML("""
203
+ <style>
204
+ .fixed-column-table {
205
+ overflow: visible !important;
206
+ position: relative !important;
207
+ max-height: 90vh !important;
208
+ height: auto !important;
209
+ }
210
+
211
+ .fixed-column-table td,
212
+ .fixed-column-table th {
213
+ padding: 0.2rem 0.3rem !important;
214
+ }
215
+
216
+ .fixed-column-table table th:first-child,
217
+ .fixed-column-table table td:first-child {
218
+ position: sticky !important;
219
+ left: 0 !important;
220
+ z-index: 2 !important;
221
+ background-color: white !important;
222
+ color: #333 !important;
223
+ min-width: 150px !important;
224
+ max-width: 150px !important;
225
+ font-weight: bold !important;
226
+ box-shadow: 1px 0 2px rgba(0,0,0,0.1) !important;
227
+ }
228
+
229
+ .fixed-column-table table thead th {
230
+ position: sticky !important;
231
+ top: 0 !important;
232
+ z-index: 1 !important;
233
+ background-color: white !important;
234
+ color: #333 !important;
235
+ }
236
+
237
+ .fixed-column-table table thead th:first-child {
238
+ z-index: 3 !important;
239
+ }
240
+
241
+ /* 修改这里:允许第二列及其他列自动换行 */
242
+ .fixed-column-table table th:nth-child(2),
243
+ .fixed-column-table table td:nth-child(2) {
244
+ min-width: 215px !important;
245
+ /* 移除固定最大宽度限制 */
246
+ /* max-width: 215px !important; */
247
+ /* 允许文本换行 */
248
+ white-space: normal !important;
249
+ /* 移除溢出隐藏和省略号 */
250
+ overflow: visible !important;
251
+ text-overflow: clip !important;
252
+ }
253
+
254
+ /* 为其他可能的指标列添加样式 */
255
+ .fixed-column-table table th:not(:first-child):not(:nth-child(2)),
256
+ .fixed-column-table table td:not(:first-child):not(:nth-child(2)) {
257
+ white-space: normal !important;
258
+ overflow: visible !important;
259
+ text-overflow: clip !important;
260
+ }
261
+
262
+ .fixed-column-table .dataframe-container {
263
+ overflow: visible !important;
264
+ }
265
+
266
+ @media (prefers-color-scheme: dark) {
267
+ .fixed-column-table table th:first-child,
268
+ .fixed-column-table table td:first-child {
269
+ background-color: #333 !important;
270
+ color: #fff !important;
271
+ box-shadow: 1px 0 2px rgba(0,0,0,0.3) !important;
272
+ }
273
+
274
+ .fixed-column-table table thead th {
275
+ background-color: #333 !important;
276
+ color: #fff !important;
277
+ }
278
+ }
279
+ </style>
280
+ """)
281
+
282
+ # 保存标题组件引用
283
+ title_markdown = gr.Markdown(f"# {lang.get('title')}")
284
+
285
+ # 添加语言切换按钮
286
+ with gr.Row():
287
+ lang_btn = gr.Button(f"Switch to English" if lang.current_lang == "zh" else f"切换至中文")
288
+
289
+ with gr.Tabs() as main_tabs:
290
+ # 模型排行榜标签页
291
+ with gr.Tab(lang.get("model_leaderboard")) as leaderboard_tab:
292
+ # 保存筛选条件标题引用
293
+ filter_conditions = gr.Markdown(f"### {lang.get('filter_conditions')}")
294
+
295
+ with gr.Row():
296
+ with gr.Column(scale=1):
297
+ model_type = gr.Dropdown(
298
+ choices=model_type_choices,
299
+ label=lang.get("model_type"),
300
+ value="All"
301
+ )
302
+
303
+ strategies = gr.CheckboxGroup(
304
+ choices=strategy_choices,
305
+ label=lang.get("strategies"),
306
+ value=[]
307
+ )
308
+
309
+ filter_mode = gr.Radio(
310
+ choices=[lang.get("intersection"), lang.get("union")],
311
+ label=lang.get("filter_mode"),
312
+ value=lang.get("intersection")
313
+ )
314
+
315
+ with gr.Row():
316
+ refresh_btn = gr.Button(lang.get("refresh"))
317
+ apply_btn = gr.Button(lang.get("apply_filters"))
318
+
319
+ with gr.Column(scale=3):
320
+ empty_state = gr.Markdown(visible=False)
321
+
322
+ with gr.Tabs() as category_tabs:
323
+ category_dataframes = []
324
+ category_tabs_list = []
325
+ for category in categories:
326
+ tab = gr.Tab(category["name"])
327
+ category_tabs_list.append(tab)
328
+ with tab:
329
+ df_component = gr.Dataframe(
330
+ interactive=False,
331
+ wrap=True,
332
+ label=category["description"],
333
+ elem_classes="fixed-column-table"
334
+ )
335
+ category_dataframes.append(df_component)
336
+
337
+ # 关于标签页 - 支持多语言切换
338
+ about_tab = gr.Tab(lang.get("about_tab"))
339
+ with about_tab:
340
+ about_markdown = gr.Markdown(
341
+ f"## {lang.get('about_title')}\n{lang.get('about_content')}"
342
+ )
343
+
344
+ # 事件处理
345
+ apply_btn.click(
346
+ fn=apply_filters,
347
+ inputs=[model_type, strategies, filter_mode],
348
+ outputs=category_dataframes + [empty_state]
349
+ )
350
+
351
+ refresh_btn.click(
352
+ fn=refresh_leaderboard,
353
+ outputs=category_dataframes + [empty_state]
354
+ )
355
+
356
+ demo.load(
357
+ fn=refresh_leaderboard,
358
+ outputs=category_dataframes + [empty_state]
359
+ )
360
+
361
+ def toggle_language():
362
+ new_lang = lang.switch_language()
363
+ btn_text = "切换至中文" if new_lang == "en" else "Switch to English"
364
+
365
+ # 更新标题
366
+ new_title = gr.update(value=f"# {lang.get('title')}")
367
+
368
+ # 更新标签页标题
369
+ leaderboard_tab_title = gr.update(label=lang.get("model_leaderboard"))
370
+
371
+ # 更新筛选条件标题
372
+ new_filter_conditions = gr.update(value=f"### {lang.get('filter_conditions')}")
373
+
374
+ # 更新各种组件的标签
375
+ new_model_type_label = gr.update(label=lang.get("model_type"))
376
+ new_strategies_label = gr.update(label=lang.get("strategies"))
377
+ new_filter_mode_label = gr.update(label=lang.get("filter_mode"))
378
+ new_refresh_label = gr.update(value=lang.get("refresh"))
379
+ new_apply_label = gr.update(value=lang.get("apply_filters"))
380
+ new_filter_mode_choices = [lang.get("intersection"), lang.get("union")]
381
+ new_filter_mode = gr.update(
382
+ choices=new_filter_mode_choices,
383
+ value=lang.get("intersection")
384
+ )
385
+
386
+ # 重新获取多语言配置
387
+ new_categories = get_metric_categories()
388
+ refreshed_data = refresh_leaderboard()
389
+ dataframes = refreshed_data[:-1]
390
+ empty_state_msg = refreshed_data[-1]
391
+
392
+ # 准备更新列表
393
+ updates = [
394
+ btn_text,
395
+ new_title,
396
+ leaderboard_tab_title,
397
+ new_filter_conditions,
398
+ new_model_type_label,
399
+ new_strategies_label,
400
+ new_filter_mode,
401
+ new_refresh_label,
402
+ new_apply_label
403
+ ]
404
+
405
+
406
+
407
+ # 更新指标类别标签页
408
+ for tab, new_cat in zip(category_tabs_list, new_categories):
409
+ updates.append(gr.update(label=new_cat["name"]))
410
+
411
+
412
+ # 更新指标表格
413
+ for df_comp, new_cat, df in zip(category_dataframes, new_categories, dataframes):
414
+ updates.append(gr.update(
415
+ label=new_cat["description"],
416
+ value=df,
417
+ visible=True
418
+ ))
419
+
420
+ # 更新空状态提示
421
+ updates.append(gr.update(value=empty_state_msg, visible=bool(empty_state_msg)))
422
+ updates.append(gr.update(label=lang.get("about_tab")))
423
+ updates.append(gr.update(value=f"## {lang.get('about_title')}\n{lang.get('about_content')}"))
424
+
425
+ return updates
426
+
427
+ # 语言切换按钮绑定
428
+ lang_btn.click(
429
+ fn=toggle_language,
430
+ inputs=[],
431
+ outputs=[
432
+ lang_btn,
433
+ title_markdown,
434
+ leaderboard_tab,
435
+ filter_conditions,
436
+ model_type,
437
+ strategies,
438
+ filter_mode,
439
+ refresh_btn,
440
+ apply_btn
441
+ ] + category_tabs_list + category_dataframes + [empty_state, about_tab, about_markdown]
442
+ )
443
+
444
+ return demo
445
+
446
+
447
+ if __name__ == "__main__":
448
+ print(f"正在启动Aries模型评估排行榜,结果目录: {RESULTS_PATH}")
449
+ demo = create_interface()
450
  demo.launch()
src/__pycache__/language.cpython-39.pyc CHANGED
Binary files a/src/__pycache__/language.cpython-39.pyc and b/src/__pycache__/language.cpython-39.pyc differ
 
src/language.py CHANGED
@@ -1,129 +1,129 @@
1
- # src/language.py
2
- class LanguageManager:
3
- def __init__(self):
4
- self.current_lang = "en" # 默认中文
5
- self.translations = {
6
- "zh": {
7
- # app.py 中的文本
8
- "title": "🚀 ARIES TEST 预测模型性能排名",
9
- "model_leaderboard": "模型排行榜",
10
- "filter_conditions": "筛选条件",
11
- "model_type": "模型类型",
12
- "strategies": "策略",
13
- "filter_mode": "筛选模式",
14
- "refresh": "刷新",
15
- "apply_filters": "应用筛选",
16
- "all": "All", # 保持英文
17
- "intersection": "交集 (满足所有选中策略)",
18
- "union": "并集 (满足任一选中策略)",
19
- "no_results": "⚠️ 没有找到符合筛选条件的模型。",
20
- "results_dir_not_exist": "❌ 结果目录不存在: {path}",
21
- "not_a_directory": "❌ {path} 不是一个目录",
22
- "no_model_data": "⚠️ 找到模型文件夹,但无法加载数据",
23
- "no_model_folders": "⚠️ 未在 {path} 中找到模型",
24
- "switch_lang": "切换语言",
25
-
26
- # 指标类别 - src/display/filters.py
27
- "regular_metrics": "总体性能",
28
- "stationarity": "平稳性/非平稳性",
29
- "trend_strength": "趋势强度",
30
- "seasonality_strength": "季节强度",
31
- "seasonality_count": "季节数",
32
- "volatility": "波动性",
33
- "memory": "记忆性",
34
- "variance_characteristics": "方差特性",
35
- "outliers": "异常值",
36
-
37
- # 指标描述
38
- "regular_desc": "总体性能的评估指标,在所有Synth子序列上的性能",
39
- "stationarity_desc": "模型在平稳和非平稳序列上的表现",
40
- "trend_strength_desc": "模型在不同趋势强度数据上的表现",
41
- "seasonality_strength_desc": "模型在不同季节强度数据上的表现",
42
- "seasonality_count_desc": "模型在不同季节计数(周期数量)数据上的表现",
43
- "volatility_desc": "模型在不同波动性特征数据上的表现",
44
- "memory_desc": "模型在不同记忆性特征数据上的表现",
45
- "variance_characteristics_desc": "模型在同方差和异方差数据上的表现",
46
- "outliers_desc": "模型在包含不同比例异常值数据上的表现",
47
-
48
- "about_tab": "关于", # 标签页名称
49
- "about_title": "关于 ARIES TEST 预测模型性能排名", # 标题
50
- "about_content": "该排行榜展示了各种模型在标准基准测试中的表现,包含所有评估指标。\n\n"
51
- "### 评估范围\n"
52
- "- 支持多种时间序列预测模型\n"
53
- "- 涵盖平稳性、趋势强度等多维度指标\n"
54
- "- 实时更新最新模型性能数据\n" # 带Markdown格式的内容
55
- "\n我们的所有baselines来自BasicTS: https://github.com/GestaltCogTeam/BasicTS\n"
56
- "\n我们的数据集已经在HuggingFace上开源:https://huggingface.co/datasets/Blisky-li/ARIES_Synth\n"
57
- "\n我们的论文已经开源:https://arxiv.org/abs/2509.06060\n"
58
-
59
- },
60
- "en": {
61
- # app.py 中的文本
62
- "title": "🚀 ARIES TEST: Forecasting Model Performance Rankings",
63
- "model_leaderboard": "Model Leaderboard",
64
- "filter_conditions": "Filter Conditions",
65
- "model_type": "Model Type",
66
- "strategies": "Strategies",
67
- "filter_mode": "Filter Mode",
68
- "refresh": "Refresh",
69
- "apply_filters": "Apply Filters",
70
- "all": "All",
71
- "intersection": "Intersection (meet all selected strategies)",
72
- "union": "Union (meet any selected strategy)",
73
- "no_results": "⚠️ No models found matching the filter criteria.",
74
- "results_dir_not_exist": "❌ Results directory does not exist: {path}",
75
- "not_a_directory": "❌ {path} is not a directory",
76
- "no_model_data": "⚠️ Model folders found, but unable to load data",
77
- "no_model_folders": "⚠️ No models found in {path}",
78
-
79
- # 指标类别
80
- "regular_metrics": "Regular Metrics",
81
- "stationarity": "Stationarity/Non-stationarity",
82
- "trend_strength": "Trend Strength",
83
- "seasonality_strength": "Seasonality Strength",
84
- "seasonality_count": "Seasonality Count",
85
- "volatility": "Volatility",
86
- "memory": "Memory",
87
- "variance_characteristics": "Variance Characteristics",
88
- "outliers": "Anomalies",
89
-
90
- # 指标描述
91
- "regular_desc": "Overall performance across all Synth sub-sequences",
92
- "stationarity_desc": "Model performance on stationary and non-stationary sequences",
93
- "trend_strength_desc": "Model performance on data with different trend strengths",
94
- "seasonality_strength_desc": "Model performance on data with different seasonality strengths",
95
- "seasonality_count_desc": "Model performance on data with different seasonality counts (number of cycles)",
96
- "volatility_desc": "Model performance on data with different volatility characteristics",
97
- "memory_desc": "Model performance on data with different memory characteristics",
98
- "variance_characteristics_desc": "Model performance on homoscedastic and heteroscedastic data",
99
- "outliers_desc": "Model performance on data containing different proportions of outliers",
100
- "switch_lang": "Switch Language",
101
-
102
- "about_tab": "About", # 标签页名称
103
- "about_title": "About ARIES TEST: Forecasting Model Performance Rankings", # 标题
104
- "about_content": "This leaderboard displays the performance of various models on standard benchmark tests in ARIES, including all evaluation metrics.\n\n"
105
- "### Evaluation Scope\n"
106
- "- Supports multiple time series forecasting models\n"
107
- "- Covers multi-dimensional metrics such as stationarity and trend strength\n"
108
- "- Real-time updates of the latest model performance data\n"
109
- "\nOur baselines come from BasicTS: https://github.com/GestaltCogTeam/BasicTS\n"
110
- "\nOur datasets is upload to Hugging Face: https://huggingface.co/datasets/Blisky-li/ARIES_Synth\n"
111
- "\nOur paper is now accessible: https://arxiv.org/abs/2509.06060" , # 带Markdown格式的内容
112
- }
113
- }
114
-
115
- def switch_language(self):
116
- """切换语言"""
117
- self.current_lang = "en" if self.current_lang == "zh" else "zh"
118
- return self.current_lang
119
-
120
- def get(self, key, **kwargs):
121
- """获取翻译文本,支持格式化参数"""
122
- text = self.translations[self.current_lang].get(key, key)
123
- if kwargs:
124
- return text.format(**kwargs)
125
- return text
126
-
127
-
128
- # 创建全局实例
129
  lang = LanguageManager()
 
1
+ # src/language.py
2
+ class LanguageManager:
3
+ def __init__(self):
4
+ self.current_lang = "en" # 默认中文
5
+ self.translations = {
6
+ "zh": {
7
+ # app.py 中的文本
8
+ "title": "🚀 ARIES TEST 预测模型性能排名",
9
+ "model_leaderboard": "模型排行榜",
10
+ "filter_conditions": "筛选条件",
11
+ "model_type": "模型类型",
12
+ "strategies": "策略",
13
+ "filter_mode": "筛选模式",
14
+ "refresh": "刷新",
15
+ "apply_filters": "应用筛选",
16
+ "all": "All", # 保持英文
17
+ "intersection": "交集 (满足所有选中策略)",
18
+ "union": "并集 (满足任一选中策略)",
19
+ "no_results": "⚠️ 没有找到符合筛选条件的模型。",
20
+ "results_dir_not_exist": "❌ 结果目录不存在: {path}",
21
+ "not_a_directory": "❌ {path} 不是一个目录",
22
+ "no_model_data": "⚠️ 找到模型文件夹,但无法加载数据",
23
+ "no_model_folders": "⚠️ 未在 {path} 中找到模型",
24
+ "switch_lang": "切换语言",
25
+
26
+ # 指标类别 - src/display/filters.py
27
+ "regular_metrics": "总体性能",
28
+ "stationarity": "平稳性",
29
+ "trend_strength": "趋势强度",
30
+ "seasonality_strength": "季节强度",
31
+ "seasonality_count": "季节数",
32
+ "volatility": "波动性",
33
+ "memory": "记忆性",
34
+ "variance_characteristics": "方差特性",
35
+ "outliers": "异常值",
36
+
37
+ # 指标描述
38
+ "regular_desc": "总体性能的评估指标,在所有Synth子序列上的性能",
39
+ "stationarity_desc": "模型在平稳和非平稳序列上的表现",
40
+ "trend_strength_desc": "模型在不同趋势强度数据上的表现",
41
+ "seasonality_strength_desc": "模型在不同季节强度数据上的表现",
42
+ "seasonality_count_desc": "模型在不同季节计数(周期数量)数据上的表现",
43
+ "volatility_desc": "模型在不同波动性特征数据上的表现",
44
+ "memory_desc": "模型在不同记忆性特征数据上的表现",
45
+ "variance_characteristics_desc": "模型在同方差和异方差数据上的表现",
46
+ "outliers_desc": "模型在包含不同比例异常值数据上的表现",
47
+
48
+ "about_tab": "关于", # 标签页名称
49
+ "about_title": "关于 ARIES TEST 预测模型性能排名", # 标题
50
+ "about_content": "该排行榜展示了各种模型在标准基准测试中的表现,包含所有评估指标。\n\n"
51
+ "### 评估范围\n"
52
+ "- 支持多种时间序列预测模型\n"
53
+ "- 涵盖平稳性、趋势强度等多维度指标\n"
54
+ "- 实时更新最新模型性能数据\n" # 带Markdown格式的内容
55
+ "\n我们的所有baselines来自BasicTS: https://github.com/GestaltCogTeam/BasicTS\n"
56
+ "\n我们的数据集已经在HuggingFace上开源:https://huggingface.co/datasets/Blisky-li/ARIES_Synth\n"
57
+ "\n我们的论文已经开源:https://arxiv.org/abs/2509.06060\n"
58
+
59
+ },
60
+ "en": {
61
+ # app.py 中的文本
62
+ "title": "🚀 ARIES TEST: Forecasting Model Performance Rankings",
63
+ "model_leaderboard": "Model Leaderboard",
64
+ "filter_conditions": "Filter Conditions",
65
+ "model_type": "Model Type",
66
+ "strategies": "Strategies",
67
+ "filter_mode": "Filter Mode",
68
+ "refresh": "Refresh",
69
+ "apply_filters": "Apply Filters",
70
+ "all": "All",
71
+ "intersection": "Intersection (meet all selected strategies)",
72
+ "union": "Union (meet any selected strategy)",
73
+ "no_results": "⚠️ No models found matching the filter criteria.",
74
+ "results_dir_not_exist": "❌ Results directory does not exist: {path}",
75
+ "not_a_directory": "❌ {path} is not a directory",
76
+ "no_model_data": "⚠️ Model folders found, but unable to load data",
77
+ "no_model_folders": "⚠️ No models found in {path}",
78
+
79
+ # 指标类别
80
+ "regular_metrics": "Regular",
81
+ "stationarity": "Stationarity",
82
+ "trend_strength": "Trend Strength",
83
+ "seasonality_strength": "Seasonality Strength",
84
+ "seasonality_count": "Seasonality Count",
85
+ "volatility": "Volatility",
86
+ "memory": "Memory",
87
+ "variance_characteristics": "Scadasticity",
88
+ "outliers": "Anomaly",
89
+
90
+ # 指标描述
91
+ "regular_desc": "Overall performance across all Synth sub-sequences",
92
+ "stationarity_desc": "Model performance on stationary and non-stationary sequences",
93
+ "trend_strength_desc": "Model performance on data with different trend strengths",
94
+ "seasonality_strength_desc": "Model performance on data with different seasonality strengths",
95
+ "seasonality_count_desc": "Model performance on data with different seasonality counts (number of cycles)",
96
+ "volatility_desc": "Model performance on data with different volatility characteristics",
97
+ "memory_desc": "Model performance on data with different memory characteristics",
98
+ "variance_characteristics_desc": "Model performance on homoscedastic and heteroscedastic data",
99
+ "outliers_desc": "Model performance on data containing different proportions of outliers",
100
+ "switch_lang": "Switch Language",
101
+
102
+ "about_tab": "About", # 标签页名称
103
+ "about_title": "About ARIES TEST: Forecasting Model Performance Rankings", # 标题
104
+ "about_content": "This leaderboard displays the performance of various models on standard benchmark tests in ARIES, including all evaluation metrics.\n\n"
105
+ "### Evaluation Scope\n"
106
+ "- Supports multiple time series forecasting models\n"
107
+ "- Covers multi-dimensional metrics such as stationarity and trend strength\n"
108
+ "- Real-time updates of the latest model performance data\n"
109
+ "\nOur baselines come from BasicTS: https://github.com/GestaltCogTeam/BasicTS\n"
110
+ "\nOur datasets is upload to Hugging Face: https://huggingface.co/datasets/Blisky-li/ARIES_Synth\n"
111
+ "\nOur paper is now accessible: https://arxiv.org/abs/2509.06060" , # 带Markdown格式的内容
112
+ }
113
+ }
114
+
115
+ def switch_language(self):
116
+ """切换语言"""
117
+ self.current_lang = "en" if self.current_lang == "zh" else "zh"
118
+ return self.current_lang
119
+
120
+ def get(self, key, **kwargs):
121
+ """获取翻译文本,支持格式化参数"""
122
+ text = self.translations[self.current_lang].get(key, key)
123
+ if kwargs:
124
+ return text.format(**kwargs)
125
+ return text
126
+
127
+
128
+ # 创建全局实例
129
  lang = LanguageManager()