# 通用语体分析器 v0.3.0 操作手册

## 一、工具简介

通用语体分析器 v0.3.0（GeneralStylisticAnalyzer）是一个面向中国近现代作家作品的语体分析工具，可对任意中文文本进行五维语体指标计算、跨作家校准分类、谱系可视化与基准库批处理扩充。

**v0.3.0 相对 v0.2.1 的核心升级**：
- 基准库从 **30 篇 / 17 位作家** 扩充至 **88 篇 / 55 位作家**（覆盖 9 大流派）
- 新增 **双版本校准** 机制：`calibrate('v0.2.1')`（默认，100% 向后兼容）与 `calibrate('v0.3.0')`（63 篇 train，分位数更稳定）
- 新增 5 个加载器 API：`load_full_benchmark` / `load_val_samples` / `load_test_samples` / `load_samples_by`
- 新增 **谱系可视化** 模块 `lineage_pca_v030.py`：PCA 降维 + 流派颜色编码 + 融合度红框标记
- 新增 **批处理流水线** `batch_pipeline_v030.py`：注册 → 预计算 → 幂等追加 → 兼容性回归测试（四步一键完成）
- 61 项兼容性回归测试全绿，v0.2.1 旧脚本零修改即可运行

**核心功能**（继承 v0.2.1）：
- 计算五维原始语体指标：文言密度、白话密度、欧化指数、大众语指数、融合度
- 跨作家校准（分位数映射 + z-score，线性插值法）
- cross_quantile 宏观语体分类（文言 / 文白交织 / 白话 / 混合语体）
- 作家内 z-score（当基准库中该作家样本 ≥2 时启用）

---

## 一·补、适用范围

本工具的基准库基于 **1895—1999 年** 中国近现代作家作品构建（以 1900—1949 为主体），分位数映射反映的是文本在这一时期语体空间中的相对位置。

- **域内使用**（1900—1949 年代文本）：分位数可直接解释为"在该时期作家中的相对位置"。
- **域外使用**（1950 后文本）：分位数的绝对值意义会发生变化，需谨慎解释。例如，当代学术文本的"文言分位 0.15"不意味着"文言影响很低"，而是"在民国基准库中排到底部 15%"。建议域外使用时同时报告 raw 值和基准库分布摘要。
- v0.3.0 基准库已含少量域外样本（如萧乾 1999、王元化 1979），用于验证域外文本在域内基准中的表现，不代表分位数可直接外推。

---

## 二、环境要求

| 项目 | 要求 |
|------|------|
| Python 版本 | 3.8 及以上（已在 3.14 测试通过） |
| 操作系统 | Windows / macOS / Linux 均可 |
| 外部依赖库 | jieba（中文分词）、scikit-learn、pandas、numpy、matplotlib（仅谱系可视化需要） |
| 标准库 | os, sys, json, re, bisect, statistics, collections, pathlib |

> 仅做五维分析（不含谱系图）只需 `jieba`；谱系可视化需额外安装 `scikit-learn pandas numpy matplotlib`。

---

## 三、安装步骤

### 3.1 解压

将 `general_stylistic_analyzer_v0.3.0.zip` 解压到任意目录，例如：

