52 changed files with 4073 additions and 13 deletions
@ -0,0 +1,32 @@ |
|||||
|
package io.sc.engine.mv.sample.controller; |
||||
|
|
||||
|
import io.sc.engine.mv.sample.service.CardGongXinImporterService; |
||||
|
import io.sc.engine.mv.sample.service.CardJingyingImporterService; |
||||
|
import io.sc.engine.mv.sample.service.DaiKuanImporterService; |
||||
|
import io.sc.engine.mv.sample.service.TestCaseImporterService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
@RestController |
||||
|
@RequestMapping("/api/mv/sample") |
||||
|
public class SampleWebController { |
||||
|
@Autowired private TestCaseImporterService testCaseImporterService; |
||||
|
|
||||
|
@Autowired private CardGongXinImporterService cardGongXinImporterService; |
||||
|
@Autowired private CardJingyingImporterService cardJingyingImporterService; |
||||
|
@Autowired private DaiKuanImporterService daiKuanImporterService; |
||||
|
|
||||
|
@PostMapping("testCase") |
||||
|
public void importTestCase() throws Exception { |
||||
|
testCaseImporterService.load(); |
||||
|
} |
||||
|
|
||||
|
@PostMapping("sample") |
||||
|
public void importSample() throws Exception{ |
||||
|
cardGongXinImporterService.load(); |
||||
|
cardJingyingImporterService.load(); |
||||
|
daiKuanImporterService.load(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
package io.sc.engine.mv; |
||||
|
|
||||
|
/** |
||||
|
* 执行进度跟踪器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
public interface ProgressTracker { |
||||
|
public int getExecuteTimeWeight(); |
||||
|
} |
@ -0,0 +1,80 @@ |
|||||
|
package io.sc.engine.mv; |
||||
|
|
||||
|
import io.sc.platform.core.support.KeyValue; |
||||
|
import io.sc.platform.core.util.DateUtil; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 模型验证运行时上下文 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
public class RuntimeContext { |
||||
|
private ExecuteMode executeMode; //模型验证执行模式
|
||||
|
private Date validateDate; //模型验证执行日期
|
||||
|
private Date rateStartDateFrom; //源数据评级有效期开始日期(起始日期)
|
||||
|
private Date rateStartDateTo; //源数据评级有效期开始日期(结束日期)
|
||||
|
private int performPeriod; //模型表现期(月)
|
||||
|
private double binomialSignificanceLevel; //二项检验采用的显著水平
|
||||
|
private double chiSquareSignificanceLevel; //卡方检验采用的显著水平
|
||||
|
|
||||
|
/** |
||||
|
* 获取模型验证运行上下文参数列表 |
||||
|
* @return 模型验证运行上下文参数列表 |
||||
|
*/ |
||||
|
public List<KeyValue<String, String>> getRuntimeParameters(){ |
||||
|
List<KeyValue<String, String>> result =new ArrayList<KeyValue<String, String>>(); |
||||
|
result.add(new KeyValue<String,String>("rateStartDateFrom", DateUtil.formatDate(rateStartDateFrom,DateUtil.yyyy_MM_dd))); |
||||
|
result.add(new KeyValue<String,String>("rateStartDateTo", DateUtil.formatDate(rateStartDateTo,DateUtil.yyyy_MM_dd))); |
||||
|
result.add(new KeyValue<String,String>("performPeriod", Integer.toString(performPeriod))); |
||||
|
result.add(new KeyValue<String,String>("binomialSignificanceLevel", Double.toString(binomialSignificanceLevel))); |
||||
|
result.add(new KeyValue<String,String>("chiSquareSignificanceLevel", Double.toString(chiSquareSignificanceLevel))); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
public ExecuteMode getExecuteMode() { |
||||
|
return executeMode; |
||||
|
} |
||||
|
public void setExecuteMode(ExecuteMode executeMode) { |
||||
|
this.executeMode = executeMode; |
||||
|
} |
||||
|
public Date getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
public void setValidateDate(Date validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
public Date getRateStartDateFrom() { |
||||
|
return rateStartDateFrom; |
||||
|
} |
||||
|
public void setRateStartDateFrom(Date rateStartDateFrom) { |
||||
|
this.rateStartDateFrom = rateStartDateFrom; |
||||
|
} |
||||
|
public Date getRateStartDateTo() { |
||||
|
return rateStartDateTo; |
||||
|
} |
||||
|
public void setRateStartDateTo(Date rateStartDateTo) { |
||||
|
this.rateStartDateTo = rateStartDateTo; |
||||
|
} |
||||
|
public int getPerformPeriod() { |
||||
|
return performPeriod; |
||||
|
} |
||||
|
public void setPerformPeriod(int performPeriod) { |
||||
|
this.performPeriod = performPeriod; |
||||
|
} |
||||
|
public double getBinomialSignificanceLevel() { |
||||
|
return binomialSignificanceLevel; |
||||
|
} |
||||
|
public void setBinomialSignificanceLevel(double binomialSignificanceLevel) { |
||||
|
this.binomialSignificanceLevel = binomialSignificanceLevel; |
||||
|
} |
||||
|
public double getChiSquareSignificanceLevel() { |
||||
|
return chiSquareSignificanceLevel; |
||||
|
} |
||||
|
public void setChiSquareSignificanceLevel(double chiSquareSignificanceLevel) { |
||||
|
this.chiSquareSignificanceLevel = chiSquareSignificanceLevel; |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package io.sc.engine.mv; |
||||
|
|
||||
|
/** |
||||
|
* 标尺枚举值 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
public enum ScaleType { |
||||
|
SINGLE, //单个标尺(所有模型采用一套等级和违约概率的对应关系)
|
||||
|
MULTIPLE; //多个标尺(每个模型采用一套等级和违约概率的对应关系)
|
||||
|
} |
@ -0,0 +1,102 @@ |
|||||
|
package io.sc.engine.mv.controller.sc; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.GeneralResultHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.ScRocHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScRocHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.GeneralResultHistoryRepository; |
||||
|
import io.sc.engine.mv.jpa.repository.ScRocHistoryRepository; |
||||
|
import io.sc.engine.mv.sc.echarts.Coordinates; |
||||
|
import io.sc.engine.mv.service.sc.ScRocHistoryService; |
||||
|
import io.sc.engine.mv.vo.ScRocHistoryVo; |
||||
|
import io.sc.platform.core.util.CollectionUtil; |
||||
|
import io.sc.platform.mvc.controller.support.RestCrudController; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.dao.DataAccessException; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.jdbc.core.PreparedStatementCreator; |
||||
|
import org.springframework.jdbc.core.ResultSetExtractor; |
||||
|
import org.springframework.stereotype.Controller; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||
|
import org.springframework.web.servlet.ModelAndView; |
||||
|
|
||||
|
import java.sql.Connection; |
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
|
||||
|
@Controller |
||||
|
@RequestMapping("/mv/sc/roc") |
||||
|
public class RocWebController extends RestCrudController<ScRocHistoryVo, ScRocHistory, ScRocHistoryId, ScRocHistoryRepository, ScRocHistoryService> { |
||||
|
//模型验证结果DAO
|
||||
|
@Autowired private GeneralResultHistoryRepository generalResultHistoryRepository; |
||||
|
//jdbc 模板
|
||||
|
@Autowired private JdbcTemplate jdbcTemplate; |
||||
|
|
||||
|
/** |
||||
|
* 查看模型区分能力验证 ROC 指标数据UI |
||||
|
* @param modelId 模型标识 |
||||
|
* @param validateDate 验证日期 |
||||
|
* @return UI视图 |
||||
|
*/ |
||||
|
@RequestMapping("rocDataView") |
||||
|
public ModelAndView rocDataView( |
||||
|
@RequestParam(name="modelId",required=false) String modelId, |
||||
|
@RequestParam(name="validateDate",required=false) String validateDate |
||||
|
){ |
||||
|
ModelAndView mv =new ModelAndView("org/wsp/model/validator/view/sc/rocDataView.html"); |
||||
|
mv.addObject("removeNavbar", true); |
||||
|
mv.addObject("modelId", modelId); |
||||
|
mv.addObject("validateDate", validateDate); |
||||
|
mv.addObject("distinctModelIdAndNames", CollectionUtil.arrayList2Map(service.getRepository().findDistinctModelIdAndNames())); |
||||
|
return mv; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取模型区分能力 ROC 曲线的 echarts Options |
||||
|
* @param modelId 模型标识 |
||||
|
* @param validateDate 验证日期 |
||||
|
* @return 模型区分能力 ROC 曲线的 echarts Options 的 javascript |
||||
|
* @throws Exception 违例 |
||||
|
*/ |
||||
|
@RequestMapping("roc.js") |
||||
|
public ModelAndView roc( |
||||
|
@RequestParam("modelId") String modelId, |
||||
|
@RequestParam("validateDate") String validateDate |
||||
|
) throws Exception{ |
||||
|
ModelAndView mv =new ModelAndView("org/wsp/model/validator/view/sc/echarts/roc.js"); |
||||
|
GeneralResultHistory resultSummary =generalResultHistoryRepository.findByModelIdAndValidateDate(modelId, validateDate); |
||||
|
mv.addObject("resultSummary", resultSummary); |
||||
|
mv.addObject("coordinates",getCoordinates(modelId,validateDate)); |
||||
|
return mv; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取 ROC 曲线图中 X,Y 坐标集 |
||||
|
* @param modelId 模型标识 |
||||
|
* @param validateDate 验证日期 |
||||
|
* @return ROC 曲线图中 X,Y 坐标集 |
||||
|
*/ |
||||
|
private Coordinates getCoordinates(final String modelId, final String validateDate){ |
||||
|
return jdbcTemplate.query(new PreparedStatementCreator() { |
||||
|
@Override |
||||
|
public PreparedStatement createPreparedStatement(Connection con) throws SQLException { |
||||
|
String sql ="select FD_X,FD_Y from MV_SC_ROC_HIS where FD_MODEL_ID=? and FD_VALIDATE_DATE=? group by FD_X,FD_Y order by FD_X"; |
||||
|
PreparedStatement ps =con.prepareStatement(sql); |
||||
|
ps.setString(1, modelId); |
||||
|
ps.setString(2, validateDate); |
||||
|
return ps; |
||||
|
} |
||||
|
}, new ResultSetExtractor<Coordinates>() { |
||||
|
@Override |
||||
|
public Coordinates extractData(ResultSet rs) throws SQLException, DataAccessException { |
||||
|
Coordinates coordinates =new Coordinates(); |
||||
|
while(rs.next()){ |
||||
|
coordinates.add(rs.getBigDecimal("FD_X"), rs.getBigDecimal("FD_Y")); |
||||
|
} |
||||
|
coordinates.setScale(6); |
||||
|
return coordinates; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
@ -0,0 +1,88 @@ |
|||||
|
package io.sc.engine.mv.controller.st; |
||||
|
|
||||
|
import java.sql.Connection; |
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
import java.text.DecimalFormat; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.GeneralResultHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.StPsiHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.StPsiHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.GeneralResultHistoryRepository; |
||||
|
import io.sc.engine.mv.jpa.repository.StPsiHistoryRepository; |
||||
|
import io.sc.engine.mv.sc.echarts.XyCoordinates; |
||||
|
import io.sc.engine.mv.service.st.StPsiHistoryService; |
||||
|
import io.sc.engine.mv.vo.StPsiHistoryVo; |
||||
|
import io.sc.platform.core.util.CollectionUtil; |
||||
|
import io.sc.platform.mvc.controller.support.RestCrudController; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.dao.DataAccessException; |
||||
|
import org.springframework.jdbc.core.JdbcTemplate; |
||||
|
import org.springframework.jdbc.core.PreparedStatementCreator; |
||||
|
import org.springframework.jdbc.core.ResultSetExtractor; |
||||
|
import org.springframework.stereotype.Controller; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||
|
import org.springframework.web.servlet.ModelAndView; |
||||
|
|
||||
|
@Controller |
||||
|
@RequestMapping("/mv/st/psi") |
||||
|
public class PsiWebController extends RestCrudController<StPsiHistoryVo, StPsiHistory, StPsiHistoryId, StPsiHistoryRepository, StPsiHistoryService> { |
||||
|
@Autowired private GeneralResultHistoryRepository generalResultHistoryRepository; |
||||
|
@Autowired private JdbcTemplate jdbcTemplate; |
||||
|
|
||||
|
@RequestMapping("psiDataView") |
||||
|
public ModelAndView rocKpiDataView( |
||||
|
@RequestParam(name="modelId",required=false) String modelId, |
||||
|
@RequestParam(name="validateDate",required=false) String validateDate |
||||
|
){ |
||||
|
ModelAndView mv =new ModelAndView("org/wsp/model/validator/view/st/psiDataView.html"); |
||||
|
mv.addObject("removeNavbar", true); |
||||
|
mv.addObject("modelId", modelId); |
||||
|
mv.addObject("validateDate", validateDate); |
||||
|
mv.addObject("distinctModelIdAndNames", CollectionUtil.arrayList2Map(service.getRepository().findDistinctModelIdAndNames())); |
||||
|
return mv; |
||||
|
} |
||||
|
|
||||
|
@RequestMapping("psi.js") |
||||
|
public ModelAndView cap( |
||||
|
@RequestParam("modelId") String modelId, |
||||
|
@RequestParam("validateDate") String validateDate |
||||
|
) throws Exception{ |
||||
|
ModelAndView mv =new ModelAndView("org/wsp/model/validator/view/st/echarts/psi.js"); |
||||
|
GeneralResultHistory resultSummary =generalResultHistoryRepository.findByModelIdAndValidateDate(modelId, validateDate); |
||||
|
mv.addObject("resultSummary", resultSummary); |
||||
|
mv.addObject("coordinates",getCoordinates(modelId,validateDate)); |
||||
|
return mv; |
||||
|
} |
||||
|
|
||||
|
private XyCoordinates<Integer> getCoordinates(final String modelId, final String validateDate){ |
||||
|
final DecimalFormat df =new DecimalFormat("###.#"); |
||||
|
return jdbcTemplate.query(new PreparedStatementCreator() { |
||||
|
@Override |
||||
|
public PreparedStatement createPreparedStatement(Connection con) throws SQLException { |
||||
|
String sql ="select FD_SCORE_SEG_START,FD_SCORE_SEG_END,FD_COUNT_DEV,FD_COUNT_APP from MV_ST_PSI_HIS where FD_MODEL_ID=? and FD_VALIDATE_DATE=? order by FD_SCORE_SEG_START"; |
||||
|
PreparedStatement ps =con.prepareStatement(sql); |
||||
|
ps.setString(1, modelId); |
||||
|
ps.setString(2, validateDate); |
||||
|
return ps; |
||||
|
} |
||||
|
}, new ResultSetExtractor<XyCoordinates<Integer>>() { |
||||
|
@Override |
||||
|
public XyCoordinates<Integer> extractData(ResultSet rs) throws SQLException, DataAccessException { |
||||
|
XyCoordinates<Integer> coordinates =new XyCoordinates<Integer>(); |
||||
|
coordinates.add("0",0,0); |
||||
|
while(rs.next()){ |
||||
|
coordinates.add( |
||||
|
"[" + df.format(rs.getBigDecimal("FD_SCORE_SEG_START")) + "," + df.format(rs.getBigDecimal("FD_SCORE_SEG_END")) + "]", |
||||
|
rs.getInt("FD_COUNT_DEV"), |
||||
|
rs.getInt("FD_COUNT_APP") |
||||
|
); |
||||
|
} |
||||
|
coordinates.add("",0,0); |
||||
|
return coordinates; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
@ -0,0 +1,188 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import io.sc.platform.core.support.KeyValue; |
||||
|
import io.sc.platform.core.support.ProgressInfo; |
||||
|
import io.sc.platform.core.util.DateUtil; |
||||
|
import org.springframework.jdbc.core.PreparedStatementSetter; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 模型验证结果执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ResultExecutor extends AbstractExecutor{ |
||||
|
private static final int ORDER =10000; |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return ORDER; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void execute(RuntimeContext runtimeContext, ProgressInfo progressInfo) { |
||||
|
//删除模型验证结果历史数据
|
||||
|
deleteMV_GENERAL_RESULT_HIS(runtimeContext); |
||||
|
//删除模型验证执行时参数数据
|
||||
|
deleteMV_RUNTIME_PARAMETER(runtimeContext); |
||||
|
//将[模型验证结果表]中的所有数据插入到[模型验证结果历史表]中
|
||||
|
insertIntoMV_GENERAL_RESULT_HIS(runtimeContext); |
||||
|
//将当前运行时参数插入到[模型验证执行时参数配置表]中
|
||||
|
insertIntoMV_RUNTIME_PARAMETER(runtimeContext); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除模型验证结果历史数据 |
||||
|
* @param runtimeContext 运行时上下文 |
||||
|
*/ |
||||
|
private void deleteMV_GENERAL_RESULT_HIS(RuntimeContext runtimeContext){ |
||||
|
final String runtimeDateString = DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
log.info("开始删除[模型验证结果历史表]中符合(模型验证日期=" + runtimeDateString + ")的记录..."); |
||||
|
String sql ="delete from MV_GENERAL_RESULT_HIS where FD_VALIDATE_DATE=?"; |
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
log.info("完成删除[模型验证结果历史表]中符合(模型验证日期=" + runtimeDateString + ")的记录."); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除模型验证执行时参数数据 |
||||
|
* @param runtimeContext 运行时上下文 |
||||
|
*/ |
||||
|
private void deleteMV_RUNTIME_PARAMETER(RuntimeContext runtimeContext){ |
||||
|
final String runtimeDateString =DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
log.info("开始删除[模型验证执行时参数配置表]中符合[模型验证日期=" + runtimeDateString + "]的记录..."); |
||||
|
String sql ="delete from MV_RUNTIME_PARAMETER where FD_VALIDATE_DATE=?"; |
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
log.info("完成删除[模型验证执行时参数配置表]中符合[模型验证日期=" + runtimeDateString + "]的记录..."); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将[模型验证结果表]中的所有数据插入到[模型验证结果历史表]中 |
||||
|
* @param runtimeContext 运行时上下文 |
||||
|
*/ |
||||
|
private void insertIntoMV_GENERAL_RESULT_HIS(final RuntimeContext runtimeContext){ |
||||
|
log.info("开始将[模型验证结果表]中全部数据插入到[模型验证结果历史表]中..."); |
||||
|
final String runtimeDateString =DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
final String executeMode =runtimeContext.getExecuteMode().toString(); |
||||
|
String sql = "" |
||||
|
+ " insert into MV_GENERAL_RESULT_HIS(" |
||||
|
+ " FD_VALIDATE_DATE," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_EXECUTE_MODE," |
||||
|
|
||||
|
+ " FD_TOTAL_SAMPLE_COUNT," |
||||
|
+ " FD_DEFAULT_SAMPLE_COUNT," |
||||
|
|
||||
|
+ " FD_SC_AUC," |
||||
|
+ " FD_SC_AUC_QUANTITATIVE," |
||||
|
+ " FD_SC_AUC_QUALITATIVE," |
||||
|
|
||||
|
+ " FD_SC_AR," |
||||
|
+ " FD_SC_AR_QUANTITATIVE," |
||||
|
+ " FD_SC_AR_QUALITATIVE," |
||||
|
|
||||
|
+ " FD_SC_KS," |
||||
|
+ " FD_SC_KS_QUANTITATIVE," |
||||
|
+ " FD_SC_KS_QUALITATIVE," |
||||
|
|
||||
|
+ " FD_ST_SVD," |
||||
|
+ " FD_ST_PSI," |
||||
|
+ " FD_COE_CHI_SQUARE," |
||||
|
+ " FD_COE_BINOMIAL" |
||||
|
+ " )" |
||||
|
+ " select " |
||||
|
+ " ?," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " ?," |
||||
|
+ " FD_TOTAL_SAMPLE_COUNT," |
||||
|
+ " FD_DEFAULT_SAMPLE_COUNT," |
||||
|
+ " FD_SC_AUC," |
||||
|
+ " FD_SC_AUC_QUANTITATIVE," |
||||
|
+ " FD_SC_AUC_QUALITATIVE," |
||||
|
|
||||
|
+ " FD_SC_AR," |
||||
|
+ " FD_SC_AR_QUANTITATIVE," |
||||
|
+ " FD_SC_AR_QUALITATIVE," |
||||
|
|
||||
|
+ " FD_SC_KS," |
||||
|
+ " FD_SC_KS_QUANTITATIVE," |
||||
|
+ " FD_SC_KS_QUALITATIVE," |
||||
|
|
||||
|
+ " FD_ST_SVD," |
||||
|
+ " FD_ST_PSI," |
||||
|
+ " FD_COE_CHI_SQUARE," |
||||
|
+ " FD_COE_BINOMIAL" |
||||
|
+ " from MV_GENERAL_RESULT"; |
||||
|
|
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
pstmt.setObject(2, executeMode); |
||||
|
} |
||||
|
}); |
||||
|
log.info("完成将[模型验证结果表]中全部数据插入到[模型验证结果历史表]中."); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将当前运行时参数插入到[模型验证执行时参数配置表]中 |
||||
|
* @param runtimeContext 运行时上下文 |
||||
|
*/ |
||||
|
private void insertIntoMV_RUNTIME_PARAMETER(final RuntimeContext runtimeContext){ |
||||
|
log.info("开始将当前运行时参数插入到[模型验证执行时参数配置表]中..."); |
||||
|
final String runtimeDateString =DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
List<KeyValue<String,String>> parameters =runtimeContext.getRuntimeParameters(); |
||||
|
if(parameters!=null && parameters.size()>0){ |
||||
|
for(int i=0;i<parameters.size();i++){ |
||||
|
final KeyValue<String,String> parameter =parameters.get(i); |
||||
|
final int sno =i; |
||||
|
if(parameter!=null){ |
||||
|
String sql = "" |
||||
|
+ "insert into MV_RUNTIME_PARAMETER(" |
||||
|
+ " FD_VALIDATE_DATE," |
||||
|
+ " FD_PARAM_NAME," |
||||
|
+ " FD_PARAM_VALUE," |
||||
|
+ " FD_SNO" |
||||
|
+ ") values(" |
||||
|
+ " ?," |
||||
|
+ " ?," |
||||
|
+ " ?," |
||||
|
+ " ?" |
||||
|
+ ")"; |
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
pstmt.setObject(2, parameter.getKey()); |
||||
|
pstmt.setObject(3, parameter.getValue()); |
||||
|
pstmt.setObject(4, sno); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
log.info("完成将当前运行时参数插入到[模型验证执行时参数配置表]中."); |
||||
|
} |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import io.sc.platform.core.support.ProgressInfo; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型验证结果初始化执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ResultInitExecutor extends AbstractExecutor{ |
||||
|
private static final int ORDER =100; |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return ORDER; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 5; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void execute(RuntimeContext runtimeContext, ProgressInfo progressInfo) { |
||||
|
//删除模型验证结果数据
|
||||
|
deleteMV_GENERAL_RESULT(runtimeContext); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除模型验证结果历史数据 |
||||
|
* @param runtimeContext 运行时上下文 |
||||
|
*/ |
||||
|
private void deleteMV_GENERAL_RESULT(RuntimeContext runtimeContext){ |
||||
|
log.info("开始删除模型验证结果表的数据..."); |
||||
|
String sql ="delete from MV_GENERAL_RESULT"; |
||||
|
jdbcTemplate.execute(sql); |
||||
|
log.info("完成删除模型验证结果表的数据"); |
||||
|
} |
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
|
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import io.sc.platform.core.support.ProgressInfo; |
||||
|
import org.springframework.jdbc.core.RowCallbackHandler; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 样本统计数据执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class SampleCountExecutor extends AbstractExecutor{ |
||||
|
private static final int ORDER =150; |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return ORDER; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void execute(RuntimeContext runtimeContext, ProgressInfo progressInfo) { |
||||
|
log.info("开始执行样本统计数据..."); |
||||
|
String sql ="" |
||||
|
+ " select " |
||||
|
+ " t0.FD_MODEL_ID," |
||||
|
+ " t0.FD_MODEL_NAME," |
||||
|
+ " t1.FD_TOTAL_SAMPLE_COUNT," |
||||
|
+ " t2.FD_DEFAULT_SAMPLE_COUNT" |
||||
|
+ " from (" |
||||
|
+ " select " |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " max(FD_MODEL_NAME) FD_MODEL_NAME" |
||||
|
+ " from MV_GENERAL_SAMPLE" |
||||
|
+ " group by FD_MODEL_ID" |
||||
|
+ " ) t0" |
||||
|
+ " left join (" |
||||
|
+ " select " |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " count(*) FD_TOTAL_SAMPLE_COUNT" |
||||
|
+ " from MV_GENERAL_SAMPLE" |
||||
|
+ " group by FD_MODEL_ID" |
||||
|
+ " ) t1" |
||||
|
+ " on t0.FD_MODEL_ID=t1.FD_MODEL_ID" |
||||
|
+ " left join (" |
||||
|
+ " select" |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " count(*) FD_DEFAULT_SAMPLE_COUNT" |
||||
|
+ " from MV_GENERAL_SAMPLE" |
||||
|
+ " where FD_DEFAULT_STATUS='D'" |
||||
|
+ " group by FD_MODEL_ID" |
||||
|
+ " ) t2" |
||||
|
+ " on t0.FD_MODEL_ID=t2.FD_MODEL_ID"; |
||||
|
|
||||
|
jdbcTemplate.query(sql, new RowCallbackHandler() { |
||||
|
@Override |
||||
|
public void processRow(ResultSet rs) throws SQLException { |
||||
|
String modelId = rs.getString("FD_MODEL_ID"); |
||||
|
String modelName = rs.getString("FD_MODEL_NAME"); |
||||
|
long totalSampleCount =rs.getLong("FD_TOTAL_SAMPLE_COUNT"); |
||||
|
long defaultSampleCount =rs.getLong("FD_DEFAULT_SAMPLE_COUNT"); |
||||
|
|
||||
|
//更新模型验证结果表
|
||||
|
int updated =jdbcTemplate.update("update MV_GENERAL_RESULT set FD_TOTAL_SAMPLE_COUNT=?,FD_DEFAULT_SAMPLE_COUNT=? where FD_MODEL_ID=?", totalSampleCount,defaultSampleCount,modelId); |
||||
|
if(updated==0){ |
||||
|
jdbcTemplate.update("insert into MV_GENERAL_RESULT(FD_MODEL_ID,FD_MODEL_NAME,FD_TOTAL_SAMPLE_COUNT,FD_DEFAULT_SAMPLE_COUNT) values(?,?,?,?)", modelId,modelName,totalSampleCount,defaultSampleCount); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
jdbcTemplate.update("update MV_GENERAL_RESULT set FD_TOTAL_SAMPLE_COUNT=0 where FD_TOTAL_SAMPLE_COUNT is null"); |
||||
|
jdbcTemplate.update("update MV_GENERAL_RESULT set FD_DEFAULT_SAMPLE_COUNT=0 where FD_DEFAULT_SAMPLE_COUNT is null"); |
||||
|
log.info("完成执行样本统计数据."); |
||||
|
} |
||||
|
} |
@ -0,0 +1,522 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import io.sc.platform.core.support.ProgressInfo; |
||||
|
import io.sc.platform.core.util.DateUtil; |
||||
|
import io.sc.platform.jdbc.sql.dialect.DateTimePart; |
||||
|
import io.sc.platform.jdbc.sql.dialect.Dialect; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.dao.DataAccessException; |
||||
|
import org.springframework.jdbc.core.PreparedStatementSetter; |
||||
|
import org.springframework.jdbc.core.ResultSetExtractor; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型验证样本执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class SampleExecutor extends AbstractExecutor{ |
||||
|
private static final int ORDER =0; |
||||
|
@Autowired private Dialect dialect; |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return ORDER; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void execute(RuntimeContext runtimeContext, ProgressInfo progressInfo) { |
||||
|
info(progressInfo,"开始执行处理合格验证样本..."); |
||||
|
//初始化合格样本表及合格样本临时表
|
||||
|
initSample(runtimeContext,progressInfo); |
||||
|
//生成合格样本表
|
||||
|
generateSample(runtimeContext,progressInfo); |
||||
|
//将合格样本数据保存到历史表
|
||||
|
saveToHistory(runtimeContext,progressInfo); |
||||
|
info(progressInfo,"完成执行处理合格验证样本..."); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 初始化合格样本表 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param progressInfo 执行进度对象 |
||||
|
*/ |
||||
|
protected void initSample(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始执行初始化合格样本表..."); |
||||
|
jdbcTemplate.execute("delete from MV_GENERAL_SAMPLE"); |
||||
|
info(progressInfo,"完成执行初始化合格样本表"); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成合格样本表 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param progressInfo 执行进度对象 |
||||
|
*/ |
||||
|
private void generateSample(final RuntimeContext runtimeContext,ProgressInfo progressInfo) { |
||||
|
info(progressInfo,"开始执行生成合格样本..."); |
||||
|
//生成好的合格样本
|
||||
|
generateGoodSample(runtimeContext,progressInfo); |
||||
|
//生成坏的合格样本
|
||||
|
generateBadSample(runtimeContext,progressInfo); |
||||
|
info(progressInfo,"完成执行生成合格样本"); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成好的合格样本 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param progressInfo 执行进度对象 |
||||
|
*/ |
||||
|
private void generateGoodSample(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始生成合格样本(好样本)..."); |
||||
|
//删除临时表
|
||||
|
deleteTempTables(runtimeContext); |
||||
|
//插入好客户的评分记录到临时表中
|
||||
|
insertGoodRecord2TempTable(runtimeContext,progressInfo); |
||||
|
//生成好的合格样本
|
||||
|
_generateGoodSample(runtimeContext,progressInfo); |
||||
|
info(progressInfo,"完成生成合格样本(好样本)."); |
||||
|
} |
||||
|
|
||||
|
private void generateBadSample(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始生成合格样本(坏样本)..."); |
||||
|
//删除临时表
|
||||
|
deleteTempTables(runtimeContext); |
||||
|
//将违约客户评级信息插入到合格样本临时表中
|
||||
|
insertBadRecord2TempTable(runtimeContext,progressInfo); |
||||
|
//生成坏的合格样本
|
||||
|
_generateBadSample(runtimeContext,progressInfo); |
||||
|
info(progressInfo,"完成生成合格样本(坏样本)."); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除临时表 |
||||
|
*/ |
||||
|
private void deleteTempTables(final RuntimeContext runtimeContext){ |
||||
|
jdbcTemplate.execute("delete from MV_SCORE_RECORD_TMP"); |
||||
|
jdbcTemplate.execute("delete from MV_GENERAL_SAMPLE_TMP"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将非违约客户评级信息插入到合格样本临时表中 |
||||
|
*/ |
||||
|
private void insertGoodRecord2TempTable(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始执行将好客户评级信息插入到评分临时表中..."); |
||||
|
final Date from =runtimeContext.getRateStartDateFrom(); |
||||
|
final Date to =runtimeContext.getRateStartDateTo(); |
||||
|
String sql ="" |
||||
|
+ " insert into MV_SCORE_RECORD_TMP(" |
||||
|
+ " FD_CUSTOM_ID," //客户标识
|
||||
|
+ " FD_CUSTOM_NAME," //客户名称
|
||||
|
+ " FD_MODEL_ID," //模型标识
|
||||
|
+ " FD_MODEL_NAME," //模型名称
|
||||
|
+ " FD_PD," //评级结果(违约概率)
|
||||
|
+ " FD_SCORE," //评级结果(得分)
|
||||
|
+ " FD_SCORE_QUANTITATIVE," //评级结果(得分-定量)
|
||||
|
+ " FD_SCORE_QUALITATIVE," //评级结果(得分-定性)
|
||||
|
+ " FD_LEVEL," //评级结果(等级)
|
||||
|
+ " FD_SCORE_BEGIN_DATE," //评级有效期开始日期
|
||||
|
+ " FD_SCORE_END_DATE" //评级有效期结束日期
|
||||
|
+ " )" |
||||
|
+ " select" |
||||
|
+ " S.FD_CUSTOM_ID," |
||||
|
+ " S.FD_CUSTOM_NAME," |
||||
|
+ " S.FD_MODEL_ID," |
||||
|
+ " S.FD_MODEL_NAME," |
||||
|
+ " S.FD_PD," |
||||
|
+ " S.FD_SCORE," |
||||
|
+ " S.FD_SCORE_QUANTITATIVE," |
||||
|
+ " S.FD_SCORE_QUALITATIVE," |
||||
|
+ " S.FD_LEVEL," |
||||
|
+ " S.FD_SCORE_BEGIN_DATE," |
||||
|
+ " S.FD_SCORE_END_DATE" |
||||
|
+ " from MV_SCORE_RECORD S" |
||||
|
+ " left join (select distinct FD_CUSTOM_ID from MV_DEFAULT_RECORD) T" |
||||
|
+ " on S.FD_CUSTOM_ID=T.FD_CUSTOM_ID" |
||||
|
+ " where" |
||||
|
+ " T.FD_CUSTOM_ID is null" //排除评分记录表中客户标识在违约认定记录表中的数据
|
||||
|
+ " and S.FD_CUSTOM_ID is not null" //排除不正常的评分记录(无客户标识)
|
||||
|
+ " and S.FD_MODEL_ID is not null " //排除不正常的评分记录(无模型标识)
|
||||
|
+ " and S.FD_SCORE is not null " //排除不正常的评分记录(无总体评分)
|
||||
|
+ " and S.FD_LEVEL is not null"; //排除不正常的评分记录(无等级)
|
||||
|
|
||||
|
if(from!=null){ |
||||
|
sql +=" and FD_SCORE_BEGIN_DATE>=?"; //排除评分有效期开始日期在指定的日期范围外的评分记录
|
||||
|
} |
||||
|
if(to!=null){ |
||||
|
sql +=" and FD_SCORE_BEGIN_DATE<=?"; |
||||
|
} |
||||
|
|
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
if(from!=null && to!=null){ |
||||
|
pstmt.setObject(1, DateUtil.toSqlDate(from)); |
||||
|
pstmt.setObject(2, DateUtil.toSqlDate(to)); |
||||
|
}else if(from!=null){ |
||||
|
pstmt.setObject(1, DateUtil.toSqlDate(from)); |
||||
|
}else if(to!=null){ |
||||
|
pstmt.setObject(1, DateUtil.toSqlDate(to)); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
info(progressInfo,"完成执行将好客户评级信息插入到评分临时表中."); |
||||
|
} |
||||
|
|
||||
|
private void _generateGoodSample(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始执行生成合格的好样本..."); |
||||
|
|
||||
|
String sql ="" |
||||
|
+ " insert into MV_GENERAL_SAMPLE_TMP(" |
||||
|
+ " FD_CUSTOM_ID," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_SCORE_BEGIN_DATE," |
||||
|
+ " FD_SCORE_END_DATE," |
||||
|
+ " FD_DEL" |
||||
|
+ " )" |
||||
|
+ " select" |
||||
|
+ " S.FD_CUSTOM_ID," |
||||
|
+ " S.FD_MODEL_ID," |
||||
|
+ " S.FD_SCORE_BEGIN_DATE," |
||||
|
+ " S.FD_SCORE_END_DATE," |
||||
|
+ " 1" |
||||
|
+ " from MV_SCORE_RECORD_TMP S" |
||||
|
+ " join MV_SCORE_RECORD_TMP T" |
||||
|
+ " on " |
||||
|
+ " S.FD_CUSTOM_ID=T.FD_CUSTOM_ID " |
||||
|
+ " and S.FD_MODEL_ID=T.FD_MODEL_ID" |
||||
|
+ " where " |
||||
|
+ " T.FD_SCORE_BEGIN_DATE>S.FD_SCORE_BEGIN_DATE" |
||||
|
+ " and T.FD_SCORE_BEGIN_DATE<S.FD_SCORE_END_DATE"; |
||||
|
jdbcTemplate.execute(sql); |
||||
|
|
||||
|
sql ="" |
||||
|
+ " insert into MV_GENERAL_SAMPLE(" |
||||
|
+ " FD_CUSTOM_ID," //客户标识
|
||||
|
+ " FD_CUSTOM_NAME," //客户名称
|
||||
|
+ " FD_MODEL_ID," //模型标识
|
||||
|
+ " FD_MODEL_NAME," //模型名称
|
||||
|
+ " FD_PD," //评级结果(违约概率)
|
||||
|
+ " FD_SCORE," //评级结果(得分)
|
||||
|
+ " FD_SCORE_QUANTITATIVE," //评级结果(得分-定量)
|
||||
|
+ " FD_SCORE_QUALITATIVE," //评级结果(得分-定性)
|
||||
|
+ " FD_LEVEL," //评级结果(等级)
|
||||
|
+ " FD_SCORE_BEGIN_DATE," //评级有效期开始日期
|
||||
|
+ " FD_SCORE_END_DATE," //评级有效期结束日期
|
||||
|
+ " FD_DEFAULT_STATUS" //实际违约状态
|
||||
|
+ " )" |
||||
|
+ " select" |
||||
|
+ " S.FD_CUSTOM_ID," |
||||
|
+ " S.FD_CUSTOM_NAME," |
||||
|
+ " S.FD_MODEL_ID," |
||||
|
+ " S.FD_MODEL_NAME," |
||||
|
+ " S.FD_PD," |
||||
|
+ " S.FD_SCORE," |
||||
|
+ " S.FD_SCORE_QUANTITATIVE," |
||||
|
+ " S.FD_SCORE_QUALITATIVE," |
||||
|
+ " S.FD_LEVEL," |
||||
|
+ " S.FD_SCORE_BEGIN_DATE," |
||||
|
+ " S.FD_SCORE_END_DATE," |
||||
|
+ " 'N'" |
||||
|
+ " from MV_SCORE_RECORD_TMP S" |
||||
|
+ " left join MV_GENERAL_SAMPLE_TMP T" |
||||
|
+ " on " |
||||
|
+ " S.FD_CUSTOM_ID=T.FD_CUSTOM_ID " |
||||
|
+ " and S.FD_MODEL_ID=T.FD_MODEL_ID " |
||||
|
+ " and S.FD_SCORE_BEGIN_DATE=T.FD_SCORE_BEGIN_DATE" |
||||
|
+ " where T.FD_DEL is null"; |
||||
|
jdbcTemplate.execute(sql); |
||||
|
info(progressInfo,"完成执行生成合格的好样本..."); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将坏客户评级记录插入到临时表 |
||||
|
*/ |
||||
|
private void insertBadRecord2TempTable(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始执行将坏客户评级记录插入到临时表..."); |
||||
|
final Date from =runtimeContext.getRateStartDateFrom(); |
||||
|
final Date to =runtimeContext.getRateStartDateTo(); |
||||
|
String sql ="" |
||||
|
+ " insert into MV_SCORE_RECORD_TMP(" |
||||
|
+ " FD_CUSTOM_ID," //客户标识
|
||||
|
+ " FD_CUSTOM_NAME," //客户名称
|
||||
|
+ " FD_MODEL_ID," //模型标识
|
||||
|
+ " FD_MODEL_NAME," //模型名称
|
||||
|
+ " FD_PD," //评级结果(违约概率)
|
||||
|
+ " FD_SCORE," //评级结果(得分)
|
||||
|
+ " FD_SCORE_QUANTITATIVE," //评级结果(得分-定量)
|
||||
|
+ " FD_SCORE_QUALITATIVE," //评级结果(得分-定性)
|
||||
|
+ " FD_LEVEL," //评级结果(等级)
|
||||
|
+ " FD_SCORE_BEGIN_DATE," //评级有效期开始日期
|
||||
|
+ " FD_SCORE_END_DATE" //评级有效期结束日期
|
||||
|
+ " )" |
||||
|
+ " select" |
||||
|
+ " S.FD_CUSTOM_ID," |
||||
|
+ " S.FD_CUSTOM_NAME," |
||||
|
+ " S.FD_MODEL_ID," |
||||
|
+ " S.FD_MODEL_NAME," |
||||
|
+ " S.FD_PD," |
||||
|
+ " S.FD_SCORE," |
||||
|
+ " S.FD_SCORE_QUANTITATIVE," |
||||
|
+ " S.FD_SCORE_QUALITATIVE," |
||||
|
+ " S.FD_LEVEL," |
||||
|
+ " S.FD_SCORE_BEGIN_DATE," |
||||
|
+ " S.FD_SCORE_END_DATE" |
||||
|
+ " from MV_SCORE_RECORD S" |
||||
|
+ " left join (select distinct FD_CUSTOM_ID from MV_DEFAULT_RECORD) T" |
||||
|
+ " on S.FD_CUSTOM_ID=T.FD_CUSTOM_ID" |
||||
|
+ " where " |
||||
|
+ " T.FD_CUSTOM_ID is not null" //保留坏客户的评分记录
|
||||
|
+ " and S.FD_CUSTOM_ID is not null" //排除不正常的评分记录(无客户标识)
|
||||
|
+ " and S.FD_MODEL_ID is not null " //排除不正常的评分记录(无模型标识)
|
||||
|
+ " and S.FD_SCORE is not null " //排除不正常的评分记录(无总体评分)
|
||||
|
+ " and S.FD_LEVEL is not null"; //排除不正常的评分记录(无等级)
|
||||
|
|
||||
|
if(from!=null){ |
||||
|
sql +=" and FD_SCORE_BEGIN_DATE>=?"; //排除评分有效期开始日期在指定的日期范围外的评分记录
|
||||
|
} |
||||
|
if(to!=null){ |
||||
|
sql +=" and FD_SCORE_BEGIN_DATE<=?"; |
||||
|
} |
||||
|
|
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
if(from!=null && to!=null){ |
||||
|
pstmt.setObject(1, DateUtil.toSqlDate(from)); |
||||
|
pstmt.setObject(2, DateUtil.toSqlDate(to)); |
||||
|
}else if(from!=null){ |
||||
|
pstmt.setObject(1, DateUtil.toSqlDate(from)); |
||||
|
}else if(to!=null){ |
||||
|
pstmt.setObject(1, DateUtil.toSqlDate(to)); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
info(progressInfo,"完成执行将坏客户评级记录插入到临时表."); |
||||
|
} |
||||
|
|
||||
|
private void _generateBadSample(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始执行生成合格的坏样本..."); |
||||
|
String sql ="" |
||||
|
+ " insert into MV_GENERAL_SAMPLE_TMP(" |
||||
|
+ " FD_CUSTOM_ID," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_SCORE_BEGIN_DATE," |
||||
|
+ " FD_SCORE_END_DATE," |
||||
|
+ " FD_DEFAULT_CONFIRM_DATE" |
||||
|
+ " )" |
||||
|
+ " select " |
||||
|
+ " S.FD_CUSTOM_ID," |
||||
|
+ " S.FD_MODEL_ID," |
||||
|
+ " S.FD_SCORE_BEGIN_DATE," |
||||
|
+ " S.FD_SCORE_END_DATE," |
||||
|
+ " T.FD_DEFAULT_CONFIRM_DATE" |
||||
|
+ " from MV_SCORE_RECORD_TMP S" |
||||
|
+ " join MV_DEFAULT_RECORD T" |
||||
|
+ " on S.FD_CUSTOM_ID=T.FD_CUSTOM_ID" |
||||
|
+ " where" |
||||
|
+ " T.FD_DEFAULT_CONFIRM_DATE>=S.FD_SCORE_BEGIN_DATE" |
||||
|
+ " and T.FD_DEFAULT_CONFIRM_DATE<=" + dialect.dateAdd(DateTimePart.MONTH, "S.FD_SCORE_BEGIN_DATE", runtimeContext.getPerformPeriod()) |
||||
|
+ ""; |
||||
|
jdbcTemplate.execute(sql); |
||||
|
|
||||
|
sql ="" |
||||
|
+ " insert into MV_GENERAL_SAMPLE(" |
||||
|
+ " FD_CUSTOM_ID," //客户标识
|
||||
|
+ " FD_CUSTOM_NAME," //客户名称
|
||||
|
+ " FD_MODEL_ID," //模型标识
|
||||
|
+ " FD_MODEL_NAME," //模型名称
|
||||
|
+ " FD_PD," //评级结果(违约概率)
|
||||
|
+ " FD_SCORE," //评级结果(得分)
|
||||
|
+ " FD_SCORE_QUANTITATIVE," //评级结果(得分-定量)
|
||||
|
+ " FD_SCORE_QUALITATIVE," //评级结果(得分-定性)
|
||||
|
+ " FD_LEVEL," //评级结果(等级)
|
||||
|
+ " FD_SCORE_BEGIN_DATE," //评级有效期开始日期
|
||||
|
+ " FD_SCORE_END_DATE," //评级有效期结束日期
|
||||
|
+ " FD_DEFAULT_CONFIRM_DATE"//违约认定日期
|
||||
|
+ " )" |
||||
|
+ " select" |
||||
|
+ " S.FD_CUSTOM_ID," |
||||
|
+ " S.FD_CUSTOM_NAME," |
||||
|
+ " S.FD_MODEL_ID," |
||||
|
+ " S.FD_MODEL_NAME," |
||||
|
+ " S.FD_PD," |
||||
|
+ " S.FD_SCORE," |
||||
|
+ " S.FD_SCORE_QUANTITATIVE," |
||||
|
+ " S.FD_SCORE_QUALITATIVE," |
||||
|
+ " S.FD_LEVEL," |
||||
|
+ " S.FD_SCORE_BEGIN_DATE," |
||||
|
+ " S.FD_SCORE_END_DATE," |
||||
|
+ " T.FD_DEFAULT_CONFIRM_DATE" |
||||
|
+ " from MV_SCORE_RECORD_TMP S" |
||||
|
+ " left join (" |
||||
|
+ " select distinct" |
||||
|
+ " FD_CUSTOM_ID," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_SCORE_BEGIN_DATE," |
||||
|
+ " FD_SCORE_END_DATE," |
||||
|
+ " FD_DEFAULT_CONFIRM_DATE" |
||||
|
+ " from MV_GENERAL_SAMPLE_TMP" |
||||
|
+ " ) T" |
||||
|
+ " on " |
||||
|
+ " S.FD_CUSTOM_ID=T.FD_CUSTOM_ID" |
||||
|
+ " and S.FD_MODEL_ID=T.FD_MODEL_ID" |
||||
|
+ " and S.FD_SCORE_BEGIN_DATE=T.FD_SCORE_BEGIN_DATE" |
||||
|
+ ""; |
||||
|
jdbcTemplate.execute(sql); |
||||
|
|
||||
|
//删除
|
||||
|
sql ="" |
||||
|
+ " select " |
||||
|
+ " FD_CUSTOM_ID," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_SCORE_BEGIN_DATE," |
||||
|
+ " FD_SCORE_END_DATE," |
||||
|
+ " FD_DEFAULT_CONFIRM_DATE" |
||||
|
+ " from MV_GENERAL_SAMPLE_TMP" |
||||
|
+ " order by FD_CUSTOM_ID,FD_MODEL_ID,FD_SCORE_BEGIN_DATE"; |
||||
|
jdbcTemplate.query(sql, new ResultSetExtractor<Object>(){ |
||||
|
@Override |
||||
|
public Object extractData(ResultSet rs) throws SQLException, DataAccessException { |
||||
|
String updateSql ="" |
||||
|
+ " update MV_GENERAL_SAMPLE set" |
||||
|
+ " FD_DEFAULT_CONFIRM_DATE=NULL" |
||||
|
+ " where" |
||||
|
+ " FD_CUSTOM_ID=?" |
||||
|
+ " and FD_MODEL_ID=?" |
||||
|
+ " and FD_SCORE_BEGIN_DATE=?"; |
||||
|
|
||||
|
String preCustomId =null; |
||||
|
String preModelId =null; |
||||
|
Date preScoreBeginDate =null; |
||||
|
Date preScoreEndDate =null; |
||||
|
Date preDefaultConfirmDate =null; |
||||
|
|
||||
|
while(rs.next()){ |
||||
|
String customId =rs.getString("FD_CUSTOM_ID"); |
||||
|
String modelId =rs.getString("FD_MODEL_ID"); |
||||
|
Date scoreBeginDate =rs.getDate("FD_SCORE_BEGIN_DATE"); |
||||
|
Date scoreEndDate =rs.getDate("FD_SCORE_END_DATE"); |
||||
|
Date defaultConfirmDate =rs.getDate("FD_DEFAULT_CONFIRM_DATE"); |
||||
|
|
||||
|
final String _preCustomId =preCustomId; |
||||
|
final String _preModelId =preModelId; |
||||
|
final Date _preScoreBeginDate =preScoreBeginDate; |
||||
|
if( |
||||
|
preCustomId!=null && preModelId!=null && preScoreBeginDate!=null && preScoreEndDate!=null && preDefaultConfirmDate!=null |
||||
|
&& customId!=null && modelId!=null && scoreBeginDate!=null && scoreEndDate!=null && defaultConfirmDate!=null |
||||
|
&& customId.equalsIgnoreCase(preCustomId) && modelId.equalsIgnoreCase(preModelId) |
||||
|
&& preDefaultConfirmDate.getTime()>preScoreEndDate.getTime() |
||||
|
&& preDefaultConfirmDate.getTime()>=scoreBeginDate.getTime() |
||||
|
&& preDefaultConfirmDate.getTime()<=scoreEndDate.getTime() |
||||
|
){ |
||||
|
jdbcTemplate.update(updateSql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, _preCustomId); |
||||
|
pstmt.setObject(2, _preModelId); |
||||
|
pstmt.setObject(3, _preScoreBeginDate); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
preCustomId =customId; |
||||
|
preModelId =modelId; |
||||
|
preScoreBeginDate =scoreBeginDate; |
||||
|
preScoreEndDate =scoreEndDate; |
||||
|
preDefaultConfirmDate =defaultConfirmDate; |
||||
|
|
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
//
|
||||
|
jdbcTemplate.update("update MV_GENERAL_SAMPLE set FD_DEFAULT_STATUS='D' where FD_DEFAULT_CONFIRM_DATE is not null"); |
||||
|
jdbcTemplate.update("update MV_GENERAL_SAMPLE set FD_DEFAULT_STATUS='N' where FD_DEFAULT_CONFIRM_DATE is null"); |
||||
|
|
||||
|
//移除评级有效期开始日期距今小于评级表现期的好样本
|
||||
|
sql ="" |
||||
|
+ " delete from MV_GENERAL_SAMPLE" |
||||
|
+ " where FD_DEFAULT_STATUS='N'" |
||||
|
+ " and " + dialect.currentDate() + "<=" + dialect.dateAdd(DateTimePart.MONTH, "FD_SCORE_BEGIN_DATE", runtimeContext.getPerformPeriod()); |
||||
|
jdbcTemplate.update(sql); |
||||
|
info(progressInfo,"完成执行生成合格的坏样本..."); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将合格样本数据保存到历史表 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param progressInfo 执行进度对象 |
||||
|
*/ |
||||
|
protected void saveToHistory(final RuntimeContext runtimeContext,ProgressInfo progressInfo){ |
||||
|
info(progressInfo,"开始执行将合格样本数据保存到历史表..."); |
||||
|
final String runtimeDateString =DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
String sql ="delete from MV_GENERAL_SAMPLE_HIS where FD_VALIDATE_DATE=?"; |
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
sql = "" |
||||
|
+ " insert into MV_GENERAL_SAMPLE_HIS(" |
||||
|
+ " FD_VALIDATE_DATE," |
||||
|
+ " FD_CUSTOM_ID," |
||||
|
+ " FD_CUSTOM_NAME," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_PD," |
||||
|
+ " FD_SCORE," |
||||
|
+ " FD_SCORE_QUANTITATIVE," |
||||
|
+ " FD_SCORE_QUALITATIVE," |
||||
|
+ " FD_LEVEL," |
||||
|
+ " FD_SCORE_BEGIN_DATE," |
||||
|
+ " FD_SCORE_END_DATE," |
||||
|
+ " FD_DEFAULT_STATUS," |
||||
|
+ " FD_DEFAULT_CONFIRM_DATE" |
||||
|
+ " )" |
||||
|
+ " select " |
||||
|
+ " ?," |
||||
|
+ " FD_CUSTOM_ID," |
||||
|
+ " FD_CUSTOM_NAME," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_PD," |
||||
|
+ " FD_SCORE," |
||||
|
+ " FD_SCORE_QUANTITATIVE," |
||||
|
+ " FD_SCORE_QUALITATIVE," |
||||
|
+ " FD_LEVEL," |
||||
|
+ " FD_SCORE_BEGIN_DATE," |
||||
|
+ " FD_SCORE_END_DATE," |
||||
|
+ " FD_DEFAULT_STATUS," |
||||
|
+ " FD_DEFAULT_CONFIRM_DATE" |
||||
|
+ " from MV_GENERAL_SAMPLE"; |
||||
|
|
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
info(progressInfo,"完成执行将合格样本数据保存到历史表."); |
||||
|
} |
||||
|
|
||||
|
private void info(ProgressInfo progressInfo,String msg){ |
||||
|
log.info(msg); |
||||
|
progressInfo.setMessageKey(msg); |
||||
|
} |
||||
|
} |
@ -0,0 +1,361 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import io.sc.engine.mv.executor.support.CutOffPointFinder; |
||||
|
import io.sc.engine.mv.executor.support.ExecutorUtil; |
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import io.sc.platform.core.support.NumberIterator; |
||||
|
import io.sc.platform.core.support.ProgressInfo; |
||||
|
import io.sc.platform.core.util.DateUtil; |
||||
|
import io.sc.platform.jdbc.util.SqlBatcher; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.dao.DataAccessException; |
||||
|
import org.springframework.jdbc.core.PreparedStatementSetter; |
||||
|
import org.springframework.jdbc.core.ResultSetExtractor; |
||||
|
import org.springframework.jdbc.core.RowCallbackHandler; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 CAP(总体) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScCapExecutor extends AbstractExecutor{ |
||||
|
protected static final int ORDER =300; |
||||
|
@Autowired protected CutOffPointFinder cutOffPointFinder; |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return ORDER; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_AR"); |
||||
|
result.setTableName("MV_SC_CAP"); |
||||
|
result.setHisTableName("MV_SC_CAP_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_CAP); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void execute(RuntimeContext runtimeContext, ProgressInfo progressInfo){ |
||||
|
//获取变量
|
||||
|
ScVariable variable =getRuntimeVariable(); |
||||
|
|
||||
|
//初始化指标表
|
||||
|
initKpi(runtimeContext,variable); |
||||
|
|
||||
|
//计算并生成指标表数据
|
||||
|
generateKpi(runtimeContext,variable); |
||||
|
|
||||
|
//计算 AR 值,并更新到模型验证结果表中
|
||||
|
calAr(runtimeContext,variable); |
||||
|
|
||||
|
//将计算并生成指标表数据保存到历史表中
|
||||
|
saveToHistory(runtimeContext,variable); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除指标表历史数据 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void initKpi(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始执行初始化指标表..."); |
||||
|
jdbcTemplate.execute("delete from " + variable.getTableName()); |
||||
|
log.info("完成执行初始化指标表"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算并生成指标表 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void generateKpi(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始执行计算并生成指标表数据..."); |
||||
|
final NumberIterator cutOffPointer =cutOffPointFinder.getCufOffPoint(variable.getCutOffPointName()); |
||||
|
if(cutOffPointer==null){ |
||||
|
throw new RuntimeException("无法获取截断点配置信息,请查看是否已经配置了截断点配置信息."); |
||||
|
} |
||||
|
initCutOffPoint(cutOffPointer,variable); |
||||
|
doGenerateKpi(cutOffPointer,variable); |
||||
|
log.info("完成执行计算并生成指标表数据"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据截断点初始化指标表 |
||||
|
* @param cutOffPointer |
||||
|
* @param variable |
||||
|
*/ |
||||
|
private void initCutOffPoint(final NumberIterator cutOffPointer,ScVariable variable){ |
||||
|
log.info("开始执行初始化截断点..."); |
||||
|
final SqlBatcher sqlBatcher =new SqlBatcher("" |
||||
|
+ " insert into " + variable.getTableName() + "(" |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT" |
||||
|
+ " ) values (" |
||||
|
+ " ?," |
||||
|
+ " ?," |
||||
|
+ " ?" |
||||
|
+ ")" |
||||
|
); |
||||
|
|
||||
|
Map<String,String> models = ExecutorUtil.getAllModels(jdbcTemplate); |
||||
|
if(models!=null && models.size()>0){ |
||||
|
for(String key : models.keySet()){ |
||||
|
String modelId =key; |
||||
|
String modelName =models.get(key); |
||||
|
cutOffPointer.reset(); |
||||
|
while(cutOffPointer.hasNext()){ |
||||
|
sqlBatcher.addArg(new Object[]{ |
||||
|
modelId, |
||||
|
modelName, |
||||
|
cutOffPointer.next() |
||||
|
}); |
||||
|
} |
||||
|
sqlBatcher.execute(jdbcTemplate); |
||||
|
} |
||||
|
} |
||||
|
log.info("完成执行初始化截断点"); |
||||
|
} |
||||
|
|
||||
|
private void doGenerateKpi(NumberIterator cutOffPointer,final ScVariable variable){ |
||||
|
final SqlBatcher sqlBatcher =new SqlBatcher("" |
||||
|
+ " update " + variable.getTableName() |
||||
|
+ " set" |
||||
|
+ " FD_TS=?," |
||||
|
+ " FD_TT=?," |
||||
|
+ " FD_TDS=?," |
||||
|
+ " FD_TDT=?," |
||||
|
+ " FD_Y=?," |
||||
|
+ " FD_X=?" |
||||
|
+ " where" |
||||
|
+ " FD_MODEL_ID=?" |
||||
|
+ " and FD_SCORE_CUT_OFF_POINT=?" |
||||
|
); |
||||
|
|
||||
|
cutOffPointer.reset(); |
||||
|
while(cutOffPointer.hasNext()){ |
||||
|
final BigDecimal cutOffPointValue =cutOffPointer.next(); |
||||
|
String sql = " select" |
||||
|
+ " t0.FD_MODEL_ID," //模型ID
|
||||
|
+ " t0.CUT_OFF_POINT," //截断点
|
||||
|
+ " t1.FD_TS," //评分小于等于截断点的客户个数
|
||||
|
+ " t2.FD_TT," //客户总数
|
||||
|
+ " t3.FD_TDS," //评分小于等于截断点的事实违约客户个数
|
||||
|
+ " t4.FD_TDT" //事实违约的总客户数
|
||||
|
+ " from " |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT from MV_GENERAL_SAMPLE group by FD_MODEL_ID) t0" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TS from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " group by FD_MODEL_ID) t1" |
||||
|
+ " on t0.FD_MODEL_ID=t1.FD_MODEL_ID and t0.CUT_OFF_POINT=t1.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TT from MV_GENERAL_SAMPLE group by FD_MODEL_ID) t2" |
||||
|
+ " on t0.FD_MODEL_ID=t2.FD_MODEL_ID and t0.CUT_OFF_POINT=t2.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TDS from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " and FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t3" |
||||
|
+ " on t0.FD_MODEL_ID=t3.FD_MODEL_ID and t0.CUT_OFF_POINT=t3.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TDT from MV_GENERAL_SAMPLE where FD_DEFAULT_STATUS = 'D' group by FD_MODEL_ID) t4" |
||||
|
+ " on t0.FD_MODEL_ID=t4.FD_MODEL_ID and t0.CUT_OFF_POINT=t4.CUT_OFF_POINT" |
||||
|
+ ""; |
||||
|
jdbcTemplate.query(sql, new RowCallbackHandler() { |
||||
|
@Override |
||||
|
public void processRow(ResultSet rs) throws SQLException { |
||||
|
sqlBatcher.addArg(new Object[]{ |
||||
|
rs.getDouble("FD_TS"), |
||||
|
rs.getDouble("FD_TT"), |
||||
|
rs.getDouble("FD_TDS"), |
||||
|
rs.getDouble("FD_TDT"), |
||||
|
rs.getDouble("FD_TDT")==0?0:rs.getDouble("FD_TDS")/rs.getDouble("FD_TDT"), |
||||
|
rs.getDouble("FD_TT")==0?0:rs.getDouble("FD_TS")/rs.getDouble("FD_TT"), |
||||
|
|
||||
|
rs.getString("FD_MODEL_ID"), |
||||
|
rs.getInt("CUT_OFF_POINT") |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
sqlBatcher.execute(jdbcTemplate); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算 AR 值,并更新到模型验证结果表中 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void calAr(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始计算 AR 值,并更新到模型验证结果表中..."); |
||||
|
Map<String,String> models =ExecutorUtil.getAllModels(jdbcTemplate); |
||||
|
if(models!=null && models.size()>0){ |
||||
|
for(String key : models.keySet()){ |
||||
|
final String modelId =key; |
||||
|
final String modelName =models.get(key); |
||||
|
String sql ="" |
||||
|
+ " select" |
||||
|
+ " FD_X," |
||||
|
+ " FD_Y " |
||||
|
+ " from " + variable.getTableName() |
||||
|
+ " where FD_MODEL_ID='"+modelId+"'" |
||||
|
+ " group by FD_X,FD_Y" |
||||
|
+ " order by FD_X"; |
||||
|
jdbcTemplate.query(sql, new ResultSetExtractor<Object>(){ |
||||
|
@Override |
||||
|
public Object extractData(ResultSet rs) throws SQLException, DataAccessException { |
||||
|
//计算 CAP 曲线下面的面积
|
||||
|
Double area = 0.0; |
||||
|
Double Yn_1 = null; |
||||
|
Double Xn_1 = null; |
||||
|
|
||||
|
while (rs.next()) { |
||||
|
Double Yn = rs.getDouble("FD_Y"); |
||||
|
Double Xn = rs.getDouble("FD_X"); |
||||
|
|
||||
|
if(Yn_1 != null && Xn_1 != null){ |
||||
|
area = area + (Yn_1 + Yn)*(Xn - Xn_1); |
||||
|
} |
||||
|
|
||||
|
Yn_1 = rs.getDouble("FD_Y"); |
||||
|
Xn_1 = rs.getDouble("FD_X"); |
||||
|
} |
||||
|
area = area/2; |
||||
|
|
||||
|
//某个模型事实违约总客户个数
|
||||
|
long defaultCount =getDefaultCustomerCount(modelId); |
||||
|
//某个模型总客户个数
|
||||
|
long allCount =getAllCustomerCount(modelId); |
||||
|
|
||||
|
//计算 AR 值
|
||||
|
//计算斜率
|
||||
|
double slope =0; |
||||
|
if(allCount!=0){ |
||||
|
slope =(double)defaultCount/(double)allCount; |
||||
|
} |
||||
|
//计算 AR 值
|
||||
|
double ar =(area-0.5)/((1-slope+1)/2-0.5); |
||||
|
|
||||
|
//更新模型验证结果表
|
||||
|
int updated =jdbcTemplate.update("update MV_GENERAL_RESULT set " + variable.getKpiFieldName() + "=? where FD_MODEL_ID=?", ar,modelId); |
||||
|
if(updated==0){ |
||||
|
jdbcTemplate.update("insert into MV_GENERAL_RESULT(FD_MODEL_ID,FD_MODEL_NAME," + variable.getKpiFieldName() + ") values(?,?,?)", modelId,modelName,ar); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
log.info("完成计算 AR 值,并更新到模型验证结果表中"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将计算并生成指标表数据保存到历史表中 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void saveToHistory(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始将计算并生成指标表数据保存到历史表中..."); |
||||
|
final String runtimeDateString = DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
String sql ="delete from " + variable.getHisTableName() + " where FD_VALIDATE_DATE=?"; |
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
sql = "" |
||||
|
+ " insert into " + variable.getHisTableName() + "(" |
||||
|
+ " FD_VALIDATE_DATE," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT," |
||||
|
+ " FD_TS," |
||||
|
+ " FD_TT," |
||||
|
+ " FD_TDS," |
||||
|
+ " FD_TDT," |
||||
|
+ " FD_X," |
||||
|
+ " FD_Y" |
||||
|
+ " )" |
||||
|
+ " select " |
||||
|
+ " ?," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT," |
||||
|
+ " FD_TS," |
||||
|
+ " FD_TT," |
||||
|
+ " FD_TDS," |
||||
|
+ " FD_TDT," |
||||
|
+ " FD_X," |
||||
|
+ " FD_Y" |
||||
|
+ " from " + variable.getTableName(); |
||||
|
|
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
log.info("完成将计算并生成指标表数据保存到历史表中"); |
||||
|
} |
||||
|
|
||||
|
//某个模型事实违约总客户个数
|
||||
|
protected long getDefaultCustomerCount(String modelId){ |
||||
|
Long result =jdbcTemplate.query( |
||||
|
"select count(*) from MV_GENERAL_SAMPLE where FD_MODEL_ID='" + modelId + "' and FD_DEFAULT_STATUS='D'", |
||||
|
new ResultSetExtractor<Long>(){ |
||||
|
public Long extractData(ResultSet rs) throws SQLException, DataAccessException{ |
||||
|
if(rs.next()){ |
||||
|
return rs.getLong(1); |
||||
|
}else{ |
||||
|
return 0L; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
if(result!=null) { |
||||
|
return result; |
||||
|
}else { |
||||
|
return 0L; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//某个模型总客户个数
|
||||
|
protected long getAllCustomerCount(String modelId){ |
||||
|
Long result =jdbcTemplate.query( |
||||
|
"select count(*) from MV_GENERAL_SAMPLE where FD_MODEL_ID='" + modelId + "'", |
||||
|
new ResultSetExtractor<Long>(){ |
||||
|
public Long extractData(ResultSet rs) throws SQLException, DataAccessException{ |
||||
|
if(rs.next()){ |
||||
|
return rs.getLong(1); |
||||
|
}else{ |
||||
|
return 0L; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
if(result!=null) { |
||||
|
return result; |
||||
|
}else { |
||||
|
return 0L; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 CAP(定性) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScCapQualitativeExecutor extends ScCapExecutor{ |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return super.getOrder() + 20; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_AR_QUALITATIVE"); |
||||
|
result.setTableName("MV_SC_CAP_QUALITATIVE"); |
||||
|
result.setHisTableName("MV_SC_CAP_QUALITATIVE_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_CAP_QUALITATIVE); |
||||
|
return result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 CAP(定量) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScCapQuantitativeExecutor extends ScCapExecutor{ |
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return super.getOrder() + 10; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_AR_QUANTITATIVE"); |
||||
|
result.setTableName("MV_SC_CAP_QUANTITATIVE"); |
||||
|
result.setHisTableName("MV_SC_CAP_QUANTITATIVE_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_CAP_QUANTITATIVE); |
||||
|
return result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,280 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import io.sc.engine.mv.executor.support.CutOffPointFinder; |
||||
|
import io.sc.engine.mv.executor.support.ExecutorUtil; |
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import io.sc.platform.core.support.NumberIterator; |
||||
|
import io.sc.platform.core.support.ProgressInfo; |
||||
|
import io.sc.platform.core.util.DateUtil; |
||||
|
import io.sc.platform.jdbc.util.SqlBatcher; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.jdbc.core.PreparedStatementSetter; |
||||
|
import org.springframework.jdbc.core.RowCallbackHandler; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 KS(总体) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScKsExecutor extends AbstractExecutor{ |
||||
|
protected static final int ORDER =400; |
||||
|
@Autowired protected CutOffPointFinder cutOffPointFinder; |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return ORDER; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_KS"); |
||||
|
result.setTableName("MV_SC_KS"); |
||||
|
result.setHisTableName("MV_SC_KS_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_KS); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void execute(RuntimeContext runtimeContext, ProgressInfo progressInfo) { |
||||
|
//获取变量
|
||||
|
ScVariable variable =getRuntimeVariable(); |
||||
|
|
||||
|
//初始化指标表
|
||||
|
initKpi(runtimeContext,variable); |
||||
|
|
||||
|
//计算并生成指标表数据
|
||||
|
generateKpi(runtimeContext,variable); |
||||
|
|
||||
|
//计算 AR 值,并更新到模型验证结果表中
|
||||
|
calKs(runtimeContext,variable); |
||||
|
|
||||
|
//将计算并生成指标表数据保存到历史表中
|
||||
|
saveToHistory(runtimeContext,variable); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除指标表历史数据 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void initKpi(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始执行初始化指标表..."); |
||||
|
jdbcTemplate.execute("delete from " + variable.getTableName()); |
||||
|
log.info("完成执行初始化指标表"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算并生成指标表 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void generateKpi(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始执行计算并生成指标表数据..."); |
||||
|
final NumberIterator cutOffPointer =cutOffPointFinder.getCufOffPoint(variable.getCutOffPointName()); |
||||
|
if(cutOffPointer==null){ |
||||
|
throw new RuntimeException("无法获取截断点配置信息,请查看是否已经配置了截断点配置信息."); |
||||
|
} |
||||
|
initCutOffPoint(cutOffPointer,variable); |
||||
|
doGenerateKpi(cutOffPointer,variable); |
||||
|
log.info("完成执行计算并生成指标表数据"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据截断点初始化指标表 |
||||
|
* @param cutOffPointer |
||||
|
* @param variable |
||||
|
*/ |
||||
|
private void initCutOffPoint(final NumberIterator cutOffPointer,ScVariable variable){ |
||||
|
log.info("开始执行初始化截断点..."); |
||||
|
final SqlBatcher sqlBatcher =new SqlBatcher("" |
||||
|
+ " insert into " + variable.getTableName() + "(" |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT" |
||||
|
+ " ) values (" |
||||
|
+ " ?," |
||||
|
+ " ?," |
||||
|
+ " ?" |
||||
|
+ ")" |
||||
|
); |
||||
|
|
||||
|
Map<String,String> models = ExecutorUtil.getAllModels(jdbcTemplate); |
||||
|
if(models!=null && models.size()>0){ |
||||
|
for(String key : models.keySet()){ |
||||
|
String modelId =key; |
||||
|
String modelName =models.get(key); |
||||
|
cutOffPointer.reset(); |
||||
|
while(cutOffPointer.hasNext()){ |
||||
|
sqlBatcher.addArg(new Object[]{ |
||||
|
modelId, |
||||
|
modelName, |
||||
|
cutOffPointer.next() |
||||
|
}); |
||||
|
} |
||||
|
sqlBatcher.execute(jdbcTemplate); |
||||
|
} |
||||
|
} |
||||
|
log.info("完成执行初始化截断点"); |
||||
|
} |
||||
|
|
||||
|
private void doGenerateKpi(NumberIterator cutOffPointer,final ScVariable variable){ |
||||
|
final SqlBatcher sqlBatcher =new SqlBatcher("" |
||||
|
+ " update " + variable.getTableName() |
||||
|
+ " set" |
||||
|
+ " FD_N=?," |
||||
|
+ " FD_TN=?," |
||||
|
+ " FD_D=?," |
||||
|
+ " FD_TD=?," |
||||
|
+ " FD_Y1=?," |
||||
|
+ " FD_Y2=?" |
||||
|
+ " where" |
||||
|
+ " FD_MODEL_ID=?" |
||||
|
+ " and FD_SCORE_CUT_OFF_POINT=?" |
||||
|
); |
||||
|
|
||||
|
cutOffPointer.reset(); |
||||
|
while(cutOffPointer.hasNext()){ |
||||
|
final BigDecimal cutOffPointValue =cutOffPointer.next(); |
||||
|
String sql ="" |
||||
|
+ "select" |
||||
|
+ " t0.FD_MODEL_ID," //模型ID
|
||||
|
+ " t0.CUT_OFF_POINT," //截断点
|
||||
|
+ " t1.FD_N," //评分小于等于截断点事实正常的客户个数
|
||||
|
+ " t2.FD_TN," //事实正常的总客户个数
|
||||
|
+ " t3.FD_D," //评分小于等于截断点事实违约客户个数
|
||||
|
+ " t4.FD_TD" //事实违约的总客户个数
|
||||
|
+ " from " |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT from MV_GENERAL_SAMPLE group by FD_MODEL_ID) t0" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_N from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " and FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t1" |
||||
|
+ " on t0.FD_MODEL_ID=t1.FD_MODEL_ID and t0.CUT_OFF_POINT=t1.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TN from MV_GENERAL_SAMPLE where FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t2" |
||||
|
+ " on t0.FD_MODEL_ID=t2.FD_MODEL_ID and t0.CUT_OFF_POINT=t2.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_D from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " and FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t3" |
||||
|
+ " on t0.FD_MODEL_ID=t3.FD_MODEL_ID and t0.CUT_OFF_POINT=t3.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TD from MV_GENERAL_SAMPLE where FD_DEFAULT_STATUS = 'D' group by FD_MODEL_ID) t4" |
||||
|
+ " on t0.FD_MODEL_ID=t4.FD_MODEL_ID and t0.CUT_OFF_POINT=t4.CUT_OFF_POINT" |
||||
|
+ ""; |
||||
|
jdbcTemplate.query(sql, new RowCallbackHandler() { |
||||
|
@Override |
||||
|
public void processRow(ResultSet rs) throws SQLException { |
||||
|
sqlBatcher.addArg(new Object[]{ |
||||
|
rs.getDouble("FD_N"), |
||||
|
rs.getDouble("FD_TN"), |
||||
|
rs.getDouble("FD_D"), |
||||
|
rs.getDouble("FD_TD"), |
||||
|
rs.getDouble("FD_TN")==0?0:rs.getDouble("FD_N")/rs.getDouble("FD_TN"), |
||||
|
rs.getDouble("FD_TD")==0?0:rs.getDouble("FD_D")/rs.getDouble("FD_TD"), |
||||
|
|
||||
|
rs.getString("FD_MODEL_ID"), |
||||
|
rs.getInt("CUT_OFF_POINT") |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
sqlBatcher.execute(jdbcTemplate); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算 KS 值,并更新到模型验证结果表中 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void calKs(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始计算 KS 值,并更新到模型验证结果表中..."); |
||||
|
String sql ="" |
||||
|
+ " select" |
||||
|
+ " FD_MODEL_ID" |
||||
|
+ " ,max(FD_MODEL_NAME) as FD_MODEL_NAME" |
||||
|
+ " ,max(abs(FD_Y1-FD_Y2)) as KS" |
||||
|
+ " from " + variable.getTableName() |
||||
|
+ " group by FD_MODEL_ID"; |
||||
|
jdbcTemplate.query(sql, new RowCallbackHandler() { |
||||
|
@Override |
||||
|
public void processRow(ResultSet rs) throws SQLException { |
||||
|
final String modelId = rs.getString("FD_MODEL_ID"); |
||||
|
final String modelName = rs.getString("FD_MODEL_NAME"); |
||||
|
//更新模型验证结果表
|
||||
|
//更新模型验证结果表
|
||||
|
int updated =jdbcTemplate.update("update MV_GENERAL_RESULT set " + variable.getKpiFieldName() + "=? where FD_MODEL_ID=?", rs.getDouble("KS"),modelId); |
||||
|
if(updated==0){ |
||||
|
jdbcTemplate.update("insert into MV_GENERAL_RESULT(FD_MODEL_ID,FD_MODEL_NAME," + variable.getKpiFieldName() + ") values(?,?,?)", modelId,modelName,rs.getDouble("KS")); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
log.info("完成计算 KS 值,并更新到模型验证结果表中"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将计算并生成指标表数据保存到历史表中 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void saveToHistory(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始将计算并生成指标表数据保存到历史表中..."); |
||||
|
final String runtimeDateString = DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
String sql ="delete from " + variable.getHisTableName() + " where FD_VALIDATE_DATE=?"; |
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
sql = "" |
||||
|
+ " insert into " + variable.getHisTableName() + "(" |
||||
|
+ " FD_VALIDATE_DATE," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT," |
||||
|
+ " FD_N," |
||||
|
+ " FD_TN," |
||||
|
+ " FD_D," |
||||
|
+ " FD_TD," |
||||
|
+ " FD_Y1," |
||||
|
+ " FD_Y2" |
||||
|
+ " )" |
||||
|
+ " select " |
||||
|
+ " ?," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT," |
||||
|
+ " FD_N," |
||||
|
+ " FD_TN," |
||||
|
+ " FD_D," |
||||
|
+ " FD_TD," |
||||
|
+ " FD_Y1," |
||||
|
+ " FD_Y2" |
||||
|
+ " from " + variable.getTableName(); |
||||
|
|
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
log.info("完成将计算并生成指标表数据保存到历史表中"); |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 KS(定性) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScKsQualitativeExecutor extends ScKsExecutor{ |
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return super.getOrder() + 20; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_KS_QUALITATIVE"); |
||||
|
result.setTableName("MV_SC_KS_QUALITATIVE"); |
||||
|
result.setHisTableName("MV_SC_KS_QUALITATIVE_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_KS_QUALITATIVE); |
||||
|
return result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 KS(定量) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScKsQuantitativeExecutor extends ScKsExecutor{ |
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return super.getOrder() + 10; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_KS_QUANTITATIVE"); |
||||
|
result.setTableName("MV_SC_KS_QUANTITATIVE"); |
||||
|
result.setHisTableName("MV_SC_KS_QUANTITATIVE_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_KS_QUANTITATIVE); |
||||
|
return result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,333 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.ResultSet; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import io.sc.engine.mv.executor.support.CutOffPointFinder; |
||||
|
import io.sc.engine.mv.executor.support.ExecutorUtil; |
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import io.sc.platform.core.support.NumberIterator; |
||||
|
import io.sc.platform.core.support.ProgressInfo; |
||||
|
import io.sc.platform.core.util.DateUtil; |
||||
|
import io.sc.platform.jdbc.util.SqlBatcher; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.dao.DataAccessException; |
||||
|
import org.springframework.jdbc.core.PreparedStatementSetter; |
||||
|
import org.springframework.jdbc.core.ResultSetExtractor; |
||||
|
import org.springframework.jdbc.core.RowCallbackHandler; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 ROC 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScRocExecutor extends AbstractExecutor{ |
||||
|
protected static final int ORDER =200; |
||||
|
@Autowired protected CutOffPointFinder cutOffPointFinder; |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return ORDER; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_AUC"); |
||||
|
result.setTableName("MV_SC_ROC"); |
||||
|
result.setHisTableName("MV_SC_ROC_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_ROC); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public void execute(RuntimeContext runtimeContext, ProgressInfo progressInfo) { |
||||
|
//获取变量
|
||||
|
ScVariable variable =getRuntimeVariable(); |
||||
|
|
||||
|
//初始化指标表
|
||||
|
initKpi(runtimeContext,variable); |
||||
|
|
||||
|
//计算并生成指标表数据
|
||||
|
generateKpi(runtimeContext,variable); |
||||
|
|
||||
|
//计算 AUC 值,并更新到模型验证结果表中
|
||||
|
calAuc(runtimeContext,variable); |
||||
|
|
||||
|
//将计算并生成指标表数据保存到历史表中
|
||||
|
saveToHistory(runtimeContext,variable); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除指标表历史数据 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void initKpi(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始执行初始化指标表..."); |
||||
|
jdbcTemplate.execute("delete from " + variable.getTableName()); |
||||
|
log.info("完成执行初始化指标表"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算并生成指标表 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void generateKpi(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始执行计算并生成指标表数据..."); |
||||
|
final NumberIterator cutOffPointer =cutOffPointFinder.getCufOffPoint(variable.getCutOffPointName()); |
||||
|
if(cutOffPointer==null){ |
||||
|
throw new RuntimeException("无法获取截断点配置信息,请查看是否已经配置了截断点配置信息."); |
||||
|
} |
||||
|
initCutOffPoint(cutOffPointer,variable); |
||||
|
doGenerateKpi(cutOffPointer,variable); |
||||
|
log.info("完成执行计算并生成指标表数据"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据截断点初始化指标表 |
||||
|
* @param cutOffPointer |
||||
|
* @param variable |
||||
|
*/ |
||||
|
private void initCutOffPoint(final NumberIterator cutOffPointer,ScVariable variable){ |
||||
|
log.info("开始执行初始化截断点..."); |
||||
|
final SqlBatcher sqlBatcher =new SqlBatcher("" |
||||
|
+ " insert into " + variable.getTableName() + "(" |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT" |
||||
|
+ " ) values (" |
||||
|
+ " ?," |
||||
|
+ " ?," |
||||
|
+ " ?" |
||||
|
+ ")" |
||||
|
); |
||||
|
Map<String,String> models = ExecutorUtil.getAllModels(jdbcTemplate); |
||||
|
if(models!=null && models.size()>0){ |
||||
|
for(String key : models.keySet()){ |
||||
|
String modelId =key; |
||||
|
String modelName =models.get(key); |
||||
|
cutOffPointer.reset(); |
||||
|
while(cutOffPointer.hasNext()){ |
||||
|
sqlBatcher.addArg(new Object[]{ |
||||
|
modelId, |
||||
|
modelName, |
||||
|
cutOffPointer.next() |
||||
|
}); |
||||
|
} |
||||
|
sqlBatcher.execute(jdbcTemplate); |
||||
|
} |
||||
|
} |
||||
|
log.info("完成执行初始化截断点."); |
||||
|
} |
||||
|
|
||||
|
private void doGenerateKpi(NumberIterator cutOffPointer,ScVariable variable){ |
||||
|
final SqlBatcher sqlBatcher =new SqlBatcher("" |
||||
|
+ " update " + variable.getTableName() |
||||
|
+ " set" |
||||
|
+ " FD_DD=?," |
||||
|
+ " FD_DN=?," |
||||
|
+ " FD_ND=?," |
||||
|
+ " FD_NN=?," |
||||
|
+ " FD_TD=?," |
||||
|
+ " FD_TN=?," |
||||
|
+ " FD_Y=?," |
||||
|
+ " FD_X=?" |
||||
|
+ " where" |
||||
|
+ " FD_MODEL_ID=?" |
||||
|
+ " and FD_SCORE_CUT_OFF_POINT=?" |
||||
|
); |
||||
|
|
||||
|
cutOffPointer.reset(); |
||||
|
while(cutOffPointer.hasNext()){ |
||||
|
final BigDecimal cutOffPointValue =cutOffPointer.next(); |
||||
|
String sql =getGenerateKpiSql(cutOffPointValue,variable); |
||||
|
jdbcTemplate.query(sql, new RowCallbackHandler() { |
||||
|
@Override |
||||
|
public void processRow(ResultSet rs) throws SQLException { |
||||
|
sqlBatcher.addArg(new Object[]{ |
||||
|
rs.getDouble("FD_DD"), |
||||
|
rs.getDouble("FD_DN"), |
||||
|
rs.getDouble("FD_ND"), |
||||
|
rs.getDouble("FD_NN"), |
||||
|
rs.getDouble("FD_TD"), |
||||
|
rs.getDouble("FD_TN"), |
||||
|
rs.getDouble("FD_TD")==0?0:rs.getDouble("FD_DD")/rs.getDouble("FD_TD"), |
||||
|
rs.getDouble("FD_TN")==0?0:rs.getDouble("FD_ND")/rs.getDouble("FD_TN"), |
||||
|
|
||||
|
rs.getString("FD_MODEL_ID"), |
||||
|
rs.getDouble("CUT_OFF_POINT") |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
sqlBatcher.execute(jdbcTemplate); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算 AUC 值,并更新到模型验证结果表中 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void calAuc(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始计算 AUC 值,并更新到模型验证结果表中..."); |
||||
|
Map<String,String> models =ExecutorUtil.getAllModels(jdbcTemplate); |
||||
|
if(models!=null && models.size()>0){ |
||||
|
for(String key : models.keySet()){ |
||||
|
final String modelId =key; |
||||
|
final String modelName =models.get(key); |
||||
|
String sql ="" |
||||
|
+ " select" |
||||
|
+ " FD_X," |
||||
|
+ " FD_Y " |
||||
|
+ " from " + variable.getTableName() |
||||
|
+ " where" |
||||
|
+ " FD_MODEL_ID = '" + modelId + "'" |
||||
|
+ " group by FD_X,FD_Y" |
||||
|
+ " order by FD_X"; |
||||
|
jdbcTemplate.query(sql, new ResultSetExtractor<Object>(){ |
||||
|
@Override |
||||
|
public Object extractData(ResultSet rs) throws SQLException, DataAccessException { |
||||
|
//计算 CAP 曲线下面的面积
|
||||
|
Double area = 0.0; |
||||
|
Double Yn_1 = null; |
||||
|
Double Xn_1 = null; |
||||
|
|
||||
|
while (rs.next()) { |
||||
|
Double Yn = rs.getDouble("FD_Y"); |
||||
|
Double Xn = rs.getDouble("FD_X"); |
||||
|
|
||||
|
if(Yn_1 != null && Xn_1 != null){ |
||||
|
area = area + (Yn_1 + Yn)*(Xn - Xn_1); |
||||
|
} |
||||
|
|
||||
|
Yn_1 = rs.getDouble("FD_Y"); |
||||
|
Xn_1 = rs.getDouble("FD_X"); |
||||
|
} |
||||
|
double auc = area/2; |
||||
|
|
||||
|
//更新模型验证结果表
|
||||
|
int updated =jdbcTemplate.update("update MV_GENERAL_RESULT set " + variable.getKpiFieldName() + "=? where FD_MODEL_ID=?", auc,modelId); |
||||
|
if(updated==0){ |
||||
|
jdbcTemplate.update("insert into MV_GENERAL_RESULT(FD_MODEL_ID,FD_MODEL_NAME," + variable.getKpiFieldName() + ") values(?,?,?)", modelId,modelName,auc); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将计算并生成指标表数据保存到历史表中 |
||||
|
* @param runtimeContext 执行上下文 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
protected void saveToHistory(final RuntimeContext runtimeContext,final ScVariable variable){ |
||||
|
log.info("开始将计算并生成指标表数据保存到历史表中..."); |
||||
|
final String runtimeDateString = DateUtil.formatDate(runtimeContext.getValidateDate(), DateUtil.yyyy_MM_dd_HH_mm_ss); |
||||
|
String sql ="delete from " + variable.getHisTableName() + " where FD_VALIDATE_DATE=?"; |
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
sql = "" |
||||
|
+ " insert into " + variable.getHisTableName() + "(" |
||||
|
+ " FD_VALIDATE_DATE," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT," |
||||
|
+ " FD_DD," |
||||
|
+ " FD_DN," |
||||
|
+ " FD_ND," |
||||
|
+ " FD_NN," |
||||
|
+ " FD_TD," |
||||
|
+ " FD_TN," |
||||
|
+ " FD_Y," |
||||
|
+ " FD_X" |
||||
|
+ " )" |
||||
|
+ " select " |
||||
|
+ " ?," |
||||
|
+ " FD_MODEL_ID," |
||||
|
+ " FD_MODEL_NAME," |
||||
|
+ " FD_SCORE_CUT_OFF_POINT," |
||||
|
+ " FD_DD," |
||||
|
+ " FD_DN," |
||||
|
+ " FD_ND," |
||||
|
+ " FD_NN," |
||||
|
+ " FD_TD," |
||||
|
+ " FD_TN," |
||||
|
+ " FD_Y," |
||||
|
+ " FD_X" |
||||
|
+ " from " + variable.getTableName(); |
||||
|
|
||||
|
jdbcTemplate.update(sql, new PreparedStatementSetter() { |
||||
|
@Override |
||||
|
public void setValues(PreparedStatement pstmt) throws SQLException { |
||||
|
pstmt.setObject(1, runtimeDateString); |
||||
|
} |
||||
|
}); |
||||
|
log.info("完成将计算并生成指标表数据保存到历史表中"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取构建指标表的关键 SQL 语句 |
||||
|
* @param cutOffPointValue 截断点值 |
||||
|
* @param variable 变量 |
||||
|
* @return 构建指标表的关键 SQL 语句 |
||||
|
*/ |
||||
|
protected String getGenerateKpiSql(BigDecimal cutOffPointValue,ScVariable variable){ |
||||
|
return " select" |
||||
|
+ " t0.FD_MODEL_ID," //模型ID
|
||||
|
+ " t0.CUT_OFF_POINT," //截断点
|
||||
|
+ " t1.FD_DD," //实际违约且预测违约样本总数
|
||||
|
+ " t2.FD_DN," //实际违约且预测正常样本总数
|
||||
|
+ " t3.FD_ND," //实际正常且预测违约样本总数
|
||||
|
+ " t4.FD_NN," //实际正常且预测正常样本总数
|
||||
|
+ " t5.FD_TD," //实际违约样本总数
|
||||
|
+ " t6.FD_TN" //实际正常样本总数
|
||||
|
+ " from " |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT from MV_GENERAL_SAMPLE group by FD_MODEL_ID) t0" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_DD from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " and FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t1" |
||||
|
+ " on t0.FD_MODEL_ID=t1.FD_MODEL_ID and t0.CUT_OFF_POINT=t1.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_DN from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + ">" + cutOffPointValue + " and FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t2" |
||||
|
+ " on t0.FD_MODEL_ID=t2.FD_MODEL_ID and t0.CUT_OFF_POINT=t2.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_ND from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " and FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t3" |
||||
|
+ " on t0.FD_MODEL_ID=t3.FD_MODEL_ID and t0.CUT_OFF_POINT=t3.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_NN from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + ">" + cutOffPointValue + " and FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t4" |
||||
|
+ " on t0.FD_MODEL_ID=t4.FD_MODEL_ID and t0.CUT_OFF_POINT=t4.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TD from MV_GENERAL_SAMPLE where FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t5" |
||||
|
+ " on t0.FD_MODEL_ID=t5.FD_MODEL_ID and t0.CUT_OFF_POINT=t5.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TN from MV_GENERAL_SAMPLE where FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t6" |
||||
|
+ " on t0.FD_MODEL_ID=t6.FD_MODEL_ID and t0.CUT_OFF_POINT=t6.CUT_OFF_POINT" |
||||
|
+ ""; |
||||
|
} |
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 ROC(定性) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScRocQualitativeExecutor extends ScRocQuantitativeExecutor{ |
||||
|
@Override |
||||
|
public boolean isEnable() { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return super.getOrder() + 20; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_AUC_QUALITATIVE"); |
||||
|
result.setTableName("MV_SC_ROC_QUALITATIVE"); |
||||
|
result.setHisTableName("MV_SC_ROC_QUALITATIVE_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE_QUANTITATIVE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_ROC_QUALITATIVE); |
||||
|
return result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,85 @@ |
|||||
|
package io.sc.engine.mv.executor; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
import io.sc.engine.mv.executor.support.ScVariable; |
||||
|
import io.sc.engine.mv.jpa.entity.CfgCutOffPoint; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力 ROC(定量) 验证执行器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScRocQuantitativeExecutor extends ScRocExecutor{ |
||||
|
@Override |
||||
|
public int getOrder() { |
||||
|
return super.getOrder() + 10; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
|
||||
|
protected ScVariable getRuntimeVariable(){ |
||||
|
ScVariable result =new ScVariable(); |
||||
|
result.setKpiFieldName("FD_SC_AUC_QUANTITATIVE"); |
||||
|
result.setTableName("MV_SC_ROC_QUANTITATIVE"); |
||||
|
result.setHisTableName("MV_SC_ROC_QUANTITATIVE_HIS"); |
||||
|
result.setCutOffPointFieldName("FD_SCORE_QUALITATIVE"); |
||||
|
result.setCutOffPointName(CfgCutOffPoint.CUT_OFF_ROC_QUANTITATIVE); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 覆盖父类的 SQL |
||||
|
* 将 ">=" 条件修改为 "<=" |
||||
|
* 在总体 ROC 中,截断点为违约概率(从 1 到 0), |
||||
|
* 而定量 ROC 中,无法确定定量的违约概率,只能通过分数进行(从 0 到 100),为了跟总体 ROC 在意义上保持一致, |
||||
|
* 原有 "违约概率>=" 转化为 "定量分数<=" |
||||
|
* 类似其他几个条件依次进行转换 |
||||
|
* @param cutOffPointValue 截断点值 |
||||
|
* @param variable 变量 |
||||
|
*/ |
||||
|
@Override |
||||
|
protected String getGenerateKpiSql(BigDecimal cutOffPointValue,ScVariable variable){ |
||||
|
return " select" |
||||
|
+ " t0.FD_MODEL_ID," //模型ID
|
||||
|
+ " t0.CUT_OFF_POINT," //截断点
|
||||
|
+ " t1.FD_DD," //实际违约且预测违约样本总数
|
||||
|
+ " t2.FD_DN," //实际违约且预测正常样本总数
|
||||
|
+ " t3.FD_ND," //实际正常且预测违约样本总数
|
||||
|
+ " t4.FD_NN," //实际正常且预测正常样本总数
|
||||
|
+ " t5.FD_TD," //实际违约样本总数
|
||||
|
+ " t6.FD_TN" //实际正常样本总数
|
||||
|
+ " from " |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT from MV_GENERAL_SAMPLE group by FD_MODEL_ID) t0" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_DD from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " and FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t1" |
||||
|
+ " on t0.FD_MODEL_ID=t1.FD_MODEL_ID and t0.CUT_OFF_POINT=t1.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_DN from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + ">" + cutOffPointValue + " and FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t2" |
||||
|
+ " on t0.FD_MODEL_ID=t2.FD_MODEL_ID and t0.CUT_OFF_POINT=t2.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_ND from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + "<=" + cutOffPointValue + " and FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t3" |
||||
|
+ " on t0.FD_MODEL_ID=t3.FD_MODEL_ID and t0.CUT_OFF_POINT=t3.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_NN from MV_GENERAL_SAMPLE where " + variable.getCutOffPointFieldName() + ">" + cutOffPointValue + " and FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t4" |
||||
|
+ " on t0.FD_MODEL_ID=t4.FD_MODEL_ID and t0.CUT_OFF_POINT=t4.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TD from MV_GENERAL_SAMPLE where FD_DEFAULT_STATUS='D' group by FD_MODEL_ID) t5" |
||||
|
+ " on t0.FD_MODEL_ID=t5.FD_MODEL_ID and t0.CUT_OFF_POINT=t5.CUT_OFF_POINT" |
||||
|
|
||||
|
+ " left join" |
||||
|
+ " (select FD_MODEL_ID," + cutOffPointValue + " as CUT_OFF_POINT,count(*) as FD_TN from MV_GENERAL_SAMPLE where FD_DEFAULT_STATUS='N' group by FD_MODEL_ID) t6" |
||||
|
+ " on t0.FD_MODEL_ID=t6.FD_MODEL_ID and t0.CUT_OFF_POINT=t6.CUT_OFF_POINT" |
||||
|
+ ""; |
||||
|
} |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
package io.sc.engine.mv.executor.support; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力验证运行时变量类 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
public class ScVariable { |
||||
|
//结果字段名
|
||||
|
private String kpiFieldName; |
||||
|
//表名
|
||||
|
private String tableName; |
||||
|
//历史表名
|
||||
|
private String hisTableName; |
||||
|
//截断点判断字段名
|
||||
|
private String cutOffPointFieldName; |
||||
|
//截断点名称
|
||||
|
private String cutOffPointName; |
||||
|
|
||||
|
public String getKpiFieldName() { |
||||
|
return kpiFieldName; |
||||
|
} |
||||
|
public void setKpiFieldName(String kpiFieldName) { |
||||
|
this.kpiFieldName = kpiFieldName; |
||||
|
} |
||||
|
public String getTableName() { |
||||
|
return tableName; |
||||
|
} |
||||
|
public void setTableName(String tableName) { |
||||
|
this.tableName = tableName; |
||||
|
} |
||||
|
public String getHisTableName() { |
||||
|
return hisTableName; |
||||
|
} |
||||
|
public void setHisTableName(String hisTableName) { |
||||
|
this.hisTableName = hisTableName; |
||||
|
} |
||||
|
public String getCutOffPointName() { |
||||
|
return cutOffPointName; |
||||
|
} |
||||
|
public String getCutOffPointFieldName() { |
||||
|
return cutOffPointFieldName; |
||||
|
} |
||||
|
public void setCutOffPointFieldName(String cutOffPointFieldName) { |
||||
|
this.cutOffPointFieldName = cutOffPointFieldName; |
||||
|
} |
||||
|
public void setCutOffPointName(String cutOffPointName) { |
||||
|
this.cutOffPointName = cutOffPointName; |
||||
|
} |
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
package io.sc.engine.mv.extractor; |
||||
|
|
||||
|
import io.sc.engine.mv.DataExtractor; |
||||
|
import io.sc.engine.mv.RuntimeContext; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 评级记录源数据抽取器 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Component |
||||
|
public class ScoreRecordDataExtractor implements DataExtractor { |
||||
|
private static final Logger log =LoggerFactory.getLogger(DefaultRecordDataExtractor.class); |
||||
|
|
||||
|
@Override |
||||
|
public void extract(RuntimeContext runtimeContext) { |
||||
|
log.info("开始抽取评级记录数据..."); |
||||
|
log.info("完成抽取评级记录数据..."); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getExecuteTimeWeight() { |
||||
|
return 10; |
||||
|
} |
||||
|
} |
@ -0,0 +1,79 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.id.RuntimeParameterId; |
||||
|
import io.sc.engine.mv.vo.RuntimeParameterVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
import org.hibernate.annotations.GenericGenerator; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
|
||||
|
/** |
||||
|
* 模型验证执行时参数配置 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Entity |
||||
|
@Table(name="MV_RUNTIME_PARAMETER") |
||||
|
@IdClass(RuntimeParameterId.class) |
||||
|
public class RuntimeParameter extends BaseEntity<RuntimeParameterVo> { |
||||
|
//模型验证日期
|
||||
|
@Id |
||||
|
@GenericGenerator(name = "MvRuntimeParamIDGenerator", strategy = "assigned") |
||||
|
@Column(name="FD_VALIDATE_DATE", length=19) |
||||
|
private String validateDate; |
||||
|
|
||||
|
//运行时参数名称
|
||||
|
@Id |
||||
|
@Column(name="FD_PARAM_NAME", length=254) |
||||
|
private String name; |
||||
|
|
||||
|
//运行时参数值
|
||||
|
@Column(name="FD_PARAM_VALUE", length=254) |
||||
|
private String value; |
||||
|
|
||||
|
//参数显示顺序号
|
||||
|
@Column(name="FD_SNO") |
||||
|
private Integer sno; |
||||
|
|
||||
|
@Override |
||||
|
public RuntimeParameterVo toVo() { |
||||
|
RuntimeParameterVo vo =new RuntimeParameterVo(); |
||||
|
vo.setValidateDate(this.getValidateDate()); |
||||
|
vo.setName(this.getName()); |
||||
|
vo.setValue(this.getValue()); |
||||
|
vo.setSno(this.getSno()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getValue() { |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
public void setValue(String value) { |
||||
|
this.value = value; |
||||
|
} |
||||
|
|
||||
|
public Integer getSno() { |
||||
|
return sno; |
||||
|
} |
||||
|
|
||||
|
public void setSno(Integer sno) { |
||||
|
this.sno = sno; |
||||
|
} |
||||
|
} |
@ -0,0 +1,159 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.id.ScCapHistoryId; |
||||
|
import io.sc.engine.mv.vo.ScCapHistoryVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力验证 CAP 曲线指标表历史数据实体类 |
||||
|
* |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Entity |
||||
|
@Table(name="MV_SC_CAP_HIS") |
||||
|
@IdClass(ScCapHistoryId.class) |
||||
|
public class ScCapHistory extends BaseEntity<ScCapHistoryVo> { |
||||
|
private static final long serialVersionUID = -2157649915130031766L; |
||||
|
//模型验证日期
|
||||
|
@Id |
||||
|
@Column(name="FD_VALIDATE_DATE") |
||||
|
private String validateDate; |
||||
|
|
||||
|
//模型标识
|
||||
|
@Id |
||||
|
@Column(name="FD_MODEL_ID") |
||||
|
private String modelId; |
||||
|
|
||||
|
//模型名称
|
||||
|
@Column(name="FD_MODEL_NAME") |
||||
|
private String modelName; |
||||
|
|
||||
|
//评分截断点
|
||||
|
@Id |
||||
|
@Column(name="FD_SCORE_CUT_OFF_POINT") |
||||
|
private Integer scoreCutOffPoint; |
||||
|
|
||||
|
//评分小于等于截断点的客户个数
|
||||
|
@Column(name="FD_TS") |
||||
|
private Integer ts; |
||||
|
|
||||
|
//客户总数
|
||||
|
@Column(name="FD_TT") |
||||
|
private Integer tt; |
||||
|
|
||||
|
//评分小于等于截断点的事实违约客户个数
|
||||
|
@Column(name="FD_TDS") |
||||
|
private Integer tds; |
||||
|
|
||||
|
//事实违约的总客户数
|
||||
|
@Column(name="FD_TDT") |
||||
|
private Integer tdt; |
||||
|
|
||||
|
//客户个数百分比
|
||||
|
@Column(name="FD_X") |
||||
|
private BigDecimal x; |
||||
|
|
||||
|
//违约个数百分比
|
||||
|
@Column(name="FD_Y") |
||||
|
private BigDecimal y; |
||||
|
|
||||
|
@Override |
||||
|
public ScCapHistoryVo toVo() { |
||||
|
ScCapHistoryVo vo =new ScCapHistoryVo(); |
||||
|
vo.setValidateDate(this.getValidateDate()); |
||||
|
vo.setModelId(this.getModelId()); |
||||
|
vo.setModelName(this.getModelName()); |
||||
|
vo.setScoreCutOffPoint(this.getScoreCutOffPoint()); |
||||
|
vo.setTs(this.getTs()); |
||||
|
vo.setTt(this.getTt()); |
||||
|
vo.setTds(this.getTds()); |
||||
|
vo.setTdt(this.getTdt()); |
||||
|
vo.setX(this.getX()); |
||||
|
vo.setY(this.getY()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
|
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
|
||||
|
public String getModelName() { |
||||
|
return modelName; |
||||
|
} |
||||
|
|
||||
|
public void setModelName(String modelName) { |
||||
|
this.modelName = modelName; |
||||
|
} |
||||
|
|
||||
|
public Integer getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public void setScoreCutOffPoint(Integer scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public Integer getTs() { |
||||
|
return ts; |
||||
|
} |
||||
|
|
||||
|
public void setTs(Integer ts) { |
||||
|
this.ts = ts; |
||||
|
} |
||||
|
|
||||
|
public Integer getTt() { |
||||
|
return tt; |
||||
|
} |
||||
|
|
||||
|
public void setTt(Integer tt) { |
||||
|
this.tt = tt; |
||||
|
} |
||||
|
|
||||
|
public Integer getTds() { |
||||
|
return tds; |
||||
|
} |
||||
|
|
||||
|
public void setTds(Integer tds) { |
||||
|
this.tds = tds; |
||||
|
} |
||||
|
|
||||
|
public Integer getTdt() { |
||||
|
return tdt; |
||||
|
} |
||||
|
|
||||
|
public void setTdt(Integer tdt) { |
||||
|
this.tdt = tdt; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getX() { |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
public void setX(BigDecimal x) { |
||||
|
this.x = x; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY() { |
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
public void setY(BigDecimal y) { |
||||
|
this.y = y; |
||||
|
} |
||||
|
} |
@ -0,0 +1,159 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.id.ScKsHistoryId; |
||||
|
import io.sc.engine.mv.vo.ScKsHistoryVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力验证 KS 曲线指标表历史数据实体类 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Entity |
||||
|
@Table(name="MV_SC_KS_HIS") |
||||
|
@IdClass(ScKsHistoryId.class) |
||||
|
public class ScKsHistory extends BaseEntity<ScKsHistoryVo> { |
||||
|
private static final long serialVersionUID = -2196414266073929052L; |
||||
|
|
||||
|
//模型验证日期
|
||||
|
@Id |
||||
|
@Column(name="FD_VALIDATE_DATE") |
||||
|
private String validateDate; |
||||
|
|
||||
|
//模型标识
|
||||
|
@Id |
||||
|
@Column(name="FD_MODEL_ID") |
||||
|
private String modelId; |
||||
|
|
||||
|
//模型名称
|
||||
|
@Column(name="FD_MODEL_NAME") |
||||
|
private String modelName; |
||||
|
|
||||
|
//评分截断点
|
||||
|
@Id |
||||
|
@Column(name="FD_SCORE_CUT_OFF_POINT") |
||||
|
private Integer scoreCutOffPoint; |
||||
|
|
||||
|
//评分小于等于截断点事实正常的客户个数
|
||||
|
@Column(name="FD_N") |
||||
|
private Integer n; |
||||
|
|
||||
|
//事实正常的总客户个数
|
||||
|
@Column(name="FD_TN") |
||||
|
private Integer tn; |
||||
|
|
||||
|
//评分小于等于截断点事实违约客户个数
|
||||
|
@Column(name="FD_D") |
||||
|
private Integer d; |
||||
|
|
||||
|
//事实违约的总客户个数
|
||||
|
@Column(name="FD_TD") |
||||
|
private Integer td; |
||||
|
|
||||
|
//正常客户占比
|
||||
|
@Column(name="FD_Y1") |
||||
|
private BigDecimal y1; |
||||
|
|
||||
|
//违约客户占比
|
||||
|
@Column(name="FD_Y2") |
||||
|
private BigDecimal y2; |
||||
|
|
||||
|
@Override |
||||
|
public ScKsHistoryVo toVo() { |
||||
|
ScKsHistoryVo vo =new ScKsHistoryVo(); |
||||
|
vo.setValidateDate(this.getValidateDate()); |
||||
|
vo.setModelId(this.getModelId()); |
||||
|
vo.setModelName(this.getModelName()); |
||||
|
vo.setScoreCutOffPoint(this.getScoreCutOffPoint()); |
||||
|
vo.setN(this.getN()); |
||||
|
vo.setTn(this.getTn()); |
||||
|
vo.setD(this.getD()); |
||||
|
vo.setTd(this.getTd()); |
||||
|
vo.setY1(this.getY1()); |
||||
|
vo.setY2(this.getY2()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
|
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
|
||||
|
public String getModelName() { |
||||
|
return modelName; |
||||
|
} |
||||
|
|
||||
|
public void setModelName(String modelName) { |
||||
|
this.modelName = modelName; |
||||
|
} |
||||
|
|
||||
|
public Integer getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public void setScoreCutOffPoint(Integer scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public Integer getN() { |
||||
|
return n; |
||||
|
} |
||||
|
|
||||
|
public void setN(Integer n) { |
||||
|
this.n = n; |
||||
|
} |
||||
|
|
||||
|
public Integer getTn() { |
||||
|
return tn; |
||||
|
} |
||||
|
|
||||
|
public void setTn(Integer tn) { |
||||
|
this.tn = tn; |
||||
|
} |
||||
|
|
||||
|
public Integer getD() { |
||||
|
return d; |
||||
|
} |
||||
|
|
||||
|
public void setD(Integer d) { |
||||
|
this.d = d; |
||||
|
} |
||||
|
|
||||
|
public Integer getTd() { |
||||
|
return td; |
||||
|
} |
||||
|
|
||||
|
public void setTd(Integer td) { |
||||
|
this.td = td; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY1() { |
||||
|
return y1; |
||||
|
} |
||||
|
|
||||
|
public void setY1(BigDecimal y1) { |
||||
|
this.y1 = y1; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY2() { |
||||
|
return y2; |
||||
|
} |
||||
|
|
||||
|
public void setY2(BigDecimal y2) { |
||||
|
this.y2 = y2; |
||||
|
} |
||||
|
} |
@ -0,0 +1,183 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.id.ScRocHistoryId; |
||||
|
import io.sc.engine.mv.vo.ScRocHistoryVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
|
||||
|
import javax.persistence.*; |
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
/** |
||||
|
* 模型区分能力验证 ROC 曲线指标表历史数据实体类 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
@Entity |
||||
|
@Table(name="MV_SC_ROC_HIS") |
||||
|
@IdClass(ScRocHistoryId.class) |
||||
|
public class ScRocHistory extends BaseEntity<ScRocHistoryVo> { |
||||
|
//模型验证日期
|
||||
|
@Id |
||||
|
@Column(name="FD_VALIDATE_DATE") |
||||
|
private String validateDate; |
||||
|
|
||||
|
//模型标识
|
||||
|
@Id |
||||
|
@Column(name="FD_MODEL_ID") |
||||
|
private String modelId; |
||||
|
|
||||
|
//模型名称
|
||||
|
@Column(name="FD_MODEL_NAME") |
||||
|
private String modelName; |
||||
|
|
||||
|
//违约概率截断点
|
||||
|
@Id |
||||
|
@Column(name="FD_SCORE_CUT_OFF_POINT") |
||||
|
private Double scoreCutOffPoint; |
||||
|
|
||||
|
//实际违约且预测违约样本总数
|
||||
|
@Column(name="FD_DD") |
||||
|
private Integer dd; |
||||
|
|
||||
|
//实际违约且预测正常样本总数
|
||||
|
@Column(name="FD_DN") |
||||
|
private Integer dn; |
||||
|
|
||||
|
//实际正常且预测违约样本总数
|
||||
|
@Column(name="FD_ND") |
||||
|
private Integer nd; |
||||
|
|
||||
|
//实际正常且预测正常样本总数
|
||||
|
@Column(name="FD_NN") |
||||
|
private Integer nn; |
||||
|
|
||||
|
//实际违约样本总数
|
||||
|
@Column(name="FD_TD") |
||||
|
private Integer td; |
||||
|
|
||||
|
//实际正常样本总数
|
||||
|
@Column(name="FD_TN") |
||||
|
private Integer tn; |
||||
|
|
||||
|
//违约预测误警率
|
||||
|
@Column(name="FD_X") |
||||
|
private BigDecimal x; |
||||
|
|
||||
|
//违约预测命中率
|
||||
|
@Column(name="FD_Y") |
||||
|
private BigDecimal y; |
||||
|
|
||||
|
@Override |
||||
|
public ScRocHistoryVo toVo() { |
||||
|
ScRocHistoryVo vo =new ScRocHistoryVo(); |
||||
|
vo.setValidateDate(this.getValidateDate()); |
||||
|
vo.setModelId(this.getModelId()); |
||||
|
vo.setModelName(this.getModelName()); |
||||
|
vo.setScoreCutOffPoint(this.getScoreCutOffPoint()); |
||||
|
vo.setDd(this.getDd()); |
||||
|
vo.setDn(this.getDn()); |
||||
|
vo.setNd(this.getNd()); |
||||
|
vo.setNn(this.getNn()); |
||||
|
vo.setTd(this.getTd()); |
||||
|
vo.setTn(this.getTn()); |
||||
|
vo.setX(this.getX()); |
||||
|
vo.setY(this.getY()); |
||||
|
return vo; |
||||
|
} |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
|
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
|
||||
|
public String getModelName() { |
||||
|
return modelName; |
||||
|
} |
||||
|
|
||||
|
public void setModelName(String modelName) { |
||||
|
this.modelName = modelName; |
||||
|
} |
||||
|
|
||||
|
public Double getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public void setScoreCutOffPoint(Double scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public Integer getDd() { |
||||
|
return dd; |
||||
|
} |
||||
|
|
||||
|
public void setDd(Integer dd) { |
||||
|
this.dd = dd; |
||||
|
} |
||||
|
|
||||
|
public Integer getDn() { |
||||
|
return dn; |
||||
|
} |
||||
|
|
||||
|
public void setDn(Integer dn) { |
||||
|
this.dn = dn; |
||||
|
} |
||||
|
|
||||
|
public Integer getNd() { |
||||
|
return nd; |
||||
|
} |
||||
|
|
||||
|
public void setNd(Integer nd) { |
||||
|
this.nd = nd; |
||||
|
} |
||||
|
|
||||
|
public Integer getNn() { |
||||
|
return nn; |
||||
|
} |
||||
|
|
||||
|
public void setNn(Integer nn) { |
||||
|
this.nn = nn; |
||||
|
} |
||||
|
|
||||
|
public Integer getTd() { |
||||
|
return td; |
||||
|
} |
||||
|
|
||||
|
public void setTd(Integer td) { |
||||
|
this.td = td; |
||||
|
} |
||||
|
|
||||
|
public Integer getTn() { |
||||
|
return tn; |
||||
|
} |
||||
|
|
||||
|
public void setTn(Integer tn) { |
||||
|
this.tn = tn; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getX() { |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
public void setX(BigDecimal x) { |
||||
|
this.x = x; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY() { |
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
public void setY(BigDecimal y) { |
||||
|
this.y = y; |
||||
|
} |
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity.id; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class RuntimeParameterId implements Serializable{ |
||||
|
private static final long serialVersionUID = 1367562856018529543L; |
||||
|
private String validateDate; |
||||
|
private String name; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int hashCode() { |
||||
|
final int prime = 31; |
||||
|
int result = 1; |
||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode()); |
||||
|
result = prime * result + ((validateDate == null) ? 0 : validateDate.hashCode()); |
||||
|
return result; |
||||
|
} |
||||
|
@Override |
||||
|
public boolean equals(Object obj) { |
||||
|
if (this == obj) |
||||
|
return true; |
||||
|
if (obj == null) |
||||
|
return false; |
||||
|
if (getClass() != obj.getClass()) |
||||
|
return false; |
||||
|
RuntimeParameterId other = (RuntimeParameterId) obj; |
||||
|
if (name == null) { |
||||
|
if (other.name != null) |
||||
|
return false; |
||||
|
} else if (!name.equals(other.name)) |
||||
|
return false; |
||||
|
if (validateDate == null) { |
||||
|
if (other.validateDate != null) |
||||
|
return false; |
||||
|
} else if (!validateDate.equals(other.validateDate)) |
||||
|
return false; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity.id; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class ScCapHistoryId implements Serializable{ |
||||
|
private static final long serialVersionUID = -269346483593245329L; |
||||
|
private String validateDate; |
||||
|
private String modelId; |
||||
|
private Integer scoreCutOffPoint; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
public Integer getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
public void setScoreCutOffPoint(Integer scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int hashCode() { |
||||
|
final int prime = 31; |
||||
|
int result = 1; |
||||
|
result = prime * result + ((modelId == null) ? 0 : modelId.hashCode()); |
||||
|
result = prime * result + ((scoreCutOffPoint == null) ? 0 : scoreCutOffPoint.hashCode()); |
||||
|
result = prime * result + ((validateDate == null) ? 0 : validateDate.hashCode()); |
||||
|
return result; |
||||
|
} |
||||
|
@Override |
||||
|
public boolean equals(Object obj) { |
||||
|
if (this == obj) |
||||
|
return true; |
||||
|
if (obj == null) |
||||
|
return false; |
||||
|
if (getClass() != obj.getClass()) |
||||
|
return false; |
||||
|
ScCapHistoryId other = (ScCapHistoryId) obj; |
||||
|
if (modelId == null) { |
||||
|
if (other.modelId != null) |
||||
|
return false; |
||||
|
} else if (!modelId.equals(other.modelId)) |
||||
|
return false; |
||||
|
if (scoreCutOffPoint == null) { |
||||
|
if (other.scoreCutOffPoint != null) |
||||
|
return false; |
||||
|
} else if (!scoreCutOffPoint.equals(other.scoreCutOffPoint)) |
||||
|
return false; |
||||
|
if (validateDate == null) { |
||||
|
if (other.validateDate != null) |
||||
|
return false; |
||||
|
} else if (!validateDate.equals(other.validateDate)) |
||||
|
return false; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity.id; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class ScKsHistoryId implements Serializable{ |
||||
|
private static final long serialVersionUID = 6247313483047348351L; |
||||
|
private String validateDate; |
||||
|
private String modelId; |
||||
|
private Integer scoreCutOffPoint; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
public Integer getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
public void setScoreCutOffPoint(Integer scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int hashCode() { |
||||
|
final int prime = 31; |
||||
|
int result = 1; |
||||
|
result = prime * result + ((modelId == null) ? 0 : modelId.hashCode()); |
||||
|
result = prime * result + ((scoreCutOffPoint == null) ? 0 : scoreCutOffPoint.hashCode()); |
||||
|
result = prime * result + ((validateDate == null) ? 0 : validateDate.hashCode()); |
||||
|
return result; |
||||
|
} |
||||
|
@Override |
||||
|
public boolean equals(Object obj) { |
||||
|
if (this == obj) |
||||
|
return true; |
||||
|
if (obj == null) |
||||
|
return false; |
||||
|
if (getClass() != obj.getClass()) |
||||
|
return false; |
||||
|
ScKsHistoryId other = (ScKsHistoryId) obj; |
||||
|
if (modelId == null) { |
||||
|
if (other.modelId != null) |
||||
|
return false; |
||||
|
} else if (!modelId.equals(other.modelId)) |
||||
|
return false; |
||||
|
if (scoreCutOffPoint == null) { |
||||
|
if (other.scoreCutOffPoint != null) |
||||
|
return false; |
||||
|
} else if (!scoreCutOffPoint.equals(other.scoreCutOffPoint)) |
||||
|
return false; |
||||
|
if (validateDate == null) { |
||||
|
if (other.validateDate != null) |
||||
|
return false; |
||||
|
} else if (!validateDate.equals(other.validateDate)) |
||||
|
return false; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,65 @@ |
|||||
|
package io.sc.engine.mv.jpa.entity.id; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class ScRocHistoryId implements Serializable{ |
||||
|
private static final long serialVersionUID = 4863037037512170910L; |
||||
|
private String validateDate; |
||||
|
private String modelId; |
||||
|
private Double scoreCutOffPoint; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
public Double getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
public void setScoreCutOffPoint(Double scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int hashCode() { |
||||
|
final int prime = 31; |
||||
|
int result = 1; |
||||
|
result = prime * result + ((modelId == null) ? 0 : modelId.hashCode()); |
||||
|
result = prime * result + ((scoreCutOffPoint == null) ? 0 : scoreCutOffPoint.hashCode()); |
||||
|
result = prime * result + ((validateDate == null) ? 0 : validateDate.hashCode()); |
||||
|
return result; |
||||
|
} |
||||
|
@Override |
||||
|
public boolean equals(Object obj) { |
||||
|
if (this == obj) |
||||
|
return true; |
||||
|
if (obj == null) |
||||
|
return false; |
||||
|
if (getClass() != obj.getClass()) |
||||
|
return false; |
||||
|
ScRocHistoryId other = (ScRocHistoryId) obj; |
||||
|
if (modelId == null) { |
||||
|
if (other.modelId != null) |
||||
|
return false; |
||||
|
} else if (!modelId.equals(other.modelId)) |
||||
|
return false; |
||||
|
if (scoreCutOffPoint == null) { |
||||
|
if (other.scoreCutOffPoint != null) |
||||
|
return false; |
||||
|
} else if (!scoreCutOffPoint.equals(other.scoreCutOffPoint)) |
||||
|
return false; |
||||
|
if (validateDate == null) { |
||||
|
if (other.validateDate != null) |
||||
|
return false; |
||||
|
} else if (!validateDate.equals(other.validateDate)) |
||||
|
return false; |
||||
|
return true; |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package io.sc.engine.mv.jpa.repository; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.RuntimeParameter; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
|
||||
|
public interface RuntimeParameterRepository extends DaoRepository<RuntimeParameter,String> { |
||||
|
public List<RuntimeParameter> findByValidateDateOrderBySno(String validateDate); |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
package io.sc.engine.mv.jpa.repository; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScCapHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScCapHistoryId; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
import org.springframework.data.domain.Page; |
||||
|
import org.springframework.data.domain.Pageable; |
||||
|
import org.springframework.data.jpa.repository.Query; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface ScCapHistoryRepository extends DaoRepository<ScCapHistory, ScCapHistoryId> { |
||||
|
/** |
||||
|
* 分页查询某个验证日期的所有历史区分能力CAP曲线指标 |
||||
|
* @param validateDate 验证日期 |
||||
|
* @param pageable 分页信息 |
||||
|
* @return 历史区分能力CAP曲线指标分页对象 |
||||
|
*/ |
||||
|
public Page<ScCapHistory> findAllByValidateDate(String validateDate,Pageable pageable); |
||||
|
|
||||
|
/** |
||||
|
* 获取CAP指标表中包含的所有不重复的验证日期 |
||||
|
* @return ROC指标表中包含的所有不重复的验证日期 |
||||
|
*/ |
||||
|
@Query("select distinct e.validateDate from ScCapHistory e order by e.validateDate desc") |
||||
|
public List<String> findDistinctValidateDates(); |
||||
|
|
||||
|
/** |
||||
|
* 获取CAP指标表中包含的所有不重复的模型标识和名称 |
||||
|
* @return ROC指标表中包含的所有不重复的模型标识和名称 |
||||
|
*/ |
||||
|
@Query("select e.modelId,max(e.modelName) from ScCapHistory e group by e.modelId") |
||||
|
public List<Object[]> findDistinctModelIdAndNames(); |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
package io.sc.engine.mv.jpa.repository; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScKsHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScKsHistoryId; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
import org.springframework.data.domain.Page; |
||||
|
import org.springframework.data.domain.Pageable; |
||||
|
import org.springframework.data.jpa.repository.Query; |
||||
|
|
||||
|
public interface ScKsHistoryRepository extends DaoRepository<ScKsHistory, ScKsHistoryId> { |
||||
|
/** |
||||
|
* 分页查询某个验证日期的所有历史区分能力KS曲线指标 |
||||
|
* @param validateDate 验证日期 |
||||
|
* @param pageable 分页信息 |
||||
|
* @return 历史区分能力KS曲线指标分页对象 |
||||
|
*/ |
||||
|
public Page<ScKsHistory> findAllByValidateDate(String validateDate,Pageable pageable); |
||||
|
|
||||
|
/** |
||||
|
* 获取KS指标表中包含的所有不重复的验证日期 |
||||
|
* @return ROC指标表中包含的所有不重复的验证日期 |
||||
|
*/ |
||||
|
@Query("select distinct e.validateDate from ScKsHistory e order by e.validateDate desc") |
||||
|
public List<String> findDistinctValidateDates(); |
||||
|
|
||||
|
/** |
||||
|
* 获取KS指标表中包含的所有不重复的模型标识和名称 |
||||
|
* @return ROC指标表中包含的所有不重复的模型标识和名称 |
||||
|
*/ |
||||
|
@Query("select e.modelId,max(e.modelName) from ScKsHistory e group by e.modelId") |
||||
|
public List<Object[]> findDistinctModelIdAndNames(); |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
package io.sc.engine.mv.jpa.repository; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScRocHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScRocHistoryId; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
import org.springframework.data.domain.Page; |
||||
|
import org.springframework.data.domain.Pageable; |
||||
|
import org.springframework.data.jpa.repository.Query; |
||||
|
|
||||
|
public interface ScRocHistoryRepository extends DaoRepository<ScRocHistory, ScRocHistoryId> { |
||||
|
/** |
||||
|
* 分页查询某个验证日期的所有历史区分能力ROC曲线指标 |
||||
|
* @param validateDate 验证日期 |
||||
|
* @param pageable 分页信息 |
||||
|
* @return 历史区分能力ROC曲线指标分页对象 |
||||
|
*/ |
||||
|
public Page<ScRocHistory> findAllByValidateDate(String validateDate,Pageable pageable); |
||||
|
|
||||
|
/** |
||||
|
* 获取ROC指标表中包含的所有不重复的验证日期 |
||||
|
* @return ROC指标表中包含的所有不重复的验证日期 |
||||
|
*/ |
||||
|
@Query("select distinct e.validateDate from ScRocHistory e order by e.validateDate desc") |
||||
|
public List<String> findDistinctValidateDates(); |
||||
|
|
||||
|
/** |
||||
|
* 获取ROC指标表中包含的所有不重复的模型标识和名称 |
||||
|
* @return ROC指标表中包含的所有不重复的模型标识和名称 |
||||
|
*/ |
||||
|
@Query("select e.modelId,max(e.modelName) from ScRocHistory e group by e.modelId") |
||||
|
public List<Object[]> findDistinctModelIdAndNames(); |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
package io.sc.engine.mv.sc.echarts; |
||||
|
|
||||
|
public class ScValidateResult4Echarts { |
||||
|
private double auc; |
||||
|
private double ar; |
||||
|
private double ks; |
||||
|
private Coordinates coordinates; |
||||
|
|
||||
|
public double getAuc() { |
||||
|
return auc; |
||||
|
} |
||||
|
public void setAuc(double auc) { |
||||
|
this.auc = auc; |
||||
|
} |
||||
|
public double getAr() { |
||||
|
return ar; |
||||
|
} |
||||
|
public void setAr(double ar) { |
||||
|
this.ar = ar; |
||||
|
} |
||||
|
public double getKs() { |
||||
|
return ks; |
||||
|
} |
||||
|
public void setKs(double ks) { |
||||
|
this.ks = ks; |
||||
|
} |
||||
|
public Coordinates getCoordinates() { |
||||
|
return coordinates; |
||||
|
} |
||||
|
public void setCoordinates(Coordinates coordinates) { |
||||
|
this.coordinates = coordinates; |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package io.sc.engine.mv.service.sc; |
||||
|
|
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScCapHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScCapHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.ScCapHistoryRepository; |
||||
|
import io.sc.platform.orm.service.DaoService; |
||||
|
|
||||
|
public interface ScCapHistoryService extends DaoService<ScCapHistory, ScCapHistoryId, ScCapHistoryRepository> { |
||||
|
|
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package io.sc.engine.mv.service.sc; |
||||
|
|
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScKsHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScKsHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.ScKsHistoryRepository; |
||||
|
import io.sc.platform.orm.service.DaoService; |
||||
|
|
||||
|
public interface ScKsHistoryService extends DaoService<ScKsHistory, ScKsHistoryId, ScKsHistoryRepository> { |
||||
|
|
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package io.sc.engine.mv.service.sc; |
||||
|
|
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScRocHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScRocHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.ScRocHistoryRepository; |
||||
|
import io.sc.platform.orm.service.DaoService; |
||||
|
|
||||
|
public interface ScRocHistoryService extends DaoService<ScRocHistory, ScRocHistoryId, ScRocHistoryRepository> { |
||||
|
|
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package io.sc.engine.mv.service.sc.impl; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScCapHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScCapHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.ScCapHistoryRepository; |
||||
|
import io.sc.engine.mv.service.sc.ScCapHistoryService; |
||||
|
import io.sc.platform.orm.service.impl.DaoServiceImpl; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
@Service |
||||
|
public class ScCapHistoryServiceImpl extends DaoServiceImpl<ScCapHistory, ScCapHistoryId, ScCapHistoryRepository> implements ScCapHistoryService { |
||||
|
|
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package io.sc.engine.mv.service.sc.impl; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScKsHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScKsHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.ScKsHistoryRepository; |
||||
|
import io.sc.engine.mv.service.sc.ScKsHistoryService; |
||||
|
import io.sc.platform.orm.service.impl.DaoServiceImpl; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
@Service |
||||
|
public class ScKsHistoryServiceImpl extends DaoServiceImpl<ScKsHistory, ScKsHistoryId, ScKsHistoryRepository> implements ScKsHistoryService { |
||||
|
|
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package io.sc.engine.mv.service.sc.impl; |
||||
|
|
||||
|
import io.sc.engine.mv.jpa.entity.ScRocHistory; |
||||
|
import io.sc.engine.mv.jpa.entity.id.ScRocHistoryId; |
||||
|
import io.sc.engine.mv.jpa.repository.ScRocHistoryRepository; |
||||
|
import io.sc.engine.mv.service.sc.ScRocHistoryService; |
||||
|
import io.sc.platform.orm.service.impl.DaoServiceImpl; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
@Service |
||||
|
public class ScRocHistoryServiceImpl extends DaoServiceImpl<ScRocHistory, ScRocHistoryId, ScRocHistoryRepository> implements ScRocHistoryService { |
||||
|
|
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
package io.sc.engine.mv.vo; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
|
||||
|
public class RuntimeParameterVo extends BaseVo { |
||||
|
private String validateDate; |
||||
|
private String name; |
||||
|
private String value; |
||||
|
private Integer sno; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getValue() { |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
public void setValue(String value) { |
||||
|
this.value = value; |
||||
|
} |
||||
|
|
||||
|
public Integer getSno() { |
||||
|
return sno; |
||||
|
} |
||||
|
|
||||
|
public void setSno(Integer sno) { |
||||
|
this.sno = sno; |
||||
|
} |
||||
|
} |
@ -0,0 +1,99 @@ |
|||||
|
package io.sc.engine.mv.vo; |
||||
|
|
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
public class ScCapHistoryVo extends BaseVo { |
||||
|
private String validateDate; |
||||
|
private String modelId; |
||||
|
private String modelName; |
||||
|
private Integer scoreCutOffPoint; |
||||
|
private Integer ts; |
||||
|
private Integer tt; |
||||
|
private Integer tds; |
||||
|
private Integer tdt; |
||||
|
private BigDecimal x; |
||||
|
private BigDecimal y; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
|
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
|
||||
|
public String getModelName() { |
||||
|
return modelName; |
||||
|
} |
||||
|
|
||||
|
public void setModelName(String modelName) { |
||||
|
this.modelName = modelName; |
||||
|
} |
||||
|
|
||||
|
public Integer getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public void setScoreCutOffPoint(Integer scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public Integer getTs() { |
||||
|
return ts; |
||||
|
} |
||||
|
|
||||
|
public void setTs(Integer ts) { |
||||
|
this.ts = ts; |
||||
|
} |
||||
|
|
||||
|
public Integer getTt() { |
||||
|
return tt; |
||||
|
} |
||||
|
|
||||
|
public void setTt(Integer tt) { |
||||
|
this.tt = tt; |
||||
|
} |
||||
|
|
||||
|
public Integer getTds() { |
||||
|
return tds; |
||||
|
} |
||||
|
|
||||
|
public void setTds(Integer tds) { |
||||
|
this.tds = tds; |
||||
|
} |
||||
|
|
||||
|
public Integer getTdt() { |
||||
|
return tdt; |
||||
|
} |
||||
|
|
||||
|
public void setTdt(Integer tdt) { |
||||
|
this.tdt = tdt; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getX() { |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
public void setX(BigDecimal x) { |
||||
|
this.x = x; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY() { |
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
public void setY(BigDecimal y) { |
||||
|
this.y = y; |
||||
|
} |
||||
|
} |
@ -0,0 +1,98 @@ |
|||||
|
package io.sc.engine.mv.vo; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
public class ScKsHistoryVo extends BaseVo { |
||||
|
private String validateDate; |
||||
|
private String modelId; |
||||
|
private String modelName; |
||||
|
private Integer scoreCutOffPoint; |
||||
|
private Integer n; |
||||
|
private Integer tn; |
||||
|
private Integer d; |
||||
|
private Integer td; |
||||
|
private BigDecimal y1; |
||||
|
private BigDecimal y2; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
|
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
|
||||
|
public String getModelName() { |
||||
|
return modelName; |
||||
|
} |
||||
|
|
||||
|
public void setModelName(String modelName) { |
||||
|
this.modelName = modelName; |
||||
|
} |
||||
|
|
||||
|
public Integer getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public void setScoreCutOffPoint(Integer scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public Integer getN() { |
||||
|
return n; |
||||
|
} |
||||
|
|
||||
|
public void setN(Integer n) { |
||||
|
this.n = n; |
||||
|
} |
||||
|
|
||||
|
public Integer getTn() { |
||||
|
return tn; |
||||
|
} |
||||
|
|
||||
|
public void setTn(Integer tn) { |
||||
|
this.tn = tn; |
||||
|
} |
||||
|
|
||||
|
public Integer getD() { |
||||
|
return d; |
||||
|
} |
||||
|
|
||||
|
public void setD(Integer d) { |
||||
|
this.d = d; |
||||
|
} |
||||
|
|
||||
|
public Integer getTd() { |
||||
|
return td; |
||||
|
} |
||||
|
|
||||
|
public void setTd(Integer td) { |
||||
|
this.td = td; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY1() { |
||||
|
return y1; |
||||
|
} |
||||
|
|
||||
|
public void setY1(BigDecimal y1) { |
||||
|
this.y1 = y1; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY2() { |
||||
|
return y2; |
||||
|
} |
||||
|
|
||||
|
public void setY2(BigDecimal y2) { |
||||
|
this.y2 = y2; |
||||
|
} |
||||
|
} |
@ -0,0 +1,116 @@ |
|||||
|
package io.sc.engine.mv.vo; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
public class ScRocHistoryVo extends BaseVo { |
||||
|
private String validateDate; |
||||
|
private String modelId; |
||||
|
private String modelName; |
||||
|
private Double scoreCutOffPoint; |
||||
|
private Integer dd; |
||||
|
private Integer dn; |
||||
|
private Integer nd; |
||||
|
private Integer nn; |
||||
|
private Integer td; |
||||
|
private Integer tn; |
||||
|
private BigDecimal x; |
||||
|
private BigDecimal y; |
||||
|
|
||||
|
public String getValidateDate() { |
||||
|
return validateDate; |
||||
|
} |
||||
|
|
||||
|
public void setValidateDate(String validateDate) { |
||||
|
this.validateDate = validateDate; |
||||
|
} |
||||
|
|
||||
|
public String getModelId() { |
||||
|
return modelId; |
||||
|
} |
||||
|
|
||||
|
public void setModelId(String modelId) { |
||||
|
this.modelId = modelId; |
||||
|
} |
||||
|
|
||||
|
public String getModelName() { |
||||
|
return modelName; |
||||
|
} |
||||
|
|
||||
|
public void setModelName(String modelName) { |
||||
|
this.modelName = modelName; |
||||
|
} |
||||
|
|
||||
|
public Double getScoreCutOffPoint() { |
||||
|
return scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public void setScoreCutOffPoint(Double scoreCutOffPoint) { |
||||
|
this.scoreCutOffPoint = scoreCutOffPoint; |
||||
|
} |
||||
|
|
||||
|
public Integer getDd() { |
||||
|
return dd; |
||||
|
} |
||||
|
|
||||
|
public void setDd(Integer dd) { |
||||
|
this.dd = dd; |
||||
|
} |
||||
|
|
||||
|
public Integer getDn() { |
||||
|
return dn; |
||||
|
} |
||||
|
|
||||
|
public void setDn(Integer dn) { |
||||
|
this.dn = dn; |
||||
|
} |
||||
|
|
||||
|
public Integer getNd() { |
||||
|
return nd; |
||||
|
} |
||||
|
|
||||
|
public void setNd(Integer nd) { |
||||
|
this.nd = nd; |
||||
|
} |
||||
|
|
||||
|
public Integer getNn() { |
||||
|
return nn; |
||||
|
} |
||||
|
|
||||
|
public void setNn(Integer nn) { |
||||
|
this.nn = nn; |
||||
|
} |
||||
|
|
||||
|
public Integer getTd() { |
||||
|
return td; |
||||
|
} |
||||
|
|
||||
|
public void setTd(Integer td) { |
||||
|
this.td = td; |
||||
|
} |
||||
|
|
||||
|
public Integer getTn() { |
||||
|
return tn; |
||||
|
} |
||||
|
|
||||
|
public void setTn(Integer tn) { |
||||
|
this.tn = tn; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getX() { |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
public void setX(BigDecimal x) { |
||||
|
this.x = x; |
||||
|
} |
||||
|
|
||||
|
public BigDecimal getY() { |
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
public void setY(BigDecimal y) { |
||||
|
this.y = y; |
||||
|
} |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
import groovy.sql.Sql; |
||||
|
|
||||
|
/** |
||||
|
* 以下预定义变量可以直接在脚本中使用: |
||||
|
* 1. dataExtractor: 数据抽取器配置对象,通过该对象可获取本数据抽取器的配置信息 |
||||
|
* 2. runtimeContext: 模型验证执行时的执行上下文对象,通过该对象可获取模型验证执行时的相关参数 |
||||
|
* 3. applicationContext: spring 应用上下文 |
||||
|
* 4. defaultDataSource: 应用默认数据源 |
||||
|
* 5. dataSource: 本数据抽取器配置的外部数据源 |
||||
|
**/ |
||||
|
|
||||
|
//定义获取评分记录数据的查询SQL语句 |
||||
|
/* ----------------通常以下部分为客户定制部分---------------- */ |
||||
|
def query =""" |
||||
|
select |
||||
|
'客户唯一标识' as FD_CUSTOM_ID, /*客户唯一标识*/ |
||||
|
null as FD_DEFAULT_CONFIRM_DATE /*违约认定日期*/ |
||||
|
from MV_DEFAULT_RECORD |
||||
|
"""; |
||||
|
/* --------------------客户定制部分结束--------------------- */ |
||||
|
|
||||
|
//定义插入到评分记录表的 SQL 语句 |
||||
|
def insert =""" |
||||
|
insert into MV_DEFAULT_RECORD( |
||||
|
FD_CUSTOM_ID, |
||||
|
FD_DEFAULT_CONFIRM_DATE |
||||
|
) values (?,?) |
||||
|
"""; |
||||
|
|
||||
|
//首先删除评级记录表的历史数据 |
||||
|
def defaultSql = new Sql(defaultDataSource); |
||||
|
defaultSql.execute("delete from MV_DEFAULT_RECORD"); |
||||
|
|
||||
|
//从数据抽取器配置的数据源中获取相关数据 |
||||
|
def Sql =new Sql(dataSource); |
||||
|
defaultSql.withBatch(5000,insert){ps -> |
||||
|
Sql.eachRow(query){ row -> |
||||
|
ps.addBatch([row['FD_CUSTOM_ID'],row['FD_DEFAULT_CONFIRM_DATE']]); |
||||
|
} |
||||
|
} |
@ -0,0 +1,70 @@ |
|||||
|
import groovy.sql.Sql; |
||||
|
|
||||
|
/** |
||||
|
* 以下预定义变量可以直接在脚本中使用: |
||||
|
* 1. dataExtractor: 数据抽取器配置对象,通过该对象可获取本数据抽取器的配置信息 |
||||
|
* 2. runtimeContext: 模型验证执行时的执行上下文对象,通过该对象可获取模型验证执行时的相关参数 |
||||
|
* 3. applicationContext: spring 应用上下文 |
||||
|
* 4. defaultDataSource: 应用默认数据源 |
||||
|
* 5. dataSource: 本数据抽取器配置的外部数据源 |
||||
|
**/ |
||||
|
|
||||
|
//定义获取评分记录数据的查询SQL语句 |
||||
|
/* ----------------通常以下部分为客户定制部分---------------- */ |
||||
|
def query =""" |
||||
|
select |
||||
|
'客户唯一标识' as FD_CUSTOM_ID, /*客户唯一标识*/ |
||||
|
'客户名称' as FD_CUSTOM_NAME, /*客户名称*/ |
||||
|
'评级模型标识' as FD_MODEL_ID, /*评级模型标识*/ |
||||
|
'评级模型名称' as FD_MODEL_NAME, /*评级模型名称*/ |
||||
|
0.6 as FD_PD, /*评级结果(违约概率)*/ |
||||
|
50 as FD_SCORE, /*评级结果(总体得分)*/ |
||||
|
30 as FD_SCORE_QUANTITATIVE, /*评级结果(定量部分得分)*/ |
||||
|
20 as FD_SCORE_QUALITATIVE, /*评级结果(定性部分得分)*/ |
||||
|
'8' as FD_LEVEL, /*评级结果(等级)*/ |
||||
|
null as FD_SCORE_BEGIN_DATE, /*评级有效期开始日期*/ |
||||
|
null as FD_SCORE_END_DATE /*评级有效期结束日期*/ |
||||
|
from MV_SCORE_RECORD |
||||
|
"""; |
||||
|
/* --------------------客户定制部分结束--------------------- */ |
||||
|
|
||||
|
//定义插入到评分记录表的 SQL 语句 |
||||
|
def insert =""" |
||||
|
insert into MV_SCORE_RECORD( |
||||
|
FD_CUSTOM_ID, |
||||
|
FD_CUSTOM_NAME, |
||||
|
FD_MODEL_ID, |
||||
|
FD_MODEL_NAME, |
||||
|
FD_PD, |
||||
|
FD_SCORE, |
||||
|
FD_SCORE_QUANTITATIVE, |
||||
|
FD_SCORE_QUALITATIVE, |
||||
|
FD_LEVEL, |
||||
|
FD_SCORE_BEGIN_DATE, |
||||
|
FD_SCORE_END_DATE |
||||
|
) values (?,?,?,?,?,?,?,?,?,?,?) |
||||
|
"""; |
||||
|
|
||||
|
//首先删除评级记录表的历史数据 |
||||
|
def defaultSql = new Sql(defaultDataSource); |
||||
|
defaultSql.execute("delete from MV_SCORE_RECORD"); |
||||
|
|
||||
|
//从数据抽取器配置的数据源中获取相关数据 |
||||
|
def Sql =new Sql(dataSource); |
||||
|
defaultSql.withBatch(5000,insert){ps -> |
||||
|
Sql.eachRow(query){ row -> |
||||
|
ps.addBatch([ |
||||
|
row['FD_CUSTOM_ID'], |
||||
|
row['FD_CUSTOM_NAME'], |
||||
|
row['FD_MODEL_ID'], |
||||
|
row['FD_MODEL_NAME'], |
||||
|
row['FD_PD'], |
||||
|
row['FD_SCORE'], |
||||
|
row['FD_SCORE_QUANTITATIVE'], |
||||
|
row['FD_SCORE_QUALITATIVE'], |
||||
|
row['FD_LEVEL'], |
||||
|
row['FD_SCORE_BEGIN_DATE'], |
||||
|
row['FD_SCORE_END_DATE'] |
||||
|
]); |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package io.sc.platform.core.enums; |
||||
|
|
||||
|
public enum RoundingMode { |
||||
|
UP, |
||||
|
DOWN, |
||||
|
CEILING, |
||||
|
FLOOR, |
||||
|
HALF_UP, |
||||
|
HALF_DOWN, |
||||
|
HALF_EVEN; |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
package io.sc.platform.data.csv; |
||||
|
|
||||
|
public class Record { |
||||
|
private RecordMapper mapper; |
||||
|
private Object[] values; |
||||
|
|
||||
|
public Record(RecordMapper mapper, Object[] values){ |
||||
|
this.mapper =mapper; |
||||
|
this.values =values; |
||||
|
} |
||||
|
|
||||
|
public Object get(String name){ |
||||
|
return values[mapper.getIndex(name)]; |
||||
|
} |
||||
|
|
||||
|
public <T> T get(String name,Class<T> clazz){ |
||||
|
return mapper.getConversionService().convert(values[mapper.getIndex(name)],clazz); |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
package io.sc.platform.data.csv; |
||||
|
|
||||
|
import org.springframework.core.convert.ConversionService; |
||||
|
import org.springframework.core.convert.support.DefaultConversionService; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
public class RecordMapper { |
||||
|
private ConversionService conversionService =DefaultConversionService.getSharedInstance(); |
||||
|
private Map<String,Integer> mapping =new HashMap<>(); |
||||
|
|
||||
|
public RecordMapper addMapping(String name, int index){ |
||||
|
mapping.put(name,index); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public int getIndex(String name){ |
||||
|
return mapping.get(name); |
||||
|
} |
||||
|
|
||||
|
public ConversionService getConversionService() { |
||||
|
return conversionService; |
||||
|
} |
||||
|
|
||||
|
public void setConversionService(ConversionService conversionService) { |
||||
|
this.conversionService = conversionService; |
||||
|
} |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
package io.sc.platform.orm.service.support; |
||||
|
|
||||
|
import java.util.Comparator; |
||||
|
|
||||
|
public interface QueryResultSorter<T> { |
||||
|
public Comparator<T> getComparator(String propertyName,boolean isAscending); |
||||
|
} |
Loading…
Reference in new issue