Explorar o código

1.接入主诉现病史症状相似度算法接口
2.主诊断与主诉不符 BEH0002 添加相似度算法
3.规则修改逻辑

hujing %!s(int64=5) %!d(string=hai) anos
pai
achega
0907742683

+ 43 - 22
kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0002.java

@@ -1,6 +1,10 @@
 package com.lantone.qc.kernel.catalogue.behospitalized;
 
+import com.alibaba.fastjson.JSONArray;
+import com.google.common.collect.Lists;
 import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.client.ChiefPresentSimilarityServiceClient;
+import com.lantone.qc.kernel.structure.ai.ModelAI;
 import com.lantone.qc.kernel.util.KernelConstants;
 import com.lantone.qc.kernel.util.RedisUtil;
 import com.lantone.qc.pub.model.InputInfo;
@@ -11,7 +15,6 @@ import com.lantone.qc.pub.model.entity.Diag;
 import com.lantone.qc.pub.model.label.ChiefLabel;
 import com.lantone.qc.pub.model.label.DiagLabel;
 import com.lantone.qc.pub.util.StringUtil;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -29,6 +32,8 @@ import java.util.Map;
 public class BEH0002 extends QCCatalogue {
     @Autowired
     private RedisUtil redisUtil;
+    @Autowired
+    ChiefPresentSimilarityServiceClient chiefPresentSimilarityServiceClient;
 
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         BeHospitalizedDoc beHospitalizedDoc = inputInfo.getBeHospitalizedDoc();
@@ -65,40 +70,56 @@ public class BEH0002 extends QCCatalogue {
             String firstHDiag = diags.get(0).getHospitalDiagName();
             String mainDiag = StringUtil.isBlank(firstHDiag) ? firstDiag : firstHDiag;
             List<String> symptoms = null;
-//            Map<String, String> hostpital_standDiag = redisUtil.getJsonStringValue(KernelConstants.HOSPITAL_DIAG_MAP);
-//            if (!hostpital_standDiag.containsKey(mainDiag)) {
-//                status.set("0");
-//                return;
-//            }
+            //Map<String, String> hostpital_standDiag = redisUtil.getJsonStringValue(KernelConstants.HOSPITAL_DIAG_MAP);
+            //if (!hostpital_standDiag.containsKey(mainDiag)) {
+            //    status.set("0");
+            //    return;
+            //}
             Map<String, Map<String, Object>> diagMap = redisUtil.getJsonStringValue(KernelConstants.CONCEPT_DIAG_PROPERTY_MAP);
             Map<String, Object> map = (Map<String, Object>) diagMap.get(mainDiag);
             if (map != null && map.size() > 0) {
                 symptoms = (List<String>) map.get("symptoms");
             }
-            if (symptoms == null){
+            if (symptoms == null) {
                 status.set("0");
                 return;
             }
             List<Clinical> clinicals = inputInfo.getBeHospitalizedDoc().getChiefLabel().getClinicals();
             if (clinicals != null && clinicals.size() > 0) {
                 String firstClinical = clinicals.get(0).getName();
-                if (symptoms.contains(firstClinical)) {
-                    status.set("0");
+                /* 主诉现病史相似度算法接口 */
+                ModelAI modelAI = new ModelAI();
+                JSONArray jsonArray = modelAI.loadChiefPresentSimilarAI(firstClinical, symptoms, false, chiefPresentSimilarityServiceClient);
+                if (jsonArray.size() == 2) {
+                    /* 相似度最高症状 */
+                    String symptom = jsonArray.getString(0);
+                    /* 相似度分数 */
+                    double likeRate = jsonArray.getDoubleValue(1);
+                    if (likeRate > 0.9) {
+                        status.set("0");
+                    } else {
+                        status.set("-1");
+                        info.set(symptom);
+                    }
                 }
-//                for (Clinical clinical : clinicals) {
-//                    String clinicalName = clinical.getName();
-//                    if (symptoms != null && !symptoms.contains(clinicalName)) {
-//                        if (StringUtils.isEmpty(info.get())) {
-//                            info.set(clinicalName);
-//                        } else {
-//                            info.set(info.get() + "," + clinicalName);
-//                        }
-//                    }
-//                }
+
+                //if (symptoms.contains(firstClinical)) {
+                //    status.set("0");
+                //}
+                //for (Clinical clinical : clinicals) {
+                //    String clinicalName = clinical.getName();
+                //    if (symptoms != null && !symptoms.contains(clinicalName)) {
+                //        if (StringUtils.isEmpty(info.get())) {
+                //            info.set(clinicalName);
+                //        } else {
+                //            info.set(info.get() + "," + clinicalName);
+                //        }
+                //    }
+                //}
             }
-//            if (StringUtils.isEmpty(info.get())) {
-            //                status.set("0");
-            //            }
+            //if (StringUtils.isEmpty(info.get())) {
+            //    status.set("0");
+            //}
         }
     }
 }

+ 11 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0074.java

@@ -3,6 +3,7 @@ package com.lantone.qc.kernel.catalogue.behospitalized;
 import com.lantone.qc.kernel.catalogue.QCCatalogue;
 import com.lantone.qc.pub.model.InputInfo;
 import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.entity.Diag;
 import com.lantone.qc.pub.model.entity.Family;
 import com.lantone.qc.pub.model.label.FamilyLabel;
 import com.lantone.qc.pub.util.ListUtil;
@@ -37,7 +38,17 @@ public class BEH0074 extends QCCatalogue {
         for (Family family : families) {
             if (family.getTumour() != null) {
                 status.set("0");
+                return;
             }
+            for (Diag diag : family.getDiags()) {
+                if (diag.getNegative() == null &&
+                        (diag.getHospitalDiagName().contains("肿瘤") || diag.getHospitalDiagName().contains("癌"))) {
+                    status.set("0");
+                    return;
+                }
+            }
+
         }
+
     }
 }