```
D:\tools\general_stylistic_analyzer_v0.3.0\
├── general_stylistic_analyzer.py     # 核心分析器
├── v2_analyzer.py                    # 底层依赖（五维raw+六功能+潜语言检测）
├── three_style_classifier.py         # 最底层依赖（三语体基础分类）
├── benchmark_self_contained.json     # 自包含基准库（88篇，55位作家，含预计算指标）
├── benchmark_loader.py               # 基准库加载器（双版本，无外部依赖）
├── example_usage.py                  # 示例脚本（v0.2.1兼容模式）
├── tests_compatibility.py            # 61项兼容性回归测试
├── batch_pipeline_v030.py            # 批处理流水线（注册/预计算/追加/测试）
├── lineage_pca_v030.py               # 谱系可视化（PCA气泡图）
├── register_batch002~005.py          # 各批次注册脚本（可作模板复用）
├── fill_schema_fields_v030.py        # schema 补填工具
├── _inspect_state.py                 # 主库状态盘点工具
├── requirements.txt                  # 依赖清单
├── 操作手册.md                        # 本文件
├── v030_benchmark_index.md           # 基准库索引（88样本清单）
├── v030_benchmark_text_sources.md    # 文本来源说明
├── _benchmark_v030_fetch/            # 批处理数据目录
│   ├── txt/                          # 58 篇全文 txt（公版/公开选段）
│   └── batch00X_manifest.json        # 各批次元数据 manifest
├── _v030_outputs/                    # 谱系图输出目录
│   ├── lineage_pca_v030.png
│   ├── lineage_pca_v030.svg
│   └── lineage_pca_v030.csv
└── lineage/                          # 作家个人谱系分析子模块
```

### 3.2 安装依赖

```bash
pip install jieba scikit-learn pandas numpy matplotlib
```

### 3.3 验证安装

```bash
cd D:\tools\general_stylistic_analyzer_v0.3.0
python example_usage.py           # v0.2.1 兼容 demo
python tests_compatibility.py     # 61 项回归测试（应全绿）
```

---

## 四、快速开始（5 分钟上手）

### 4.1 分析单篇文本（v0.2.1 兼容模式，旧脚本零修改）

```python
import sys
sys.path.insert(0, '.')

from general_stylistic_analyzer import GeneralStylisticAnalyzer
from benchmark_loader import load_train_samples

train_samples = load_train_samples()          # 默认 v0.2.1 → 19 篇 train
analyzer = GeneralStylisticAnalyzer()
analyzer.calibrate(train_samples)             # 等价于 calibrate('v0.2.1')

text = "吾幼时好读书，虽不能解其义，然颇好之。"
result = analyzer.normalize_and_classify(
    analyzer.analyze_text(text, title='测试', author='佚名', year=1920))
print(f"分类: {result['classification']}")
print(f"文言分位: {result['cross_quantile']['classical_density']:.3f}")
```

### 4.2 分析单篇文本（v0.3.0 新版，63 篇 train 校准更稳定）

```python
from general_stylistic_analyzer import GeneralStylisticAnalyzer

analyzer = GeneralStylisticAnalyzer()
analyzer.calibrate('v0.3.0')                  # ← 一行切版，63 篇 train 动态算分位数

text = "这是一沟绝望的死水，清风吹不起半点漪沦。"
result = analyzer.normalize_and_classify(
    analyzer.analyze_text(text, title='死水', author='闻一多', year=1928))
print(f"分类: {result['classification']}")
print(f"校准版本: {analyzer._calibrated_version}")   # → 'v0.3.0'
```

### 4.3 生成谱系 PCA 图（v0.3.0 新功能）

```bash
python lineage_pca_v030.py
# 输出：_v030_outputs/lineage_pca_v030.png + .svg + .csv
```

谱系图说明：
- **PC1（横轴，右=文言↑ / 左=白话↑）**：方差解释 ~58%
- **PC2（纵轴，上=欧化↑ / 下=大众语↑）**：方差解释 ~26%
- **气泡大小**：由潜语言指数（OSI / old_submerged_index）决定
- **气泡颜色**：9 大粗粒度流派（A 文言锚点 / B 语丝派 / C 文学研究会 / D 创造社 / E 左翼 / F 新月 / G 京派 / H 海派通俗 / I 学术文论）
- **红色边框**：融合度 fusion_index ≥ 0.040 的样本（文白并用度突出）

### 4.4 批量扩充基准库（v0.3.0 新功能）

