Loading... ### PMML模型概率值转换分数 数据组给出的PMML模型文件通过Java的jpmml运行后获取的值是一个(0,1)的概率值,指的是概率为1的值(二分类模型)。项目上需要将其均匀转换成一个分数,但是不同模型所属场景不同,需要转换的目标也不同。大致有两种情况,一种是模型阈值为0.5,一种是模型阈值不为0.5,这两种的Java转换思路如下。 - 0-100标准分数且模型阈值不为0.5。 这种情况一般模型会给出一个模型阈值,即区分好坏样本的中间值,一般的二分类模型可能是0.5,即大于0.5则为1,小于0.5则为0。但是实际生成中这个值会根据模型情况变动,不一定为0.5,这时候就需要结合该值进行转换,转换后0-100的分数中间值为50。 ```java /** * @param p 特征重要性 * @param modelScore 模型概率 * @return 模型分数 */ private String exchange(Double p, String modelScore) { //如果是科学计算,需要转换下 if (modelScore.contains("E")) { modelScore = new BigDecimal(modelScore).toPlainString(); } double x = Double.parseDouble(modelScore); double k; if (x > p) { if (p > 1 - 1E-6) { k = 1 / (x - p); } else { k = 1 / (1 - p); } } else { if (p < 1E-6) { k = 1; } else { k = 1 / p; } } //50+50*转化斜率*(概率值与模型阈值的差),String expression = "50+50*k*(x-p)"; double score = Math.abs(50 + 50 * k * (x - p)); return String.format("%.2f", score); } ``` 例如,当模型阈值为0.45,模型概率值为0.5,映射到0-100分数为: ```java 50 + 50 * 1 / (1 - 0.45) * (0.5 - 0.45) = 54.55 ``` 大致推导过程可以将映射过程分为两段即`[0, k)`映射到`[0-50)`, `[k,1]`映射到`[50,100]`。并合并成通项公式,转换到其他区间也是如此。 - 模型阈值为0.5,并转换为300-900 ```java /** * 模型分输出分值, 0-1概率,转换为300-900 * 1-高风险, 0-低风险 * @param targetValue 目标值 * @return */ private String exchange(Double targetValue){ String modelScore = ""; if(targetValue == null){ return modelScore; } BigDecimal original = BigDecimal.valueOf(targetValue); int score = new BigDecimal(300).add(new BigDecimal(600).multiply(original)).intValue(); //极值处理 if(score == 300){ score = score + RandomUtils.nextInt(0,10); } if(score == 900){ score = score - RandomUtils.nextInt(0,10); } modelScore = String.valueOf(score); return modelScore; } ``` 公式如下 ```java newScore = 300 + ((oldScore - 0) * (900 - 300) / (1 - 0)) = 300 + 600 * oldScore ``` 推导如下: 假设我们有一个原始区间 [a, b],我们想要将其均匀放大到目标区间 [c, d]。为了完成这个映射,我们可以使用以下的线性变换公式: ``` x_new = c + ((x_old - a) * (d - c) / (b - a)) ``` 其中: - `x_old` 是原始区间 [a, b] 内的任意数。 - `x_new` 是 `x_old` 映射到目标区间 [c, d] 后的对应数。 - `a` 和 `b` 是原始区间的下限和上限。 - `c` 和 `d` 是目标区间的下限和上限。 这个公式的原理是,首先计算 `x_old` 在原始区间内的相对位置(通过 `(x_old - a) / (b - a)` 得到,其值在 0 到 1 之间),然后将这个相对位置乘以目标区间的长度 `(d - c)`,最后加上目标区间的下限 `c`,从而得到 `x_new`。但该公式仅用于模型阈值为0.5的情况,也就是均匀分布,均匀放大。 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 2 If you think my article is useful to you, please feel free to appreciate