+ 20 - 18
kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0082.java

@@ -22,26 +22,28 @@ public class BEH0082 extends QCCatalogue {
             status.set("0");
             return;
         }
-        if (inputInfo.getBeHospitalizedDoc().getPacsLabel() != null) {
-            if (inputInfo.getBeHospitalizedDoc().getPacsLabel().getPacses() == null) {
-                status.set("0");
-                return;
-            }
-            int outerCourtyardObjNum = 0;
-            for (Pacs pacs : inputInfo.getBeHospitalizedDoc().getPacsLabel().getPacses()) {
-                if (pacs.getOuterCourtyard() == null) {
-                    outerCourtyardObjNum++;
-                } else {
-                    OuterCourtyard outerCourtyard = pacs.getOuterCourtyard();
-                    if (outerCourtyard.getPd().size() > 0 && StringUtil.isNotBlank(outerCourtyard.getPacsValue().getName())) {
-                        status.set("0");
-                        break;
-                    }
+        if (inputInfo.getBeHospitalizedDoc().getPacsLabel() == null) {
+            status.set("0");
+            return;
+        }
+        if (inputInfo.getBeHospitalizedDoc().getPacsLabel().getPacses() == null) {
+            status.set("0");
+            return;
+        }
+        int outerCourtyardObjNum = 0;
+        for (Pacs pacs : inputInfo.getBeHospitalizedDoc().getPacsLabel().getPacses()) {
+            if (pacs.getOuterCourtyard() == null) {
+                outerCourtyardObjNum++;
+            } else {
+                OuterCourtyard outerCourtyard = pacs.getOuterCourtyard();
+                if (outerCourtyard.getPd().size() > 0 && StringUtil.isNotBlank(outerCourtyard.getPacsValue().getName())) {
+                    status.set("0");
+                    break;
                 }
             }
-            if (outerCourtyardObjNum == inputInfo.getBeHospitalizedDoc().getPacsLabel().getPacses().size()) {
-                status.set("0");
-            }
+        }
+        if (outerCourtyardObjNum == inputInfo.getBeHospitalizedDoc().getPacsLabel().getPacses().size()) {
+            status.set("0");
         }
     }
 }

+ 23 - 0
kernel/src/main/java/com/lantone/qc/kernel/client/ChiefPresentSimilarityServiceClient.java

@@ -0,0 +1,23 @@
+package com.lantone.qc.kernel.client;
+
+
+import com.lantone.qc.pub.model.vo.ChiefPresentSimilarityVo;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+
+/**
+ * @Description: 调用主诉现病史症状相似度服务
+ * @author: 胡敬
+ * @time: 2020/06/01 15:41
+ */
+@FeignClient(value = "ChiefPresentSimilarity-service", url="${ChiefPresentSimilarity.url}")
+public interface ChiefPresentSimilarityServiceClient {
+
+    @PostMapping(value = "")
+    String getAnnotation(@RequestBody ChiefPresentSimilarityVo chiefPresentSimilarityVo);
+}
+
+
+

+ 4 - 1
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/BeHospitalizedAI.java

@@ -67,7 +67,10 @@ public class BeHospitalizedAI extends ModelAI {
             //专科体格检查
             String vitalSpecial_text = beHospitalizedDoc.getVitalLabelSpecial().getText();
             if (beHospitalizedDoc.getChiefLabel().isCrfLabel()) {
-                putContent(crfContent, medicalTextType.get(3), chief_text, Content.chief);  //主诉
+                if (StringUtil.isNotBlank(chief_text)) {
+                    chief_text = StringUtil.removeBlank(chief_text);
+                    putContent(crfContent, medicalTextType.get(3), chief_text, Content.chief);  //主诉
+                }
             }
             if (beHospitalizedDoc.getPresentLabel().isCrfLabel()) {
                 putContent(crfContent, medicalTextType.get(7), present_text, Content.present);//现病史

+ 114 - 40
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/ModelAI.java

@@ -4,13 +4,18 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.lantone.qc.kernel.client.CRFServiceClient;
+import com.lantone.qc.kernel.client.ChiefPresentSimilarityServiceClient;
 import com.lantone.qc.kernel.client.SimilarityServiceClient;
 import com.lantone.qc.kernel.util.CatalogueUtil;
 import com.lantone.qc.pub.model.entity.Annotation;
+import com.lantone.qc.pub.model.entity.ChiefPresentAnnotation;
 import com.lantone.qc.pub.model.vo.CRFVo;
+import com.lantone.qc.pub.model.vo.ChiefPresentSimilarityVo;
 import com.lantone.qc.pub.model.vo.SimilarityVo;
 import com.lantone.qc.pub.util.StringUtil;
 
+import java.util.List;
+
 /**
  * @ClassName : ModelAI
  * @Description : 算法基类
@@ -35,22 +40,6 @@ public class ModelAI {
         return midData;
     }
 
-    /**
-     * 获取文本相似度返回数据
-     *
-     * @param similarContent
-     * @param similarityServiceClient
-     * @return
-     */
-    public double loadSimilarAI(JSONArray similarContent, SimilarityServiceClient similarityServiceClient) {
-        //存储CRF完整所需结构数据
-        SimilarityVo similarityVo = new SimilarityVo();
-        similarityVo.setData(similarContent);
-        //获取CRF模型返回数据
-        JSONArray data = getAnnotation(similarityServiceClient, similarityVo).getData();
-        return getSimilarOutputs(data);
-    }
-
     protected JSONObject loadEntity(JSONObject jsonObject, String entityRelationObject, String outputs, String content) {
         if (jsonObject == null) {
             return new JSONObject();
@@ -72,18 +61,6 @@ public class ModelAI {
         }
     }
 
-    private Annotation getAnnotation(SimilarityServiceClient similarityServiceClient, SimilarityVo similarityVo) {
-        Annotation annotation = new Annotation();
-        try {
-            String annotation_str = similarityServiceClient.getAnnotation(similarityVo);
-            annotation = JSON.parseObject(annotation_str, Annotation.class);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-        } finally {
-            return annotation;
-        }
-    }
-
     protected void putContent(JSONArray crfContent, String medicalTextType, String text, String sign) {
         String move_text = CatalogueUtil.removeSpecialChar(text);
         if (StringUtil.isEmpty(move_text)) {
@@ -109,6 +86,26 @@ public class ModelAI {
         crfContent.add(detailContent);
     }
 
+    /**
+     * 获取CRF模型输出并处理
+     *
+     * @param data
+     * @return
+     */
+    public JSONObject getOutputs(JSONArray data) {
+        JSONObject midData = new JSONObject();
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject detailContent = data.getJSONObject(i);
+            String detail_title = detailContent.getString("detail_title");
+            if (StringUtil.isNotEmpty(detail_title) && midData.get(detail_title) == null) {
+                midData.put(detail_title, detailContent);
+            }
+        }
+        return midData;
+    }
+
+    /*****************************文本相似度算法************************************/
+
     /**
      * 存放文本相似度入参内容
      *
@@ -128,22 +125,32 @@ public class ModelAI {
         similarContent.add(detailContent);
     }
 
+    private Annotation getAnnotation(SimilarityServiceClient similarityServiceClient, SimilarityVo similarityVo) {
+        Annotation annotation = new Annotation();
+        try {
+            String annotation_str = similarityServiceClient.getAnnotation(similarityVo);
+            annotation = JSON.parseObject(annotation_str, Annotation.class);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            return annotation;
+        }
+    }
+
     /**
-     * 获取CRF模型输出并处理
+     * 获取文本相似度返回数据
      *
-     * @param data
+     * @param similarContent
+     * @param similarityServiceClient
      * @return
      */
-    public JSONObject getOutputs(JSONArray data) {
-        JSONObject midData = new JSONObject();
-        for (int i = 0; i < data.size(); i++) {
-            JSONObject detailContent = data.getJSONObject(i);
-            String detail_title = detailContent.getString("detail_title");
-            if (StringUtil.isNotEmpty(detail_title) && midData.get(detail_title) == null) {
-                midData.put(detail_title, detailContent);
-            }
-        }
-        return midData;
+    public double loadSimilarAI(JSONArray similarContent, SimilarityServiceClient similarityServiceClient) {
+        //存储CRF完整所需结构数据
+        SimilarityVo similarityVo = new SimilarityVo();
+        similarityVo.setData(similarContent);
+        //获取CRF模型返回数据
+        JSONArray data = getAnnotation(similarityServiceClient, similarityVo).getData();
+        return getSimilarOutputs(data);
     }
 
     /**
@@ -160,4 +167,71 @@ public class ModelAI {
         }
         return likeRate;
     }
+    /*****************************主诉现病史症状文本相似度算法************************************/
+
+    /**
+     * 存放主诉现病史症状文本相似度入参内容
+     */
+    public void putContent(JSONObject similarContent, String firstText, List<String> clinicArr) {
+        if (StringUtil.isEmpty(firstText) || clinicArr.size() == 0) {
+            return;
+        }
+        similarContent.put("string1", firstText);
+        similarContent.put("string2", clinicArr);
+    }
+
+    /**
+     * 获取主诉现病史症状相似度返回数据
+     *
+     * @param string1
+     * @param string2
+     * @param chiefPresentSimilarityServiceClient
+     * @return
+     */
+    public JSONArray loadChiefPresentSimilarAI(String string1, List<String> string2, boolean directionCheck
+            , ChiefPresentSimilarityServiceClient chiefPresentSimilarityServiceClient) {
+        //存储CRF完整所需结构数据
+        ChiefPresentSimilarityVo similarityVo = new ChiefPresentSimilarityVo();
+        JSONObject data = new JSONObject();
+        putContent(data, string1, string2);
+        similarityVo.setData(data);
+        similarityVo.setDirection_check(directionCheck);
+        //获取CRF模型返回数据
+        JSONArray predY = getAnnotation(chiefPresentSimilarityServiceClient, similarityVo).getPred_y();
+        return getChiefPresentSimilarOutputs(predY);
+    }
+
+    /**
+     * 主诉现病史相似度接口返回
+     *
+     * @param chiefPresentSimilarityServiceClient
+     * @param chiefPresentSimilarityVo
+     * @return
+     */
+    private ChiefPresentAnnotation getAnnotation(ChiefPresentSimilarityServiceClient chiefPresentSimilarityServiceClient,
+                                                 ChiefPresentSimilarityVo chiefPresentSimilarityVo) {
+        ChiefPresentAnnotation annotation = new ChiefPresentAnnotation();
+        try {
+            String annotation_str = chiefPresentSimilarityServiceClient.getAnnotation(chiefPresentSimilarityVo);
+            annotation = JSON.parseObject(annotation_str, ChiefPresentAnnotation.class);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            return annotation;
+        }
+    }
+
+    /**
+     * 获取主诉现病史文本相似度模型输出并处理
+     *
+     * @param predY
+     * @return
+     */
+    public JSONArray getChiefPresentSimilarOutputs(JSONArray predY) {
+        JSONArray dataArr = new JSONArray();
+        if (predY.size() > 0) {
+            dataArr = predY.getJSONArray(0);
+        }
+        return dataArr;
+    }
 }

+ 18 - 0
public/src/main/java/com/lantone/qc/pub/model/entity/ChiefPresentAnnotation.java

@@ -0,0 +1,18 @@
+package com.lantone.qc.pub.model.entity;
+
+
+import com.alibaba.fastjson.JSONArray;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @Description:主诉现病史症状相似度算法
+ * @time: 2020-06-01
+ */
+
+@Getter
+@Setter
+public class ChiefPresentAnnotation {
+    private JSONArray pred_y;
+    private boolean status;
+}

+ 12 - 0
public/src/main/java/com/lantone/qc/pub/model/vo/ChiefPresentSimilarityVo.java

@@ -0,0 +1,12 @@
+package com.lantone.qc.pub.model.vo;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ChiefPresentSimilarityVo {
+    private JSONObject data;
+    private boolean direction_check;
+}