java里面用JavaScript执行动态字符串公式

项目中有个需求:对客户画像进行打分,客户画像的一些标签有:年龄、家庭年收入、所在省份、想购买什么保险、家庭人口等。
这个客户的评分就是由这些画像标签的评分组合起来的,这个组合有一个公式,如下所示:

1/(1+exp(-(0.00188
 +(0.49799*age)
 +(0.47557*createputinintervald)
 +(0.37217*mediatypename)
 +(0.33848*isdact)
 +(0.18899*forinsur)
 +(0.3288*province)
 +(0.28564*wantbuy)
 +(0.17985*createtimetoappointmenttime)
 +(0.15602*understandtherisks_counts)
 +(0.10727*fertilitycircumstance)
 +(0.19211*isbuycommercialinsurance_jc)
 +(0.05253*pushtypename)
 ))) 

现在问题是:每个客户的详细标签的内容不一样,那么他们的标签评分也不一样,最终的客户评分也不一样,这就需要我们动态的执行上面这个公式,在执行公式的时候,里面的变量值需要动态替换。我的实现思路如下,具体代码如下。

@Slf4j
public enum CustScoreFormulaEnum {

    SCORE_FORMULA("1/(1+Math.exp(-(0.00188+(0.49799*"+FieldNameEnum.AGE.fieldName+")" +
            "+(0.47557*"+FieldNameEnum.CREATE_PUT_IN_INTERVAL.fieldName+")" +
            "+(0.37217*"+FieldNameEnum.MEDIA_TYPENAME.fieldName+")" +
            "+(0.33848*"+FieldNameEnum.IS_DAC_T.fieldName+")" +
            "+(0.18899*"+FieldNameEnum.FOR_INSURE.fieldName+")" +
            "+(0.3288*"+FieldNameEnum.PROVINCE.fieldName+")" +
            "+(0.28564*"+FieldNameEnum.WANT_BUY.fieldName+")" +
            "+(0.17985*"+FieldNameEnum.CREATE_TIME_TO_APPOINTMENT_TIME.fieldName+")" +
            "+(0.15602*"+FieldNameEnum.UNDERSTAND_THE_RISKS_COUNTS.fieldName+")" +
            "+(0.10727*"+FieldNameEnum.FERTILITY_CIRCUMSTANCE.fieldName+")" +
            "+(0.19211*"+FieldNameEnum.IS_BUY_COMMERCIAL_INSURANCE.fieldName+")" +
            "+(0.05253*"+FieldNameEnum.PUSH_TYPE_NAME.fieldName+"))))","客户评分公式");


    /**
     * 公式
     */
    public final String formula;

    /**
     * 公式具体描述
     */
    public final String formulaDesc;

    CustScoreFormulaEnum(String formula, String formulaDesc) {
        this.formula = formula;
        this.formulaDesc = formulaDesc;
    }
    
   /**
    * @description 动态执行公式
    * @param fieldMapping 字段名称和字段值的mapping
    * @return java.lang.Double
    **/
    public static Double calc(Map<String,Double> fieldMapping) {
        String formula = CustScoreFormulaEnum.SCORE_FORMULA.formula;
        //先把公式里面的字段key值动态替换成数字
        for (String fieldName : fieldMapping.keySet()) {
            formula = formula.replace(fieldName, fieldMapping.get(fieldName).toString());
        }
        //打印替换完后的公式
        log.info("formula公式为:{}", formula);
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        try {
            // 执行字符串公式
            Object result = engine.eval(formula);
            //将结果保留4位小数
            return Math.round(Double.parseDouble(result.toString()) * 10000D) / 10000D;
          } catch (Exception e) {
            log.error("ScriptEngine 执行 字符串公式异常", e);
         }
        return 0D;
    }
}        

其中FieldNameEnum 这个枚举存的是每个字段英文名称和中文描述,还有每个字段的评分值我也会记录在表里面,相当于一个中间值的记录,这里具体的代码我也不做展示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值