Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
138 lines
5.2 KiB
Python
138 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
测试脚本:完整Pipeline - 数据加载→赋分→PCA→标准化→水平判定→统计分析
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
import json
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "backend"))
|
|
|
|
from app.engines.data_engine import DataEngine
|
|
from app.engines.scoring_engine import ScoringEngine
|
|
from app.engines.stats_engine import StatsEngine
|
|
from app.config import DIMENSION_FRAMEWORK, LEVEL_THRESHOLDS
|
|
import logging
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s")
|
|
|
|
|
|
def main():
|
|
print("=" * 80)
|
|
print("完整Pipeline测试:Excel → 赋分 → PCA → 标准化 → 水平判定")
|
|
print("=" * 80)
|
|
|
|
# Step 1: 加载数据
|
|
print("\n[Step 1] 加载Excel数据...")
|
|
data_engine = DataEngine()
|
|
data_engine.load_all()
|
|
|
|
# Step 2: 赋分
|
|
print("\n[Step 2] 对所有学校进行赋分...")
|
|
scoring_engine = ScoringEngine(data_engine)
|
|
raw_scores = scoring_engine.score_all_schools()
|
|
|
|
# 打印赋分结果概要
|
|
print("\n📊 赋分结果概要:")
|
|
for school in data_engine.schools:
|
|
scores = raw_scores[school]
|
|
print(f"\n 🏫 {school}:")
|
|
for dim, vals in scores.items():
|
|
avg = sum(vals) / len(vals) if vals else 0
|
|
print(f" {dim}: {len(vals)}个指标, 均值={avg:.2f}, 值={[round(v,1) for v in vals[:5]]}{'...' if len(vals) > 5 else ''}")
|
|
|
|
# Step 3: 统计分析
|
|
print("\n[Step 3] PCA合成 + 标准化...")
|
|
stats_engine = StatsEngine()
|
|
sub_scores = stats_engine.compute_dimension_scores(raw_scores)
|
|
print(f"\n三级维度标准化得分 (均值50, 标准差10):")
|
|
print(sub_scores.round(2).to_string())
|
|
|
|
# Step 4: 二级维度聚合
|
|
print("\n[Step 4] 二级维度聚合...")
|
|
dim_scores = stats_engine.compute_dimension_aggregates(sub_scores)
|
|
print(f"\n二级维度得分:")
|
|
print(dim_scores.round(2).to_string())
|
|
|
|
# Step 5: 水平判定
|
|
print("\n[Step 5] 水平判定...")
|
|
levels = stats_engine.compute_levels(sub_scores)
|
|
print(f"\n各学校各维度水平:")
|
|
print(levels.to_string())
|
|
|
|
# Step 6: 聚类分析
|
|
print("\n[Step 6] 聚类分析...")
|
|
dim_cols = [c for c in dim_scores.columns if c in DIMENSION_FRAMEWORK]
|
|
clusters = stats_engine.cluster_analysis(dim_scores[dim_cols])
|
|
print(f"\n学校聚类结果:")
|
|
for school, cluster in clusters["school_clusters"].items():
|
|
print(f" {school}: {cluster}")
|
|
|
|
# Step 7: 相关性
|
|
print("\n[Step 7] 维度间相关性:")
|
|
corr = stats_engine.correlation_analysis(dim_scores)
|
|
print(corr.round(3).to_string())
|
|
|
|
# Step 8: 生成一所学校的完整报告数据
|
|
test_school = "延安中学"
|
|
print(f"\n[Step 8] 生成 {test_school} 的完整报告数据包...")
|
|
report_data = stats_engine.compute_school_report_data(test_school, sub_scores, dim_scores)
|
|
|
|
print(f"\n📋 {test_school} 报告数据概要:")
|
|
print(f" 总体得分: {report_data['overall']['score']}")
|
|
print(f" 区内排名: {report_data['overall']['rank_in_district']}/{report_data['overall']['total_schools']}")
|
|
print(f" 聚类类型: {report_data['overall']['cluster']}")
|
|
|
|
print(f"\n 二级维度得分:")
|
|
for dim, data in report_data['dimensions'].items():
|
|
print(f" {dim}: {data['score']} (区均值{data['district_avg']}, 差异{data['diff_district']:+.2f})")
|
|
|
|
print(f"\n 三级维度水平:")
|
|
for sub_dim, data in report_data['sub_dimensions'].items():
|
|
print(f" {sub_dim}: 得分{data['score']}, 水平{data['level']}, {data['level_description'][:30]}")
|
|
|
|
# 保存报告数据为JSON
|
|
output_dir = Path(__file__).parent.parent / "output"
|
|
output_dir.mkdir(exist_ok=True)
|
|
|
|
# 清理numpy类型以便JSON序列化
|
|
def clean_for_json(obj):
|
|
import numpy as np
|
|
if isinstance(obj, dict):
|
|
return {k: clean_for_json(v) for k, v in obj.items()}
|
|
elif isinstance(obj, list):
|
|
return [clean_for_json(v) for v in obj]
|
|
elif isinstance(obj, (np.integer,)):
|
|
return int(obj)
|
|
elif isinstance(obj, (np.floating,)):
|
|
return round(float(obj), 4)
|
|
elif isinstance(obj, np.ndarray):
|
|
return obj.tolist()
|
|
elif isinstance(obj, float):
|
|
return round(obj, 4)
|
|
return obj
|
|
|
|
report_clean = clean_for_json(report_data)
|
|
with open(output_dir / f"{test_school}_report_data.json", "w", encoding="utf-8") as f:
|
|
json.dump(report_clean, f, ensure_ascii=False, indent=2)
|
|
print(f"\n✅ 报告数据已保存到 output/{test_school}_report_data.json")
|
|
|
|
# 保存所有学校的得分汇总
|
|
all_scores = {
|
|
"sub_dimension_scores": clean_for_json(sub_scores.to_dict()),
|
|
"dimension_scores": clean_for_json(dim_scores.to_dict()),
|
|
"levels": clean_for_json(levels.to_dict()),
|
|
"clusters": clean_for_json(clusters),
|
|
}
|
|
with open(output_dir / "all_schools_scores.json", "w", encoding="utf-8") as f:
|
|
json.dump(all_scores, f, ensure_ascii=False, indent=2)
|
|
print(f"✅ 全校得分汇总已保存到 output/all_schools_scores.json")
|
|
|
|
print("\n" + "=" * 80)
|
|
print("✅ 完整Pipeline测试完成!")
|
|
print("=" * 80)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|