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 trainDist, List currentDist, int binCount) {
// 合并数据确定分箱边界
List allValues = new ArrayList<>();
allValues.addAll(trainDist);
allValues.addAll(currentDist);
// 计算分箱边界
List 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 trainDist, List 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 trainDist, List currentDist) {
List sortedTrain = trainDist.stream().sorted().collect(Collectors.toList());
List 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 values, double percentile) {
List 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 values, List 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 trainData = Arrays.asList(1.2, 1.5, 1.7, 1.8, 2.0, 2.1, 2.3, 2.5, 2.7, 3.0);
List 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
《回荡的钟摆》和《置身事内》
分税制简介