跳转至

随机森林滑坡易发性评估

随机森林通过多棵决策树集成得到稳定的二分类结果,适合滑坡易发性评价中的非线性因子关系。

本节对应完整代码:

examples/02_random_forest

训练脚本

examples/02_random_forest/train.py
from __future__ import annotations

import json
import sys
from pathlib import Path

import joblib
import pandas as pd
from sklearn.model_selection import train_test_split

PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT / "src"))

from landslide.features import make_factor_table
from landslide.metrics import evaluate_binary_classifier
from landslide.models import train_random_forest
from landslide.plotting import save_roc_curve

OUTPUT_DIR = Path(__file__).resolve().parent / "output"
TARGET = "landslide"


def main() -> None:
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    table = make_factor_table(sample_count=900, random_state=42)
    x = table.drop(columns=[TARGET])
    y = table[TARGET]

    x_train, x_test, y_train, y_test = train_test_split(
        x,
        y,
        test_size=0.3,
        stratify=y,
        random_state=42,
    )

    model = train_random_forest(random_state=42)
    model.fit(x_train, y_train)
    probability = model.predict_proba(x_test)[:, 1]
    metrics = evaluate_binary_classifier(y_test.to_numpy(), probability)

    joblib.dump({"model": model, "feature_names": list(x.columns)}, OUTPUT_DIR / "rf_model.joblib")
    (OUTPUT_DIR / "metrics.json").write_text(
        json.dumps(metrics, indent=2, ensure_ascii=False),
        encoding="utf-8",
    )
    save_roc_curve(model, x_test, y_test, OUTPUT_DIR / "roc_curve.png")

    importance = pd.DataFrame(
        {"feature": x.columns, "importance": model.feature_importances_}
    ).sort_values("importance", ascending=False)
    importance.to_csv(OUTPUT_DIR / "feature_importance.csv", index=False)

    print(json.dumps(metrics, indent=2, ensure_ascii=False))


if __name__ == "__main__":
    main()

预测脚本

examples/02_random_forest/predict.py
from __future__ import annotations

import sys
from pathlib import Path

import joblib

PROJECT_ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(PROJECT_ROOT / "src"))

from landslide.features import make_factor_table

OUTPUT_DIR = Path(__file__).resolve().parent / "output"
MODEL_PATH = OUTPUT_DIR / "rf_model.joblib"


def main() -> None:
    if not MODEL_PATH.exists():
        raise FileNotFoundError("Run examples/02_random_forest/train.py before prediction.")

    bundle = joblib.load(MODEL_PATH)
    model = bundle["model"]
    feature_names = bundle["feature_names"]

    table = make_factor_table(sample_count=120, random_state=7)
    probability = model.predict_proba(table[feature_names])[:, 1]
    output = table.copy()
    output["susceptibility_probability"] = probability
    output.to_csv(OUTPUT_DIR / "predictions.csv", index=False)

    print(f"Saved predictions to {OUTPUT_DIR / 'predictions.csv'}")


if __name__ == "__main__":
    main()

结果解释

训练脚本会输出模型文件、ROC 曲线、指标 JSON 和特征重要性表。真实工程中不要只看总体 AUC,还应检查训练样本来源、空间分布和高易发区是否符合地貌认知。