```bash
# 1) 编写注册脚本（参考 register_batch005.py 模板）
python register_batch005.py                    # 生成 manifest JSON

# 2) 一键跑四步流水线
python batch_pipeline_v030.py -m _benchmark_v030_fetch/batch005_manifest.json all
#   step1: 注册样本元数据
#   step2: precompute 五维指标
#   step3: 幂等追加到主库（自动备份，跳过重复 id）
#   step4: 61 项兼容性回归测试
```

---

## 五、API 详解

### 5.1 benchmark_loader.py（v0.3.0 加载器）

| API | 说明 | 返回 |
|-----|------|------|
| `load_benchmark()` | v0.2.1 冻结 30 篇（JSON 前 30 条） | list[dict] |
| `load_train_samples(version='v0.2.1')` | train-split 样本；`'v0.2.1'`→19篇，`'v0.3.0'`→63篇 | list[dict] |
| `load_full_benchmark(version='v0.3.0')` | 全量基准库；`'v0.3.0'`→88篇，`'v0.2.1'`→30篇 | list[dict] |
| `load_val_samples(version='v0.3.0')` | val-split（近邻验证集） | list[dict] |
| `load_test_samples(version='v0.3.0')` | test-split（盲测集，v0.2.1 返回空） | list[dict] |
| `load_samples_by(query, version='v0.3.0')` | 按元数据筛选（author/year_min/year_max/genre/split/sub_genre/literary_group/...） | list[dict] |

### 5.2 GeneralStylisticAnalyzer 类

#### `calibrate(self, samples_or_version='v0.2.1')`（v0.3.0 升级为三模式）

| 调用方式 | 校准样本 | 用途 |
|----------|----------|------|
| `calibrate()` / `calibrate('v0.2.1')` | 19 篇（v0.2.1 冻结） | **默认**，旧脚本 100% 复现 |
| `calibrate('v0.3.0')` | 63 篇 train（含新样本） | 新项目，分位数更稳定 |
| `calibrate(my_list)` | 自定义 list[dict] | 与 v0.2.1 完全等价 |

校准为**动态计算**：每次调用都从传入样本实时算 mean/stdev/percentiles，无冻结常量、无缓存文件。`self._calibrated_version` 记录所用版本。

#### `analyze_text(self, text, title='', author='', year=1936, genre='')`
计算单篇文本五维原始指标。返回 dict 含 classical_density / vernacular_density / eurasian_index / mass_index_v2 / fusion_index / old_submerged_index / char_count。

#### `normalize_and_classify(self, raw)`
完整分析：raw 五维 + 跨作家分位数（线性插值）+ z-score + 作家内 z-score + 分类。返回 dict 含 raw / cross_quantile / cross_quantile_detail / cross_zscore / within_author_zscore / classification / benchmark_summary。

---

## 六、五维指标说明

| 指标 | 字段名 | 含义 | 范围 |
|------|--------|------|------|
| 文言密度 | `classical_density` | 文言虚词/句式在文本中的密度 | 0-1 |
| 白话密度 | `vernacular_density` | 白话特征词在文本中的密度 | 0-1 |
| 欧化指数 | `eurasian_index` | 欧化句式/代词/连词密度 | 0-1 |
| 大众语指数 | `mass_index_v2` | 大众语特征（可说性/可听性/可写性/可懂性） | 0-1 |
| 融合度 | `fusion_index` | c·v/(c+v) 调和公式，**文白并用度**（非潜语言度量） | 0-0.5 |

### 附：潜语言代理指标
`old_submerged_index`（V2Analyzer 内置潜语言检测器输出），含虚词链密度、句法残留、修辞模式、凝练度四子模块。谱系图中气泡大小即由该指标决定。

---

## 七、cross_quantile 分类规则（v0.2.1 规则，v0.3.0 继承不变）

