# AutoScore 全自动风控建模库中文使用手册

`AutoScore` 是一个专为信用评分卡模型开发设计的Python库，旨在通过自动化流程简化数据清洗、分箱、特征选择、模型训练及评分卡生成的全过程。

---

## 目录

1.  [安装与环境](#1-安装与环境)
2.  [快速开始](#2-快速开始)
3.  [核心类：AutoScore](#3-核心类-autoscore)
    *   [初始化](#31-初始化)
    *   [核心方法：fit](#32-核心方法-fit)
    *   [其他方法](#33-其他方法)
4.  [高级功能](#4-高级功能)
    *   [智能类型识别](#41-智能类型识别)
    *   [OOT 跨时间验证](#42-oot-跨时间验证)
    *   [单调性约束与自动调整](#43-单调性约束与自动调整)
    *   [可视化与人工干预](#44-可视化与人工干预)
    *   [日期格式处理](#45-日期格式处理)
    *   [轻量级模型部署](#46-轻量级模型部署)
    *   [在线学习](#47-在线学习)
5.  [独立组件使用](#5-独立组件使用)
6.  [最佳实践](#6-最佳实践)
7.  [常见问题与错误处理](#7-常见问题与错误处理)

---

## 1. 安装与环境

```bash
pip install autoscore
```

依赖库：
*   pandas, numpy, scikit-learn
*   matplotlib (绘图)
*   openpyxl (Excel报表)
*   joblib (模型保存)

---

## 2. 快速开始

```python
import pandas as pd
from autoscore import AutoScore

# 1. 加载数据
df = pd.read_csv('dataset.csv')

# 2. 初始化
score = AutoScore(random_state=42)

# 3. 训练 (一键完成全流程)
results = score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    date_col='create_time',
    oot_split_date='2023-10-01',
    selection_method='stepwise'
)

# 4. 生成模型开发报告
score.create_report('scorecard_report.xlsx')

# 5. 查看关键结果
print("入模特征:", results['selected_features'])
print("模型性能:", results['performance'])
```

---

## 3. 核心类：AutoScore

### 3.1 初始化

```python
score = AutoScore(random_state=42)
```
*   `random_state`: 随机种子，保证结果可复现。

### 3.2 核心方法：fit

`fit` 方法是整个库的核心引擎，负责编排所有步骤。

**参数详解**:

*   **基础数据**:
    *   `X` (pd.DataFrame): 特征矩阵。
    *   `y` (pd.Series): 目标变量（0/1，1代表坏客户）。
    *   `test_size` (float, default=0.3): 测试集比例。

*   **数据预处理**:
    *   `excluded_features` (list): 明确不参与建模的列（如ID、电话号码）。
    *   `special_values` (list): 特殊值列表（如 -999），这些值将作为独立的分箱处理。
    *   **智能类型识别**: 自动检测类似数值的字符串列（如 "123", "45.6"）并强制转换为数值型。

*   **OOT (Out-of-Time) 验证**:
    *   `date_col` (str): 日期列名。
    *   `oot_split_date` (str): OOT切分日期（如 '2023-10-01'）。大于该日期的数据将被划分为OOT集，不参与训练，仅做验证。
    *   **重要**: `oot_split_date` 必须使用 'yyyy-mm-dd' 格式，如 '2023-10-01'。

*   **分箱 (Binning)**:
    *   `max_bins` (int, default=10): 最大分箱数。
    *   `min_bin_pct` (float, default=0.05): 最小箱占比（防止微小箱）。
    *   `monotonicity_constraints` (dict): 单调性约束字典。
        *   `1`: 单调递增（值越大，坏率越高）。
        *   `-1`: 单调递减（值越大，坏率越低）。
        *   `0` 或 `None`: 自动检测趋势。
    *   `custom_binning_rules` (dict): 自定义分箱规则。传入后跳过自动分箱。
    *   `final_bins` (dict, optional): 最终分箱规则，直接跳过分箱步骤。
        *   格式: `{feature: {'type': 'numeric'|'categorical', 'cutoffs': [...], 'categories': [...], 'woe_map': {...}}}`
        *   使用场景: 当已有成熟的分箱规则，或需要复用之前的分箱结果时

*   **特征选择 (Selection)**:
    *   `iv_threshold` (float, default=0.02): IV筛选阈值，低于此值的特征被剔除。
    *   `selection_method` (str):
        *   `'stepwise'`: 逐步回归（推荐，解决共线性）。
        *   `'iv'`: 仅使用IV排序选Top特征。
    *   `final_features` (list): 强制指定入模特征列表。传入后跳过特征选择。

*   **评分卡参数**:
    *   `pdo` (int, default=20): PDO (Points to Double the Odds)，当坏率翻倍时分数的变化量。
    *   `base_score` (int, default=600): 基础分数。
    *   `base_odds` (int, default=50): 基础赔率。

**返回值**:
返回一个字典 `fit_result`，包含：
*   `numeric_features`, `categorical_features`: 识别出的特征类型。
*   `converted_cols`: 自动转换为数值型的列列表。
*   `selected_features`: 最终选择的特征。
*   `monotonicity_constraints`: 应用的单调性约束。
*   `binning_rules`: 分箱规则详情。
*   `iv_df`: IV值表。
*   `data_summary`: 数据摘要。
*   `woe_transformer`: WOE转换器对象。
*   `model_trainer`: 模型训练器对象。
*   `model`: 训练好的逻辑回归模型对象。
*   `scorecard_transformer`: 评分卡转换器对象。
*   `performance`: Train/Test/OOT 的 AUC, KS, PSI 指标。
*   `scorecard_df`: 标准评分卡表。

### 3.3 其他方法

*   `predict_proba(X)`: 预测违约概率。
*   `predict_score(X)`: 预测评分。
*   `create_report(filename)`: 生成全维度Excel报表。
*   `save_model(path)` / `load_model(path)`: 模型持久化（完整对象）。

#### 3.3.1 模型报告详解

`create_report()` 方法会生成一个包含模型开发全流程信息的Excel报表，包含以下工作表：

**1. 数据摘要 (Data_Summary)**
- 数据集基本信息（样本数、特征数、目标变量分布）
- 训练集、测试集、OOT集的样本分布
- 缺失值统计
- 特征类型统计（数值型/类别型）
- 单值率、众数、中位数、与target的相关系数、IV值等

**2. 特征IV值 (Feature_IV)**
- 所有特征的IV值排序
- IV值筛选结果
- 特征重要性排名

**3. 分箱详情 (Binning_Details)**
- 每个特征的分箱规则
- 每个箱的样本数、坏账率、WOE值
- IV值贡献
- 单调性检查结果

**4. 评分卡表 (Scorecard_Table)**
- 标准评分卡格式
- 每个特征每个箱的分数
- 基础分数和PDO设置

**5. 模型性能 (Model_Performance)**
- 训练集、测试集、OOT集的AUC、KS值
- 混淆矩阵
- ROC曲线数据
- PSI指标（Train vs Test, Train vs OOT）
- 性能评级（优秀/良好/中等/一般/较差）

**6. 特征相关性 (Feature_Correlation)**
- 入模特征的相关性矩阵
- 共线性检查结果

**7. 分箱可视化 (Binning_Visualization)**
- 关键特征的分箱图表
- 坏账率趋势图

**使用示例**:
```python
# 生成完整报告
score.create_report('model_report.xlsx')

# 报告生成后，可以打开Excel查看各个工作表
# 每个工作表都包含详细的模型开发信息
```
*   `export_lightweight(output_path)`: 导出轻量级模型（仅包含必要组件，无需autoscore依赖）。
*   `online_fit(X_new, y_new, retain_binning=True, retain_features=True)`: 在线学习，使用新数据增量更新模型。
*   `visualize_binning(feature, filename=None, show=True)`: 可视化分箱结果。
*   `adjust_rules(new_rules, X_train, y_train)`: 手动调整分箱规则。
*   `update_model_weights(coef_dict, intercept=None)`: 手动调整模型系数。
*   `validate_date_format(date_str)`: 验证日期格式并转换为标准格式。
*   `convert_date_column(date_series)`: 转换日期列为标准格式。

---

## 4. 高级功能

### 4.1 智能类型识别

`fit` 函数会自动扫描所有 `object` 类型的列。如果一列中超过 80% 的值可以转换为数字，系统将自动将其转换为数值型进行处理。这对于清洗不彻底的数据集（如包含 "NULL" 字符串的数值列）非常有用。

**示例**:
```python
# 假设数据中有一个 'duration_str' 列，大部分是数字字符串
df['duration_str'] = df['duration'].astype(str)
df.loc[0:5, 'duration_str'] = 'unknown'  # 添加一些噪声

# AutoScore 会自动检测并转换
score = AutoScore(random_state=42)
results = score.fit(X=df.drop(columns=['target']), y=df['target'])
# 输出: Automatically converted to numeric: ['duration_str']
```

### 4.2 OOT 跨时间验证

通过设置 `date_col` 和 `oot_split_date`，系统会自动将数据分为三部分：
1.  **Train**: 训练模型（时间窗内）。
2.  **Test**: 验证模型（时间窗内，随机）。
3.  **OOT**: 跨时间验证（时间窗外），用于评估模型的未来稳定性。

报告中会自动计算 **PSI (Train vs OOT)**，这是衡量模型衰减的重要指标。

**示例**:
```python
score = AutoScore(random_state=42)
results = score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    date_col='create_time',
    oot_split_date='2023-10-01',  # 必须使用 'yyyy-mm-dd' 格式
    test_size=0.3
)

# 查看性能指标
print("Train AUC:", results['performance']['train']['auc'])
print("Test AUC:", results['performance']['test']['auc'])
print("OOT AUC:", results['performance']['oot']['auc'])
print("PSI (Train vs OOT):", results['performance']['psi_train_oot'])
```

### 4.3 单调性约束与自动调整

工业级评分卡要求特征具有可解释的单调性。
*   如果不指定约束，AutoScore 会自动计算 Spearman 相关系数来判断趋势（递增或递减）。
*   **强制单调**: 算法会通过合并违反趋势的箱体，强制让分箱后的坏率呈现严格的单调性。

**示例**:
```python
constraints = {
    'duration': 1,       # 单调递增：贷款期限越长，风险越高
    'credit_amount': 0,  # 自动检测趋势
    'age': -1            # 单调递减：年龄越大，风险越低
}

score = AutoScore(random_state=42)
results = score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    monotonicity_constraints=constraints
)
```

### 4.4 可视化与人工干预

```python
# 1. 查看自动分箱结果
score.visualize_binning('age', filename='age_binning.png', show=False)

# 2. 发现某些切分点不合理，手动调整
new_rules = {'age': {'cutoffs': [25, 40, 60]}}
score.adjust_rules(new_rules, X_train, y_train)

# 3. 再次查看
score.visualize_binning('age', filename='age_binning_adjusted.png', show=False)
```

### 4.5 日期格式处理

AutoScore 提供了智能的日期格式处理功能，可以自动识别和转换各种日期格式。

#### 4.5.1 日期格式验证

使用 `validate_date_format()` 方法验证日期格式：

```python
from autoscore import AutoScore

# 验证正确格式的日期
try:
    validated = AutoScore.validate_date_format('2023-10-01')
    print(f"验证通过: {validated}")
except ValueError as e:
    print(f"验证失败: {e}")

# 验证错误格式的日期
try:
    validated = AutoScore.validate_date_format('2023/10/01')
    print(f"验证通过: {validated}")
except ValueError as e:
    print(f"验证失败: {e}")
```

**支持的日期格式**:
- 'yyyy-mm-dd' (推荐): '2023-10-01'
- 'yyyy/mm/dd': '2023/10/01'
- 'yyyy-m-d': '2023-10-1'
- 'yyyy/m/d': '2023/10/1'
- 以及其他 pandas.to_datetime 支持的格式

#### 4.5.2 日期列转换

使用 `convert_date_column()` 方法转换日期列：

```python
# 转换日期列
df['create_time'] = AutoScore.convert_date_column(df['create_time'])
print(f"转换后的日期: {df['create_time'].head()}")
```

**自动转换功能**:
- 自动检测日期格式
- 统一转换为 'yyyy-mm-dd' 格式
- 处理缺失值和异常值
- 提供详细的错误提示

#### 4.5.3 在 fit() 中自动处理日期

在 `fit()` 方法中，如果指定了 `date_col` 和 `oot_split_date`，系统会自动：
1. 验证 `oot_split_date` 的格式
2. 转换数据集中的日期列格式
3. 进行 OOT 切分

```python
score = AutoScore(random_state=42)
results = score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    date_col='create_time',
    oot_split_date='2023-10-01',  # 自动验证格式
    test_size=0.3
)
# 系统会自动转换日期列并输出提示信息
```

### 4.6 轻量级模型部署

AutoScore 提供了轻量级模型导出功能，可以在不安装 autoscore 包的环境中进行模型部署。

#### 4.6.1 导出轻量级模型

使用 `export_lightweight()` 方法导出轻量级模型：

```python
# 训练模型
score = AutoScore(random_state=42)
results = score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    selection_method='stepwise'
)

# 导出轻量级模型
score.export_lightweight('lightweight_model.json')
```

**导出的模型包含**:
- 模型系数和截距
- 分箱规则（cutoffs、categories、WOE映射）
- 评分卡参数（factor、offset）
- 选中的特征列表
- 模型元数据（版本、创建时间等）

#### 4.6.2 加载轻量级模型

在部署环境中，使用 `LightweightScorer` 类加载模型：

```python
from autoscore import LightweightScorer

# 加载轻量级模型
scorer = LightweightScorer('lightweight_model.json')

# 预测概率
proba = scorer.predict_proba(X_new)

# 预测评分
scores = scorer.predict_score(X_new)

# 获取评分卡表
scorecard = scorer.get_scorecard()
print(scorecard)

# 获取特征重要性
importance = scorer.get_feature_importance()
print(importance)

# 获取模型信息
info = scorer.get_model_info()
print(info)
```

**优势**:
- 无需安装 autoscore 包
- 仅需 numpy 和 pandas
- 支持所有预测功能
- 包含完整的评分卡信息
- 适合生产环境部署

### 4.7 在线学习

AutoScore 支持在线学习，可以使用新数据增量更新模型，而无需重新训练整个模型。

#### 4.7.1 在线学习基础

使用 `online_fit()` 方法进行在线学习：

```python
# 初始训练
score = AutoScore(random_state=42)
results = score.fit(
    X=df_train.drop(columns=['target']),
    y=df_train['target'],
    selection_method='stepwise'
)

# 获取新数据
X_new = df_new.drop(columns=['target'])
y_new = df_new['target']

# 在线学习（保留分箱规则和特征选择）
new_metrics = score.online_fit(X_new, y_new, retain_binning=True, retain_features=True)

# 查看更新后的性能
print(f"更新后的性能: {new_metrics['online']}")
```

#### 4.7.2 在线学习参数

`online_fit()` 方法支持以下参数：

*   `retain_binning` (bool, default=True):
    *   `True`: 保留现有分箱规则，仅更新模型系数（推荐）
    *   `False`: 在新数据上重新进行分箱

*   `retain_features` (bool, default=True):
    *   `True`: 保留现有特征选择
    *   `False`: 重新进行特征选择

#### 4.7.3 在线学习场景

**场景1: 定期模型更新**
```python
# 每月收集新数据后更新模型
for month in range(1, 13):
    # 获取当月新数据
    X_month = get_monthly_data(month)
    y_month = X_month['target']
    X_month = X_month.drop(columns=['target'])
    
    # 在线学习
    new_metrics = score.online_fit(X_month, y_month)
    print(f"Month {month} - AUC: {new_metrics['online']['auc']:.4f}")
```

**场景2: 实时数据流**
```python
# 处理实时数据流
for batch in data_stream:
    X_batch, y_batch = batch
    
    # 在线学习
    score.online_fit(X_batch, y_batch)
    
    # 实时预测
    scores = score.predict_score(X_batch)
    process_scores(scores)
```

**场景3: 保留分箱规则**
```python
# 当数据分布变化不大时，保留分箱规则
# 这样可以保证模型的稳定性
new_metrics = score.online_fit(X_new, y_new, retain_binning=True)
```

#### 4.7.4 在线学习与完整重训练对比

| 特性 | 在线学习 | 完整重训练 |
| :--- | :--- | :--- |
| **速度** | 快（仅更新系数） | 慢（重新训练） |
| **稳定性** | 高（保留分箱规则） | 中（可能改变分箱） |
| **适应性** | 中（增量更新） | 高（完全适应新数据） |
| **适用场景** | 数据分布稳定 | 数据分布变化大 |
| **推荐使用** | 定期小批量更新 | 大数据集更新 |

**建议**:
- 数据分布稳定时：使用在线学习，保留分箱规则
- 数据分布变化大时：使用完整重训练，重新分箱
- 混合策略：定期在线学习 + 定期完整重训练

---

## 5. 独立组件使用

如果您只想使用 AutoScore 的某一部分功能（如分箱），可以单独导入组件：

### 5.1 FeatureAnalyzer - 数据探索分析

```python
from autoscore import FeatureAnalyzer

analyzer = FeatureAnalyzer()

# 数据分析
summary = analyzer.analyze(X)
print(summary)

# 获取建议删除的列
drop_cols = analyzer.get_drop_columns(threshold_missing=0.95)
print(f"建议删除的列: {drop_cols}")

# 智能类型转换
X_converted, converted_cols = analyzer.detect_and_convert_types(X)
print(f"自动转换的列: {converted_cols}")
```

### 5.2 BinningProcess - 特征分箱

```python
from autoscore import BinningProcess

binning = BinningProcess(max_bins=5, min_bin_pct=0.05)
binning.fit(X, y)

# 查看分箱规则
print(f"'duration' 的切分点: {binning.rules['duration']['cutoffs']}")
print(f"'duration' 的 IV 值: {binning.rules['duration']['iv']}")

# 查看 IV 表
print(binning.iv_df.head(10))

# 转换为 WOE
X_woe = binning.transform(X)
```

### 5.3 FeatureSelector - 特征选择

```python
from autoscore import FeatureSelector

selector = FeatureSelector()

# IV 筛选
features_iv = selector.filter_by_iv(binning.iv_df, threshold=0.02)
print(f"IV 筛选后的特征: {features_iv}")

# 逐步回归选择
selected = selector.stepwise_selection(X_woe[features_iv], y, method='forward')
print(f"逐步回归选择的特征: {selected}")
```

### 5.4 ModelTrainer - 模型训练

```python
from autoscore import ModelTrainer

trainer = ModelTrainer(random_state=42)
model = trainer.train(X_woe[selected], y)

# 预测
pred_proba = trainer.predict_proba(X_woe[selected])
```

### 5.5 ModelEvaluator - 模型评估

```python
from autoscore import ModelEvaluator

evaluator = ModelEvaluator()

# 评估模型
metrics = evaluator.evaluate(y, pred_proba)
print(f"AUC: {metrics['auc']}")
print(f"KS: {metrics['ks']}")

# 计算 PSI
psi = evaluator.calculate_psi(pred_train, pred_test)
print(f"PSI: {psi}")
```

---

## 6. 最佳实践

### 6.1 数据准备

1. **数据清洗**: 在使用 AutoScore 之前，建议先进行基本的数据清洗
   - 处理明显的异常值
   - 统一数据格式
   - 处理缺失值（可选，分箱可以处理缺失值）

2. **特征工程**: 根据业务需求进行特征工程
   - 创建衍生变量
   - 处理类别变量
   - 标准化数值变量（可选）

### 6.2 参数调优建议

1. **分箱参数**:
   - `max_bins`: 通常设置为 5-10，过多会导致过拟合
   - `min_bin_pct`: 通常设置为 0.05-0.1，确保每个箱有足够的样本

2. **特征选择**:
   - `iv_threshold`: 通常设置为 0.02-0.05，根据数据集调整
   - `selection_method`: 推荐使用 'stepwise'，可以解决共线性问题

3. **评分卡参数**:
   - `pdo`: 通常设置为 20-50，控制分数的敏感度
   - `base_score`: 通常设置为 500-600，根据业务需求调整
   - `base_odds`: 通常设置为 50-100，根据坏客户比例调整

### 6.3 模型验证

1. **交叉验证**: 使用 OOT 验证确保模型的稳定性
2. **PSI 监控**: 定期计算 PSI，监控模型衰减
3. **人工审核**: 检查分箱结果和评分卡的可解释性

### 6.4 模型部署

1. **模型保存**: 使用 `save_model()` 保存训练好的模型
2. **版本控制**: 对模型进行版本管理
3. **性能监控**: 部署后持续监控模型性能

---

## 7. 常见问题与错误处理

### 7.1 日期格式错误

**问题**: 使用错误的日期格式导致 OOT 切分失败

**错误信息**:
```
ValueError: Invalid date format: '2023/10/01'. Expected format: yyyy-mm-dd
```

**解决方案**:
```python
# 错误示例
score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    oot_split_date='2023/10/01'  # 错误格式
)

# 正确示例
score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    oot_split_date='2023-10-01'  # 正确格式
)
```

### 7.2 日期列不存在

**问题**: 指定的日期列在数据集中不存在

**错误信息**:
```
KeyError: 'create_time' not found in columns
```

**解决方案**:
```python
# 检查数据集列名
print(df.columns.tolist())

# 使用正确的列名
score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    date_col='正确的日期列名',
    oot_split_date='2023-10-01'
)
```

### 7.3 缺失值处理

**问题**: 数据集中存在大量缺失值

**解决方案**:
```python
# 方案1: 在分箱前处理缺失值
df.fillna(-999, inplace=True)

# 方案2: 使用 special_values 参数
score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    special_values=[-999, np.nan]
)

# 方案3: 让分箱模块自动处理（推荐）
# 分箱模块会自动将缺失值作为独立的箱处理
```

### 7.4 特征选择失败

**问题**: 特征选择后没有选择任何特征

**解决方案**:
```python
# 方案1: 降低 IV 阈值
score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    iv_threshold=0.01  # 降低阈值
)

# 方案2: 直接指定特征
score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    final_features=['feature1', 'feature2', 'feature3']
)
```

### 7.5 模型性能不佳

**问题**: 模型的 AUC 或 KS 值较低

**解决方案**:
```python
# 方案1: 调整分箱参数
score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    max_bins=8,  # 增加分箱数
    min_bin_pct=0.03  # 降低最小箱占比
)

# 方案2: 调整单调性约束
constraints = {
    'duration': 1,
    'age': -1,
    'credit_amount': 0  # 让某些特征自动检测趋势
}

# 方案3: 使用自定义分箱规则
custom_rules = {
    'duration': {'cutoffs': [12, 24, 36, 48]},
    'age': {'cutoffs': [25, 35, 45, 55]}
}

score.fit(
    X=df.drop(columns=['target']),
    y=df['target'],
    custom_binning_rules=custom_rules
)
```

### 7.6 内存不足

**问题**: 处理大数据集时内存不足

**解决方案**:
```python
# 方案1: 减少特征数量
score.fit(
    X=df.drop(columns=['target', '不重要的特征1', '不重要的特征2']),
    y=df['target'],
    iv_threshold=0.05  # 提高 IV 阈值，减少特征
)

# 方案2: 使用采样
df_sample = df.sample(n=10000, random_state=42)
score.fit(
    X=df_sample.drop(columns=['target']),
    y=df_sample['target']
)
```

---

## 完整示例代码

请参考项目根目录下的 `example.py` 文件，其中包含：
- 标准完整流程示例
- 独立组件使用示例
- 日期处理示例
- 错误处理示例
- 模型保存与加载示例

运行示例：
```bash
python example.py
```

---

## 技术支持

如有问题或建议，请通过以下方式联系：
- 提交 Issue
- 查看项目文档
- 参考示例代码

---

**版本**: 1.0.5  
**更新日期**: 2026-02-07