Analysis¶
状态:Stable。 使用方式见数据画像和 分箱与风险评估。
mars.analysis.MarsDataProfiler ¶
Bases: MarsBaseEstimator
数据质量、统计分布和稳定性画像器。
构造函数保存缺失处理和 PSI 分箱策略。每次调用 :meth:generate_profile
都会接收本次数据、特征和分组配置,同一实例可以连续处理不同 DataFrame。
示例:
>>> import polars as pl
>>> df = pl.DataFrame({"age": [20, 30, None], "month": ["202601", "202601", "202602"]})
>>> profiler = MarsDataProfiler(missing_values=[-999])
>>> report = profiler.generate_profile(df, group_col="month")
>>> report.get_profile_data().overview.height > 0
True
__init__ ¶
__init__(
*,
missing_values: list[int | float | str] | None = None,
special_values: list[Any] | None = None,
psi_n_bins: int = 10,
psi_bin_method: ProfileBinMethod = "quantile",
psi_remove_empty_bins: bool = True,
psi_merge_small_bins: bool = True,
psi_min_bin_size: float = 0.02,
psi_cv_ignore_threshold: float = 0.05,
psi_batch_size: int = 50,
overview_batch_size: int = 500
) -> None
初始化画像策略。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
missing_values
|
list[int | float | str] | None
|
除 null 和 NaN 外,额外视为缺失的取值。默认不增加业务缺失码。 |
None
|
special_values
|
list[Any] | None
|
从连续统计中排除、在 PSI 中单独分箱的取值。默认无额外特殊值。 |
None
|
psi_n_bins
|
int
|
PSI 数值分箱数上限及类别 Top-K 数量,默认 10。 类别特征只保留频数最高的 K 个类别,其他类别进入 Other 箱。 |
10
|
psi_bin_method
|
ProfileBinMethod
|
PSI 数值分箱方法,默认等频分箱 |
'quantile'
|
psi_remove_empty_bins
|
bool
|
是否移除 PSI 数值分箱中没有拟合样本的箱,默认开启。 |
True
|
psi_merge_small_bins
|
bool
|
是否合并 PSI 数值分箱中的小样本箱,默认开启。 |
True
|
psi_min_bin_size
|
float
|
PSI 数值分箱合并小箱时的最小样本占比,默认 0.02;
仅在 |
0.02
|
psi_cv_ignore_threshold
|
float
|
分组 PSI 最大值低于此阈值时,将变异系数置零,默认 0.05。 |
0.05
|
psi_batch_size
|
int
|
每批计算 PSI 的特征数,默认 50;控制中间表规模,不改变指标口径。 |
50
|
overview_batch_size
|
int
|
每批计算 overview 的特征数,默认 500;控制中间表规模,不改变指标口径。 |
500
|
generate_profile ¶
generate_profile(
df: DataFrame | DataFrame,
*,
metrics: list[str] | None = None,
features: list[str] | None = None,
feature_metadata: FeatureMetadata | None = None,
business_context: dict[str, Any] | None = None,
benchmark_df: DataFrame | DataFrame | None = None,
categorical_features: list[str] | None = None,
exclude_features: list[str] | None = None,
include_dtypes: (
type | DataType | list[type | DataType] | None
) = None,
group_col: str | None = None,
time_col: str | None = None,
time_grain: str | None = None,
enable_sparkline: bool = True,
sparkline_bins: int = 8,
sparkline_sample_size: int = 200000,
psi_include_missing: bool = False,
psi_include_special: bool = False
) -> MarsProfileReport
生成一次数据画像报告。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
df
|
DataFrame | DataFrame
|
待画像样本表。 |
必需 |
metrics
|
list[str] | None
|
本次计算的指标。默认计算数据质量和统计指标;
|
None
|
features
|
list[str] | None
|
本次画像的特征列;不传时使用过滤后的全部候选列。 对比指标默认检查当前表与基准表的列名并集,排除分组、日期和显式排除列。 |
None
|
feature_metadata
|
FeatureMetadata | None
|
完整特征字典或含 feature 列的 Pandas/Polars 表。 |
None
|
business_context
|
dict[str, Any] | None
|
用户提供的 JSON 业务上下文,未知信息不推断。 |
None
|
benchmark_df
|
DataFrame | DataFrame | None
|
PSI 和对比指标的基准样本。计算 PSI 时,用全部基准样本拟合分箱, 并以基准整体分布为参考;未分组时仍可比较两表的整体分布。 基准样本不计入 overview、数据质量或其他当前数据统计。 未提供时,PSI 在当前数据上拟合分箱,并以最小分组为参考。 |
None
|
categorical_features
|
list[str] | None
|
额外声明为类别的特征,供 unseen 和 PSI 识别整数编码类别。 默认按字段类型判断;声明的列必须属于本次分析范围。 |
None
|
exclude_features
|
list[str] | None
|
本次画像需要排除的列名。 |
None
|
include_dtypes
|
type | DataType | list[type | DataType] | None
|
只保留指定数据类型的特征列。 |
None
|
group_col
|
str | None
|
已存在的趋势分组列。与时间列同时提供时,优先使用此列分组。 |
None
|
time_col
|
str | None
|
原始日期列。未指定 |
None
|
time_grain
|
str | None
|
时间聚合粒度,例如 |
None
|
enable_sparkline
|
bool
|
是否在 overview 中生成数值特征的字符分布图,默认开启。 |
True
|
sparkline_bins
|
int
|
字符分布图的直方图分箱数,默认 8;仅在启用字符图时生效。 |
8
|
sparkline_sample_size
|
int
|
字符分布图使用的最多行数,默认 200,000。超出时仅为字符图随机抽样, 不改变画像统计指标使用的样本。 |
200000
|
psi_include_missing
|
bool
|
是否将缺失值箱计入 PSI。默认排除,缺失率仍单独计算。 |
False
|
psi_include_special
|
bool
|
是否将特殊值箱计入 PSI。默认排除,不影响特殊值识别。 |
False
|
返回:
| 类型 | 描述 |
|---|---|
MarsProfileReport
|
包含 overview、数据质量趋势表、统计趋势表、对比表和运行元数据的报告。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
指标、特征、benchmark 或对比配置无效时抛出。 |
Notes
当前数据的统计指标使用全部样本,字符分布图可按 sparkline_sample_size 抽样。
缺失率等数据质量指标以样本总数为分母;均值、分位数等连续统计排除
null、NaN、自定义缺失值和特殊值。
多 chunk 输入保持原值和 chunk 结构,无需预先 rechunk;不适用的统计
保留 typed null。PSI 独立计算,无参考或当前人口为空时保留表和特征身份,
并记录未计算原因;空当前人口仍校验 benchmark 结构,不拟合分箱。
示例:
mars.analysis.profile_stats ¶
profile_stats(
df: DataFrame | DataFrame,
*,
metrics: list[str],
features: list[str] | None = None,
feature_metadata: FeatureMetadata | None = None,
business_context: dict[str, Any] | None = None,
benchmark_df: DataFrame | DataFrame | None = None,
categorical_features: list[str] | None = None,
group_col: str | None = None,
time_col: str | None = None,
time_grain: str | None = None,
missing_values: list[int | float | str] | None = None,
special_values: list[Any] | None = None,
exclude_features: list[str] | None = None,
include_dtypes: (
type | DataType | list[type | DataType] | None
) = None,
enable_sparkline: bool = False,
sparkline_bins: int = 8,
sparkline_sample_size: int = 200000,
psi_include_missing: bool = False,
psi_include_special: bool = False,
psi_remove_empty_bins: bool = True,
psi_merge_small_bins: bool = True,
psi_min_bin_size: float = 0.02
) -> MarsProfileReport
按指定指标生成数据画像,默认不生成字符分布图。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
df
|
DataFrame | DataFrame
|
待画像样本表。 |
必需 |
metrics
|
list[str]
|
本次计算的数据质量、统计或对比指标,必须显式传入。
|
必需 |
features
|
list[str] | None
|
本次画像的特征列。默认从当前表中选择符合排除列和类型条件的列; 对比指标默认检查当前表与基准表的列名并集。 |
None
|
feature_metadata
|
FeatureMetadata | None
|
完整特征字典或含 feature 列的 Pandas/Polars 表;按本次特征裁剪。 |
None
|
business_context
|
dict[str, Any] | None
|
用户提供的 JSON 业务上下文,与实际计算配置分开保存。 |
None
|
benchmark_df
|
DataFrame | DataFrame | None
|
PSI 和对比指标的基准样本。计算 PSI 时,用全部基准样本拟合分箱, 并以基准整体分布为参考;未分组时仍可计算当前整体相对基准的 PSI。 基准样本不计入 overview、数据质量或其他当前数据统计。 未提供时,PSI 在当前数据上拟合分箱,并以最小分组为参考。 |
None
|
categorical_features
|
list[str] | None
|
额外声明为类别的特征,供 unseen 和 PSI 识别整数编码类别。 默认按字段类型判断;声明的列必须属于本次分析范围。 |
None
|
group_col
|
str | None
|
已存在的趋势分组列。与时间列同时提供时,优先使用此列分组。 |
None
|
time_col
|
str | None
|
原始日期列。未指定 |
None
|
time_grain
|
str | None
|
时间聚合粒度,例如 |
None
|
missing_values
|
list[int | float | str] | None
|
除 null 和 NaN 外,额外视为缺失的取值。默认不增加业务缺失码。 |
None
|
special_values
|
list[Any] | None
|
从连续统计中排除、在 PSI 中单独分箱的取值。默认无额外特殊值;
是否将特殊值箱计入 PSI 由 |
None
|
exclude_features
|
list[str] | None
|
本次画像需要排除的列名。 |
None
|
include_dtypes
|
type | DataType | list[type | DataType] | None
|
本次画像允许保留的数据类型。 |
None
|
enable_sparkline
|
bool
|
是否在 overview 中生成数值特征的字符分布图。默认关闭,不影响统计指标。 |
False
|
sparkline_bins
|
int
|
字符分布图的直方图分箱数,默认 8;仅在启用字符图时生效。 |
8
|
sparkline_sample_size
|
int
|
字符分布图使用的最多行数,默认 200,000。超出时仅为字符图随机抽样, 不改变画像统计指标使用的样本。 |
200000
|
psi_include_missing
|
bool
|
是否将缺失值箱计入 PSI。默认排除,缺失率仍单独计算。 |
False
|
psi_include_special
|
bool
|
是否将特殊值箱计入 PSI。默认排除,不影响特殊值识别。 |
False
|
psi_remove_empty_bins
|
bool
|
是否移除 PSI 数值分箱中没有拟合样本的箱,默认开启。 |
True
|
psi_merge_small_bins
|
bool
|
是否合并 PSI 数值分箱中的小样本箱,默认开启。 |
True
|
psi_min_bin_size
|
float
|
PSI 数值分箱合并小箱时的最小样本占比,默认 0.02;
仅在 |
0.02
|
返回:
| 类型 | 描述 |
|---|---|
MarsProfileReport
|
包含 overview、所请求的趋势表、对比表和运行元数据的报告。 |
Notes
缺失率、零值率、唯一值率和众数占比均以当前样本总数为分母。
均值、分位数等连续统计排除 null、NaN、自定义缺失值和特殊值。
PSI 的缺失值箱、特殊值箱是否参与计算由对应开关控制。
多 chunk 输入无需先 rechunk;不适用的连续统计保留 typed null。
无分组、时间和 benchmark 的 PSI 保留表与特征身份,并在 calculation_status
中标记 not_computed/no_group_or_benchmark。
有参考但当前样本为空时,PSI 仍校验 benchmark 结构,并标记
not_computed/empty_current_population,不拟合分箱。
示例:
>>> import polars as pl
>>> df = pl.DataFrame({"x": [1, 2, None], "month": ["202601", "202601", "202602"]})
>>> report = profile_stats(df, metrics=["missing", "mean"], group_col="month")
>>> "missing" in report.dq_tables
True
>>> benchmark = pl.DataFrame({"x": [1, 1, 2, 2]})
>>> current = pl.DataFrame({"x": [1, 2, 2, 2]})
>>> psi_report = profile_stats(current, metrics=["psi"], benchmark_df=benchmark)
>>> psi_report.stats_tables["psi"].columns
['feature', 'dtype', 'total']
mars.analysis.MarsBinEvaluator ¶
Bases: MarsBaseEstimator
分箱效果评估器。
根据特征分箱计算 IV、KS、AUC、PSI、Lift 和单调性,并生成分组趋势及分箱明细。
构造函数保存可复用的评估策略和默认分箱配置。
每次 evaluate 调用接收数据、目标、特征、分组和时间聚合粒度。
每次 evaluate 都会返回新的 MarsRiskProfile,其中包含报告对象和本次使用的
分箱器。评估器实例不会把上一次拟合出的分箱器作为下一次调用的隐式状态,
因此同一个实例可以安全地连续评估不同特征集合或不同数据集。
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
binning_type |
str
|
默认分箱器类型。 |
binner_params |
dict
|
默认分箱器参数副本。 |
示例:
>>> import polars as pl
>>> from mars.analysis import MarsBinEvaluator
>>> df = pl.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> evaluator = MarsBinEvaluator(
... binning_type="native",
... binner_params={"method": "quantile", "n_bins": 2},
... )
>>> profile = evaluator.evaluate(df, target="y", features=["age"])
>>> "age" in profile.report.summary_table.get_column("feature").to_list()
True
__init__ ¶
__init__(
*,
binning_type: Literal[
"native", "optimal", "lite_opt"
] = "native",
binner_params: Dict[str, Any] | None = None,
feature_start_aware_reference: bool = False,
risk_corr_baseline: RiskCorrBaseline = "total",
ordered_metric_sort_by: OrderedMetricSortBy = "woe"
) -> None
初始化分箱评估器。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
binning_type
|
Literal['native', 'optimal', 'lite_opt']
|
未显式传入分箱器时使用的默认分箱策略。 |
'native'
|
binner_params
|
Dict[str, Any] | None
|
构造默认分箱器时使用的参数,默认使用引擎自身的默认配置。
与 |
None
|
feature_start_aware_reference
|
bool
|
是否默认启用按特征上线时间重锚的稳定性参考,默认为 成功识别的特征使用上线首期分布作为 PSI 基准,并只在上线后计算 PSI/RC
趋势;其他特征沿用默认参考。RC 是否改用上线首期坏率仍由
|
False
|
risk_corr_baseline
|
RiskCorrBaseline
|
RC 的默认坏率基准。 |
'total'
|
ordered_metric_sort_by
|
OrderedMetricSortBy
|
KS/AUC 的默认排序口径。 |
'woe'
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
当 |
evaluate ¶
evaluate(
df: DataFrame | DataFrame,
*,
target: str | None = None,
features: list[str] | None = None,
group_col: str | None = None,
time_col: str | None = None,
time_grain: str | None = None,
feature_data_source: dict[str, list[str]] | None = None,
feature_metadata: FeatureMetadata | None = None,
business_context: dict[str, Any] | None = None,
weights_col: str | None = None,
amount_col: str | None = None,
binner: MarsBinnerBase | None = None,
benchmark_df: DataFrame | DataFrame | None = None,
psi_include_missing: bool = False,
psi_include_special: bool = False,
feature_start_aware_reference: bool | None = None,
risk_corr_baseline: RiskCorrBaseline | None = None,
ordered_metric_sort_by: (
OrderedMetricSortBy | None
) = None,
batch_size: int = 100
) -> MarsRiskProfile
使用自动拟合或显式传入的分箱器评估本次样本。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
df
|
DataFrame | DataFrame
|
待评估样本表。 |
必需 |
target
|
str | None
|
二分类目标列,非缺失值须为 0 或 1。为 |
None
|
features
|
list[str] | None
|
本次评估的特征列,金额列始终排除。默认排除目标、内部分组、权重和金额列; 建议显式传入业务特征,避免将原始日期或原始分组列纳入评估。 |
None
|
group_col
|
str | None
|
已存在的趋势分组列,例如月份、客群或样本切片。与时间列同时提供时, 优先使用此列分组。 |
None
|
time_col
|
str | None
|
原始日期列。未指定 |
None
|
time_grain
|
str | None
|
时间聚合粒度,例如 |
None
|
feature_data_source
|
dict[str, list[str]] | None
|
数据源名称到特征列表的映射,仅为本次评估的特征保存来源。 |
None
|
feature_metadata
|
FeatureMetadata | None
|
以英文标识为键的完整业务字典或含 feature 列的 Pandas/Polars 表。 |
None
|
business_context
|
dict[str, Any] | None
|
可选 JSON 业务上下文,多标签信息按 labels 中的目标字段组织。 |
None
|
weights_col
|
str | None
|
样本权重列。提供后按权重计算分布和风险指标;默认按样本数计算。 |
None
|
amount_col
|
str | None
|
金额列名;传入后会在 |
None
|
binner
|
MarsBinnerBase | None
|
已拟合的分箱器。传入后直接复用固定规则,不重新拟合;
不能同时设置评估器构造参数 |
None
|
benchmark_df
|
DataFrame | DataFrame | None
|
基准期样本。未传入 |
None
|
psi_include_missing
|
bool
|
是否将缺失值箱计入 PSI,默认排除;不改变其他指标的缺失处理。 |
False
|
psi_include_special
|
bool
|
是否将特殊值箱计入 PSI,默认排除;不改变特殊值分箱。 |
False
|
feature_start_aware_reference
|
bool | None
|
是否按特征上线时间重锚稳定性参考。传入 成功识别的特征按上线日映射到 |
None
|
risk_corr_baseline
|
RiskCorrBaseline | None
|
本次评估使用的 RC 基准;传入 |
None
|
ordered_metric_sort_by
|
OrderedMetricSortBy | None
|
本次评估使用的 KS/AUC 排序口径;传入 |
None
|
batch_size
|
int
|
每批评估的特征数,默认 100,必须为正整数。控制中间表规模,不改变指标口径。 |
100
|
返回:
| 类型 | 描述 |
|---|---|
MarsRiskProfile
|
单次风险画像结果,包含评估报告、分箱器、目标列列表和运行元数据。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
当必要列缺失、分箱器配置冲突或输入数据无法评估时抛出。 |
mars.analysis.profile_risk ¶
profile_risk(
df: DataFrame | DataFrame,
*,
target: str | list[str] | None = None,
features: list[str] | None = None,
feature_data_source: dict[str, list[str]] | None = None,
feature_metadata: FeatureMetadata | None = None,
business_context: dict[str, Any] | None = None,
group_col: str | None = None,
time_col: str | None = None,
time_grain: str | None = None,
weights_col: str | None = None,
amount_col: str | None = None,
binning_type: Literal[
"native", "optimal", "lite_opt"
] = "native",
method: (
Literal["quantile", "uniform", "cart"] | None
) = None,
n_bins: int | None = None,
min_bin_size: float | int | None = None,
monotonic_trend: (
Literal[
"ascending",
"descending",
"peak",
"valley",
"auto",
"auto_asc_desc",
]
| None
) = None,
missing_values: list[Any] | None = None,
special_values: list[Any] | None = None,
psi_include_missing: bool = False,
psi_include_special: bool = False,
binner_params: dict[str, Any] | None = None,
benchmark_df: DataFrame | DataFrame | None = None,
feature_start_aware_reference: bool = False,
risk_corr_baseline: RiskCorrBaseline = "total",
ordered_metric_sort_by: OrderedMetricSortBy = "woe",
ks_method: Literal["binned", "raw"] = "binned",
max_raw_ks_features: int = 50,
batch_size: int = 100,
n_jobs: int | None = None
) -> MarsRiskProfile
自动拟合分箱,并生成一个或多个目标的风险评估结果。
返回的 MarsRiskProfile 包含报告和已拟合分箱器。多目标共享同一套分箱边界,
汇总表和明细表分别保存各目标的结果。调用后不会自动绘图,
可用 report.plot_risk_trends(...) 查看趋势。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
df
|
DataFrame | DataFrame
|
待评估样本表。 |
必需 |
target
|
str | list[str] | None
|
目标列名或目标列列表。传入 |
None
|
features
|
list[str] | None
|
本次参与评估的特征列。传入 |
None
|
feature_data_source
|
dict[str, list[str]] | None
|
数据源名称到特征列表的映射,用于在报告中标明特征来源。 |
None
|
feature_metadata
|
FeatureMetadata | None
|
完整业务字典或含 feature 列的 Pandas/Polars 表;英文标识保持不变。 |
None
|
business_context
|
dict[str, Any] | None
|
可选 JSON 业务上下文,多标签定义按 labels 的目标标识登记。 |
None
|
group_col
|
str | None
|
已存在的趋势分组列。与时间列同时提供时,优先使用此列分组。 |
None
|
time_col
|
str | None
|
原始日期列。未指定 |
None
|
time_grain
|
str | None
|
时间聚合粒度,例如 |
None
|
weights_col
|
str | None
|
样本权重列。提供后按权重计算分布和风险指标;默认按样本数计算。 |
None
|
amount_col
|
str | None
|
金额列。提供后额外计算金额统计和金额坏率;默认不计算金额指标。 |
None
|
binning_type
|
Literal['native', 'optimal', 'lite_opt']
|
自动拟合使用的分箱引擎,默认 |
'native'
|
method
|
Literal['quantile', 'uniform', 'cart'] | None
|
数值分箱方法。 |
None
|
n_bins
|
int | None
|
正常分箱数量上限,不含缺失值箱和特殊值箱。 |
None
|
min_bin_size
|
float | int | None
|
拟合时的最小箱样本约束, |
None
|
monotonic_trend
|
Literal['ascending', 'descending', 'peak', 'valley', 'auto', 'auto_asc_desc'] | None
|
分箱坏率的趋势约束。仅对 |
None
|
missing_values
|
list[Any] | None
|
除 null 和 NaN 外,额外视为缺失的取值。 |
None
|
special_values
|
list[Any] | None
|
需要单独分箱的特殊值。默认无额外特殊值,与缺失值箱分开保存。 |
None
|
psi_include_missing
|
bool
|
是否将缺失值箱计入 PSI,默认排除;不改变其他指标的缺失处理。 |
False
|
psi_include_special
|
bool
|
是否将特殊值箱计入 PSI,默认排除;不改变特殊值分箱。 |
False
|
binner_params
|
dict[str, Any] | None
|
分箱引擎的额外参数,使用单层字典。同一份字典可以包含多种引擎的参数;
运行时只读取当前 当前允许的高级参数如下:
|
None
|
benchmark_df
|
DataFrame | DataFrame | None
|
用于拟合分箱规则并构造 PSI 基准的样本。未提供时,在当前 |
None
|
feature_start_aware_reference
|
bool
|
是否启用按特征上线时间重锚的稳定性参考,默认为 只有成功识别上线日的特征会改用上线首期的分箱分布计算 PSI,并从 PSI/RC
监控窗口中排除上线前分组;其他特征沿用默认参考。 |
False
|
risk_corr_baseline
|
RiskCorrBaseline
|
各正常箱坏率相关性(RC)的基准。默认 |
'total'
|
ordered_metric_sort_by
|
OrderedMetricSortBy
|
KS/AUC 的排序口径。默认 |
'woe'
|
ks_method
|
Literal['binned', 'raw']
|
默认使用分箱 KS。 |
'binned'
|
max_raw_ks_features
|
int
|
正整数。raw 模式允许的最多数值特征数,默认 50;超限在分箱和排序前报错。 类别特征不占额度,binned 模式不执行数量限制。 |
50
|
batch_size
|
int
|
每批评估的特征数,默认 100,必须为正整数。控制中间表规模,不改变指标口径。 |
100
|
n_jobs
|
int | None
|
分箱器的并行任务数。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
MarsRiskProfile
|
单次风险评估结果,包含 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
KS 参数非法、raw 模式数值特征超限、参与计算的权重非法,或输入不符合评估契约。 |
Notes
report.report_meta["feature_start_aware_reference"] 表示本次是否实际构造出
按特征上线日构造的参考。已识别的特征及上线日期分别
保存在 feature_start_reference_features 和 feature_start_reference_dates 中。
示例:
>>> import polars as pl
>>> from mars.analysis import profile_risk
>>> df = pl.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> profile = profile_risk(
... df,
... target="y",
... features=["age"],
... method="quantile",
... n_bins=3,
... )
>>> profile.targets
['y']
>>> temporal_df = pl.DataFrame(
... {
... "dt": [
... "2024-01-01", "2024-01-02", "2024-01-03",
... "2024-02-15", "2024-02-16", "2024-02-17",
... ],
... "score": [None, None, None, 0.1, 0.5, 0.9],
... "y": [0, 1, 0, 0, 1, 1],
... }
... )
>>> temporal_profile = profile_risk(
... temporal_df,
... target="y",
... features=["score"],
... time_col="dt",
... time_grain="month",
... feature_start_aware_reference=True,
... )
>>> temporal_profile.report.report_meta["feature_start_reference_features"]
['score']
mars.analysis.MarsRiskProfile
dataclass
¶
单次风险画像结果。
MarsRiskProfile 是 MarsBinEvaluator.evaluate 和 profile_risk 的统一返回对象,
保存报告、分箱器、本次目标列和运行元数据。
可以通过 report 查看或导出结果,也可以复用 binner 转换新样本。
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
report |
MarsBinningReport
|
风险评估报告,包含汇总表、明细表、趋势表和导出方法。 |
binner |
MarsBinnerBase
|
本次评估拟合或显式传入的分箱器。 |
targets |
list of str
|
本次画像覆盖的目标列列表;无标签画像时为空列表。 |
metadata |
dict
|
本次运行的列名、特征范围、分箱配置和其他上下文信息。 |
固定双模型分交叉¶
操作方法、统计口径与限制见相关性与模型分交叉。
mars.analysis.cross_scores ¶
cross_scores(
df: DataFrame | DataFrame,
*,
score_x: str,
score_y: str,
score_directions: dict[str, str],
targets: list[str] | None = None,
cutpoints: dict[str, list[float]] | None = None,
binning_reference: DataFrame | DataFrame | None = None,
n_bins: int | dict[str, int] = 5,
bin_definitions: (
dict[str, dict[str, Any]] | None
) = None,
binning_type: Literal[
"native", "optimal", "lite_opt"
] = "native",
method: (
Literal["quantile", "uniform", "cart"] | None
) = None,
min_bin_size: float | int | None = None,
monotonic_trend: (
_ProfileRiskMonotonicTrend | None
) = None,
binner_params: dict[str, Any] | None = None,
binning_target: str | None = None,
n_jobs: int | None = None,
group_col: str | None = None,
time_col: str | None = None,
time_grain: str | None = None,
weights_col: str | None = None,
amount_col: str | None = None,
special_values: dict[str, list[float]] | None = None,
missing_values: (
list[Any] | dict[str, list[Any]] | None
) = None,
probability_scores: list[str] | None = None,
min_observed: int = 30,
confidence_level: float = 0.95,
max_scopes: int = 10000,
feature_metadata: FeatureMetadata | None = None,
business_context: dict[str, Any] | None = None
) -> ScoreCrossReport
固定两个模型分的分箱,并统计同一样本在两轴交叉格子中的分布和风险。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
df
|
DataFrame | DataFrame
|
同一行已对齐的样本;跨引擎转换前投影必要字段,不合并独立数据集。 |
必需 |
score_x
|
str
|
作为 X 轴的主模型分列名,使用原始字段标识。 |
必需 |
score_y
|
str
|
作为 Y 轴的辅助模型分列名,必须不同于 score_x。 |
必需 |
score_directions
|
dict[str, str]
|
必须为两个分数列分别声明 |
必需 |
targets
|
list[str] | None
|
二分类标签列,非缺失值须为 0 或 1。评估样本可全好或全坏,缺失标签视为未表现。
|
None
|
cutpoints
|
dict[str, list[float]] | None
|
按两个分数列指定有限切点,使用右闭区间。两端无界,可接收参考集范围外的有限分。
与 |
None
|
binning_reference
|
DataFrame | DataFrame | None
|
拟合分箱使用的参考集。默认在当前输入上为每轴拟合一次,不按组名选择训练样本。 监督分箱须在此参考集中提供 binning_target;跨组、周期和评估目标复用定义。 |
None
|
n_bins
|
int | dict[str, int]
|
正常分箱数,须为 1~100 的整数,默认 5;可按两个原始分数列指定不同箱数。 特殊箱不占正常箱数量,实际箱数可能减少;显式切点或保存定义以其实际箱数为准。 |
5
|
bin_definitions
|
dict[str, dict[str, Any]] | None
|
|
None
|
binning_type
|
Literal['native', 'optimal', 'lite_opt']
|
复用 profile_risk 的共享分箱引擎;默认 native。显式切点/保存定义不接受拟合配置。 |
'native'
|
method
|
Literal['quantile', 'uniform', 'cart'] | None
|
native 为等频、等宽或树;optimal/lite_opt 为预分箱方法。None 使用引擎默认值, native 默认 quantile。自定义区间使用 cutpoints,不支持 method="custom"。 |
None
|
min_bin_size
|
float | int | None
|
透传共享分箱器的最小箱大小约束;None 使用引擎默认值。native CART 支持整数人数。 约束只针对拟合参考集;已启用时按同一成员适配右闭端点,无法满足写入拟合诊断。 显式切点和保存定义用于独立数据时保持固定分段,不重新约束箱占比。 |
None
|
monotonic_trend
|
_ProfileRiskMonotonicTrend | None
|
复用 profile_risk 趋势配置;监督最优分箱默认 auto_asc_desc,native 发警告并忽略。 |
None
|
binner_params
|
dict[str, Any] | None
|
复用 profile_risk 高级参数解析,如 native 的 cart_params、merge_small_bins、 remove_empty_bins。公开参数和 prebinning_method 不可放入此映射。 |
None
|
binning_target
|
str | None
|
CART/optimal/lite_opt 的唯一拟合标签;None 默认首个 targets,并保存实际标签。 可显式选择独立标签,参考集上校验 0/1/缺失及两个有效类别;不随评估目标重拟合。 |
None
|
n_jobs
|
int | None
|
共享分箱器并行参数;None 使用引擎默认值,-1 或正整数。 |
None
|
group_col
|
str | None
|
已有的样本分组列,默认不拆分样本组。分组轴与时间轴独立, 同时提供时只生成数据中实际出现的 group/period 组合。 |
None
|
time_col
|
str | None
|
用于独立时间轴的日期列。默认不划分周期,即使提供了 |
None
|
time_grain
|
str | None
|
日期聚合粒度,例如 |
None
|
weights_col
|
str | None
|
样本权重列,值须有限、非负且非缺失,允许零。提供后 bad_rate 使用 bad_weight_sum / observed_weight_sum;未提供时使用坏人数 / 有表现人数。 |
None
|
amount_col
|
str | None
|
额外计算金额统计的列。null、NaN 和负值不贡献金额,无穷值和非数值会报错。 金额坏率为 bad_amt / (good_amt + bad_amt),不受样本权重影响。 |
None
|
special_values
|
dict[str, list[float]] | None
|
按分数列指定有限特殊值,默认不增加特殊值。特殊值单独成箱,没有 risk_rank, 且优先于概率范围检查。 |
None
|
missing_values
|
list[Any] | dict[str, list[Any]] | None
|
共享缺失值语义;一个列表应用于两轴,或按原始 score ID 指定。随定义保存、加载复用。 已声明的 inf/-inf 优先进入缺失箱;未声明的非有限值继续进入 invalid。 |
None
|
probability_scores
|
list[str] | None
|
明确按 [0, 1] 概率检查的分数列。范围外取值进入 invalid 箱; 默认不将任何列视为概率,普通分数不限制在此范围内。 |
None
|
min_observed
|
int
|
有表现人数低于此值时标记 low_sample,默认 30。仅影响状态,保留实际风险值。 |
30
|
confidence_level
|
float
|
使用未加权整数坏人数和有表现人数计算的 Wilson 置信水平,默认 0.95。 加权风险仍附未加权区间,加权区间状态为 unsupported。 |
0.95
|
max_scopes
|
int
|
实际 group/period 组合数上限,默认 10,000,超出时报错。 输出行数随范围数、目标数和完整分箱对数的乘积增长。 |
10000
|
feature_metadata
|
FeatureMetadata | None
|
复用原始 ID、展示名、来源、业务描述和单位格式。 |
None
|
business_context
|
dict[str, Any] | None
|
样本及标签业务语义;未声明的单位、训练含义等记录 unknown。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
ScoreCrossReport
|
包含 bins、cells、row_summary、column_summary 和 overall 表的独立快照。 加载后仍可使用公共展示与规则回放函数。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
列、方向、分段、标签、权重或规模配置无效。 |
Notes
计数和占比包含所有特殊箱;同一批样本在各目标下重复统计,多个 target 的人数不可相加。 比例保存为小数,delta_vs_row 为格子坏率减同一 X 行坏率,展示时换算为百分点。 边际和总体先加总计数再重算风险,Lift 以同 target/group/period 的真实整体坏率为基准。 规则只精确回放完整保存分段,不支持箱内连续阈值的插值。 parameters.scope_dimensions 记录 group/period 的实际来源、列和生效时间粒度, 不从标签或周期数量猜测时间维度;未声明时间时内部 Total 只用于统计 scope。 此元数据随快照保存;旧快照缺少字段时保留原统计与参数,由展示端明确降级。
示例:
mars.analysis.ScoreCrossReport ¶
Bases: ReportSnapshot
保存固定分箱下两个模型分的交叉统计。
由 cross_scores 生成,包含分箱定义、格子、边际和整体统计。
evaluate_policy 调用公共回放函数;加载后的通用快照也可使用同一函数。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
tables
|
dict[str, Any]
|
已聚合的列式小统计表,不包含个体明细。 |
必需 |
description
|
dict[str, Any]
|
身份、单位、分段定义及真实计算参数。 |
必需 |
示例:
>>> report = cross_scores(df, score_x="main", score_y="aux",
... score_directions={"main": "lower_risk", "aux": "higher_risk"})
search_features ¶
search_features(
query: str = "",
*,
sources: str | list[str] | None = None,
limit: int = 20
) -> list[dict[str, Any]]
按英文标识、显示名、描述和来源检索,同名特征分别返回。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
query
|
str
|
在英文 ID、显示名、描述和来源中查找包含此文本的特征,不区分大小写。 默认空字符串匹配全部特征。 |
''
|
sources
|
str | list[str] | None
|
按已登记来源筛选,默认不限制;与文本条件取交集,未知来源报错。 |
None
|
limit
|
int
|
非负返回数量上限,默认 20;设为 0 时返回空列表。 |
20
|
返回:
| 类型 | 描述 |
|---|---|
list[dict[str, Any]]
|
按字典顺序返回候选,每项包含 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
查询文本、来源或数量无效时抛出。 |
示例:
save ¶
将完整报告保存为包含 JSON 清单与 Parquet 表的单个 ZIP 文件。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
path
|
str | Path
|
目标文件路径,通常使用 |
必需 |
overwrite
|
bool
|
是否覆盖已有文件,默认拒绝覆盖。设为 True 时,完整写入临时文件后再原子替换。 |
False
|
Notes
编码失败传播 ValueError;拒绝覆盖传播 FileExistsError;I/O 失败传播 OSError。 失败不会留下可误认为完整报告的半成品。
示例:
describe ¶
get_table ¶
get_table(
name: str,
*,
features: str | list[str] | None = None,
columns: list[str] | None = None,
filters: dict[str, Any] | None = None,
sort_by: str | list[str] | None = None,
descending: bool = False,
offset: int = 0,
limit: int | None = None,
sources: str | list[str] | None = None
) -> ReportFrame
查询已有结果,返回可继续加工且与原表类型一致的 DataFrame。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
name
|
str
|
|
必需 |
features
|
str | list[str] | None
|
原始英文特征 ID,默认不限制。单特征表匹配 |
None
|
columns
|
list[str] | None
|
返回字段,默认保留全部列;显式指定时只返回所列字段,并保持指定顺序。 筛选和排序可使用未返回的列。 |
None
|
filters
|
dict[str, Any] | None
|
字段到标量相等条件或 |
None
|
sort_by
|
str | list[str] | None
|
单个或多个排序字段,默认保留原行序;相同排序键保持原顺序。 |
None
|
descending
|
bool
|
是否按 |
False
|
offset
|
int
|
筛选并排序后跳过的行数,默认 0,必须为非负整数。 |
0
|
limit
|
int | None
|
非负最大行数;0 返回保留列 schema 的空表,None 不限制。 排序配合 limit 实现 Top-K;需要续页计数时使用 limit 为正整数或 None 的 query_page。 |
None
|
sources
|
str | list[str] | None
|
按已登记来源筛选,默认不限制。含多个特征角色的表匹配任一角色的来源;
与 |
None
|
返回:
| 类型 | 描述 |
|---|---|
ReportFrame
|
查询结果的独立容器;不重新计算指标。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
表名、字段、操作符、来源或分页参数无效时抛出。 |
示例:
query_page ¶
按 get_table 参数取得分页证据、总匹配数及持久引用。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
name
|
str
|
公共表目录中的表名。 |
必需 |
**query
|
Any
|
get_table 的关键字参数;默认 offset=0、limit=10。 limit 只接受正整数或 None;None 返回 offset 后全部结果且无续页。 零行精确查询使用 get_table(limit=0)。 |
{}
|
返回:
| 类型 | 描述 |
|---|---|
dict[str, Any]
|
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
limit 不是正整数或 None,或其他 get_table 查询参数无效时抛出。 |
示例:
to_ai_context ¶
to_ai_context(
*,
tables: list[str] | None = None,
features: str | list[str] | None = None,
columns: list[str] | None = None,
filters: dict[str, Any] | None = None,
limit: int = 10,
max_chars: int = 16000,
sources: str | list[str] | None = None,
sort_by: str | list[str] | None = None,
descending: bool = False,
offset: int = 0,
queries: dict[str, dict[str, Any]] | None = None
) -> str
查询已计算结果,并在字符预算内生成可回放的 JSON 摘要。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
tables
|
list[str] | None
|
需要查询的公共表名。默认采用目录的 |
None
|
features
|
str | list[str] | None
|
所有选中表共用的英文特征 ID 条件,默认不限制;匹配规则同 |
None
|
columns
|
list[str] | None
|
所有选中表共用的返回字段,默认保留全部列;宽趋势表可按日期列选择范围。 |
None
|
filters
|
dict[str, Any] | None
|
所有选中表共用的筛选条件,格式同 |
None
|
limit
|
int
|
每表的非负整数行数上限,默认 10;不接受无界的 None。 0 保留空证据、schema、匹配数和查询引用,继续取证定位另给正页长。 |
10
|
max_chars
|
int
|
最终 JSON 的 Unicode 字符预算,默认 16,000,必须至少为 512。 预算包含身份、查询、口径和省略说明,按字符计数,不按 token 计数。 非空查询至少保留一条完整证据;必要说明与证据无法同时容纳时抛出异常。 |
16000
|
sources
|
str | list[str] | None
|
所有选中表共用的来源筛选条件,默认不限制;匹配规则同 |
None
|
sort_by
|
str | list[str] | None
|
所有选中表共用的排序字段,默认保留原行序。 |
None
|
descending
|
bool
|
是否按排序字段降序排列,默认升序。 |
False
|
offset
|
int
|
每表筛选并排序后跳过的行数,默认 0。 |
0
|
queries
|
dict[str, dict[str, Any]] | None
|
表名到 |
None
|
返回:
| 类型 | 描述 |
|---|---|
str
|
标准 JSON 字符串。相同 null 口径存放在表级 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
查询无效或预算无法同时容纳最小必要说明及非空查询的一条证据时抛出。 |
示例:
get_feature ¶
读取与单个特征相关的已有统计表,并列出无可用行的结果类别。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
feature
|
str
|
原始英文特征 ID;已登记但没有匹配统计行时,
|
必需 |
limit
|
int
|
每表非负最大行数,默认 100;0 保留空表 schema、匹配状态和省略数。
需要更多行时,可用 |
100
|
返回:
| 类型 | 描述 |
|---|---|
dict[str, Any]
|
包含特征身份、元数据、 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
特征不存在或分页参数无效时抛出。 |
示例:
show_table ¶
write_html ¶
write_excel ¶
evaluate_policy ¶
evaluate_policy(
candidate: dict[str, Any],
*,
baseline: dict[str, Any] | None = None
) -> ReportSnapshot
从保存格子回放完整分段规则,保持父报告不变。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
candidate
|
dict[str, Any]
|
声明式 x_only/y_only/and/or/staircase/expression 规则,格式见 evaluate_score_policy。 |
必需 |
baseline
|
dict[str, Any] | None
|
用于比较的基准规则; |
None
|
返回:
| 类型 | 描述 |
|---|---|
ReportSnapshot
|
可保存的规则、留存/剔除、四区域和实际覆盖差;绑定父 report_id。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
规则或门槛无效;箱内连续阈值无法精确回放。 |
示例:
mars.analysis.get_score_bin_definitions ¶
提取固定分箱定义,供后续报告复用同一套边界。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
report
|
Report
|
score_cross 报告或加载后的快照。 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
dict[str, dict[str, Any]]
|
按 x、y 轴组织的独立副本,包含分数列名、方向、切点、端点和特殊值; 自动拟合的定义另含拟合来源。 自定义缺失列表中的受限非有限浮点标签恢复为 Python 值,供固定定义计算复用。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
报告类型无效。 |
示例:
mars.analysis.evaluate_score_policy ¶
evaluate_score_policy(
report: Report,
candidate: dict[str, Any],
*,
baseline: dict[str, Any] | None = None
) -> ReportSnapshot
按已保存的交叉格子回放规则,返回引用父报告的独立快照。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
report
|
Report
|
score_cross 报告,支持 load_report 的通用快照;不需要原样本。 |
必需 |
candidate
|
dict[str, Any]
|
type 为 x_only/y_only/and/or/staircase/expression。统一规则使用 x/y_max_risk_rank; staircase 使用 steps={实际 X bin_id: {action: accept, y_max_risk_rank: 整数}}, 整段拒绝为 {action: reject},未列出的 X 段拒绝。missing_score 默认 reject, accepted_special_bins 可显式接受特殊箱。仅依赖的轴影响通过条件。 expression 使用 expression="X <= X2 AND Y <= Y3";编号为保存的正常箱风险 序位,支持同轴标签或整数、比较符及大小写不敏感的 AND/OR,AND 优先于 OR。 括号覆盖优先级;最多 240 字符、96 词元、12 层括号。只覆盖完整正常箱集合, 不接受连续阈值或隐含特殊箱;不产生自动审批语义。 |
必需 |
baseline
|
dict[str, Any] | None
|
用于比较留存和风险变化的规则,格式同 |
None
|
返回:
| 类型 | 描述 |
|---|---|
ReportSnapshot
|
包含 summary(候选与基准的留存和剔除)、regions(基准与候选通过条件的四种组合)、 changes(实际留存和风险差)、cell_decisions 和 bins;AND/OR 规则另有 axis_regions。 调用和保存均不修改父报告,调用时不自动写文件。结果只描述当前历史样本。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
报告类型、规则或分段门槛无效;连续箱内阈值无法精确回放。 |
示例:
mars.analysis.get_score_cell ¶
get_score_cell(
report: Report,
x_bin: str,
y_bin: str,
*,
filters: dict[str, Any] | None = None
) -> dict[str, Any]
查询指定交叉格子的统计证据和固定区间。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
report
|
Report
|
原始 score_cross 报告或加载后的快照。 |
必需 |
x_bin
|
str
|
已保存的 X 轴 bin_id,例如 |
必需 |
y_bin
|
str
|
已保存的 Y 轴 bin_id,例如 |
必需 |
filters
|
dict[str, Any] | None
|
按 target、group 和 period 等字段筛选。默认返回此格子在全部样本范围下的记录, 每条记录保留目标、分组和周期。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
dict[str, Any]
|
|
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
报告或 bin_id 无效。 |
示例:
mars.analysis.show_score_matrix ¶
show_score_matrix(
report: Report,
*,
filters: dict[str, Any] | None = None,
metric: str = "bad_rate",
include_special: bool = False,
color_range: tuple[float, float] | None = None
) -> Any
显示单个样本范围的双分数矩阵,按低风险到高风险排列。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
report
|
Report
|
score_cross 报告或加载后的快照。 |
必需 |
filters
|
dict[str, Any] | None
|
按 target、group 和 period 筛选。默认使用首个匹配范围,并在 caption 中注明。 |
None
|
metric
|
str
|
格子展示指标,可选 bad_rate、delta_vs_row 和 sample_share,默认 bad_rate。 坏率和样本占比显示为百分比,行坏率差显示为百分点。 |
'bad_rate'
|
include_special
|
bool
|
是否展示特殊箱,默认折叠并注明省略的样本数。折叠后仍使用包含特殊箱的边际和总体。 |
False
|
color_range
|
tuple[float, float] | None
|
用小数指定色标上下界。默认坏率和样本占比使用 [0, 1],行坏率差使用 [-1, 1]。 上下界须递增,行坏率差的色标须关于 0 对称。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
Any
|
可在 Notebook 显示、用 to_html/to_excel 导出的 Pandas Styler。 格子标注有表现人数;TOTAL 展示重算后的边际指标,行坏率差视图的 TOTAL 展示坏率。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
报告、指标、色标或样本范围无效。 |
示例:
mars.analysis.write_score_cross_html ¶
write_score_cross_html(
report: Report,
path: str | Path,
*,
report_name: str = "MARS Score Cross",
policy_reports: list[Report] | None = None
) -> None
导出自包含 HTML,展示交叉矩阵、沿两轴的风险变化和分箱规则回放。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
report
|
Report
|
score_cross 报告,支持加载后的快照。 |
必需 |
path
|
str | Path
|
目标路径;父目录须存在。 |
必需 |
report_name
|
str
|
页面标题,默认 |
'MARS Score Cross'
|
policy_reports
|
list[Report] | None
|
已回放的派生规则报告,须来自当前 report_id。提供后可离线查看留存、 四区域、覆盖差和格子差异;默认不附加派生报告。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
None
|
写入自包含 HTML;使用保存分箱、行列边际及包含特殊箱的 overall。 点击或键盘选择不改变规则;规则只匹配常规完整分箱,独立应用或清除。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
报告或规则父 ID 不匹配。 |
示例: