首页  

PMML模型监控分析     所属分类 PMML 浏览量 82
PMML(Predictive Model Markup Language)是一种用于表示机器学习模型的标准格式。

对于基于PMML的模型,计算稳定性(PSI)和效果(KS)是评估模型性能的重要步骤。
PSI  Population Stability Index
PSI用于评估模型在不同时间段或不同数据集上的稳定性,反映模型预测结果的分布是否发生变化。


KS   Kolmogorov-Smirnov
KS用于评估模型区分好坏客户的能力,反映模型对正负样本的区分度


CSI (Characteristic Score of Instability) 
是一种用于评估PMML模型中样本特征分布稳定性的指标。
它可以监控模型输入特征的变化情况,从而评估模型性能可能受到的影响。
CSI衡量的是模型输入特征分布相对于训练数据分布的变化程度,
它通常结合了多种分布差异度量(如PSI、KS等)来全面评估特征稳定性。


PSI (Population Stability Index) < 0.1: 分布稳定,变化不大 0.1-0.25: 中等变化,需要关注 0.25: 显著变化,可能需要模型调整 KS (Kolmogorov-Smirnov) < 0.1: 分布相似 0.1-0.2: 有一定差异 0.2: 显著差异 CSI (Characteristic Score of Instability) 综合指标,值越大表示特征变化越大 可根据业务场景设定阈值 Interpretation: PSI < 0.1: Stable PSI 0.1-0.25: Moderate change (适度变化) PSI > 0.25: Significant change ( 重大变化) KS < 0.1: Similar distributions KS 0.1-0.2: Some difference KS > 0.2: Significant difference
实际应用建议 基准建立:在模型部署时保存训练数据的特征分布统计量 定期监控:按固定周期(如每天/每周)计算这些指标 自动化警报:当指标超过阈值时触发警报 分类特征处理:对于分类变量,可以使用卡方检验或JS散度替代PSI/KS
使用JPMML库计算PSI CSI 和 KS org.jpmml.jpmml-evaluator 1.5.11 1.6.3 // 模型监控 指标 工具类 import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class PmmlModelMetricsUtil { // 计算PSI (Population Stability Index) public static double calculatePSI(List<Double> trainDist, List<Double> currentDist, int binCount) { // 合并数据确定分箱边界 List<Double> allValues = new ArrayList<>(); allValues.addAll(trainDist); allValues.addAll(currentDist); // 计算分箱边界 List<Double> bins = new ArrayList<>(); for (int i = 0; i <= binCount; i++) { double percentile = 100.0 * i / binCount; bins.add(percentile(allValues, percentile)); } // 计算训练集和当前集在各分箱中的比例 double[] trainHist = histogram(trainDist, bins); double[] currentHist = histogram(currentDist, bins); // 计算PSI double psi = 0.0; for (int i = 0; i < binCount; i++) { if (trainHist[i] == 0) continue; if (currentHist[i] == 0) continue; double term = (currentHist[i] - trainHist[i]) * Math.log(currentHist[i] / trainHist[i]); psi += term; } return psi; } // 计算CSI (Characteristic Score of Instability) public static double calculateCSI(List<Double> trainDist, List<Double> currentDist) { // CSI通常可以使用PSI或KS作为基础指标 double psi = calculatePSI(trainDist, currentDist, 10); double ks = calculateKS(trainDist, currentDist); // 这里简单平均两种指标,实际可根据需求调整 return (psi + ks) / 2; } // 计算KS (Kolmogorov-Smirnov)统计量 public static double calculateKS(List<Double> trainDist, List<Double> currentDist) { List<Double> sortedTrain = trainDist.stream().sorted().collect(Collectors.toList()); List<Double> sortedCurrent = currentDist.stream().sorted().collect(Collectors.toList()); int n1 = sortedTrain.size(); int n2 = sortedCurrent.size(); int i1 = 0, i2 = 0; double maxDiff = 0.0; double cum1 = 0.0, cum2 = 0.0; while (i1 < n1 && i2 < n2) { double x1 = sortedTrain.get(i1); double x2 = sortedCurrent.get(i2); if (x1 <= x2) { cum1 = (++i1) / (double) n1; } if (x2 <= x1) { cum2 = (++i2) / (double) n2; } double diff = Math.abs(cum1 - cum2); if (diff > maxDiff) { maxDiff = diff; } } return maxDiff; } // 辅助方法:计算百分位数 private static double percentile(List<Double> values, double percentile) { List<Double> sorted = values.stream().sorted().collect(Collectors.toList()); int n = sorted.size(); double index = percentile / 100.0 * (n - 1); int lower = (int) Math.floor(index); int upper = (int) Math.ceil(index); if (lower == upper) { return sorted.get(lower); } double weight = index - lower; return sorted.get(lower) * (1 - weight) + sorted.get(upper) * weight; } // 辅助方法:计算直方图 private static double[] histogram(List<Double> values, List<Double> bins) { int binCount = bins.size() - 1; int[] counts = new int[binCount]; for (double value : values) { for (int i = 0; i < binCount; i++) { if (value >= bins.get(i) && (i == binCount - 1 || value < bins.get(i + 1))) { counts[i]++; break; } } } double[] hist = new double[binCount]; int total = values.size(); for (int i = 0; i < binCount; i++) { hist[i] = counts[i] / (double) total; } return hist; } public static void main(String[] args) { // 示例数据 - 训练集和当前集特征值 List<Double> trainData = Arrays.asList(1.2, 1.5, 1.7, 1.8, 2.0, 2.1, 2.3, 2.5, 2.7, 3.0); List<Double> currentData = Arrays.asList(1.3, 1.6, 1.9, 2.2, 2.4, 2.6, 2.8, 3.1, 3.3, 3.5); // 计算各项指标 double psi = calculatePSI(trainData, currentData, 5); double ks = calculateKS(trainData, currentData); double csi = calculateCSI(trainData, currentData); System.out.println("PSI (Population Stability Index): " + psi); System.out.println("KS (Kolmogorov-Smirnov): " + ks); System.out.println("CSI (Characteristic Score of Instability): " + csi); // 解释结果 System.out.println("\nInterpretation:"); System.out.println("PSI < 0.1: Stable"); System.out.println("PSI 0.1-0.25: Moderate change"); System.out.println("PSI > 0.25: Significant change"); System.out.println("\nKS < 0.1: Similar distributions"); System.out.println("KS 0.1-0.2: Some difference"); System.out.println("KS > 0.2: Significant difference"); } }

上一篇     下一篇
PMML支持的模型类型

PMML Model: Independent and Dependent Fields

PMML模型中 TargetFields 和 OutputFields 的区别

PMML与JPMML

《回荡的钟摆》和《置身事内》

分税制简介