| 分类 | 规则（c_q=文言分位, v_q=白话分位, e_q=欧化分位） |
|------|---------------------------------------------------|
| 文言 | c_q ≥ 0.60 且 v_q < 0.35 |
| 文白交织（文白过渡期） | c_q ≥ 0.75 且 v_q < 0.35 且 e_q ≥ 0.20 |
| 文白交织 | c_q ≥ 0.65 且 v_q ≥ 0.35 |
| 白话 | v_q ≥ 0.40 且 c_q < 0.60 |
| 混合语体 | 兜底（不满足上述任一） |

---

## 八、基准库构成与流派分布

### 8.1 规模

| 项 | v0.2.1 | v0.3.0 |
|----|--------|--------|
| 样本数 | 30 | **88** |
| 作家数 | 17 | **55** |
| train-split | 19 | 63 |
| val-split | 0 | 20 |
| test-split | 0 | 5 |

### 8.2 九大粗粒度流派分布（88 样本）

| 流派 | 样本数 | 代表作家 |
|------|--------|----------|
| A 文言锚点 | 9 | 严复、林纾、梁启超、章太炎、吴宓、柳诒徵 |
| B 语丝派 | 24 | 鲁迅(11)、周作人(4)、钱玄同、刘半农、朱自清 |
| C 文学研究会 | 8 | 叶圣陶、茅盾、郑振铎、王统照 |
| D 创造社 | 7 | 郭沫若、郁达夫、成仿吾、田汉 |
| E 左翼作家 | 10 | 丁玲、夏衍、萧红、柔石、沙汀、艾青 |
| F 新月/现代评论派 | 8 | 胡适、徐志摩、闻一多、梁实秋、叶公超 |
| G 京派(散文化) | 8 | 沈从文、老舍、废名、萧乾、丰子恺 |
| H 海派/沦陷/通俗 | 9 | 张爱玲、钱钟书、还珠楼主、王度庐、张恨水 |
| I 学术文论派 | 5 | 朱光潜、李长之、陈望道、林语堂、王元化 |

> 完整 55 位作家名录见 `v030_benchmark_index.md`。

### 8.3 双版本校准机制（重要）

v0.3.0 的 `calibrate()` 支持 `'v0.2.1'` 与 `'v0.3.0'` 双版本切换：
- **默认 `'v0.2.1'`**：用 19 篇 train 算分位数，与 v0.2.1 数值 100% 一致（差 < 1e-9），鲁迅/胡适旧项目零修改复现。
- **`'v0.3.0'`**：用 63 篇 train 算分位数，95%CI 从 ±0.18 缩窄到 ±0.09，推荐新项目使用。

> **注意**：新增的 58 篇样本对校准分位数的影响，**仅在显式调用 `calibrate('v0.3.0')` 时生效**。默认 `calibrate()` 仍走 v0.2.1 的 19 篇。这是向后兼容设计，不是 bug。

---

## 九、批处理流水线（batch_pipeline_v030.py）

### 9.1 四步流程

```
step1 register   → 读取 manifest，注册样本元数据到 computed JSON
step2 precompute → 对 txt 全文计算五维指标，写入 computed JSON
step3 append     → 幂等追加到 benchmark_self_contained.json（自动备份，跳过重复 id）
step4 test       → 运行 61 项兼容性回归测试
```

### 9.2 用法

```bash
# 一键全跑
python batch_pipeline_v030.py -m _benchmark_v030_fetch/batch005_manifest.json all

# 分步运行
python batch_pipeline_v030.py -m _benchmark_v030_fetch/batch005_manifest.json step1
python batch_pipeline_v030.py -m _benchmark_v030_fetch/batch005_manifest.json step2
python batch_pipeline_v030.py -m _benchmark_v030_fetch/batch005_manifest.json step3
python batch_pipeline_v030.py -m _benchmark_v030_fetch/batch005_manifest.json step4
```

### 9.3 幂等性
step3 自动检测重复 id 并跳过，重复运行不会产生重复样本。每次追加前自动生成 `.bak` 备份文件。

---

## 十、方法学注意事项

### 10.1 fusion_index 陷阱（重要）
`fusion_index = c·v/(c+v)` 是**文白并用度**，不是潜语言度量：
- 纯文言（v 极小）→ fusion 低（如钱锺书《谈艺录》c=0.155, v=0.006, fusion=0.006）
- 纯白话（c 极小）→ fusion 低
- 文白并用（c、v 均中等）→ fusion 高（如王元化《文心雕龙创作论》fusion=0.040 触发红框）

**切勿用 fusion_index 作为潜语言指数代理**。潜语言分析请用 `old_submerged_index`。

### 10.2 校准版本选择建议
- 复现 v0.2.1 旧结果 → `calibrate('v0.2.1')`（默认）
- 新研究、跨作家比较 → `calibrate('v0.3.0')`（63 篇，更稳定）
- 谱系图 `lineage_pca_v030.py` 不经 calibrate，直接用 raw 五维做 PCA，不受版本影响

### 10.3 作家内 z-score
v0.3.0 中鲁迅(11)、周作人(4)、严复(3)、叶圣陶(3) 等多位作家在 train-split 有 ≥2 样本，均可启用作家内 z-score。

---

## 十一、常见问题

**Q1：v0.2.1 旧脚本能直接在 v0.3.0 运行吗？**
A：能。默认 `calibrate()` 和 `load_train_samples()` 都走 v0.2.1 冻结值，数值 100% 一致。运行 `python tests_compatibility.py` 可验证 61 项回归全绿。

**Q2：如何让校准用上 88 样本？**
A：显式调用 `analyzer.calibrate('v0.3.0')`，即用 63 篇 train 动态算分位数。

**Q3：谱系图的红框是什么？**
A：fusion_index ≥ 0.040 的样本，表示文白并用度突出（文言和白话密度都较高）。v0.3.0 共 22 个红框样本。

**Q4：如何扩充基准库？**
A：参考 `register_batch005.py` 编写注册脚本生成 manifest，然后 `python batch_pipeline_v030.py -m <manifest> all` 一键完成注册/预计算/追加/测试。

**Q5：报错 `ModuleNotFoundError: No module named 'sklearn'`？**
A：谱系可视化需要 scikit-learn。执行 `pip install scikit-learn pandas numpy matplotlib`。

---

## 十二、文件清单

| 文件 | 说明 | 必需 |
|------|------|------|
| `general_stylistic_analyzer.py` | 核心分析器（双版本校准） | 是 |
| `v2_analyzer.py` | 底层依赖（五维raw+六功能+潜语言检测） | 是 |
| `three_style_classifier.py` | 最底层依赖（三语体基础分类） | 是 |
| `benchmark_self_contained.json` | 自包含基准库（88篇，55位作家） | 是 |
| `benchmark_loader.py` | 基准库加载器（双版本 API） | 是 |
| `example_usage.py` | 示例脚本（v0.2.1 兼容） | 否 |
| `tests_compatibility.py` | 61 项兼容性回归测试 | 否 |
| `batch_pipeline_v030.py` | 批处理流水线 | 否 |
| `lineage_pca_v030.py` | 谱系可视化 | 否 |
| `register_batch002~005.py` | 批次注册脚本（可作模板） | 否 |
| `requirements.txt` | 依赖清单 | 否 |
| `操作手册.md` | 本文件 | 否 |

---

## 十三、版本信息

- **版本**：v0.3.0
- **发布日期**：2026-08-07
- **基准库规模**：88 篇 / 55 位作家 / 9 大流派
- **向后兼容**：v0.2.1 100% 兼容（61 项回归测试全绿）
- **核心升级**：
  - 基准库 30→88 篇，作家 17→55 位
  - 双版本校准（v0.2.1 冻结 / v0.3.0 动态）
  - 谱系 PCA 可视化（两轴方差解释 84%）
  - 批处理流水线（四步一键扩充基准库）
  - fusion≥0.040 红框标记（22 个高融合度样本）
