Browse Source

Merge branch 'master' of http://192.168.2.236:10080/louhr/push

# Conflicts:
#	graph-web/src/main/java/org/diagbot/graphWeb/controller/GraphController.java
hujing 6 years ago
parent
commit
bcffdf25c4
64 changed files with 22999 additions and 9684 deletions
  1. 3 0
      bigdata-web/src/main/java/org/diagbot/bigdata/work/ResultDataProxy.java
  2. 3 3
      common-service/src/main/java/org/diagbot/common/work/SearchData.java
  3. 0 38
      graph-web/src/main/java/org/diagbot/graphWeb/controller/GraphController.java
  4. 59 35
      graph-web/src/main/java/org/diagbot/graphWeb/work/GraphCalculate.java
  5. 29 0
      graph/src/main/java/org/diagbot/graph/Diagnose/DiagnoseMain.java
  6. 91 0
      graph/src/main/java/org/diagbot/graph/Diagnose/DiagnoseProcess.java
  7. 75 16
      graph/src/main/java/org/diagbot/graph/encryptionNeo4j/ReadNeo4jData2Neo4j.java
  8. 1 1
      graph/src/main/java/org/diagbot/graph/jdbc/DriverManager.java
  9. 59 34
      graph/src/main/java/org/diagbot/graph/jdbc/Neo4jAPI.java
  10. 47 9
      graph/src/main/java/org/diagbot/graph/util/NodeRelationUtil.java
  11. 36 8
      graph/src/main/resources/bolt.properties
  12. 9 0
      graph/src/main/resources/query.properties
  13. 64 2
      nlp-web/src/main/java/org/diagbot/nlp/controller/RelationExtractionController.java
  14. 74 0
      nlp-web/src/main/java/org/diagbot/nlp/dao/model/TaggingResult.java
  15. 9 1
      nlp/src/main/java/org/diagbot/nlp/participle/ParticipleToken.java
  16. 2 1
      nlp/src/main/java/org/diagbot/nlp/participle/ParticipleUtil.java
  17. 5 5
      nlp/src/main/java/org/diagbot/nlp/participle/cfg/DefaultConfig.java
  18. 120 0
      nlp/src/main/java/org/diagbot/nlp/relation/analyze/RelationAnalyze.java
  19. 72 0
      nlp/src/main/java/org/diagbot/nlp/relation/extract/LisExtract.java
  20. 59 0
      nlp/src/main/java/org/diagbot/nlp/relation/extract/PacsExtract.java
  21. 11 32
      nlp/src/main/java/org/diagbot/nlp/relation/extract/PresentExtract.java
  22. 60 0
      nlp/src/main/java/org/diagbot/nlp/relation/extract/TreatExtract.java
  23. 51 31
      nlp/src/main/java/org/diagbot/nlp/relation/extract/VitalExtract.java
  24. 0 22
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/PD.java
  25. 0 35
      nlp/src/main/java/org/diagbot/nlp/relation/extract/output/OutputInfo.java
  26. 40 0
      nlp/src/main/java/org/diagbot/nlp/relation/module/Lis.java
  27. 29 0
      nlp/src/main/java/org/diagbot/nlp/relation/module/Pacs.java
  28. 3 30
      nlp/src/main/java/org/diagbot/nlp/relation/extract/module/Symptom.java
  29. 29 0
      nlp/src/main/java/org/diagbot/nlp/relation/module/Treat.java
  30. 16 10
      nlp/src/main/java/org/diagbot/nlp/relation/extract/module/Vital.java
  31. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/BodyPart.java
  32. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Cause.java
  33. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Degree.java
  34. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Desc.java
  35. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Factor.java
  36. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Frequency.java
  37. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Item.java
  38. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Negative.java
  39. 38 0
      nlp/src/main/java/org/diagbot/nlp/relation/module/cell/PD.java
  40. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Position.java
  41. 1 1
      nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Property.java
  42. 59 57
      nlp/src/main/java/org/diagbot/nlp/relation/RelationAnalyze.java
  43. 62 0
      nlp/src/main/java/org/diagbot/nlp/relation/util/OutputInfo.java
  44. 9 2
      nlp/src/main/java/org/diagbot/nlp/util/Constants.java
  45. 12 3
      nlp/src/main/java/org/diagbot/nlp/util/NegativeEnum.java
  46. 50 0
      nlp/src/main/java/org/diagbot/nlp/util/NlpCache.java
  47. 1 1
      nlp/src/main/java/org/diagbot/nlp/util/NlpUtil.java
  48. 8 8
      nlp/src/main/resources/classify.dict
  49. 4344 5183
      nlp/src/main/resources/push-tc.dict
  50. 72 0
      nlp/src/main/resources/relation.dict
  51. 19 16
      nlp/src/main/resources/synonym.dict
  52. 16242 3990
      nlp/src/main/resources/tc.dict
  53. 404 0
      nlp/src/test/java/org/diagbot/nlp/test/EntityExtractTest.java
  54. 14 4
      nlp/src/test/java/org/diagbot/nlp/test/LexemeDicTest.java
  55. 2 2
      public/src/main/java/org/diagbot/pub/jdbc/MysqlJdbc.java
  56. 2 2
      push-web/src/main/java/org/diagbot/push/controller/AlgorithmController.java
  57. 57 5
      push-web/src/main/java/org/diagbot/push/controller/GraphController.java
  58. 5 0
      push-web/src/main/java/org/diagbot/push/controller/RelationController.java
  59. 2 0
      push-web/src/main/resources/static/index.html
  60. 2 0
      push-web/src/main/resources/static/pages/algorithm/list.html
  61. 2 0
      push-web/src/main/resources/static/pages/extract/feature.html
  62. 210 0
      push-web/src/main/resources/static/pages/label/list.html
  63. 2 0
      push-web/src/main/resources/static/pages/participle/sample.html
  64. 315 88
      push-web/src/main/resources/static/pages/relation/sample.html

+ 3 - 0
bigdata-web/src/main/java/org/diagbot/bigdata/work/ResultDataProxy.java

@@ -101,6 +101,9 @@ public class ResultDataProxy {
         Map<String, Float> result = new HashMap<>();
         String synonym = "";
         for (Map.Entry<String, Float> entry : map.entrySet()) {
+            if (entry.getKey().equals("冠状动脉粥样硬化性心脏病")) {
+                System.out.println("冠状动脉粥样硬化性心脏病");
+            }
             synonym = standardInfoSynonymMap.get(entry.getKey());
             if (synonym != null) {
                 if (result.get(synonym) == null) {

+ 3 - 3
common-service/src/main/java/org/diagbot/common/work/SearchData.java

@@ -32,7 +32,7 @@ public class SearchData {
     protected String past = "";
     protected String other = "";
     //大数据推送诊断结果信息
-    protected List<String> pushDiags = new ArrayList<>();
+    protected List<FeatureRate> pushDiags = new ArrayList<>();
 
     //模型
     protected String algorithmClassifyValue;
@@ -215,11 +215,11 @@ public class SearchData {
         this.filters = filters;
     }
 
-    public List<String> getPushDiags() {
+    public List<FeatureRate> getPushDiags() {
         return pushDiags;
     }
 
-    public void setPushDiags(List<String> pushDiags) {
+    public void setPushDiags(List<FeatureRate> pushDiags) {
         this.pushDiags = pushDiags;
     }
 }

+ 0 - 38
graph-web/src/main/java/org/diagbot/graphWeb/controller/GraphController.java

@@ -2,9 +2,6 @@ package org.diagbot.graphWeb.controller;
 
 import com.alibaba.fastjson.JSONObject;
 import org.diagbot.graph.javabean.GdbResponse;
-import org.diagbot.graph.jdbc.DriverManager;
-import org.diagbot.graph.jdbc.Neo4jAPI;
-import org.diagbot.graph.util.HttpServletRequestUtil;
 import org.diagbot.graphWeb.dao.BackResponse;
 import org.diagbot.graphWeb.work.GraphCalculate;
 import org.diagbot.graphWeb.work.HighRiskCalculate;
@@ -18,45 +15,10 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.Map;
 
 @Controller
 @RequestMapping("/graph")
 public class GraphController {
-    @RequestMapping(value = "/push", method = RequestMethod.POST)
-    @ResponseBody
-    public Response<ResponseData> bayesPageData(HttpServletRequest request, @RequestBody SearchData searchData) throws Exception {
-        Response<ResponseData> response = new Response();
-        GraphCalculate graphCalculate = new GraphCalculate();
-        ResponseData responseData = graphCalculate.calculate(request, searchData);
-        response.setData(responseData);
-        return response;
-    }
-    @RequestMapping(value = "/highRisk", method = RequestMethod.POST)
-    @ResponseBody
-    public  Response<GdbResponse> getHighRisk(HttpServletRequest request, @RequestBody SearchData searchData) throws Exception {
-        HighRiskCalculate highRiskCalculate = new HighRiskCalculate();
-        Response<GdbResponse> gdbResponseResponse = highRiskCalculate.calculateHighRisk(request, searchData);
-        return gdbResponseResponse;
-    }
-    @RequestMapping(value = "/lisPacs", method = RequestMethod.POST)
-    @ResponseBody
-    public Response<ResponseData> lisPacsData(HttpServletRequest request, @RequestBody SearchData searchData) throws Exception {
-        Response<ResponseData> response = new Response();
-        GraphCalculate graphCalculate = new GraphCalculate();
-        ResponseData responseData = graphCalculate.getLisPacs(request, searchData);
-        response.setData(responseData);
-        return response;
-    }
-
-    @RequestMapping(value = "/scale", method = RequestMethod.POST)
-    @ResponseBody
-    public Map<String, Object> scale(HttpServletRequest request) throws Exception {
-        Neo4jAPI neo4jAPI = new Neo4jAPI(DriverManager.newDrive());
-        String scaleName = HttpServletRequestUtil.getString(request, "scaleName");
-        Map<String, Object> scale = neo4jAPI.getScale(scaleName);
-        return scale;
-    }
 
 }
 

+ 59 - 35
graph-web/src/main/java/org/diagbot/graphWeb/work/GraphCalculate.java

@@ -58,7 +58,7 @@ public class GraphCalculate {
             featureRate.setFeatureName(d.getKey());
             featureRate.setExtraProperty("");
             featureRate.setDesc(d.getValue());
-            featureRate.setRate("");
+            featureRate.setRate("neo4j");
             featureRates.add(featureRate);
         }
 
@@ -89,37 +89,63 @@ public class GraphCalculate {
         Neo4jAPI neo4jAPI = new Neo4jAPI(DriverManager.newDrive());
         String webDiag = searchData.getDiag();
         List<String> webDiagList = Arrays.asList(webDiag.split(",|,|、"));
-        List<String> bigdataDiagList = searchData.getPushDiags();
-        for (String web: webDiagList ) {
-            for (String big: bigdataDiagList ) {
-                if(big.equals(web)){
-                    bigdataDiagList.remove(big);
+        List<FeatureRate> bigdataDiagFeature = searchData.getPushDiags();
+        List<String> bigdataDiagList =new LinkedList<>();
+        if(bigdataDiagFeature.size()>0){
+            for (FeatureRate fe:bigdataDiagFeature) {
+                if("neo4j".equals(fe.getRate())){
+                    bigdataDiagList.add(fe.getFeatureName());
+                }else {
+                    bigdataDiagList.add(fe.getFeatureName());
                 }
             }
         }
-        Map<String, Set<FeatureRate>> weblisPacs = neo4jAPI.getLisPacs(webDiagList);
-        Map<String, Set<FeatureRate>> biglisPacs = neo4jAPI.getLisPacs(bigdataDiagList);
-        Set<FeatureRate> lis =null;
-        Set<FeatureRate> pacs =null;
-        //如果界面有诊断
-        if(webDiagList.size()>0){
-            lis = weblisPacs.get("LIS");
-            lis = new HashSet<>(processResult(lis));
-            lis.addAll(biglisPacs.get("LIS"));
-            pacs = weblisPacs.get("PACS");
-            pacs = new HashSet<>(processResult(pacs));
-            pacs.addAll(biglisPacs.get("PACS"));
+        for (String web: webDiagList ) {
+                for (int i=0;i<bigdataDiagList.size();i++ ) {
+                    if(bigdataDiagList.get(i).equals(web)){
+                        bigdataDiagList.remove(bigdataDiagList.get(i));
+                    }
+                }
+        }
 
+        Map<String, Set<String>> weblisPacs1 =null;
+        Map<String, Set<String>> biglisPacs1 =null;
+        if(webDiagList !=null && webDiagList.size()>0){
+            weblisPacs1=neo4jAPI.getLisPacs(webDiagList);//界面诊断推出的LIS,PACS
+        }
+        if(bigdataDiagList !=null && bigdataDiagList.size()>0){
+            biglisPacs1=neo4jAPI.getLisPacs(bigdataDiagList);//大数据推得诊断
+        }
+        Set<String> lis =null;
+        Set<String> pacs =null;
+        //如果界面有诊断
+        if(weblisPacs1 !=null && weblisPacs1.values().size()>0){
+            lis = weblisPacs1.get("LIS");
+            pacs = weblisPacs1.get("PACS");
+            if(biglisPacs1 !=null && biglisPacs1.values().size()>0){
+                Set<String> bl = biglisPacs1.get("LIS");
+                Set<String>  bp= biglisPacs1.get("PACS");
+                lis.addAll(bl);
+                pacs.addAll(bp);
+            }
         }else {
-            lis=biglisPacs.get("LIS");
-            pacs=biglisPacs.get("PACS");
+            lis = biglisPacs1.get("LIS");
+            pacs = biglisPacs1.get("PACS");
         }
-
-        lis = new HashSet<>(processResult(lis));
-        pacs = new HashSet<>(processResult(pacs));
-
-        responseData.setLabs(new ArrayList<FeatureRate>(lis));
-        responseData.setPacs(new ArrayList<FeatureRate>(pacs));
+        ArrayList<FeatureRate> lisFeature = new ArrayList<>();
+        ArrayList<FeatureRate> pacsFeature = new ArrayList<>();
+        for (String l:lis) {
+            FeatureRate featureRate = new FeatureRate();
+            featureRate.setFeatureName(l);
+            lisFeature.add(featureRate);
+        }
+        for (String p:pacs) {
+            FeatureRate featureRate = new FeatureRate();
+            featureRate.setFeatureName(p);
+            pacsFeature.add(featureRate);
+        }
+        responseData.setLabs(lisFeature);
+        responseData.setPacs(pacsFeature);
         return responseData;
     }
 
@@ -129,21 +155,19 @@ public class GraphCalculate {
      * @param set
      * @return List<FeatureRate>
      */
-    public List<FeatureRate> processResult(Set<FeatureRate> set) {
-        List<FeatureRate> frlist = new ArrayList<>();
+    public Set<String> processResult(Set<String> set) {
+        Set<String> frlist = new LinkedHashSet<>();
         Map<String, String> sortval = new HashMap<>();
-        Map<String, FeatureRate> items = new HashMap<>();
+        Map<String, String> items = new HashMap<>();
         String name;
 
         try {
             if (set != null && set.size() > 0) {
-                for (FeatureRate item : set) {
-                    name = item.getFeatureName();
-                    items.put(name, item);
-                    if (sortval.get(name) == null) {
-                        sortval.put(name, "1");
+                for (String item : set) {
+                    if (sortval.get(item) == null) {
+                        sortval.put(item, "1");
                     } else {
-                        sortval.put(name, String.valueOf(Integer.parseInt(sortval.get(name)) + 1));
+                        sortval.put(item, String.valueOf(Integer.parseInt(sortval.get(item)) + 1));
                     }
                 }
 

+ 29 - 0
graph/src/main/java/org/diagbot/graph/Diagnose/DiagnoseMain.java

@@ -0,0 +1,29 @@
+package org.diagbot.graph.Diagnose;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 处理诊断的入口类
+ */
+public class DiagnoseMain {
+    public static void main(String[] args) throws Exception {
+        List<String> quezhenDiagno = new ArrayList<>();
+//        Map<String, String> diagnose = new DiagnoseProcess().getDiagnose("近端指间关节炎","足关节炎","对称性关节肿胀","晨僵≥30分钟","类风湿因子阳性","抗CCP抗体阳性",
+//                "侵袭性骨破坏","右上腹痛","向右背部放射","墨菲斯征阳性","白细胞增多和核左移","不洁饮食","胆囊内有强回声团");
+//         Map<String, String> diagnose = new DiagnoseProcess().getDiagnose(
+//                "侵袭性骨破坏","右上腹痛","向右背部放射","墨菲斯征阳性","白细胞增多","不洁饮食","胆囊内有强回声团");
+//        Map<String, String> diagnose = new DiagnoseProcess().getDiagnose(
+//                "上腹痛","墨菲斯征阳性","白细胞增多","不洁饮食","胆囊内有强回声团");
+//        Map<String, String> diagnose = new DiagnoseProcess().getDiagnose(
+//                "咽痛","鼻塞","乏力","淋巴结肿大","扁桃体肿大","上腹痛","墨菲斯征阳性","白细胞增多","不洁饮食","胆囊内有强回声团","近端指间关节炎","足关节炎","对称性关节肿胀",
+//                "晨僵≥30分钟","类风湿因子阳性","抗CCP抗体阳性","胸腔积液","呼吸音减弱","发热","胸痛","呼吸困难","咳嗽");
+        Map<String, String> diagnose = new DiagnoseProcess().getDiagnose(
+                "咽痛","鼻塞","乏力","淋巴结肿大","扁桃体肿大","上腹痛","墨菲斯征阳性","白细胞增多","不洁饮食","胆囊内有强回声团","近端指间关节炎","足关节炎","对称性关节肿胀",
+                "晨僵≥30分钟","类风湿因子阳性","抗CCP抗体阳性","胸腔积液","呼吸音减弱","发热","咳嗽");
+        for (Map.Entry<String,String> disease:diagnose.entrySet()) {
+            System.out.println(disease.getKey()+"\t"+disease.getValue());
+        }
+    }
+}

+ 91 - 0
graph/src/main/java/org/diagbot/graph/Diagnose/DiagnoseProcess.java

@@ -0,0 +1,91 @@
+package org.diagbot.graph.Diagnose;
+
+import javafx.scene.effect.SepiaTone;
+import org.diagbot.graph.jdbc.DriverManager;
+import org.diagbot.pub.utils.PropertiesUtil;
+import org.neo4j.driver.v1.*;
+
+import java.util.*;
+
+public class DiagnoseProcess {
+    PropertiesUtil propertiesUtil = new PropertiesUtil("bolt.properties");
+    protected Map<String,String> getDiagnose(String ...filds) throws Exception {
+        Map<String,String> quezhenDiagnose = new LinkedHashMap<>();
+        List<String> startList = new ArrayList<>();
+        List<String> newList = new ArrayList<>();
+        for (String fild:filds) {
+            startList.add("\""+fild+"\"");
+        }
+        String query = "";
+        StatementResult run =null;
+        //获取driver和session
+        Driver driver = DriverManager.newDrive("192.168.2.232","neo4j","root");
+        Session session = driver.session(AccessMode.READ);
+        //第一步查找近义词
+//        String searchJinyici = propertiesUtil.getProperty("searchJinyici");
+//        String fildList = searchJinyici.replace("fildList", startList.toString());
+        query = propertiesUtil.getProperty("serchCollect").replace("fildList",startList.toString());;
+//        System.out.println("查找近义词语句:"+query+"\n");
+        run = session.run(query);
+        while (run.hasNext()){
+            Record record = run.next();
+            String fild = record.get("fild").toString();
+            List<Object> typeCollect = record.get("typeCollect").asList();
+            //如果不包含诊断依据就找它的同义词,否则就要这个词
+            if("近义词".equals(typeCollect.get(0)) && typeCollect.size() ==1){
+                query = "match(l)-[r:近义词]->(h) where l.name="+fild+" return h.name as js";
+                StatementResult jinyiResult = session.run(query);
+                while (jinyiResult.hasNext()){
+                    Record next = jinyiResult.next();
+                    String js = next.get("js").toString();
+                    startList.remove(fild);
+                    startList.add(js);
+                }
+
+            }
+        }
+        newList.addAll(startList);
+        int i =0;
+        //第二步查找能推诊断
+        while (newList.size()>0){
+            i++;
+            query = propertiesUtil.getProperty("searchCondition").replace("newList",newList.toString()).replace("fildList",startList.toString());
+//            System.out.println("第"+i+"个:"+query+"\n");
+            run = session.run(query);
+            newList.clear();
+            while (run.hasNext()){
+                Record record = run.next();
+                String condition = record.get("condition").toString();
+                String jundgement = record.get("jundgement").toString();
+                String label = record.get("label").toString();
+                if ("TRUE".equals(jundgement)) {
+                    newList.add(condition);
+                    startList.add(condition);
+                }
+            }
+        }
+        //第三步查找确诊
+        query = propertiesUtil.getProperty("searchQuezhen").replace("fildList",startList.toString());
+//        System.out.println(query);
+        run = session.run(query);
+        Set<String> dis = new LinkedHashSet<>();
+        while (run.hasNext()){
+            Record next = run.next();
+            String quezhenName = next.get("name").toString().replace("\"","");
+            String conditionType = next.get("relationType").toString().replace("\"","");
+            if("确诊".equals(conditionType)){
+                dis.add(quezhenName);
+            }else if("拟诊".equals(conditionType)){
+                dis.add(quezhenName);
+            }
+            for (String dise:dis
+                 ) {
+               quezhenDiagnose.put(dise,"疑似诊断");
+            }
+
+        }
+        session.close();
+        driver.close();
+        return quezhenDiagnose;
+    }
+}

File diff suppressed because it is too large
+ 75 - 16
graph/src/main/java/org/diagbot/graph/encryptionNeo4j/ReadNeo4jData2Neo4j.java


+ 1 - 1
graph/src/main/java/org/diagbot/graph/jdbc/DriverManager.java

@@ -21,7 +21,7 @@ public class DriverManager {
     public static Driver newDrive() throws Exception{
         if (driver == null) {
 //            driver = GraphDatabase.driver("bolt://192.168.3.112:7687", AuthTokens.basic("neo4j", "123456"),
-            driver = GraphDatabase.driver(propertiesUtil.getProperty("bolt.uri"), AuthTokens.basic(propertiesUtil.getProperty("bolt.user"), propertiesUtil.getProperty("bolt.passwd")),
+            driver = GraphDatabase.driver(propertiesUtil.getProperty("bolt232.uri"), AuthTokens.basic(propertiesUtil.getProperty("bolt232.user"), propertiesUtil.getProperty("bolt232.passwd")),
                     Config.build().withMaxConnectionLifetime(ConnLifeTime, TimeUnit.MINUTES)
                             .withMaxTransactionRetryTime(TransRetryTime, TimeUnit.SECONDS)
                             .withMaxConnectionPoolSize(ConnPoolSize)

+ 59 - 34
graph/src/main/java/org/diagbot/graph/jdbc/Neo4jAPI.java

@@ -639,12 +639,12 @@ public class Neo4jAPI {
      * @return
      */
     public Map<String, String> getCondition(String[] keys) {
-        HashMap<String, String> conditionMap = new HashMap<>();
+        Map<String, String> conditionMap = new LinkedHashMap<>();
         Map<String, String> diseaseCondition = new LinkedHashMap<>();
         List<String> newList = new ArrayList<>();
         ArrayList<String> fildList = new ArrayList<>();
         //输出确诊集合
-        Set<String> quezhen = new HashSet<>();
+        Set<String> quezhen = new LinkedHashSet<>();
         for (String fild : keys) {
             fildList.add("\"" + fild.trim() + "\"");
         }
@@ -653,7 +653,26 @@ public class Neo4jAPI {
         String query = "";
         try {
             session = driver.session(AccessMode.WRITE);
-            //判断是否有近义词
+            query = propertiesUtil.getProperty("serchCollect").replace("fildList",fildList.toString());
+            result = session.run(query);
+            while (result.hasNext()){
+                Record record = result.next();
+                String fild = record.get("fild").toString();
+                List<Object> typeCollect = record.get("typeCollect").asList();
+                //如果不包含诊断依据就找它的同义词,否则就要这个词
+                if("近义词".equals(typeCollect.get(0)) && typeCollect.size() ==1){
+                    query = "match(l)-[r:近义词]->(h) where l.name="+fild+" return h.name as js";
+                    StatementResult jinyiResult = session.run(query);
+                    while (jinyiResult.hasNext()){
+                        Record next = jinyiResult.next();
+                        String js = next.get("js").toString();
+                        fildList.remove(fild);
+                        fildList.add(js);
+                    }
+
+                }
+            }
+/*            //判断是否有近义词
             query = "match (l)-[r:近义词]->(m)\n" +
                     "where l.name in  " + fildList + "\n" +
                     "return l.name as zi,type(r),m.name as fu";
@@ -664,7 +683,8 @@ public class Neo4jAPI {
                 String d = record.get("fu").toString();
                 fildList.remove(c);
                 fildList.add(d);
-            }
+            }*/
+//            System.out.println("参与计算的词:"+fildList);
             newList.addAll(fildList);
             int i = 0;
             while (newList.size() > 0) {
@@ -676,6 +696,8 @@ public class Neo4jAPI {
                         "match (n)-[r:诊断依据]->(m)\n" +
                         "where n.name= row\n" +
                         "return m.name as condition, count(distinct r)>=m.path as jundgement, labels(m)[0] as label";
+//                System.out.println("第"+i+"次查询:");
+//                System.out.println(query);
                 result = session.run(query);
                 newList.clear();
                 while (result.hasNext()) {
@@ -691,22 +713,25 @@ public class Neo4jAPI {
             }
 
             query = "with " + fildList + " as data unwind data as row\n" +
-                    "match (n)-[r:确诊]->(m)\n" +
+                    "match (n)-[r:确诊|:拟诊]->(m)\n" +
                     "where n.name=row\n" +
                     "with distinct m,r\n" +
                     "return m.name as name, labels(m)[0] as label,type(r) as relationType";
-
             result = session.run(query);
             while (result.hasNext()) {
                 Record record = result.next();
-                String quezhenName = record.get("name").toString();
-                quezhen.add(quezhenName);
+                String quezhenName = record.get("name").toString().replace("\"","");
+                String conditionType = record.get("relationType").toString().replace("\"","");
+                if("确诊".equals(conditionType)){
+                    quezhen.add(quezhenName);
+                }else if("拟诊".equals(conditionType)){
+                    quezhen.add(quezhenName);
+                }
             }
             for (String qu : quezhen) {
-                String dis_name = qu.replaceAll("\"", "");
                 Map<String, String> dis_res = new HashMap<>();
                 dis_res.put("确诊", "");
-                diseaseCondition.put(dis_name, JSON.toJSONString(dis_res));
+                diseaseCondition.put(qu, JSON.toJSONString(dis_res));
             }
 
         } catch (Exception e) {
@@ -949,7 +974,7 @@ public class Neo4jAPI {
         nf.setMinimumFractionDigits(0);//设置该百分比数字,保留2位小数;
         nf.setRoundingMode(RoundingMode.HALF_UP); //设置满5向上进位,即四舍五入;
         Map<String, String> resultMap = new HashMap<>();
-        String[] diseaseArray = disease.split(",|,|、");
+        String[] diseaseArray = disease.split(",|,|、|;|:|;");
         List<String> diseaseList = new ArrayList<>();//诊断数组
         for (int i = 0; i < diseaseArray.length; i++) {
             diseaseList.add(diseaseArray[i]);
@@ -1041,11 +1066,11 @@ public class Neo4jAPI {
                          * 查找药类的忌用
                          */
                         Map<String, String> drugsUseMap = new HashMap<>();//key:药名 value:禁忌(慎用)
-                        query = "match (n:Disease{name:'急性胰腺炎'})-[:推荐]->(d:Drugs)<-[r0:慎用]-(m)\n" +
+                        query = "match (n:Disease{name:'"+diseaseName+"'})-[:推荐]->(d:Drugs)<-[r0:慎用]-(m)\n" +
                                 "where m.name in " + value + "" +
                                 "return d.name as ff,type(r0) as hh\n" +
                                 "union\n" +
-                                "match (n:Disease{name:'急性胰腺炎'})-[:推荐]->(d:Drugs)<-[r0:忌用]-(m)\n" +
+                                "match (n:Disease{name:'"+diseaseName+"'})-[:推荐]->(d:Drugs)<-[r0:忌用]-(m)\n" +
                                 "where m.name in " + value + "" +
                                 "return d.name as ff,type(r0) as hh";
                         result = tx.run(query);
@@ -1279,12 +1304,13 @@ public class Neo4jAPI {
      * @param diseases
      * @return
      */
-    public Map<String, Set<FeatureRate>> getLisPacs(List<String> diseases) {
+    public Map<String, Set<String>> getLisPacs(List<String> diseases) {
         Session session = null;
         StatementResult result = null;
         String serchLisPacs = propertiesUtil.getProperty("serchLisPacs");
         String query = null;
         Map<String, Set<FeatureRate>> lisPacsMap = new HashMap<>();
+        Map<String, Set<String>> lisPacsMap1 = new HashMap<>();
         List<String> diseaseList = new ArrayList<>();//诊断数组
         for (String dis : diseases) {
             diseaseList.add("\"" + dis + "\"");
@@ -1293,55 +1319,54 @@ public class Neo4jAPI {
             session = driver.session(AccessMode.WRITE);
             List<FeatureRate> lisList = new ArrayList<>();
             List<FeatureRate> pacsList = new ArrayList<>();
+            List<String> lisArray = new ArrayList<>();
+            List<String> pacsArray = new ArrayList<>();
             query = serchLisPacs.replace("diseaseNmae", diseaseList.toString());
+            System.out.println(query);
             result = session.run(query);
             while (result.hasNext()) {
-                FeatureRate featureRate = new FeatureRate();
                 Record next = result.next();
                 String lei = next.get("lei").toString().replaceAll("\"", "");
                 String name = next.get("n").toString().replaceAll("\"", "");
+                String subLis = next.get("lr").toString().replaceAll("\"", "");
                 if ("LIS".equals(lei)) {
-                    featureRate.setFeatureName(name);
-                    if (!lisList.contains(featureRate)) {
-                        lisList.add(featureRate);
-                    }
+                    lisArray.add(name);
                 } else if ("PACS".equals(lei)) {
-                    featureRate.setFeatureName(name);
-                    if (!pacsList.contains(featureRate)) {
-                        pacsList.add(featureRate);
-                    }
+                   pacsArray.add(name);
                 }
             }
 
-            lisPacsMap.put("LIS", processList(lisList));
-            lisPacsMap.put("PACS", processList(pacsList));
+//            lisPacsMap.put("LIS", processList(lisList));
+//            lisPacsMap.put("PACS", processList(pacsList));
+            lisPacsMap1.put("LIS",processList(lisArray));
+            lisPacsMap1.put("PACS",processList(pacsArray));
         } catch (Exception e) {
             e.printStackTrace();
 
         } finally {
             CloseSession(session);
-            return lisPacsMap;
+            return lisPacsMap1;
         }
     }
 
-    public Set<FeatureRate> processList(List<FeatureRate> list) {
-        Set<FeatureRate> resultSet = new LinkedHashSet<>();
-        Map<FeatureRate, Integer> featuerInt = new HashMap<FeatureRate, Integer>();
-        for (FeatureRate d : list) {
+    public Set<String> processList(List<String> list) {
+        Set<String> resultSet = new LinkedHashSet<>();
+        Map<String, Integer> featuerInt = new HashMap<String, Integer>();
+        for (String d : list) {
             if (featuerInt.containsKey(d)) {
                 featuerInt.put(d, featuerInt.get(d) + 1);
             } else {
                 featuerInt.put(d, 1);
             }
         }
-        List<Map.Entry<FeatureRate, Integer>> reslist = new ArrayList<Map.Entry<FeatureRate, Integer>>(featuerInt.entrySet());
-        Collections.sort(reslist, new Comparator<Map.Entry<FeatureRate, Integer>>() {
+        List<Map.Entry<String, Integer>> reslist = new ArrayList<Map.Entry<String, Integer>>(featuerInt.entrySet());
+        Collections.sort(reslist, new Comparator<Map.Entry<String, Integer>>() {
             @Override
-            public int compare(Map.Entry<FeatureRate, Integer> o1, Map.Entry<FeatureRate, Integer> o2) {
+            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                 return o2.getValue().compareTo(o1.getValue());
             }
         });
-        for (Map.Entry<FeatureRate, Integer> f : reslist
+        for (Map.Entry<String, Integer> f : reslist
                 ) {
             //排好序的set
             resultSet.add(f.getKey());

+ 47 - 9
graph/src/main/java/org/diagbot/graph/util/NodeRelationUtil.java

@@ -122,6 +122,52 @@ public class NodeRelationUtil {
             if (session != null) session.close();
         }
     }
+    /**
+     * 添加带属性的关系
+     */
+    public void addRelationWithProperty(final Driver driver, final String fromlbl, final String fromval, final String relation,final Integer sort, final String tolbl, final String toval){
+        Session session = null;
+        try {
+            session = driver.session(AccessMode.WRITE);
+            session.writeTransaction(new TransactionWork<Integer>() {
+                @Override
+                public Integer execute(Transaction tx) {
+                    int result =0;
+                    String query = "MATCH (e:" + fromlbl + "{name:$src}), (c:" + tolbl + "{name:$dest}) " +
+                            "MERGE (e)-[r:" + relation + "{p:"+sort+"}]->(c) RETURN e.name, type(r), c.name";
+                    result = processRelation(tx, query, "src", fromval, "dest", toval);
+                    return result;
+                }
+            });
+        }catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            if (session != null) session.close();
+        }
+    }
+    /**
+     * 添加带属性的关系
+     */
+    public void addRelationWithPropertyDouble(final Driver driver, final String fromlbl, final String fromval, final String relation,final Double sort, final String tolbl, final String toval){
+        Session session = null;
+        try {
+            session = driver.session(AccessMode.WRITE);
+            session.writeTransaction(new TransactionWork<Integer>() {
+                @Override
+                public Integer execute(Transaction tx) {
+                    int result =0;
+                    String query = "MATCH (e:" + fromlbl + "{name:$src}), (c:" + tolbl + "{name:$dest}) " +
+                            "MERGE (e)-[r:" + relation + "{rate:"+sort+"}]->(c) RETURN e.name, type(r), c.name";
+                    result = processRelation(tx, query, "src", fromval, "dest", toval);
+                    return result;
+                }
+            });
+        }catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            if (session != null) session.close();
+        }
+    }
     /**
      * 为两个节点添加关系
      * @param fromlbl 标签类型
@@ -135,15 +181,6 @@ public class NodeRelationUtil {
         //两个节点之间,有关系,先删除
         try {
             session = driver.session(AccessMode.WRITE);
-//            session.writeTransaction(new TransactionWork<Integer>() {
-//                @Override
-//                public Integer execute(Transaction tx) {
-//                    String query = "MATCH (e:" + fromlbl + "{name:$src})-[r]->(c:" +
-//                            tolbl + "{name:$dest}) DELETE r";
-//                    int result = processRelation(tx, query, "src", fromval, "dest", toval);
-//                    return result;
-//                }
-//            });
             //为两个节点添加关系
             session.writeTransaction(new TransactionWork<Integer>() {
                 @Override
@@ -174,6 +211,7 @@ public class NodeRelationUtil {
         tx.run(query, parameters(srclbl, srcname, destlbl, destname));
         return 1;
     }
+
     private int processNode(Transaction tx, String query, String label, String val) {
         tx.run(query, parameters(label, val));
         return 1;

+ 36 - 8
graph/src/main/resources/bolt.properties

@@ -19,16 +19,44 @@ bolt112.uri=bolt://192.168.3.112
 bolt112.user=neo4j
 bolt112.passwd=123456
 
-sql1=with "+newList+" as data unwind data as row\n \
-  match (l)-[r:\u8BCA\u65AD\u4F9D\u636E]->(m)\n \
-  where l.name= row\n \
-  with m,"+fildList+" as data unwind data as row\n \
-  match (n)-[r:\u8BCA\u65AD\u4F9D\u636E]->(m)\n \
-  where n.name= row\n \
-  return m.name as condition, count(distinct r)>=m.path as jundgement, labels(m)[0] as label
+#\u63A8\u786E\u8BCA\u5904\u7406sql
+#\u67E5\u627E\u8FD1\u4E49\u8BCD
+searchJinyici=with fildList as data  unwind data as  fild  \n \
+match(l)-[r:\u8FD1\u4E49\u8BCD]->(h) \n \
+where l.name=fild \n \
+return l.name as zi,labels(l)[0] as jin,h.name as fu,labels(h)[0] as da
+#\u67E5\u627E\u8FD1\u4E49\u8BCD\u7CBE\u534E\u7248
+serchCollect=match (n)-[r:\u8BCA\u65AD\u4F9D\u636E|:\u8FD1\u4E49\u8BCD]->(e) where n.name in fildList return n.name as fild,collect(distinct type(r)) as typeCollect
+#\u67E5\u627E\u80FD\u63A8\u51FA\u8BCA\u65AD\u4F9D\u636E\u7684\u8BCD
+searchCondition=with newList as data unwind data as row\n \
+match (l)-[r:\u8BCA\u65AD\u4F9D\u636E]->(m)\n \
+where l.name= row\n \
+with m,fildList as data unwind data as row\n \
+match (n)-[r:\u8BCA\u65AD\u4F9D\u636E]->(m)\n \
+where n.name= row\n \
+return m.name as condition, count(distinct r)>=m.path as jundgement, labels(m)[0] as label
+#\u67E5\u627E\u786E\u8BCA,\u62DF\u8BCA\u7684\u8BED\u53E5
+searchQuezhen=with fildList  as data unwind data as row\n \
+match (n)-[r:\u786E\u8BCA|:\u62DF\u8BCA]->(m)\n \
+where n.name=row\n \
+with distinct m,r\n \
+return m.name as name, labels(m)[0] as label,type(r) as relationType
 
 #\u67E5\u627E\u4E00\u4E9B\u8BCD\u662F\u5426\u5728\u56FE\u8C31\u4E2D
 searchWords=match(d) where d.name in fildList return distinct d.name as name
 #\u6839\u636E\u75BE\u75C5\u67E5\u627E\u76F8\u5E94\u7684Lis Pacs
 serchLisPacs=match (d:Disease)-[r1:\u63A8\u8350]->(m)\n \
-where d.name in diseaseNmae return distinct d.name as name,labels(m)[0] as lei,m.name as n
+where d.name in diseaseNmae return distinct d.name as name,labels(m)[0] as lei,m.name as n
+
+#\u66F4\u65B0\u8BCA\u65AD\u4F9D\u636E\u7684path
+updateConditionPath=match (n:Condition)<-[:\u8BCA\u65AD\u4F9D\u636E]-(m) \n \
+          with n,\n \
+          case \n \
+          when n.relation="\u6216" then 1 \n \
+          when n.relation="\u4E14" then count(distinct m) \n \
+          when n.relation="\u4EFB\u4E00" then 1 \n \
+          when n.relation="\u4EFB\u4E8C" then 2 \n \
+          when n.relation="\u4EFB\u4E09" then 3 \n \
+          when n.relation="\u4EFB\u56DB" then 4 \n\
+          else 100 end as a \n \
+          set n.path=a

+ 9 - 0
graph/src/main/resources/query.properties

@@ -0,0 +1,9 @@
+# \u5904\u7406233\u7684\u6CBB\u7597\u6570\u636E,\u5B58\u5165232
+# \u7B2C\u4E00\u6B65,\u75BE\u75C5\u5230\u7C7B,\u7C7B\u5305\u542B\u836F
+diseaseDrugsMedication=\
+  match(d:Disease{name:'diseaseName'})-[r:\u63A8\u8350]->(h)-[r1:\u5305\u542B]->(l:Medicine) \
+  return d.name,h.name as drug,labels(h)[0] as label,r.p as p,collect(l.name) as collectName
+# \u7B2C\u4E8C\u6B65,\u75BE\u75C5\u548C\u836F\u7684\u5173\u7CFB
+diseaseMedication=match(d:Disease{name:"diseaseName"})-[r:\u63A8\u8350]->(l:Medicine) return d.name,r.rate as p,l.name as collectName
+# \u7B2C\u4E09\u6B65,\u5927\u7C7B\u548C\u5B50\u7C7B\u7684\u5173\u7CFB
+bigDrugAndSubDrugs=match(d:Disease)-[r:\u63A8\u8350]->(s:Drugs)-[r1:\u5305\u542B]->(j:Drugs)where d.name="diseaseName" return s.name as big,j.name as sub

+ 64 - 2
nlp-web/src/main/java/org/diagbot/nlp/controller/RelationExtractionController.java

@@ -1,14 +1,18 @@
 package org.diagbot.nlp.controller;
 
+import org.diagbot.nlp.dao.model.TaggingResult;
 import org.diagbot.nlp.feature.FeatureType;
-import org.diagbot.nlp.relation.RelationAnalyze;
-import org.diagbot.nlp.relation.extract.output.OutputInfo;
+import org.diagbot.nlp.relation.analyze.RelationAnalyze;
+import org.diagbot.nlp.relation.util.OutputInfo;
 import org.diagbot.pub.api.Response;
+import org.diagbot.pub.jdbc.MysqlJdbc;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @ClassName org.diagbot.nlp.controller.RelationExtractionController
@@ -31,4 +35,62 @@ public class RelationExtractionController {
         response.setData(outputInfos);
         return response;
     }
+
+    @RequestMapping({"/list"})
+    @ResponseBody
+    public Response<List<TaggingResult>> list(int pageNum) throws Exception {
+        Response<List<TaggingResult>> response = new Response();
+        MysqlJdbc nlpJdbc = new MysqlJdbc("root", "diagbot@20180822", "jdbc:mysql://192.168.2.235:3306/nlp-web?useUnicode=true&characterEncoding=UTF-8");
+        List<Map<String, String>> data = nlpJdbc.query("re_tagging_result_part",
+                new String[]{"sentence_id", "sentence", "entity_1_name", "entity_2_name", "relation", "entity_1_position", "entity_2_position"},
+                " where relation = 1 order by sentence_id, sentence limit " + pageNum * 100 + ", 100");
+
+        String sentence = "";
+        String s = "";
+        String[] position1 = null;
+        String[] position2 = null;
+        List<TaggingResult> taggingResults = new ArrayList<>();
+        for (Map<String, String> map : data) {
+            TaggingResult tr = new TaggingResult();
+            tr.setSentenceId(map.get("sentence_id"));
+            tr.setEntity1Name(map.get("entity_1_name"));
+            tr.setEntity2Name(map.get("entity_2_name"));
+            tr.setEntity1Position(map.get("entity_1_position"));
+            tr.setEntity2Position(map.get("entity_2_position"));
+            tr.setRelation(map.get("relation"));
+
+            sentence = map.get("sentence");
+            position1 = tr.getEntity1Position().split(",");
+            position2 = tr.getEntity2Position().split(",");
+            if ("0".equals(position1[0])) {
+                s = "<span class=\"label label-success\">";
+            } else {
+                s = sentence.substring(0, Integer.parseInt(position1[0]))
+                        + "<span class=\"label label-success\">";
+            }
+            s = s + sentence.substring(Integer.parseInt(position1[0]), Integer.parseInt(position1[1]) + 1) + "</span>";
+            if (position1[1].equals(position2[0])) {
+                if (Integer.parseInt(position2[1]) == sentence.length() - 1) {
+                    s = s + "<span class=\"label label-success\">" + sentence.substring(Integer.parseInt(position2[0])) + "</span>";
+                } else {
+                    s = s + "<span class=\"label label-success\">" + sentence.substring(Integer.parseInt(position2[0]), Integer.parseInt(position2[1]) + 1) + "</span>";
+                }
+            } else {
+                s = s + sentence.substring(Integer.parseInt(position1[1]) + 1, Integer.parseInt(position2[0]));
+
+                if (Integer.parseInt(position2[1]) == sentence.length() - 1) {
+                    s = s + "<span class=\"label label-success\">" + sentence.substring(Integer.parseInt(position2[0])) + "</span>";
+                } else {
+                    s = s + "<span class=\"label label-success\">" + sentence.substring(Integer.parseInt(position2[0]), Integer.parseInt(position2[1]) + 1) + "</span>";
+                    s = s + sentence.substring(Integer.parseInt(position2[1]) + 1);
+                }
+            }
+
+            tr.setSentence(s);
+            taggingResults.add(tr);
+        }
+
+        response.setData(taggingResults);
+        return response;
+    }
 }

+ 74 - 0
nlp-web/src/main/java/org/diagbot/nlp/dao/model/TaggingResult.java

@@ -0,0 +1,74 @@
+package org.diagbot.nlp.dao.model;
+
+/**
+ * @ClassName org.diagbot.nlp.dao.model.TaggingResult
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/3/27/027 13:25
+ * @Version 1.0
+ **/
+public class TaggingResult {
+    private String sentenceId;
+    private String sentence;
+    private String entity1Name;
+    private String entity2Name;
+    private String relation;
+    private String entity1Position;
+    private String entity2Position;
+
+    public String getSentenceId() {
+        return sentenceId;
+    }
+
+    public void setSentenceId(String sentenceId) {
+        this.sentenceId = sentenceId;
+    }
+
+    public String getSentence() {
+        return sentence;
+    }
+
+    public void setSentence(String sentence) {
+        this.sentence = sentence;
+    }
+
+    public String getEntity1Name() {
+        return entity1Name;
+    }
+
+    public void setEntity1Name(String entity1Name) {
+        this.entity1Name = entity1Name;
+    }
+
+    public String getEntity2Name() {
+        return entity2Name;
+    }
+
+    public void setEntity2Name(String entity2Name) {
+        this.entity2Name = entity2Name;
+    }
+
+    public String getRelation() {
+        return relation;
+    }
+
+    public void setRelation(String relation) {
+        this.relation = relation;
+    }
+
+    public String getEntity1Position() {
+        return entity1Position;
+    }
+
+    public void setEntity1Position(String entity1Position) {
+        this.entity1Position = entity1Position;
+    }
+
+    public String getEntity2Position() {
+        return entity2Position;
+    }
+
+    public void setEntity2Position(String entity2Position) {
+        this.entity2Position = entity2Position;
+    }
+}

+ 9 - 1
nlp/src/main/java/org/diagbot/nlp/participle/ParticipleToken.java

@@ -135,12 +135,20 @@ public class ParticipleToken {
 
     private void matchARABIC() throws IOException {
         int position;
+        int cur_offset = this.offset;
         while (cursor < available) {
             position = Arrays.binarySearch(join_symbols, buffer[cursor]);
             if (CharacterUtil.identifyCharType(buffer[cursor]) == CharacterUtil.CHAR_ARABIC        //数字后跟'-'、'/'、'.'作为数字处理
 //                    || CharacterUtil.identifyCharType(buffer[cursor]) == CharacterUtil.CHAR_ENGLISH
                     || position > -1) {
-                cursor++;
+//                cursor++;
+                cur_offset++;
+                //先依据词库是否成词判断
+                this.matchCHN(segment, cursor, 0, false);
+                if (cursor - cur_offset > 1) {
+                    this.cursor = cur_offset;
+                    break;
+                }
             } else if (CharacterUtil.identifyCharType(buffer[cursor]) == CharacterUtil.CHAR_CHINESE) {    //数字后跟中文单位
                 break;
             } else {

+ 2 - 1
nlp/src/main/java/org/diagbot/nlp/participle/ParticipleUtil.java

@@ -8,6 +8,7 @@ import org.diagbot.nlp.participle.word.Segment;
 import org.diagbot.nlp.util.Constants;
 import org.diagbot.nlp.util.NlpUtil;
 import org.diagbot.nlp.util.NlpCache;
+import org.springframework.util.StringUtils;
 
 import java.io.IOException;
 import java.io.StringReader;
@@ -142,7 +143,7 @@ public class ParticipleUtil {
         if (index > 0) {
             index--;
             last_l = lexemes.get(index);
-            if ("×".equals(last_l.getText()) && index > 0) {
+            if (("×".equals(last_l.getText()) || StringUtils.isEmpty(last_l.getText())) && index > 0) {
                 lexeme.setOffset(last_l.getOffset());
                 lexeme.setLength(last_l.getLength() + lexeme.getLength());
                 lexeme.setText(last_l.getText() + lexeme.getText());

+ 5 - 5
nlp/src/main/java/org/diagbot/nlp/participle/cfg/DefaultConfig.java

@@ -35,7 +35,7 @@ public class DefaultConfig implements Configuration {
             EncrypDES encrypDES = new EncrypDES();
             for (i = 0; i < length; i++) {
                 String s = dicts.get(i);
-                line_string = org.apache.commons.lang3.StringUtils.split(new String(encrypDES.decryptor(dicts.get(i))), "\\|");
+                line_string = org.apache.commons.lang3.StringUtils.split(dicts.get(i), "\\|");
                 chars = line_string[0].toCharArray();
                 if (line_string.length == 3) {
                     segment.fill(segment, chars, 0, chars.length, Float.parseFloat(line_string[1]), line_string[2]);
@@ -56,9 +56,8 @@ public class DefaultConfig implements Configuration {
         String[] line_string;
         Map<String, String> map = new HashMap<>(10, 0.8f);
         try {
-            EncrypDES encrypDES = new EncrypDES();
             for (int i = 0; i < fileContents.size(); i++) {
-                line_string = org.apache.commons.lang3.StringUtils.split(new String(encrypDES.decryptor(fileContents.get(i))), "\\|");
+                line_string = org.apache.commons.lang3.StringUtils.split(fileContents.get(i), "\\|");
                 if (line_string.length == 2) {
                     if (map.get(line_string[0]) != null) {
                         map.put(line_string[0], map.get(line_string[0]) + "," + line_string[1]);
@@ -86,14 +85,15 @@ public class DefaultConfig implements Configuration {
             }
             BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"), 512);
 
+            EncrypDES encrypDES = new EncrypDES();
             String theWord = null;
             do {
                 theWord = br.readLine();
                 if (theWord != null && !"".equals(theWord.trim())) {
-                    fileContents.add(theWord.trim());
+                    fileContents.add(new String(encrypDES.decryptor(theWord.trim())));
                 }
             } while (theWord != null);
-        } catch (IOException ioe) {
+        } catch (Exception ioe) {
             System.err.println("读取文件" + path + "出错.......................");
             ioe.printStackTrace();
         } finally {

+ 120 - 0
nlp/src/main/java/org/diagbot/nlp/relation/analyze/RelationAnalyze.java

@@ -0,0 +1,120 @@
+package org.diagbot.nlp.relation.analyze;
+
+import org.algorithm.core.cnn.AlgorithmCNNExecutor;
+import org.algorithm.core.cnn.entity.Lemma;
+import org.algorithm.core.cnn.entity.Triad;
+import org.algorithm.core.cnn.model.impl.RelationExtractionModelImpl;
+import org.diagbot.nlp.feature.FeatureType;
+import org.diagbot.nlp.participle.ParticipleUtil;
+import org.diagbot.nlp.participle.word.Lexeme;
+import org.diagbot.nlp.participle.word.LexemePath;
+import org.diagbot.nlp.relation.extract.*;
+import org.diagbot.nlp.relation.util.OutputInfo;
+import org.diagbot.nlp.relation.util.LemmaUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.RelationAnalyze
+ * @Description 关系抽取入口
+ * @Author fyeman
+ * @Date 2019/1/18/018 14:36
+ * @Version 1.0
+ **/
+public class RelationAnalyze {
+    public List<OutputInfo> analyze(String content, FeatureType featureType) throws Exception {
+        String[] part_contents = content.split("\\。|\\;\\\r|\\\n|\\;");
+
+        List<OutputInfo> outputInfos = new ArrayList<>();
+
+        LemmaUtil lemmaUtil = new LemmaUtil();
+        for (String part_content : part_contents) {
+            LexemePath<Lexeme> lexemes = ParticipleUtil.participle(part_content, true);
+            //分词结果转词元结构,只提取有词性信息,因为部分特征信息未在三元组中,所以需要把分词结果也一并传入
+            List<Lemma> lemmaParticiple = lemmaUtil.lexemeToTriadLemma(lexemes);
+            //调用CNN模型
+            long start = System.currentTimeMillis();
+            AlgorithmCNNExecutor executor = new RelationExtractionModelImpl();
+            List<Triad> triads = executor.execute(part_content, lemmaParticiple);
+            //删除不作为训练样本集
+            triads = lemmaUtil.findPairTraids(triads);
+            //模型返回的三元组转树形结构
+            List<Lemma> lemmaTree = lemmaUtil.traidToTree(triads, featureType);
+            long end = System.currentTimeMillis();
+            System.out.println("end - start : " + (end - start));
+            OutputInfo outputInfo = new OutputInfo();
+            switch (featureType) {
+                case SYMPTOM:
+                    this.lemmaPresentExtract(outputInfo, lemmaTree, lemmaParticiple);
+                    this.lemmaVitalExtract(outputInfo, lemmaTree, lemmaParticiple);
+                    this.lemmaLisExtract(outputInfo, lemmaTree, lemmaParticiple);
+                    this.lemmaPacsExtract(outputInfo, lemmaTree, lemmaParticiple);
+                    this.lemmaTreatExtract(outputInfo, lemmaTree, lemmaParticiple);
+            }
+            if (outputInfo != null) {
+                outputInfos.add(outputInfo);
+            }
+        }
+        return outputInfos;
+    }
+
+    public OutputInfo lemmaPresentExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        //现病史症状信息提取
+        PresentExtract presentExtract = new PresentExtract();
+        outputInfo = presentExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
+        return outputInfo;
+    }
+
+    /**
+     * 体征特征提取
+     * @param outputInfo
+     * @param lemmaTree
+     * @param lemmaParticiple
+     * @return
+     */
+    public OutputInfo lemmaVitalExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        VitalExtract vitalExtract = new VitalExtract();
+        outputInfo = vitalExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
+        return outputInfo;
+    }
+
+    /**
+     * 化验特征提取
+     * @param outputInfo
+     * @param lemmaTree
+     * @param lemmaParticiple
+     * @return
+     */
+    public OutputInfo lemmaLisExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        LisExtract lisExtract = new LisExtract();
+        outputInfo = lisExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
+        return outputInfo;
+    }
+
+    /**
+     * 检查特征提取
+     * @param outputInfo
+     * @param lemmaTree
+     * @param lemmaParticiple
+     * @return
+     */
+    public OutputInfo lemmaPacsExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        PacsExtract pacsExtract = new PacsExtract();
+        outputInfo = pacsExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
+        return outputInfo;
+    }
+
+    /**
+     * 治疗特征提取
+     * @param outputInfo
+     * @param lemmaTree
+     * @param lemmaParticiple
+     * @return
+     */
+    public OutputInfo lemmaTreatExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        TreatExtract treatExtract = new TreatExtract();
+        outputInfo = treatExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
+        return outputInfo;
+    }
+}

+ 72 - 0
nlp/src/main/java/org/diagbot/nlp/relation/extract/LisExtract.java

@@ -0,0 +1,72 @@
+package org.diagbot.nlp.relation.extract;
+
+import org.algorithm.core.cnn.entity.Lemma;
+import org.diagbot.nlp.relation.module.Lis;
+import org.diagbot.nlp.relation.module.cell.PD;
+import org.diagbot.nlp.relation.util.OutputInfo;
+import org.diagbot.nlp.util.Constants;
+import org.diagbot.nlp.util.NlpUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.extract.LisExtract
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/3/22/022 10:23
+ * @Version 1.0
+ **/
+public class LisExtract extends BaseExtract {
+    public OutputInfo extract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        List<String> repeatLisList = new ArrayList<>();
+        for (int index = 0; index < lemmaParticiple.size(); index++) {
+            Lemma participle_lemma = lemmaParticiple.get(index);
+            String property = participle_lemma.getProperty();
+            if (NlpUtil.isFeature(property, Constants.lis_name_type)) {          //特征词 症状
+                if (repeatLisList.contains(participle_lemma.getText())) {
+                    continue;
+                }
+                Lis lis = lookLisRelations(participle_lemma, lemmaTree);
+                outputInfo.getLises().add(lis);
+
+                repeatLisList.add(participle_lemma.getText());
+            }
+        }
+        lemmaTree.removeAll(containsLemmaTree);
+        return outputInfo;
+    }
+
+    private Lis lookLisRelations(Lemma participle_lemma, List<Lemma> lemmaTree) {
+        Lis lis = new Lis();
+        lis.setLisName(participle_lemma.getText());
+        for (Lemma cnn_l : lemmaTree) {
+            if (cnn_l.getText().equals(participle_lemma.getText())
+                    && cnn_l.getPosition().equals(participle_lemma.getPosition())) {
+                for (Lemma relation_l : cnn_l.getRelationLemmas()) {
+                    addFeatureToLis(relation_l, lis);
+                }
+                containsLemmaTree.add(cnn_l);
+            }
+        }
+        return lis;
+    }
+
+    private void addFeatureToLis(Lemma lemma, Lis lis) {
+        //化验结果信息
+        if (NlpUtil.isFeature(lemma.getProperty(), Constants.unit_time_type)) {
+            PD pd = lis.getPd();
+            if (pd == null) {
+                pd = new PD();
+                pd.setValue(lemma.getText());
+            } else {
+                pd.setValue(pd.getValue() + "、" + lemma.getText());
+            }
+            lis.setPd(pd);
+        }
+
+        if (NlpUtil.isFeature(lemma.getProperty(), Constants.lis_result_type)) {
+            lis.setValue(lemma.getText());
+        }
+    }
+}

+ 59 - 0
nlp/src/main/java/org/diagbot/nlp/relation/extract/PacsExtract.java

@@ -0,0 +1,59 @@
+package org.diagbot.nlp.relation.extract;
+
+import org.algorithm.core.cnn.entity.Lemma;
+import org.diagbot.nlp.relation.module.Pacs;
+import org.diagbot.nlp.relation.util.OutputInfo;
+import org.diagbot.nlp.util.Constants;
+import org.diagbot.nlp.util.NlpUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.extract.PacsExtract
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/3/25/025 10:05
+ * @Version 1.0
+ **/
+public class PacsExtract extends BaseExtract {
+    public OutputInfo extract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        List<String> repeatPacsList = new ArrayList<>();
+        for (int index = 0; index < lemmaParticiple.size(); index++) {
+            Lemma participle_lemma = lemmaParticiple.get(index);
+            String property = participle_lemma.getProperty();
+            if (NlpUtil.isFeature(property, Constants.pacs_name_type)) {          //特征词 症状
+                if (repeatPacsList.contains(participle_lemma.getText())) {
+                    continue;
+                }
+                Pacs pacs = lookPacsRelations(participle_lemma, lemmaTree);
+                outputInfo.getPacses().add(pacs);
+
+                repeatPacsList.add(participle_lemma.getText());
+            }
+        }
+        lemmaTree.removeAll(containsLemmaTree);
+        return outputInfo;
+    }
+
+    private Pacs lookPacsRelations(Lemma participle_lemma, List<Lemma> lemmaTree) {
+        Pacs pacs = new Pacs();
+        pacs.setPacsName(participle_lemma.getText());
+        for (Lemma cnn_l : lemmaTree) {
+            if (cnn_l.getText().equals(participle_lemma.getText())
+                    && cnn_l.getPosition().equals(participle_lemma.getPosition())) {
+                for (Lemma relation_l : cnn_l.getRelationLemmas()) {
+                    addFeatureToLis(relation_l, pacs);
+                }
+                containsLemmaTree.add(cnn_l);
+            }
+        }
+        return pacs;
+    }
+
+    private void addFeatureToLis(Lemma lemma, Pacs pacs) {
+        if (NlpUtil.isFeature(lemma.getProperty(), Constants.pacs_result_type)) {
+            pacs.setValue(lemma.getText());
+        }
+    }
+}

+ 11 - 32
nlp/src/main/java/org/diagbot/nlp/relation/extract/PresentExtract.java

@@ -1,12 +1,13 @@
 package org.diagbot.nlp.relation.extract;
 
 import org.algorithm.core.cnn.entity.Lemma;
-import org.diagbot.nlp.relation.extract.cell.*;
-import org.diagbot.nlp.relation.extract.module.Symptom;
-import org.diagbot.nlp.relation.extract.output.OutputInfo;
+import org.diagbot.nlp.relation.module.Symptom;
+import org.diagbot.nlp.relation.util.OutputInfo;
+import org.diagbot.nlp.relation.module.cell.*;
 import org.diagbot.nlp.util.Constants;
 import org.diagbot.nlp.util.NlpUtil;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -18,12 +19,18 @@ import java.util.List;
  **/
 public class PresentExtract extends BaseExtract {
     public OutputInfo extract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        List<String> repeatSymptomsList = new ArrayList<>();
         for (int index = 0; index < lemmaParticiple.size(); index++) {
             Lemma participle_lemma = lemmaParticiple.get(index);
             String property = participle_lemma.getProperty();
             if (NlpUtil.isFeature(property, Constants.symptom_type)) {          //特征词 症状
+                if (repeatSymptomsList.contains(participle_lemma.getText())) {
+                    continue;
+                }
                 Symptom symptom = lookSymptomRelations(participle_lemma, lemmaTree);
                 outputInfo.getSymptoms().add(symptom);
+
+                repeatSymptomsList.add(participle_lemma.getText());
             }
         }
         lemmaTree.removeAll(containsLemmaTree);
@@ -47,7 +54,7 @@ public class PresentExtract extends BaseExtract {
 
     private void addFeatureToSymptom(Lemma lemma, Symptom symptom) {
         //时间信息
-        if (NlpUtil.isFeature(lemma.getProperty(), Constants.unit_time_type)) {
+        if (NlpUtil.isFeature(lemma.getProperty(), Constants.unit_time_type) || NlpUtil.isFeature(lemma.getProperty(), Constants.event_time_desc_type)) {
             PD pd = symptom.getPd();
             if (symptom.getPd() == null) {
                 pd = new PD();
@@ -103,33 +110,5 @@ public class PresentExtract extends BaseExtract {
             negative.setNegaName(lemma.getText());
             symptom.setNegative(negative);
         }
-
-        //体征指标
-        if (NlpUtil.isFeature(lemma.getProperty(), Constants.vital_index_type)) {
-            Item item = new Item();
-            item.setItemName(lemma.getText());
-            for (Lemma l : lemma.getRelationLemmas()) {
-                if (NlpUtil.isFeature(l.getProperty(), Constants.vital_type)) {
-                    Desc desc = new Desc();
-                    desc.setInfo(l.getText());
-                    item.setDesc(desc);
-                }
-            }
-            symptom.setItem(item);
-        }
-
-        //体征指标值 体征结果放入描述信息
-        if (NlpUtil.isFeature(lemma.getProperty(), Constants.vital_type)) {
-            Desc desc = new Desc();
-            desc.setInfo(lemma.getText());
-            for (Lemma l : lemma.getRelationLemmas()) {
-                if (NlpUtil.isFeature(l.getProperty(), Constants.degree_type)) {
-                    Degree degree = new Degree();
-                    degree.setDegreeName(l.getText());
-                    desc.setDegree(degree);
-                }
-            }
-            symptom.setDesc(desc);
-        }
     }
 }

+ 60 - 0
nlp/src/main/java/org/diagbot/nlp/relation/extract/TreatExtract.java

@@ -0,0 +1,60 @@
+package org.diagbot.nlp.relation.extract;
+
+import org.algorithm.core.cnn.entity.Lemma;
+import org.diagbot.nlp.relation.module.Pacs;
+import org.diagbot.nlp.relation.module.Treat;
+import org.diagbot.nlp.relation.util.OutputInfo;
+import org.diagbot.nlp.util.Constants;
+import org.diagbot.nlp.util.NlpUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.extract.PacsExtract
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/3/25/025 10:05
+ * @Version 1.0
+ **/
+public class TreatExtract extends BaseExtract {
+    public OutputInfo extract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
+        List<String> repeatTreatList = new ArrayList<>();
+        for (int index = 0; index < lemmaParticiple.size(); index++) {
+            Lemma participle_lemma = lemmaParticiple.get(index);
+            String property = participle_lemma.getProperty();
+            if (NlpUtil.isFeature(property, Constants.medicine_type)) {          //特征词
+                if (repeatTreatList.contains(participle_lemma.getText())) {
+                    continue;
+                }
+                Treat treat = lookTreatRelations(participle_lemma, lemmaTree);
+                outputInfo.getTreats().add(treat);
+
+                repeatTreatList.add(participle_lemma.getText());
+            }
+        }
+        lemmaTree.removeAll(containsLemmaTree);
+        return outputInfo;
+    }
+
+    private Treat lookTreatRelations(Lemma participle_lemma, List<Lemma> lemmaTree) {
+        Treat treat = new Treat();
+        treat.setTreatName(participle_lemma.getText());
+        for (Lemma cnn_l : lemmaTree) {
+            if (cnn_l.getText().equals(participle_lemma.getText())
+                    && cnn_l.getPosition().equals(participle_lemma.getPosition())) {
+                for (Lemma relation_l : cnn_l.getRelationLemmas()) {
+                    addFeatureToTreat(relation_l, treat);
+                }
+                containsLemmaTree.add(cnn_l);
+            }
+        }
+        return treat;
+    }
+
+    private void addFeatureToTreat(Lemma lemma, Treat treat) {
+        if (NlpUtil.isFeature(lemma.getProperty(), Constants.treatment_type)) {
+            treat.setValue(lemma.getText());
+        }
+    }
+}

+ 51 - 31
nlp/src/main/java/org/diagbot/nlp/relation/extract/VitalExtract.java

@@ -1,9 +1,9 @@
 package org.diagbot.nlp.relation.extract;
 
 import org.algorithm.core.cnn.entity.Lemma;
-import org.diagbot.nlp.relation.extract.cell.*;
-import org.diagbot.nlp.relation.extract.module.Vital;
-import org.diagbot.nlp.relation.extract.output.OutputInfo;
+import org.diagbot.nlp.relation.module.Vital;
+import org.diagbot.nlp.relation.module.cell.*;
+import org.diagbot.nlp.relation.util.OutputInfo;
 import org.diagbot.nlp.util.Constants;
 import org.diagbot.nlp.util.NlpUtil;
 
@@ -39,38 +39,58 @@ public class VitalExtract extends BaseExtract {
             if (cnn_l.getText().equals(participle_lemma.getText())
                     && cnn_l.getPosition().equals(participle_lemma.getPosition())) {    //三元组中存在该特征
                 vital = new Vital();
-                vital.setVitalName(cnn_l.getText());
-                for (Lemma l : cnn_l.getRelationLemmas()) {
-                    if (NlpUtil.isFeature(l.getProperty(), Constants.negative_type)) {      //阴性
-                        Negative negative = new Negative();
-                        negative.setNegaName(l.getText());
-                        vital.setNegative(negative);
-                    } else if (NlpUtil.isFeature(l.getProperty(), Constants.degree_type)) {   //程度
-                        Degree degree = new Degree();
-                        degree.setDegreeName(l.getText());
-                        vital.setDegree(degree);
-                    } else if (NlpUtil.isFeature(l.getProperty(), Constants.body_part_type)) {   //方位
-                        BodyPart bodyPart = new BodyPart();
-                        bodyPart.setPartBodyName(l.getText());
-                        //部位需要查看下有没有方位
-                        for (Lemma position_l : l.getRelationLemmas()) {
-                            if (NlpUtil.isFeature(l.getProperty(), Constants.position_type)) {
-                                Position position = new Position();
-                                position.setPositionName(position_l.getText());
-                                bodyPart.setPosition(position);
-                            }
-                        }
-                        vital.setBodyPart(bodyPart);
-                    } else if (NlpUtil.isFeature(l.getProperty(), Constants.vital_index_type)) {
-                        Item item = new Item();
-                        item.setItemName(l.getText());
-                        vital.setItem(item);
-                    }
+                if (NlpUtil.isFeature(participle_lemma.getProperty(), Constants.vital_index_type)) {
+                    vital.setVitalName(cnn_l.getText());
+                }
+                if (NlpUtil.isFeature(participle_lemma.getProperty(), Constants.body_part_type)) {
+                    BodyPart bodyPart = new BodyPart();
+                    bodyPart.setPartBodyName(cnn_l.getText());
+                    vital.setBodyPart(bodyPart);
+                }
+                for (Lemma relation_l : cnn_l.getRelationLemmas()) {
+                    addFeatureToVital(relation_l, vital);
                 }
                 containsLemmaTree.add(cnn_l);
-                break;
             }
         }
         return vital;
     }
+
+    private void addFeatureToVital(Lemma lemma, Vital vital) {
+        if (NlpUtil.isFeature(lemma.getProperty(), Constants.negative_type)) {      //阴性
+            Negative negative = new Negative();
+            negative.setNegaName(lemma.getText());
+            vital.setNegative(negative);
+        } else if (NlpUtil.isFeature(lemma.getProperty(), Constants.degree_type)) {   //程度
+            Degree degree = new Degree();
+            degree.setDegreeName(lemma.getText());
+            vital.setDegree(degree);
+        } else if (NlpUtil.isFeature(lemma.getProperty(), Constants.body_part_type)) {   //部位
+            BodyPart bodyPart = vital.getBodyPart();
+            if (bodyPart == null) {
+                bodyPart = new BodyPart();
+            }
+            bodyPart.setPartBodyName(lemma.getText());
+            //部位需要查看下有没有方位
+            for (Lemma position_l : lemma.getRelationLemmas()) {
+                if (NlpUtil.isFeature(lemma.getProperty(), Constants.position_type)) {
+                    Position position = new Position();
+                    position.setPositionName(position_l.getText());
+                    bodyPart.setPosition(position);
+                }
+            }
+            vital.setBodyPart(bodyPart);
+        } else if (NlpUtil.isFeature(lemma.getProperty(), Constants.vital_value_type)) {
+            vital.setValue(lemma.getText());
+        } else if (NlpUtil.isFeature(lemma.getProperty(), Constants.unit_time_type)) {
+            PD pd = vital.getPd();
+            if (vital.getPd() == null) {
+                pd = new PD();
+                pd.setValue(lemma.getText());
+            } else {
+                pd.setValue(pd.getValue() + "、" + lemma.getText());
+            }
+            vital.setPd(pd);
+        }
+    }
 }

+ 0 - 22
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/PD.java

@@ -1,22 +0,0 @@
-package org.diagbot.nlp.relation.extract.cell;
-
-public class PD {
-    private String value;
-    private String unit;
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    public String getUnit() {
-        return unit;
-    }
-
-    public void setUnit(String unit) {
-        this.unit = unit;
-    }
-}

+ 0 - 35
nlp/src/main/java/org/diagbot/nlp/relation/extract/output/OutputInfo.java

@@ -1,35 +0,0 @@
-package org.diagbot.nlp.relation.extract.output;
-
-import org.diagbot.nlp.relation.extract.module.Symptom;
-import org.diagbot.nlp.relation.extract.module.Vital;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @ClassName org.diagbot.nlp.relation.extract.output.OutputInfo
- * @Description TODO
- * @Author fyeman
- * @Date 2019/1/22/022 11:05
- * @Version 1.0
- **/
-public class OutputInfo {
-    List<Symptom> symptoms = new ArrayList<>();
-    List<Vital> vitals = new ArrayList<>();
-
-    public List<Symptom> getSymptoms() {
-        return symptoms;
-    }
-
-    public void setSymptoms(List<Symptom> symptoms) {
-        this.symptoms = symptoms;
-    }
-
-    public List<Vital> getVitals() {
-        return vitals;
-    }
-
-    public void setVitals(List<Vital> vitals) {
-        this.vitals = vitals;
-    }
-}

+ 40 - 0
nlp/src/main/java/org/diagbot/nlp/relation/module/Lis.java

@@ -0,0 +1,40 @@
+package org.diagbot.nlp.relation.module;
+
+import org.diagbot.nlp.relation.module.cell.PD;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.module.Lis
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/3/22/022 10:30
+ * @Version 1.0
+ **/
+public class Lis {
+    private String lisName;
+    private String value;
+    private PD pd;
+
+    public String getLisName() {
+        return lisName;
+    }
+
+    public void setLisName(String lisName) {
+        this.lisName = lisName;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public PD getPd() {
+        return pd;
+    }
+
+    public void setPd(PD pd) {
+        this.pd = pd;
+    }
+}

+ 29 - 0
nlp/src/main/java/org/diagbot/nlp/relation/module/Pacs.java

@@ -0,0 +1,29 @@
+package org.diagbot.nlp.relation.module;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.module.Pacs
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/3/25/025 10:06
+ * @Version 1.0
+ **/
+public class Pacs {
+    private String pacsName;
+    private String value;
+
+    public String getPacsName() {
+        return pacsName;
+    }
+
+    public void setPacsName(String pacsName) {
+        this.pacsName = pacsName;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}

+ 3 - 30
nlp/src/main/java/org/diagbot/nlp/relation/extract/module/Symptom.java

@@ -1,6 +1,6 @@
-package org.diagbot.nlp.relation.extract.module;
+package org.diagbot.nlp.relation.module;
 
-import org.diagbot.nlp.relation.extract.cell.*;
+import org.diagbot.nlp.relation.module.cell.*;
 
 /**
  * @ClassName org.diagbot.nlp.relation.extract.cell.Symptom
@@ -13,14 +13,11 @@ public class Symptom {
     private String symptomName;
     private Negative negative;
 
-    private BodyPart  bodyPart;
+    private BodyPart bodyPart;
     private Degree degree;
     private Cause cause;
     private Property property;
     private PD pd;
-    private Factor factor;
-    private Item item;
-    private Desc desc;
 
     public String getSymptomName() {
         return symptomName;
@@ -77,28 +74,4 @@ public class Symptom {
     public void setPd(PD pd) {
         this.pd = pd;
     }
-
-    public Factor getFactor() {
-        return factor;
-    }
-
-    public void setFactor(Factor factor) {
-        this.factor = factor;
-    }
-
-    public Item getItem() {
-        return item;
-    }
-
-    public void setItem(Item item) {
-        this.item = item;
-    }
-
-    public Desc getDesc() {
-        return desc;
-    }
-
-    public void setDesc(Desc desc) {
-        this.desc = desc;
-    }
 }

+ 29 - 0
nlp/src/main/java/org/diagbot/nlp/relation/module/Treat.java

@@ -0,0 +1,29 @@
+package org.diagbot.nlp.relation.module;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.module.Treat
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/3/25/025 17:07
+ * @Version 1.0
+ **/
+public class Treat {
+    private String treatName;
+    private String value;
+
+    public String getTreatName() {
+        return treatName;
+    }
+
+    public void setTreatName(String treatName) {
+        this.treatName = treatName;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}

+ 16 - 10
nlp/src/main/java/org/diagbot/nlp/relation/extract/module/Vital.java

@@ -1,9 +1,6 @@
-package org.diagbot.nlp.relation.extract.module;
+package org.diagbot.nlp.relation.module;
 
-import org.diagbot.nlp.relation.extract.cell.BodyPart;
-import org.diagbot.nlp.relation.extract.cell.Degree;
-import org.diagbot.nlp.relation.extract.cell.Item;
-import org.diagbot.nlp.relation.extract.cell.Negative;
+import org.diagbot.nlp.relation.module.cell.*;
 
 /**
  * @ClassName org.diagbot.nlp.relation.extract.module.Vital
@@ -17,7 +14,8 @@ public class Vital {
     private BodyPart bodyPart;
     private Degree degree;
     private Negative negative;
-    private Item item;
+    private String value;
+    private PD pd;
 
     public String getVitalName() {
         return vitalName;
@@ -51,11 +49,19 @@ public class Vital {
         this.negative = negative;
     }
 
-    public Item getItem() {
-        return item;
+    public String getValue() {
+        return value;
     }
 
-    public void setItem(Item item) {
-        this.item = item;
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public PD getPd() {
+        return pd;
+    }
+
+    public void setPd(PD pd) {
+        this.pd = pd;
     }
 }

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/BodyPart.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 public class BodyPart {
     private String partBodyName;

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Cause.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 public class Cause {
     private String causeName;

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Degree.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 public class Degree {
     private String degreeName;

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Desc.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 /**
  * @ClassName org.diagbot.nlp.relation.extract.cell.Desc

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Factor.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 /**
  * @ClassName org.diagbot.nlp.relation.extract.cell.Factor

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Frequency.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 public class Frequency {
     private String freName;

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Item.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 /**
  * @ClassName org.diagbot.nlp.relation.extract.cell.Item

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Negative.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 /**
  * @ClassName org.diagbot.nlp.relation.extract.cell.Negative

+ 38 - 0
nlp/src/main/java/org/diagbot/nlp/relation/module/cell/PD.java

@@ -0,0 +1,38 @@
+package org.diagbot.nlp.relation.module.cell;
+
+import org.diagbot.nlp.participle.ParticipleUtil;
+import org.diagbot.nlp.participle.word.Lexeme;
+import org.diagbot.nlp.participle.word.LexemePath;
+
+import java.io.IOException;
+
+public class PD {
+    private String value;
+    private String unit;
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        try {
+            LexemePath<Lexeme> lexemes = ParticipleUtil.participle(value);
+            if (lexemes.size() == 2) {
+                this.value = lexemes.get(0).getText();
+                this.unit = lexemes.get(1).getText();
+            } else {
+                this.value = value;
+            }
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+}

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Position.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 /**
  * @ClassName org.diagbot.nlp.relation.extract.cell.Position

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/relation/extract/cell/Property.java

@@ -1,4 +1,4 @@
-package org.diagbot.nlp.relation.extract.cell;
+package org.diagbot.nlp.relation.module.cell;
 
 public class Property {
     private String propertyName;

+ 59 - 57
nlp/src/main/java/org/diagbot/nlp/relation/RelationAnalyze.java

@@ -1,66 +1,33 @@
-package org.diagbot.nlp.relation;
+package org.diagbot.nlp.relation.util;
 
-import org.algorithm.core.cnn.AlgorithmCNNExecutor;
 import org.algorithm.core.cnn.entity.Lemma;
 import org.algorithm.core.cnn.entity.Triad;
-import org.algorithm.core.cnn.model.impl.RelationExtractionModelImpl;
 import org.diagbot.nlp.feature.FeatureType;
-import org.diagbot.nlp.participle.ParticipleUtil;
 import org.diagbot.nlp.participle.word.Lexeme;
 import org.diagbot.nlp.participle.word.LexemePath;
-import org.diagbot.nlp.relation.extract.PresentExtract;
-import org.diagbot.nlp.relation.extract.VitalExtract;
-import org.diagbot.nlp.relation.extract.output.OutputInfo;
 import org.diagbot.nlp.util.Constants;
 import org.diagbot.nlp.util.NegativeEnum;
+import org.diagbot.nlp.util.NlpCache;
 import org.diagbot.nlp.util.NlpUtil;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
- * @ClassName org.diagbot.nlp.relation.RelationAnalyze
- * @Description 关系抽取入口
+ * @ClassName org.diagbot.nlp.relation.util.LemmaUtil
+ * @Description TODO
  * @Author fyeman
- * @Date 2019/1/18/018 14:36
+ * @Date 2019/3/21/021 14:25
  * @Version 1.0
  **/
-public class RelationAnalyze {
-    public List<OutputInfo> analyze(String content, FeatureType featureType) throws Exception {
-        String[] part_contents = content.split("\\。|\\;\\\r|\\\n|\\;");
-
-        List<OutputInfo> outputInfos = new ArrayList<>();
-        for (String part_content : part_contents) {
-            LexemePath<Lexeme> lexemes = ParticipleUtil.participle(part_content, true);
-            //分词结果转词元结构,只提取有词性信息,因为部分特征信息未在三元组中,所以需要把分词结果也一并传入
-            List<Lemma> lemmaParticiple = lexemeToTriadLemma(lexemes);
-            //调用CNN模型
-            AlgorithmCNNExecutor executor = new RelationExtractionModelImpl();
-            List<Triad> triads = executor.execute(part_content, lemmaParticiple);
-            //模型返回的三元组转树形结构
-            List<Lemma> lemmaTree = traidToTree(triads, featureType);
-            OutputInfo outputInfo = new OutputInfo();
-            switch (featureType) {
-                case SYMPTOM:
-                    PresentExtract presentExtract = new PresentExtract();
-                    outputInfo = presentExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
-                    //如果还有体征信息 也需要抽取
-                    VitalExtract vitalExtract = new VitalExtract();
-                    outputInfo = vitalExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
-            }
-            if (outputInfo != null) {
-                outputInfos.add(outputInfo);
-            }
-        }
-        return outputInfos;
-    }
-
+public class LemmaUtil {
     /**
      * 分词结果转词元结构
      * @param lexemes
      * @return
      */
-    private List<Lemma> lexemeToTriadLemma(LexemePath<Lexeme> lexemes) {
+    public List<Lemma> lexemeToTriadLemma(LexemePath<Lexeme> lexemes) {
         List<Lemma> lemmas = new ArrayList<>();
         for (Lexeme lexeme : lexemes) {
             if (!lexeme.getProperty().equals("99")) {
@@ -81,42 +48,45 @@ public class RelationAnalyze {
      * @param featureType
      * @return
      */
-    private List<Lemma> traidToTree(List<Triad> triads, FeatureType featureType) {
+    public List<Lemma> traidToTree(List<Triad> triads, FeatureType featureType) {
         List<Lemma> lemmaTree = new ArrayList<>();
         switch (featureType) {
             case SYMPTOM:
                 select(lemmaTree, triads, Constants.symptom_type);
                 select(lemmaTree, triads, Constants.vital_type);
+                select(lemmaTree, triads, Constants.lis_name_type);
+                select(lemmaTree, triads, Constants.pacs_name_type);
+                select(lemmaTree, triads, Constants.medicine_type);
         }
         return lemmaTree;
     }
 
-    private void select(List<Lemma> lemmaTree, List<Triad> triads, NegativeEnum[] type) {
+    public void select(List<Lemma> lemmaTree, List<Triad> triads, NegativeEnum[] type) {
         List<Triad> has_add_triads = new ArrayList<>();
         for (Triad triad : triads) {
-            Lemma origin_l = null;
-            Lemma relation_l = null;
+            Lemma left_l = null;
+            Lemma right_l = null;
             if (NlpUtil.isFeature(triad.getL_1().getProperty(), type)) {
-                origin_l = this.copyProperties(triad.getL_1());
-                relation_l = this.copyProperties(triad.getL_2());
+                left_l = this.copyProperties(triad.getL_1());
+                right_l = this.copyProperties(triad.getL_2());
             }
             if (NlpUtil.isFeature(triad.getL_2().getProperty(), type)) {
-                origin_l = this.copyProperties(triad.getL_2());
-                relation_l = this.copyProperties(triad.getL_1());
+                left_l = this.copyProperties(triad.getL_2());
+                right_l = this.copyProperties(triad.getL_1());
             }
-            if (origin_l != null && relation_l != null) {
+            if (left_l != null && right_l != null) {
                 boolean isFindFromTree = false;
                 for (Lemma l : lemmaTree) {
-                    if (l.getText().equals(origin_l.getText()) && l.getPosition().equals(origin_l.getPosition())) {
-                        origin_l = l;
+                    if (l.getText().equals(left_l.getText()) && l.getPosition().equals(left_l.getPosition())) {
+                        left_l = l;
                         isFindFromTree = true;
                         break;
                     }
                 }
-                this.findRelationTriad(triads, triad, has_add_triads, relation_l, type);
-                origin_l.add(relation_l);
+                this.findRelationTriad(triads, triad, has_add_triads, right_l, type);
+                left_l.add(right_l);
                 if (!isFindFromTree) {      //树上已有节点 不需要添加
-                    lemmaTree.add(origin_l);
+                    lemmaTree.add(left_l);
                 }
                 //已添加到树中的三元组
                 has_add_triads.add(triad);
@@ -125,7 +95,7 @@ public class RelationAnalyze {
         triads.removeAll(has_add_triads);
     }
 
-    private boolean findRelationTriad(List<Triad> triads, Triad current_triad, List<Triad> has_add_triads, Lemma lemma, NegativeEnum[] type) {
+    public boolean findRelationTriad(List<Triad> triads, Triad current_triad, List<Triad> has_add_triads, Lemma lemma, NegativeEnum[] type) {
         boolean isFindRelation = false;
         for (Triad triad : triads) {
             if (current_triad == triad) {
@@ -151,7 +121,7 @@ public class RelationAnalyze {
         return isFindRelation;
     }
 
-    private Lemma copyProperties(Lemma lemma) {
+    public Lemma copyProperties(Lemma lemma) {
         Lemma l = new Lemma();
         l.setLen(lemma.getLen());
         l.setPosition(lemma.getPosition());
@@ -159,4 +129,36 @@ public class RelationAnalyze {
         l.setText(lemma.getText());
         return l;
     }
+
+    public List<Triad> findPairTraids(List<Triad> triads) {
+        Map<String, List<String>> extract_relation_property_pair_map = NlpCache.getExtract_relation_property_pair_map();
+
+        String[] prop1;
+        String[] prop2;
+        boolean isPair = false;
+        List<String> props = null;
+
+        List<Triad> pairTriads = new ArrayList<>();
+        for (Triad triad : triads) {
+            prop1 = triad.getL_1().getProperty().split(",");
+            prop2 = triad.getL_2().getProperty().split(",");
+            for (int i = 0; i < prop1.length; i++) {
+                props = extract_relation_property_pair_map.get(prop1[i]);
+                if (props == null) {
+                    continue;
+                }
+                for (int j = 0; j < prop2.length; j++) {
+                    if (props.contains(prop2[j])) {
+                        isPair = true;
+                        break;
+                    }
+                }
+            }
+            if (isPair) {
+                pairTriads.add(triad);
+            }
+            isPair = false;
+        }
+        return pairTriads;
+    }
 }

+ 62 - 0
nlp/src/main/java/org/diagbot/nlp/relation/util/OutputInfo.java

@@ -0,0 +1,62 @@
+package org.diagbot.nlp.relation.util;
+
+import org.apache.commons.collections.ArrayStack;
+import org.diagbot.nlp.relation.module.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName org.diagbot.nlp.relation.extract.output.OutputInfo
+ * @Description TODO
+ * @Author fyeman
+ * @Date 2019/1/22/022 11:05
+ * @Version 1.0
+ **/
+public class OutputInfo {
+    List<Symptom> symptoms = new ArrayList<>();
+    List<Vital> vitals = new ArrayList<>();
+    List<Lis> lises = new ArrayList<>();
+    List<Pacs> pacses = new ArrayList<>();
+    List<Treat> treats = new ArrayList<>();
+
+    public List<Symptom> getSymptoms() {
+        return symptoms;
+    }
+
+    public void setSymptoms(List<Symptom> symptoms) {
+        this.symptoms = symptoms;
+    }
+
+    public List<Vital> getVitals() {
+        return vitals;
+    }
+
+    public void setVitals(List<Vital> vitals) {
+        this.vitals = vitals;
+    }
+
+    public List<Lis> getLises() {
+        return lises;
+    }
+
+    public void setLises(List<Lis> lises) {
+        this.lises = lises;
+    }
+
+    public List<Pacs> getPacses() {
+        return pacses;
+    }
+
+    public void setPacses(List<Pacs> pacses) {
+        this.pacses = pacses;
+    }
+
+    public List<Treat> getTreats() {
+        return treats;
+    }
+
+    public void setTreats(List<Treat> treats) {
+        this.treats = treats;
+    }
+}

+ 9 - 2
nlp/src/main/java/org/diagbot/nlp/util/Constants.java

@@ -17,9 +17,10 @@ public class Constants {
     public final static String feature_type_history = "7";       //历史
     public final static String feature_type_feature = "9"; //症状描述中的特征信息 如部位、性质等
 
-    public static NegativeEnum[] symptom_type = new NegativeEnum[]{NegativeEnum.SYMPTOM};
+    public static NegativeEnum[] symptom_type = new NegativeEnum[]{NegativeEnum.SYMPTOM, NegativeEnum.SYMPTOM_INDEX, NegativeEnum.SYMPTOM_PERFORMANCE};
     public static NegativeEnum[] unit_time_type = new NegativeEnum[]{NegativeEnum.EVENT_TIME, NegativeEnum.UNIT};
-    public static NegativeEnum[] vital_type = new NegativeEnum[]{NegativeEnum.VITAL_INDEX_VALUE, NegativeEnum.VITAL_RESULT};
+    public static NegativeEnum[] event_time_desc_type = new NegativeEnum[]{NegativeEnum.EVENT_TIME_DESC};
+    public static NegativeEnum[] vital_type = new NegativeEnum[]{NegativeEnum.VITAL_INDEX, NegativeEnum.VITAL_RESULT, NegativeEnum.BODY_PART};
     public static NegativeEnum[] vital_index_type = new NegativeEnum[]{NegativeEnum.VITAL_INDEX};
     public static NegativeEnum[] vital_result_type = new NegativeEnum[]{NegativeEnum.VITAL_RESULT};
     public static NegativeEnum[] vital_value_type = new NegativeEnum[]{NegativeEnum.VITAL_INDEX_VALUE};
@@ -29,6 +30,12 @@ public class Constants {
     public static NegativeEnum[] degree_type = new NegativeEnum[]{NegativeEnum.DEEP};
     public static NegativeEnum[] cause_type = new NegativeEnum[]{NegativeEnum.CAUSE};
     public static NegativeEnum[] negative_type = new NegativeEnum[]{NegativeEnum.FEMININE};
+    public static NegativeEnum[] lis_name_type = new NegativeEnum[]{NegativeEnum.LIS_NAME};
+    public static NegativeEnum[] lis_result_type = new NegativeEnum[]{NegativeEnum.LIS_RESULT};
+    public static NegativeEnum[] pacs_name_type = new NegativeEnum[]{NegativeEnum.PACS_NAME};
+    public static NegativeEnum[] pacs_result_type = new NegativeEnum[]{NegativeEnum.PACS_RESULT};
+    public static NegativeEnum[] treatment_type = new NegativeEnum[]{NegativeEnum.TREATMENT};
+    public static NegativeEnum[] medicine_type = new NegativeEnum[]{NegativeEnum.MEDICINE};
 
     public static String[] negative_words = new String[]{"无", "未", "未及", "无殊", "否认", "未见", "不", "未闻", "未闻及", "欠", "非"};
 

+ 12 - 3
nlp/src/main/java/org/diagbot/nlp/util/NegativeEnum.java

@@ -4,12 +4,12 @@ package org.diagbot.nlp.util;
  * Created by Administrator on 2017/11/8.
  */
 public enum NegativeEnum {
-    NUMBER("0"), SYMPTOM("1"), EVENT_TIME("2"), BODY_PART("3"), PROPERTY("4"), CAUSE("5"), DEEP("6"), FEMININE("7"), POSITIVE("8"),
+    NUMBER("0"), SYMPTOM("1"), SYMPTOM_INDEX("75"), EVENT_TIME("2"), EVENT_TIME_DESC("74"), BODY_PART("3"), PROPERTY("4"), CAUSE("5"), DEEP("6"), DEEP_QUANTIFIER("80"), FEMININE("7"), POSITIVE("8"),
     UNIT("9"), MEDICINE("10"), TREATMENT("11"),
     LIS_TYPE("13"), LIS_NAME("14"), LIS_RESULT("15"), WAY("16"),
     PACS_NAME("17"), PACS_RESULT("18"),
     DISEASE("19"), JOIN("20"), POSITION("21"), FAMILY("24"), FOOD("27"), PAST("28"), OPERATION("29"),
-    HABIT("25"), SYMPTOM_PERFORMANCE("32"), EVENT_TIME_VALUE("33"), FREQUENCY("34"),
+    HABIT("25"), SYMPTOM_PERFORMANCE("32"), NUMBER_QUANTIFIER("33"), FREQUENCY("34"),
     OTHER("99"),
     VITAL_INDEX("60"), VITAL_INDEX_VALUE("61"), VITAL_RESULT("62"), VITAL_BODY_PART("63"),
     ADDRESS("70"), PERSON("72"), PERSON_FEATURE_DESC("73");
@@ -109,7 +109,7 @@ public enum NegativeEnum {
                 negativeEnum = NegativeEnum.SYMPTOM_PERFORMANCE;
                 break;
             case "33":
-                negativeEnum = NegativeEnum.EVENT_TIME_VALUE;
+                negativeEnum = NegativeEnum.NUMBER_QUANTIFIER;
                 break;
             case "34":
                 negativeEnum = NegativeEnum.FREQUENCY;
@@ -135,6 +135,15 @@ public enum NegativeEnum {
             case "73":
                 negativeEnum = NegativeEnum.PERSON_FEATURE_DESC;
                 break;
+            case "74":
+                negativeEnum = NegativeEnum.EVENT_TIME_DESC;
+                break;
+            case "75":
+                negativeEnum = NegativeEnum.SYMPTOM_INDEX;
+                break;
+            case "80":
+                negativeEnum = NegativeEnum.DEEP_QUANTIFIER;
+                break;
             case "99":
                 negativeEnum = org.diagbot.nlp.util.NegativeEnum.OTHER;
                 break;

+ 50 - 0
nlp/src/main/java/org/diagbot/nlp/util/NlpCache.java

@@ -24,6 +24,8 @@ public class NlpCache {
     public static Map<String, String> standard_info_classify_map = null;
     //树形结构存储大小类
     public static Map<String, Node> standard_info_type_tree_map = null;
+    //后结构化 有可能作为训练样本词性匹配对
+    public static Map<String, List<String>> extract_relation_property_pair_map = null;
 
     public static void createSegmentCache() {
         Configuration configuration = new DefaultConfig();
@@ -50,6 +52,46 @@ public class NlpCache {
         standard_info_classify_map = configuration.loadMapDict("classify.dict");
     }
 
+    public static void createPropertyPairCache() {
+        Configuration configuration = new DefaultConfig();
+        List<String> lines = configuration.readFileContents("relation.dict");
+
+        extract_relation_property_pair_map = new HashMap<>();
+        List<String> list = null;
+        for (String line : lines) {
+            String[] prop = line.split("\\|");
+            if(prop.length != 2) {
+                continue;
+            }
+            String prop1_id = prop[0];
+            String prop2_id = prop[1];
+
+            list = extract_relation_property_pair_map.get(prop1_id);
+            if (list == null) {
+                list = new ArrayList<>();
+                list.add(prop2_id);
+                extract_relation_property_pair_map.put(prop1_id, list);
+            } else {
+                if (!list.contains(prop2_id)) {
+                    list.add(prop2_id);
+                    extract_relation_property_pair_map.put(prop1_id, list);
+                }
+            }
+
+            list = extract_relation_property_pair_map.get(prop2_id);
+            if (list == null) {
+                list = new ArrayList<>();
+                list.add(prop1_id);
+                extract_relation_property_pair_map.put(prop2_id, list);
+            } else {
+                if (!list.contains(prop1_id)) {
+                    list.add(prop1_id);
+                    extract_relation_property_pair_map.put(prop2_id, list);
+                }
+            }
+        }
+    }
+
     public static Segment getSegment_cache() {
         if (segment_cache == null) {
             createSegmentCache();
@@ -78,6 +120,14 @@ public class NlpCache {
         return standard_info_classify_map;
     }
 
+    public static Map<String, List<String>> getExtract_relation_property_pair_map() {
+        if (extract_relation_property_pair_map == null) {
+            createPropertyPairCache();
+        }
+        return extract_relation_property_pair_map;
+    }
+
+
     public static Map<String, Node> getStandard_info_type_tree_map() {
         if (standard_info_type_tree_map == null) {
             standard_info_type_tree_map = new HashMap<>();

+ 1 - 1
nlp/src/main/java/org/diagbot/nlp/util/NlpUtil.java

@@ -22,7 +22,7 @@ public class NlpUtil {
 
     public static boolean isNumberString(Lexeme l) {
         if (l == null) return false;
-        if (NlpUtil.isFeature(l.getProperty(), new NegativeEnum[]{NegativeEnum.EVENT_TIME_VALUE})) {
+        if (NlpUtil.isFeature(l.getProperty(), new NegativeEnum[]{NegativeEnum.NUMBER_QUANTIFIER})) {
             return true;
         }
         for (char c : l.getText().toCharArray()) {

+ 8 - 8
nlp/src/main/resources/classify.dict

@@ -143,7 +143,7 @@ g7F3bdUcW/MdZ7mb5tfIEvQgFkoqQ3ok+bP1BUHLLW3wYw3OmFaMwEpgEZ36UZf7
 kgZeMHClCtrV6WCFAuDDHfy2M233kiTsN+cFpTQY4RQVxdo99LJipw==
 XTjWGwZLoH0EwBtHs6e4X5aTgvdBbdzhoTbcX2nGOsoDnhZWZUP0yiCpA/DS6Qi8oY2s9ppwh6M=
 is24Ye5iddm6fEywKHx9B7MZhgmOUsbzxTk1DIXFBE8=
-is24Ye5iddmK0fcjJ8eyd7MZhgmOUsbznbNZRJ/hVHrpk0rO900abpW1xItpyjyyVCJvdpd4jdXN/myMdNF0eg==
+is24Ye5iddmK0fcjJ8eyd7MZhgmOUsbzxTk1DIXFBE8=
 KbKku7ucQ39uoije31Jd6G+W3nM3rIhmF2tqckCSSA0=
 KbKku7ucQ39uoije31Jd6KWz2PnvTBpZIF7qeEkmeBaCktTytUBlMf4KRsAz3E/ISmARnfpRl/s=
 J0yrijbW4+gGnMcXRCEMfosqN66+ar7W
@@ -166,7 +166,6 @@ ZS17Dgm0g5sr9CAO6fuC/753qq2yF2cWRRuFBtx13KM=
 ZS17Dgm0g5uWR6gm1zbExfAZVFfu7NX1kG57ceWMY4U=
 ZS17Dgm0g5tIBVGJQ5x2a7I5g1QSIqIgK4DYmKUtYzA=
 ZS17Dgm0g5tIBVGJQ5x2a7LMlg0j5ZRh9csoaYhecJCqne2lkXR8xlSdFN30dJby
-ZS17Dgm0g5vdPmsNsdD0Um4OXV6Tw9PG7V4GyMOt7zhW9jHJ+r/xLg==
 ZS17Dgm0g5vdPmsNsdD0UiKD3zwhl3gh7V4GyMOt7zhW9jHJ+r/xLg==
 ZS17Dgm0g5vdPmsNsdD0Umh6VPbMFwmv7V4GyMOt7zhW9jHJ+r/xLg==
 ZS17Dgm0g5ua8k4aUM5PKiW+LiiN/JuVK4DYmKUtYzA=
@@ -571,7 +570,7 @@ biT7+6/eTStA73c5BkU8Iv00Tw+Yuuba1Mzbbxn2BUM=
 biT7+6/eTSvQqRYkRXd1mqem6OVL2DYu
 biT7+6/eTStuoije31Jd6G+W3nM3rIhmF2tqckCSSA0=
 biT7+6/eTSuAB2gzKtqpWq4nf19T2MqU
-8umKBf1Jy6sfaicHeoCF8OXjpx5nA4g6MjIxj1svdxSvPxEIH24i11LahghHpJv6Uq1EeihJtnM=
+8umKBf1Jy6sfaicHeoCF8JgRO58rvB9tJBHhGXbs1X8=
 x6GEiGzz2ICU5ROAz9tjdNR2w5vXjcqyxuEEjLQMIC4=
 CzsC/WThmpzhQinr3CS6ekHtQNj0yevSOaeYvhBHXvY=
 CzsC/WThmpxRAA1DKWfSfFyeT2PysZmfBPYSNyNJvJo=
@@ -652,6 +651,7 @@ VdEaXpjHPMhE3KrXtZ4jFnyx141wnrJVrK5K/t8x433+cEOlbfXBvIw+DoB3tNkx
 VdEaXpjHPMhE3KrXtZ4jFjbl5mp04vwp7V4GyMOt7zhW9jHJ+r/xLg==
 nfxM7lh8NBwr9CAO6fuC/+y3tyd/IYsPRRuFBtx13KM=
 nfxM7lh8NBxIBVGJQ5x2a7LMlg0j5ZRh9csoaYhecJCqne2lkXR8xlSdFN30dJby
+nfxM7lh8NBzdPmsNsdD0Um4OXV6Tw9PG7V4GyMOt7zhW9jHJ+r/xLg==
 nfxM7lh8NBzdPmsNsdD0Umh6VPbMFwmv7V4GyMOt7zhW9jHJ+r/xLg==
 kQcn4rJ5+wSIw8AEuG/52HRYmXGVWc2IbApsV2kPNEPyHOff8EOfXEpgEZ36UZf7
 kQcn4rJ5+wRQbAZnM3n7QqFv4anH8q04vk1evuCxkYg=
@@ -1069,9 +1069,9 @@ Sv5ZUVDRNO6Q/Hq/3wswJrQPYpPed4B+jAyjgJoQ7Ej8DhMCAel7YQ==
 YKSqFk1xtnBrzoKhrZS3vnd/7tYSAD6ST2UBSEnXHBGzQ9JfHdJhdA==
 kAEpqZYOYUh8Mi3g+UtmRn7Nem7FwaKaBf1kAP5SPwPN/myMdNF0eg==
 n92aLzVCbMZrzoKhrZS3vnd/7tYSAD6ST2UBSEnXHBGzQ9JfHdJhdA==
-vGTRMHlT7dWOdyOfGb/v2IOn+gdxCgtJqv4SN0ostZ4OynHGZLHJ1U1ON5/3sXda
-vGTRMHlT7dV5S2ww+pFvI6JZQ5HykUcZnbNZRJ/hVHrpk0rO900abpW1xItpyjyyVCJvdpd4jdXN/myMdNF0eg==
-yKOlDzIs7nhc6O7BcB2C80SqVvpudkC5H3dH0UgopHaZ1XjihVhZez0cM3bNkS7nr8oAyF3WZ8WCMsNy95esFA==
+vGTRMHlT7dX989ugDrA41289/V8tnqxZ
+vGTRMHlT7dV5S2ww+pFvI6JZQ5HykUcZxTk1DIXFBE8=
+yKOlDzIs7nhc6O7BcB2C80SqVvpudkC546B3tliOrXzN/myMdNF0eg==
 oSQHJTlVLKOK5t5HyKapDIc+GSo+6OPiDHPXiXbzwlsvCXM1oTHVbv03uMLuMSSK
 FOwbzxk4y2jqIs9UBW/+q+mmSU9RNbMwkGZr4+eRI4U=
 1RQlKom7Ksj6D33VUx9Eo2LMfrf1IZ61+g991VMfRKM07ugzK4Ztkg==
@@ -1993,7 +1993,7 @@ TG2nF5Ncrsi2eQd7E/7L8/pi6Ttg5z9+
 uv91IvrscdLTynF7OSe7JJSFGbVKXZx6XzoE/7ysP5E=
 I0AfMaFGa87qfEAsH2aNCeo3TLgrrtwUbFfWwvqv6DtcnVkK0sLzWA==
 UNMVVx+jvGPotR/wAotGZEOVhk4XHR6MPEs1Vn6TkzBK+6t+kXFLTGjmiJmNa7uO
-UQVK32p0OFYfaicHeoCF8OXjpx5nA4g6MjIxj1svdxSvPxEIH24i11LahghHpJv6Uq1EeihJtnM=
+UQVK32p0OFYfaicHeoCF8JgRO58rvB9tJBHhGXbs1X8=
 f/sXuEGD6e9wRp1E8yretyXXtuXEHsB4MHs42UaG4wNKLWjKHv1eUdL3dRY2lfzJ+JZjg2TPXwU=
 f/sXuEGD6e9wRp1E8yretw8GUQEjhNr8ioeOOo+g20RKLWjKHv1eUdL3dRY2lfzJ+JZjg2TPXwU=
 f/sXuEGD6e9wRp1E8yret4AqHoDzTlq+TSy+5AyFc67/Ni1owawmXIy/FH+BLmIGB8iyRjE9KCtKYBGd+lGX+w==
@@ -2194,7 +2194,7 @@ RxS/ltnTmctRAA1DKWfSfFyeT2PysZmfBPYSNyNJvJo=
 IGE9zsJW+7u57CjpIxjk5yS6TQX02J3xjX3GVGWRdyY=
 IGE9zsJW+7shU63syh3o+38G7P2LSuQNwMuCBul29yA=
 ViVL+gbQRbiqknvwnneFey5oQObe3c/6
-dw/Z+L2dU+BUIm92l3iN1WOJQMog79cqMjIxj1svdxSvPxEIH24i11LahghHpJv6Uq1EeihJtnM=
+dw/Z+L2dU+BUIm92l3iN1VuqjpbrBDsKJBHhGXbs1X8=
 DmfFhMe8hpr4immMUcbPkHFb/7z+pNwsld+rWZv9GwM=
 MAvV7aUBpfZc4D9aUywXLBEKMyzUpfW+AO31stI86C54gGsKOYirNQ==
 gxyJNUO3VhzP9r6DlKDR48FOuZAGXCCFQSiGXZnEpBM=

File diff suppressed because it is too large
+ 4344 - 5183
nlp/src/main/resources/push-tc.dict


+ 72 - 0
nlp/src/main/resources/relation.dict

@@ -0,0 +1,72 @@
+RNMak3cFWH4=
+ddolNu+ruoI=
+crSKo8ZJQWw=
+z9odaTsZTe4=
+UtapbxnvICk=
+zCUYt/gJFTA=
+Zz6Ubw81PD0=
+yclD2AmKHJg=
+h4pBhb+B4Lk=
+8hKk85iZesU=
+0hgDIdsSBy4=
+rbTBQUekfEs=
+fxkh89TwKsc=
+ENBQhPq5htU=
+nK40VLls5Zw=
+hlUmDNbK6a4=
+rHRYnTdjAKA=
+5JujAdVP5E8=
+X2j2cnCysms=
+YEYDcVHi1BI=
+YLWWPYmlo7s=
+28BY78TjZOw=
+1zF5xvlmigE=
+5iH5AYe9ogQ=
+dCLIxiAaEPQ=
+nLmMNwLd9hU=
+KO6x8jrh1Go=
+PGU7FXe4EVw=
+Vt65EYLJtik=
+MowtsJaT+Eg=
+15XjiZKWWOQ=
+tvD9gnRGuE0=
+TS5FqQfA3Bo=
+8OTyr31+HZE=
+33mX5o5YCuI=
+eN8E9yHmcuQ=
+Wrhyd5KGRwU=
+oXEQgo+FISY=
+In0GOQRAoNc=
+WeQ7RhGnT3E=
+izBKC43U5Do=
+yIxj3i9brYw=
+6/AAsiRaYHk=
+d6U7t3U9wHI=
+N6s43nxbRgM=
+o15aELxdA/0=
+csWORUAoN0g=
+IheffyTAFTQ=
+URoSRuJSqzQ=
+Hu0VMvGeJYM=
+qi/diuSUvPk=
+2lkFuZbZfSo=
+sVfatV4286o=
+JxjFv6u9Xg0=
+GHAXRYXi1X4=
+3PiS9MWTEcU=
+h0qS3XYvg7w=
+exAkRV4R8YY=
+u6Lr+Jfr3PY=
+Slw/FnB9o4g=
+r7bymlovf1w=
+bSkSwBpuGHs=
+Xoa3vcFiseU=
+TXb4vMJd3ok=
+rc7iV++H97Y=
+itwdzE4pvKw=
+yuYZf2CANH0=
+2J2g4AT+OI4=
+cKsJV2K7OCI=
+yXcIkexvskc=
+W5cHtxiabQI=
+GDA1Yq67XoE=

+ 19 - 16
nlp/src/main/resources/synonym.dict

@@ -629,7 +629,6 @@ ZS17Dgm0g5sr9CAO6fuC/8hcc+w9cvGzRNyq17WeIxYgKxfKdv/2STQt0BAiEkw1
 ZS17Dgm0g5sr9CAO6fuC/35sZlzOzlcLRNyq17WeIxYgKxfKdv/2STQt0BAiEkw1
 ZS17Dgm0g5uWR6gm1zbExWUtew4JtIObSAVRiUOcdmuyzJYNI+WUYfXLKGmIXnCQVu1VNingzjo=
 ZS17Dgm0g5tIBVGJQ5x2aycHVxupfSwiA3e/hrLacJyeWEPZoG2eWrhsKNhJ+U8g
-ZS17Dgm0g5vdPmsNsdD0Um4OXV6Tw9PGaXOWE5tzEK+IJZr3POR7Sf5pqy+r9yUWOxgqIHpj3G0=
 ZS17Dgm0g5vdPmsNsdD0Umh6VPbMFwmvaXOWE5tzEK+IJZr3POR7SRHISdV4Hc+fydPG0/OzNPR3RjFcViAD/g==
 ZS17Dgm0g5ua8k4aUM5PKq73S6nwnkppA3e/hrLacJwXL5Tq4h/ozb5l3nVmjNgjQwipD9IysUYUEksYV8b9Bw==
 +hIX2IIIwtSEneK88ldV/r7DLJTv6yKM
@@ -1128,13 +1127,13 @@ de3O9146cmXEf7AYlPTtLz0ptOovES5U8QoYEmymkjxKmNwK5J+nJW89/V8tnqxZ
 de3O9146cmU+qBAy6BP5slscF5ARDUxqJBHhGXbs1X8=
 9UQdU1VIB/a1n0bOieelh01yVTwP1qU9kx3krtyTE7P2MQI6lBnzMmvbDh0e7DLEooGAMkxTT8qKKpLgWgnmPQ==
 9UQdU1VIB/bATytW1HDZWrJCusFQIYykVxIYv/I8ImOds1lEn+FUen9DQUawJnywlwMFIsKVwg0=
-9UQdU1VIB/b2lKc5o6xU31tgWhqdfi+qH3dH0UgopHaZ1XjihVhZez0cM3bNkS7nr8oAyF3WZ8WCMsNy95esFA==
+9UQdU1VIB/b2lKc5o6xU31tgWhqdfi+q46B3tliOrXzN/myMdNF0eg==
 9UQdU1VIB/bCoJsmyfMt75l8T7eOXMOlCRpADMcl1aSQwS7VHa/rlUpgEZ36UZf7
-9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PWH3dH0UgopHaZ1XjihVhZez0cM3bNkS7nr8oAyF3WZ8WCMsNy95esFA==
-9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PWOknbIYzP/rgfd0fRSCikdpnVeOKFWFl7PRwzds2RLuevygDIXdZnxYIyw3L3l6wU
-9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PW0p78q8LIq9Afd0fRSCikdpnVeOKFWFl7PRwzds2RLuevygDIXdZnxYIyw3L3l6wU
+9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PW46B3tliOrXzN/myMdNF0eg==
+9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PWOknbIYzP/rjjoHe2WI6tfM3+bIx00XR6
+9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PW0p78q8LIq9DjoHe2WI6tfM3+bIx00XR6
 9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PWLEy+qjcuA1d3pTXTAKLhpvD2oC+bvnn9
-9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PWLEy+qjcuA1dER03fpAB4dnShSN3MTs7md3/u1hIAPpLchbqz0R3o2UMqBLNK8zcBsCLzUUAIUVY7wH4mxvF0fw==
+9UQdU1VIB/Ztd8WtUYdrl/znlgPCB6PWLEy+qjcuA1dER03fpAB4dnShSN3MTs7m8PagL5u+ef0=
 9UQdU1VIB/Zwt6UpRfaDDfDwwQo29ArSG+9wnSeRaNIpkv6kJrpjXg4nnFjcirxM
 9UQdU1VIB/YCemFOIJjudWYAKjuUUIzqH3dH0UgopHbOvBG0kT8+ebAaN1gC9dry
 l8H5GqJ5C5tnrJCBvdnECNrzivFvriXe3fJUDeMmb0hx85BcxSKCpZrsogROL6eQyN5bmrQ4iMo=
@@ -1180,7 +1179,6 @@ qN3qWT2bGk0lhEi58dRQU0MLaMkQGL5p
 0NdbQ1JU67PxmnQ46QAyrL5mrHhC2c0D
 MIqhjxJmusPrfgC7wGdnmKCUMFUcmUqK
 rn8GV7gaU3UD7zrtOhTM7UpgEZ36UZf7
-6PVclh97Li9kZ3B7iyrR4IK6LuRYaN4w
 shc7AW2Xd8aiCoIwYr9UnIK6LuRYaN4w
 ptgLW3r/PWnU3bM62p5k2+VSu8PfUGPHZbG8KUhskwQ=
 SZw+xPbMTLaoJwnEzmAuk0pgEZ36UZf7
@@ -1308,8 +1306,8 @@ e8PUaMqGKBh/boeU1LayQ/eAZANdp2NqlwMFIsKVwg0=
 e8PUaMqGKBgnOeG/vzDKa/eAZANdp2NqlwMFIsKVwg0=
 e8PUaMqGKBgnOeG/vzDKa5/Js1I36o/I94BkA12nY2qXAwUiwpXCDQ==
 6gl1PQtSPITAM1Cn4tvRWYWXXw0xPh16UNny9B8YYdiAzuLCdJndHw==
-6gl1PQtSPIThUupcRu/meltgWhqdfi+qH3dH0UgopHaZ1XjihVhZez0cM3bNkS7nr8oAyF3WZ8WCMsNy95esFA==
-6gl1PQtSPIThUupcRu/meltgWhqdfi+qOknbIYzP/rgfd0fRSCikdpnVeOKFWFl7PRwzds2RLuevygDIXdZnxYIyw3L3l6wU
+6gl1PQtSPIThUupcRu/meltgWhqdfi+q46B3tliOrXzN/myMdNF0eg==
+6gl1PQtSPIThUupcRu/meltgWhqdfi+qOknbIYzP/rjjoHe2WI6tfM3+bIx00XR6
 6gl1PQtSPITuEalfNPhjrJCllYm3poEuk+Mh7vVsVNCvPxEIH24i10hQhszzwn4w
 g6f6B3EKC0mq/hI3Siy1nglQqGIMmVSGXADhFGeuui4=
 g6f6B3EKC0mq/hI3Siy1ntTz7b53mErNb1C6VNNaNeBcAOEUZ666Lg==
@@ -1612,6 +1610,7 @@ dlvIGPFnmQpX8enb6BlG6BnbBLCi9C1xdig3icfaFQlw2EZUYZ9TOUs17/uBe6qF
 L8PH6RYvQ4lWgHE3Y5h4cldsnAssKndjhawXDHx/XgCbj/LPAa7CXNgUKjvPI0f/
 kb80gvcxzar3vBhNkU59YyzV5/OP8SC7ryKysOD+KUY=
 AIvTjMd3sKt841qlXVGmBBlLFlAQ+u3i
+ZZW35Jl3SZkifvj0UAEZU34diksKryCjFWN3xRThYNo=
 cZarH8MV8sEWjRnZhCj020pgEZ36UZf7
 H0UnDFxpQ1VWgHE3Y5h4cldsnAssKndjiOTt1VlHverHofGbR/+lo9gUKjvPI0f/
 MfArfnKi0sbS/VhD/5yr6fCKLkTxTRsjQsjDFyh0etI=
@@ -3540,6 +3539,7 @@ bK8Zpab/PptNYls6bckCKxinOyXiON3Htew4/25sQfh7zD+13Aep3lpFaNgH43hC
 bK8Zpab/PptNYls6bckCKxinOyXiON3HgDYFNCmIYdO17Dj/bmxB+HvMP7XcB6neWkVo2AfjeEI=
 bK8Zpab/PptNYls6bckCKxinOyXiON3HgDYFNCmIYdOANgU0KYhh07XsOP9ubEH4e8w/tdwHqd5aRWjYB+N4Qg==
 gJj1miT0Dpc1Teioz1asRWmZ459ubdRU3yRSpwZ0fTK1nwJu9BVlioqjLl2lbokkftghrsieFJwwNgYSse52/Q==
+pGY+NbyU+NkrrFGAy9hf932uwRjCoH5r51xSaTWBb1w=
 w0WmywVpDHSNrqDg67izJrYnEsXqsKL9
 QQ6kZzWcKiS1QXPpBNd8kVhwc9eBN/mHj7bszohDE5Tg6njkDcx/a3rgmStR4H73
 QQ6kZzWcKiS1QXPpBNd8kVNMtFmODhCbtdI2dzduC63g6njkDcx/a3rgmStR4H73
@@ -3654,8 +3654,8 @@ ZBtYs5JxlYCjkX6oscEYTJi/5Ct45y/IKoRVmqDu6EpM/c4nf660CgenDUwirkO7/tQdv6HyW9I=
 JfAqQw/V4b/QcyJFGRC0xlYTsyw0VJlFE4IQ/Ea/Dk7Op9M+hg4jyCxjPw/dRXfhAk8boZMV758=
 Q6m4w98ORDPTnCoNuopNUbNgOYQqZs9WQ6m4w98ORDPTnCoNuopNUVYTsyw0VJlFz2KI26nysDk=
 glZpOO/W/STyqlwFzfkxER1oYwm/AKPa81jxr1KQOS2hgsStmYZQsGXtBri4gB36e9i2hhOP1R0UEksYV8b9Bw==
-lxlNfXS6NWoqC7DeKTSFhqiU41bUh06N82LkqoFOvqov02E+PS4tY4JjAKIXjxhCOUMiJ6qCUVrXu1uNY2YQ7dAeOtvsKZvp3oJBa7qTZsRKYBGd+lGX+w==
-K3XY2gXxrj6O9I/bVh3qKlN/DqrmR/+onpFBOf2lo8T3bF2YBLVV7hrhQcdmHdP4HKwrdc8Bhd6KtGGykPQJRA==
+lxlNfXS6NWoqC7DeKTSFhqiU41bUh06N82LkqoFOvqov02E+PS4tY4JjAKIXjxhCOUMiJ6qCUVrrOptbxROGjg==
+K3XY2gXxrj6O9I/bVh3qKlN/DqrmR/+onpFBOf2lo8T3bF2YBLVV7hrhQcdmHdP4Em+yvP+dZGo=
 7PEEmsxzMavBVR112c45PK1CSrL3ubfqXm5TESfZ1kFTfw6q5kf/qDekRsSu48ACSmARnfpRl/s=
 7PEEmsxzMavBVR112c45PFYTsyw0VJlFZ3D0Nl+7C0A7YcIVms4lTfNi5KqBTr6q4F3GxB/D7m0=
 7PEEmsxzMavrinzVJ0GqWMwzq+/sQN3edfInOFUXreTOp9M+hg4jyPNi5KqBTr6qV2Le1m4XGVw=
@@ -3886,7 +3886,7 @@ R6xz8nmzr3Xlb8gQKmU9YUesc/J5s691yPqa609z0ko=
 TyZCs03OO61kV2x2dib4E08mQrNNzjut7NLBEkDmDJE=
 b2+cfjq6Fbi5I2VYQwgBtEpgEZ36UZf7
 gmLn+L6avv8FFenp4KQhsYJaywY2UE6j
-fZq/mbmr6SEACmBJZPhpj32av5m5q+kh9MBjceAxlF4oWyTBbLHbfvIYOSEL/t19
+fZq/mbmr6SEACmBJZPhpj32av5m5q+khQHEd+Y7x1d4=
 fZq/mbmr6SGr+VybLywcTN78OJA4ATxqLq/XRt9FbeH9N7jC7jEkig==
 fZq/mbmr6SGyOK0rmuVkhy2USdf7wSSZw3dFKQusy1kur9dG30Vt4f03uMLuMSSK
 2BSM+1lBtjxIqeqTZMg7q6sRqNjb0yycdqq3ze1kqOavsHaAJMce6g==
@@ -4517,7 +4517,7 @@ vex7K0bOHIGOR+IyZWBLhGkKT3CtulN5
 KI6VTaqubnu4RS5mEn/iyx4LqGcyn5L82/ac/I99K9htexZ15YnMopUfeC/WJulCXZ/HAkHq0qN1+RhYXqM100OrEUSwHU6W/106SjBTEu2XcnkrfHl5wRO2icIlBY3e
 KI6VTaqubnu4RS5mEn/iyybITkU+QsAQ8ovKqaT50Bhjbi6oMwq51ieSpmlySTag31VqLkIaWnU=
 YpvY+G8a1eSDWVXzQCYSoOnsg1FMZCBUg1lV80AmEqD8C0Ms3Yu4qA==
-wmRvRyr6N5yAmEiSg+1tM8I503QdVi5x
+5jM/3b9i31E9a96tOwWxlkZqz4/zUosBFWN3xRThYNo=
 zF+QtFd3/zOZlLyuqFrbpnNh2kJa4EYYd/dwi31nZXg=
 wY62Cw7bf9UPQGI0Um6WxIZc9HnDKZwuWWEtRbtOPFA=
 bXsWdeWJzKIhj0+n6MoMdJdyeSt8eXnBE7aJwiUFjd4=
@@ -4597,7 +4597,9 @@ FeneHV0jniV+QJMdObX42idOUF2fo3Vfdaak9DBsX0/1IQBYBPMjZZ2chw2JdeqnK1E/wxTJGka2KqzI
 FeneHV0jniViKLplWTxde0aGKBDe6KHgFwOrsCFAWPttd7Uiq/ivKg==
 FeneHV0jniXH6G7p2o7OmE9fABqP9Xek+hh3HD/b6EpEi+MQl+GiV54vUh3E8iWx
 Q+cjzMmYU+6yrAI8b6C0g0pgEZ36UZf7
+bFjFv7/SHH8F2H5RglN53b5U44NPPMQwfkRC94tU/To=
 OYu/p+Z1BL8nOyzdN3BUYEpgEZ36UZf7
+LfX+of1ooG7dIWWmQpCPJGrAhdGym+dGfkRC94tU/To=
 BrdHo2/KIq/ZSNPYgFwKJwa3R6NvyiKvDJMY4fCtDFY=
 BrdHo2/KIq/8ABeAT8ORjLR/UMlmTa53QFfN5c9EqNhvKO84YTnyQ4EruWqVpiHh
 HWLb/nfuHAkpw9nl6LwU96G5PfH0Oralbz39Xy2erFk=
@@ -5225,6 +5227,7 @@ ySmvEQkp+QnDVB+FOWxfQqIfbBaKuOTwesVRDwyG1+rvq8gD9jrJi33hFtJfBaSgaOaImY1ru44=
 ySmvEQkp+QnDVB+FOWxfQm4kpY+Uw9aXX4TGvKe7ChFT0jPxNVIYaq/YuAHzCZ7mgAre32dOKcEAN2vwm/8xqVN/DqrmR/+o3C2dAq296HPP8GBhzPctH2rERi9wNKpAYVVeUs9o0SM=
 ySmvEQkp+QlYsYlOjJf65juETX9TuLx5dEofaAkvq0zWeNdZ3kO++W2Nuxn2SU1l9GBUoa5JGn3O7tfDrONcIAESvSwUZDzP
 TTZnVqSyUmHOmew3/oTijw==
+4uadpArGqCfeoIvuUniQ8uW7BrAdxwgo
 2s+Nci9wvwdZqPGtQn/hwCr2WNh4R9dDKQFzrAJDaZc=
 x1YYrWRa5HvjsXZ3A7sitUpgEZ36UZf7
 zMEGGathOY5DKMBhndIq8GK633mBPuhHfXpg2jZoGZlnlaMm6UyUQQ==
@@ -5294,7 +5297,6 @@ NxH/k5Kw1zRFMs6dfy4e+g==
 hU2JsvCVd8h/G+pSk/DU1J/BpKWov8L8hU2JsvCVd8jFsQ/2b03/Ag==
 QRRawhtQjw9SNf5GnzWF/A==
 kUUgvamYK4HrilGZfSe60Q==
-fGbs93rwRczzEpRMHp+90w==
 VBRgeKuJ7PjWeNdZ3kO++ZI/hKRWCsMo
 /xGMK7LNshCdpnC0XD4MGw==
 IsVzTv93VpAJXKD0DIc8rg==
@@ -5357,7 +5359,7 @@ jDc+I5DLhjfCoj1DBrmTZb07UWCqWi6/Le6jWvY+EOw6FxNEsc+CmUKPm+UN1WcG
 jDc+I5DLhjcgtkRUkcx1/C3uo1r2PhDsOhcTRLHPgplCj5vlDdVnBg==
 jDc+I5DLhjcgtkRUkcx1/NbvkPoUxHEmOhcTRLHPgplCj5vlDdVnBg==
 jDc+I5DLhjev5CnjxWLdWUzkJFOBOazAFSRIAu1hEegKJZuCHMXeWEpgEZ36UZf7
-sOt8Hu+fh1fZRWVDAXGH/F9FQ+5x9IFZlkKQ4jx5xBc=
+sOt8Hu+fh1do/VvBBU1qybDrfB7vn4dXkSlT2wHlmBI=
 3V3869ulMfYcAs4LRBtWOfOgtC3urvRzHOlg6a72ToWwQJXgvPwD7slFVJy9t4QF
 p9xqtUeJYuVeJKC1Gwo1gZ/BpKWov8L8p9xqtUeJYuXCArlCzKmjAw==
 am6mi0e3+dmx5mhrEdvgkRApXgoL452bSJAqyeGLlGQ=
@@ -6205,6 +6207,7 @@ RmdvwfLNayZfroQ+x6I5zJ/Js1I36o/IR4E0DI/N9m/KSqm/hVqrhg==
 1XzDXoXAd++hFsW90x0cOF8m7Hn5ueD31XzDXoXAd+9pbo+u8k2ZvA==
 1XzDXoXAd++hFsW90x0cOCHoUhwn+q4A1XzDXoXAd+9pbo+u8k2ZvA==
 1XzDXoXAd+8Nk3vYyUw3rFKaXqLtcC4+JdoLa5V/XCa5OeBLEXi0fJcDBSLClcIN
+TtyaRnokW84a0HQISHomR6XKNvciEBnB
 TtyaRnokW87Z5+YxrRuIUOHr9YA0+LL7FWN3xRThYNo=
 vBv0+XanS1xy02rvkOmlZtg0B8HVH9dkB451+nWReBM=
 3Us4hTxwFHUTedVcW+1ACu0liRe9U4t8
@@ -7827,6 +7830,7 @@ IktfsfyMWm7clP9Ii58LNHI1r7s51gHJBCwP8JTwb7rM1vPXRZ/8mVOlBV102mLp9iDZhXhDlM4=
 IktfsfyMWm57ko0EuedelZ/BpKWov8L8IktfsfyMWm4EHpBBsvMLUA==
 +QcUSjkdonhy40or12/sGgQRLw+xuWJZah2H2V59QN4=
 tFAlzsMnb+LIAHh1qZ4IWtfY3AGky2hs
+iGEVqbed1ReJ+SxO/CjoZ8ydZx9MvdRI
 UmfuMXcjH+3SUR91SkRm53XSEWqDKmJuNC0MX2gH6Hs=
 mdJR4ErXZk7fvd05/i8Dew==
 Kne5s2y3NYP2aXMD1JQvMqCdw0eXUe4I
@@ -8031,7 +8035,6 @@ f4Bsgs1TLUfXnN3+7N0eCzUYiY5PmsEoum4XKEI1ZZTclP9Ii58LNHZ2SZI3b3Dl
 f4Bsgs1TLUfXnN3+7N0eC4iIuWJGYpEtvp/oXdR6WA/clP9Ii58LNHZ2SZI3b3Dl
 cxIZrq1MlLrdvSYsqXiVgsJs3WzgRo2va1bm6p+Q5PjCbN1s4EaNr7aClMyVtRtE
 uKyAHyqaIxfXG+wCtdLL17s83OBoLlJqHqU5Lyx5fpKzbiZPFjI/BD+TziM2DqE3
-Si3i0N+haNjbxvLiNJw/h8k4LfnoNlE3
 P4WI8m/LWq3E9Q59E2C13NveCQfKaHmxcPdBYsgvPQg=
 wM+FgacqLJ/O8peESPke16l9UD9WNl4N5iLhPJLE63E2cff/jH5cKUpgEZ36UZf7
 b8nVx09fy5I4ol1WGH/UY00tZnoopWBlhKfxEUnLzjemS28QynV3zClyN7vDVREblwMFIsKVwg0=

File diff suppressed because it is too large
+ 16242 - 3990
nlp/src/main/resources/tc.dict


+ 404 - 0
nlp/src/test/java/org/diagbot/nlp/test/EntityExtractTest.java

@@ -0,0 +1,404 @@
+package org.diagbot.nlp.test;
+
+import org.diagbot.nlp.participle.ParticipleUtil;
+import org.diagbot.nlp.participle.cfg.Configuration;
+import org.diagbot.nlp.participle.cfg.DefaultConfig;
+import org.diagbot.nlp.participle.word.Lexeme;
+import org.diagbot.nlp.participle.word.LexemePath;
+import org.diagbot.nlp.participle.word.Segment;
+import org.diagbot.nlp.util.Constants;
+import org.diagbot.nlp.util.NegativeEnum;
+import org.diagbot.pub.jdbc.MysqlJdbc;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class EntityExtractTest {
+    public static void main(String[] args) {
+
+        Configuration configuration = new DefaultConfig();
+        Segment segment = configuration.loadMainDict("tc.dict");
+
+        EntityExtractTest entityExtractTest = new EntityExtractTest();
+        List<Map<String, String>> data = entityExtractTest.searchData();
+
+        Map<String, List<String>> pairList =  entityExtractTest.searchPropertyPair();
+
+        Map<String, String> lexiconTypeMap = entityExtractTest.searchLexiconType();
+
+        String present = "";
+        String[] partPresents;
+        String sentenceId = "";
+        LexemePath<Lexeme> lexemes = null;
+        List<Map<String, Object>> results_pair = new ArrayList<>();
+        List<Map<String, Object>> results_none_pair = new ArrayList<>();
+        try {
+            for (int i = 0; i < data.size(); i++) {
+                present = data.get(i).get("xbs");
+                present = present.replaceAll("\r\n", "");
+                sentenceId = data.get(i).get("zyxh");
+                partPresents = present.split(";|;|。");
+                for (int k = 0; k < partPresents.length; k++) {
+                    if (partPresents[k].length() == 0) {
+                        continue;
+                    }
+                    lexemes = ParticipleUtil.participle(partPresents[k], segment);
+
+                    lexemes = entityExtractTest.combineValidate(lexemes);
+                    for (int l_1 = 0; l_1 < lexemes.size(); l_1++) {
+                        Lexeme lexeme_1 = lexemes.get(l_1);
+                        if ("99".equals(lexeme_1.getProperty())) {
+                            continue;
+                        } else {
+                            for (int l_2 = l_1 + 1; l_2 < lexemes.size(); l_2++) {
+                                Lexeme lexeme_2 = lexemes.get(l_2);
+                                if (!"99".equals(lexeme_2.getProperty())) {
+                                    boolean isPair = entityExtractTest.isPair(pairList, lexeme_1.getProperty(), lexeme_2.getProperty());
+                                    Map<String, Object> result = new HashMap<>();
+                                    result.put("sentence_id", sentenceId);
+                                    result.put("sentence_uuid", sentenceId + "_" + k);
+                                    result.put("sentence", partPresents[k]);
+                                    result.put("entity_1_name", lexeme_1.getText());
+                                    result.put("entity_1_position", lexeme_1.getOffset() + "," + (lexeme_1.getOffset() + lexeme_1.getLength() - 1));
+                                    result.put("entity_1_prop", lexeme_1.getProperty());
+                                    result.put("entity_1_prop_name", entityExtractTest.propId2Name(lexiconTypeMap, lexeme_1.getProperty()));
+                                    result.put("entity_2_name", lexeme_2.getText());
+                                    result.put("entity_2_position", lexeme_2.getOffset() + "," + (lexeme_2.getOffset() + lexeme_2.getLength() - 1));
+                                    result.put("entity_2_prop", lexeme_2.getProperty());
+                                    result.put("entity_2_prop_name", entityExtractTest.propId2Name(lexiconTypeMap, lexeme_2.getProperty()));
+                                    result.put("relation", "0");
+                                    if (isPair) {
+                                        results_pair.add(result);
+                                    } else {
+                                        results_none_pair.add(result);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (results_pair.size() > 0) {
+                MysqlJdbc nlpJdbc = new MysqlJdbc("root", "diagbot@20180822", "jdbc:mysql://192.168.2.235:3306/nlp-web?useUnicode=true&characterEncoding=UTF-8");
+                nlpJdbc.insert(results_pair, "re_tagging_result_part_new", new String[]{"sentence_id", "sentence_uuid", "sentence", "entity_1_position", "entity_2_position",
+                        "entity_1_name", "entity_2_name", "entity_1_prop", "entity_2_prop", "entity_1_prop_name", "entity_2_prop_name", "relation"});
+            }
+
+            if (results_none_pair.size() > 0) {
+                MysqlJdbc nlpJdbc = new MysqlJdbc("root", "diagbot@20180822", "jdbc:mysql://192.168.2.235:3306/nlp-web?useUnicode=true&characterEncoding=UTF-8");
+                nlpJdbc.insert(results_none_pair, "re_tagging_result_part_new_none", new String[]{"sentence_id", "sentence_uuid", "sentence", "entity_1_position", "entity_2_position",
+                        "entity_1_name", "entity_2_name", "entity_1_prop", "entity_2_prop", "entity_1_prop_name", "entity_2_prop_name", "relation"});
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void participleReload() {
+        Configuration configuration = new DefaultConfig();
+        Segment segment = configuration.loadMainDict("tc.dict");
+
+        EntityExtractTest entityExtractTest = new EntityExtractTest();
+        List<Map<String, String>> data = entityExtractTest.searchData();
+
+        Map<String, List<String>> pairList =  entityExtractTest.searchPropertyPair();
+
+        Map<String, String> lexiconTypeMap = entityExtractTest.searchLexiconType();
+
+        String present = "";
+        String[] partPresents;
+        String sentenceId = "";
+        LexemePath<Lexeme> lexemes = null;
+        try {
+            for (int i = 0; i < data.size(); i++) {
+                present = data.get(i).get("xbs");
+                present = present.replaceAll("\r\n", "");
+                sentenceId = data.get(i).get("zyxh");
+                partPresents = present.split(";|;|。");
+                for (int k = 0; k < partPresents.length; k++) {
+                    if (partPresents[k].length() == 0) {
+                        continue;
+                    }
+
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public List<Map<String, String>> searchData() {
+        MysqlJdbc nlpJdbc = new MysqlJdbc("root", "diagbot@20180822", "jdbc:mysql://192.168.2.235:3306/nlp-web?useUnicode=true&characterEncoding=UTF-8");
+        List<Map<String, String>> data = nlpJdbc.query("tb_ryjl_extract", new String[]{"zyxh", "xbs"}, " limit 15, 100");
+        return data;
+    }
+
+    public Map<String, String> searchLexiconType() {
+        MysqlJdbc nlpJdbc = new MysqlJdbc("root", "diagbot@20180822", "jdbc:mysql://192.168.2.235:3306/nlp-web?useUnicode=true&characterEncoding=UTF-8");
+        List<Map<String, String>> data = nlpJdbc.query("re_lexicon_type", new String[]{"id", "name"}, " limit 0, 1000");
+
+        Map<String, String> result = new HashMap<>();
+        for (Map<String, String> map : data) {
+            result.put(map.get("id"), map.get("name"));
+        }
+        return result;
+    }
+
+    public List<Map<String, String>> searchTaggingResult() {
+        MysqlJdbc nlpJdbc = new MysqlJdbc("root", "diagbot@20180822", "jdbc:mysql://192.168.2.235:3306/nlp-web?useUnicode=true&characterEncoding=UTF-8");
+        List<Map<String, String>> data = nlpJdbc.query("re_tagging_result_part", new String[]{"sentence_id", "sentence_uuid", "sentence", "entity_1_name", "entity_2_name", "entity_1_position", "entity_2_position"}, " order by sentence_id, sentence_uuid");
+
+        Map<String, List<Map<String, List<Map<String, String>>>>> taggingResults = new HashMap<>();
+
+        String sentence_id = "";
+        String sentence_uuid = "";
+
+        List<Map<String, List<Map<String, String>>>> sentence_id_list = null;
+        Map<String, List<Map<String, String>>> sentence_id_map = null;
+        List<Map<String, String>> sentence_uuid_list = null;
+        for (Map<String, String> map : data) {
+            sentence_id = map.get("sentence_id");
+            sentence_uuid = map.get("sentence_uuid");
+            if (taggingResults.get(sentence_id) == null) {
+                sentence_id_list = new ArrayList<>();
+                sentence_uuid_list = new ArrayList<>();
+                sentence_uuid_list.add(map);
+
+
+            }
+        }
+        return data;
+    }
+
+    public Map<String, List<String>> searchPropertyPair() {
+        MysqlJdbc nlpJdbc = new MysqlJdbc("root", "diagbot@20180822", "jdbc:mysql://192.168.2.235:3306/nlp-web?useUnicode=true&characterEncoding=UTF-8");
+        List<Map<String, String>> data = nlpJdbc.query("re_lexicon_property_pair", new String[]{"prop1_id", "prop2_id"}, " where has_relation = 1");
+
+        Map<String, List<String>> result = new HashMap<>();
+        List<String> list = null;
+        for (Map<String, String> map : data) {
+            String prop1_id = map.get("prop1_id");
+            String prop2_id = map.get("prop2_id");
+
+            list = result.get(prop1_id);
+            if (list == null) {
+                list = new ArrayList<>();
+                list.add(prop2_id);
+                result.put(prop1_id, list);
+            } else {
+                if (!list.contains(prop2_id)) {
+                    list.add(prop2_id);
+                    result.put(prop1_id, list);
+                }
+            }
+
+            list = result.get(prop2_id);
+            if (list == null) {
+                list = new ArrayList<>();
+                list.add(prop1_id);
+                result.put(prop2_id, list);
+            } else {
+                if (!list.contains(prop1_id)) {
+                    list.add(prop1_id);
+                    result.put(prop2_id, list);
+                }
+            }
+        }
+        return result;
+    }
+
+    private boolean isPair(Map<String, List<String>> result, String prop1_id, String prop2_id) {
+        String[] prop1_ids = prop1_id.split(",");
+        String[] prop2_ids = prop2_id.split(",");
+        List<String> list = null;
+        for (int i = 0; i < prop1_ids.length; i++) {
+            list = result.get(prop1_ids[i]);
+            if (list == null) continue;
+            for (int j = 0; j < prop2_ids.length; j++) {
+                if (list.contains(prop2_ids[j])) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public String propId2Name(Map<String, String> map, String prop_id) {
+        String[] prop_ids = prop_id.split(",");
+
+        String prop_name = "";
+        for (int i = 0; i < prop_ids.length; i++) {
+            if (i == 0) {
+                prop_name = map.get(prop_ids[i]);
+            } else {
+                prop_name = prop_name + "," + map.get(prop_ids[i]);
+            }
+        }
+        return prop_name;
+    }
+
+    public String lexeme2Text(List<Lexeme> lexemes) {
+        String text = "";
+        for (Lexeme l : lexemes) {
+            text = text + l.getText();
+        }
+        return text;
+    }
+
+    private LexemePath<Lexeme> combineValidate(LexemePath<Lexeme> lexemes) {
+        Lexeme l = null;
+        LexemePath<Lexeme> results = new LexemePath<>();
+        for (int i = 0, len = lexemes.size(); i < len; i++) {
+            l = lexemes.get(i);
+            if (l.getProperty() != null
+                    && (l.getProperty().equals(Constants.word_property_time) || l.getProperty().equals(Constants.word_property_unit))) {
+                findLast(lexemes, i, l, results);
+            } else {
+                results.add(l);
+            }
+        }
+        return results;
+    }
+
+    private void findLast(LexemePath<Lexeme> lexemes, int index, Lexeme lexeme, LexemePath<Lexeme> results) {
+        Lexeme last_l = null;
+        if (index > 0) {
+            index--;
+            last_l = lexemes.get(index);
+            if ("×".equals(last_l.getText()) && index > 0) {
+                lexeme.setOffset(last_l.getOffset());
+                lexeme.setLength(last_l.getLength() + lexeme.getLength());
+                lexeme.setText(last_l.getText() + lexeme.getText());
+                results.remove(results.size() - 1);
+                index--;
+                last_l = lexemes.get(index);
+            }
+            if (isNumberString(last_l)) {
+                lexeme.setOffset(last_l.getOffset());
+                lexeme.setLength(last_l.getLength() + lexeme.getLength());
+                lexeme.setText(last_l.getText() + lexeme.getText());
+                results.remove(results.size() - 1);
+            }
+            results.add(lexeme);
+        }
+    }
+
+    public static boolean isNumberString(Lexeme l) {
+        if (l == null) return false;
+        if (isFeature(l.getProperty(), new NegativeEnum[]{NegativeEnum.NUMBER_QUANTIFIER})) {
+            return true;
+        }
+        for (char c : l.getText().toCharArray()) {
+            if (c >= '0' && c <= '9') {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isFeature(String property, NegativeEnum[] features) {
+        if (property == null) {
+            return false;
+        }
+        if (features == null || features.length == 0) {
+            return true;
+        }
+        if (property.indexOf(",") > 0) {
+            String[] properties = property.split(",");
+            for (int i = 0; i < properties.length; i++) {
+                for (NegativeEnum nenum : features) {
+                    if (NegativeEnum.parseOfValue(properties[i]) == nenum) {
+                        return true;
+                    }
+                }
+            }
+        } else {
+            for (NegativeEnum nenum : features) {
+                if (NegativeEnum.parseOfValue(property) == nenum) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    class TaggingResult {
+        private String sentence_id;
+        private String sentence_uuid;
+        private String sentence;
+        private String entity_1_name;
+        private String entity_2_name;
+        private String entity_1_position;
+        private String entity_2_position;
+
+        List<TaggingResult> taggingResults = new ArrayList<>();
+
+        public String getSentence_id() {
+            return sentence_id;
+        }
+
+        public void setSentence_id(String sentence_id) {
+            this.sentence_id = sentence_id;
+        }
+
+        public String getSentence_uuid() {
+            return sentence_uuid;
+        }
+
+        public void setSentence_uuid(String sentence_uuid) {
+            this.sentence_uuid = sentence_uuid;
+        }
+
+        public String getSentence() {
+            return sentence;
+        }
+
+        public void setSentence(String sentence) {
+            this.sentence = sentence;
+        }
+
+        public String getEntity_1_name() {
+            return entity_1_name;
+        }
+
+        public void setEntity_1_name(String entity_1_name) {
+            this.entity_1_name = entity_1_name;
+        }
+
+        public String getEntity_2_name() {
+            return entity_2_name;
+        }
+
+        public void setEntity_2_name(String entity_2_name) {
+            this.entity_2_name = entity_2_name;
+        }
+
+        public String getEntity_1_position() {
+            return entity_1_position;
+        }
+
+        public void setEntity_1_position(String entity_1_position) {
+            this.entity_1_position = entity_1_position;
+        }
+
+        public String getEntity_2_position() {
+            return entity_2_position;
+        }
+
+        public void setEntity_2_position(String entity_2_position) {
+            this.entity_2_position = entity_2_position;
+        }
+
+        public List<TaggingResult> getTaggingResults() {
+            return taggingResults;
+        }
+
+        public void setTaggingResults(List<TaggingResult> taggingResults) {
+            this.taggingResults = taggingResults;
+        }
+    }
+
+}

+ 14 - 4
nlp/src/test/java/org/diagbot/nlp/test/LexemeDicTest.java

@@ -31,7 +31,7 @@ public class LexemeDicTest {
             String path = this.getClass().getClassLoader().getResource("").getPath();
             path = path.substring(0, path.indexOf("target"));
             //所有词典库
-            String sql = "select distinct name, category_id, status from kl_standard_info where category_id != 100 and category_id is not null && category is not null order by name";
+            String sql = "select distinct name, category_id, status from kl_standard_info_0318 where category_id != 100 and category_id is not null && category is not null order by name";
             st = conn.createStatement();
             rs = st.executeQuery(sql);
             List<Map.Entry<String, String>> libraryList = rsToMap(rs, true);
@@ -43,7 +43,7 @@ public class LexemeDicTest {
             }
             fw.close();
             //推送词典
-            sql = "select distinct name, category_id from kl_standard_info where status = 1 and category_id != 100 and category_id is not null && category is not null order by name";
+            sql = "select distinct name, category_id from kl_standard_info_0318 where status = 1 and category_id != 100 and category_id is not null && category is not null order by name";
             st = conn.createStatement();
             rs = st.executeQuery(sql);
             libraryList = rsToMap(rs, true);
@@ -55,7 +55,7 @@ public class LexemeDicTest {
             }
             fw.close();
 
-            sql = "select distinct name, relation_name from kl_standard_info where relation_type = 2 and relation_name is not null order by name";
+            sql = "select distinct name, relation_name from kl_standard_info_0318 where relation_type = 2 and relation_name is not null order by name";
             st = conn.createStatement();
             rs = st.executeQuery(sql);
 
@@ -68,7 +68,7 @@ public class LexemeDicTest {
             }
             fw.close();
 
-            sql = "select distinct name, relation_name from kl_standard_info where relation_type = 3 and relation_name is not null order by name";
+            sql = "select distinct name, relation_name from kl_standard_info_0318 where relation_type = 3 and relation_name is not null order by name";
             st = conn.createStatement();
             rs = st.executeQuery(sql);
 
@@ -81,6 +81,16 @@ public class LexemeDicTest {
             }
             fw.close();
 
+            fw = new FileWriter(path + "src/main/resources/relation.dict");
+            sql = "select distinct prop1_id, prop2_id from re_lexicon_property_pair where has_relation = 1";
+            st = conn.createStatement();
+            rs = st.executeQuery(sql);
+            while (rs.next()) {
+                fw.write(encrypDES.encrytor(rs.getString(1) + "|" + rs.getString(2)));
+                fw.write("\n");
+            }
+            fw.close();
+
         } catch (IOException ioe) {
             ioe.printStackTrace();
         } catch (SQLException sqle) {

+ 2 - 2
public/src/main/java/org/diagbot/pub/jdbc/MysqlJdbc.java

@@ -151,13 +151,13 @@ public class MysqlJdbc {
                 sb.append(")");
                 first_index++;
 
-                if ((cursor + 1) % 10000 == 0) {
+                if ((cursor + 1) % 1000 == 0) {
                     st.executeUpdate(sql + sb.toString());
                     sb = new StringBuffer();
                     first_index = 0;
                 }
             }
-            if (data.size() % 10000 != 0) {
+            if (data.size() % 1000 != 0) {
                 st.executeUpdate(sql + sb.toString());
             }
             conn.commit();

+ 2 - 2
push-web/src/main/java/org/diagbot/push/controller/AlgorithmController.java

@@ -80,9 +80,9 @@ public class AlgorithmController extends BaseController {
         }
 
         //推送出的诊断信息作为参数传入知识图谱
-        List<String> pushDiags = new ArrayList<>();
+        List<FeatureRate> pushDiags = new ArrayList<>();
         for (FeatureRate fr : bigDataResponseData.getDis()) {
-            pushDiags.add(fr.getFeatureName());
+            pushDiags.add(fr);
         }
         searchData.setPushDiags(pushDiags);
 

+ 57 - 5
push-web/src/main/java/org/diagbot/push/controller/GraphController.java

@@ -1,17 +1,69 @@
 package org.diagbot.push.controller;
 
+import org.diagbot.common.work.ResponseData;
+import org.diagbot.common.work.SearchData;
+import org.diagbot.graph.javabean.GdbResponse;
+import org.diagbot.graphWeb.work.GraphCalculate;
+import org.diagbot.graphWeb.work.HighRiskCalculate;
+import org.diagbot.pub.api.Response;
 import org.diagbot.pub.web.BaseController;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+
 @Controller
 @RequestMapping("/graph")
 public class GraphController extends BaseController {
-    {
-        listView = "/pages/graph/list.html";
+    /**
+     * 推送诊断,治疗
+     * @param request
+     * @param searchData
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/push", method = RequestMethod.POST)
+    @ResponseBody
+    public Response<ResponseData> bayesPageData(HttpServletRequest request, @RequestBody SearchData searchData) throws Exception {
+        Response<ResponseData> response = new Response();
+        GraphCalculate graphCalculate = new GraphCalculate();
+        ResponseData responseData = graphCalculate.calculate(request, searchData);
+        response.setData(responseData);
+        return response;
+    }
+
+    /**
+     * 推送警惕
+     * @param request
+     * @param searchData
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/highRisk", method = RequestMethod.POST)
+    @ResponseBody
+    public Response<GdbResponse> getHighRisk(HttpServletRequest request, @RequestBody SearchData searchData) throws Exception {
+        HighRiskCalculate highRiskCalculate = new HighRiskCalculate();
+        Response<GdbResponse> gdbResponseResponse = highRiskCalculate.calculateHighRisk(request, searchData);
+        return gdbResponseResponse;
     }
 
-    @RequestMapping({"/index"})
-    public String index() {
-        return listView;
+    /**
+     * 推送化验,辅检
+     * @param request
+     * @param searchData
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/lisPacs", method = RequestMethod.POST)
+    @ResponseBody
+    public Response<ResponseData> lisPacsData(HttpServletRequest request, @RequestBody SearchData searchData) throws Exception {
+        Response<ResponseData> response = new Response();
+        GraphCalculate graphCalculate = new GraphCalculate();
+        ResponseData responseData = graphCalculate.getLisPacs(request, searchData);
+        response.setData(responseData);
+        return response;
     }
 }

+ 5 - 0
push-web/src/main/java/org/diagbot/push/controller/RelationController.java

@@ -21,4 +21,9 @@ public class RelationController extends BaseController {
     public String index() {
         return listView;
     }
+
+    @RequestMapping({"/list"})
+    public String list() {
+        return "/pages/label/list.html";
+    }
 }

+ 2 - 0
push-web/src/main/resources/static/index.html

@@ -67,6 +67,8 @@
             <li class="active"><a href="/push-web/participle/index"><i class="fa fa-circle-o"></i>分词示例</a></li>
             <li class="active"><a href="/push-web/extract/index"><i class="fa fa-circle-o"></i>提取特征</a></li>
             <li class="active"><a href="/push-web/relation/index"><i class="fa fa-circle-o"></i>关系抽取</a></li>
+            <li class="active"><a href="/push-web/relation/list"><i class="fa fa-circle-o"></i>数据标注</a>
+            </li>
             <li class="active"><a href="/push-web/algorithm/index"><i class="fa fa-circle-o"></i>算法分析</a></li>
             <li class="active"><a href="/push-web/graph/index"><i class="fa fa-circle-o"></i>知识图谱分析</a></li>
           </ul>

+ 2 - 0
push-web/src/main/resources/static/pages/algorithm/list.html

@@ -63,6 +63,8 @@
                     <ul class="treeview-menu">
                         <li class="active"><a href="/push-web/participle/index"><i class="fa fa-circle-o"></i>分词示例</a></li>
                         <li class="active"><a href="/push-web/extract/index"><i class="fa fa-circle-o"></i>提取特征</a></li>
+                        <li class="active"><a href="/push-web/relation/list"><i class="fa fa-circle-o"></i>数据标注</a>
+                        </li>
                         <li class="active"><a href="/push-web/relation/index"><i class="fa fa-circle-o"></i>关系抽取</a></li>
                         <li class="active"><a href="/push-web/algorithm/index"><i class="fa fa-circle-o"></i>算法分析</a></li>
                     </ul>

+ 2 - 0
push-web/src/main/resources/static/pages/extract/feature.html

@@ -63,6 +63,8 @@
                     <ul class="treeview-menu">
                         <li class="active"><a href="/push-web/participle/index"><i class="fa fa-circle-o"></i>分词示例</a></li>
                         <li class="active"><a href="/push-web/extract/index"><i class="fa fa-circle-o"></i>提取特征</a></li>
+                        <li class="active"><a href="/push-web/relation/list"><i class="fa fa-circle-o"></i>数据标注</a>
+                        </li>
                         <li class="active"><a href="/push-web/relation/index"><i class="fa fa-circle-o"></i>关系抽取</a></li>
                         <li class="active"><a href="/push-web/algorithm/index"><i class="fa fa-circle-o"></i>算法分析</a></li>
                     </ul>

+ 210 - 0
push-web/src/main/resources/static/pages/label/list.html

@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <title>AdminLTE 2 | Invoice</title>
+    <!-- Tell the browser to be responsive to screen width -->
+    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
+    <!-- Bootstrap 3.3.6 -->
+    <link rel="stylesheet" href="../bootstrap/css/bootstrap.min.css">
+    <!-- Font Awesome -->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
+    <!-- Ionicons -->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
+    <!-- Theme style -->
+    <link rel="stylesheet" href="../dist/css/AdminLTE.min.css">
+    <!-- AdminLTE Skins. Choose a skin from the css/skins
+         folder instead of downloading all of them to reduce the load. -->
+    <link rel="stylesheet" href="../dist/css/skins/_all-skins.min.css">
+
+    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
+    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
+    <!--[if lt IE 9]>
+    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
+    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
+    <![endif]-->
+    <style>
+        .interval {
+            padding: 1px 8px !important;
+        }
+
+        #my_file {
+            visibility: hidden; /* 隐藏 */
+        }
+    </style>
+</head>
+<body class="hold-transition skin-blue sidebar-mini">
+<div class="wrapper">
+
+    <header class="main-header">
+        <!-- Logo -->
+        <a href="#" class="logo">
+            <!-- logo for regular state and mobile devices -->
+            <span class="logo-lg"><b>D</b>iagbot</span>
+        </a>
+
+    </header>
+    <!-- Left side column. contains the logo and sidebar -->
+    <aside class="main-sidebar">
+        <!-- sidebar: style can be found in sidebar.less -->
+        <section class="sidebar">
+            <!-- /.search form -->
+            <!-- sidebar menu: : style can be found in sidebar.less -->
+            <ul class="sidebar-menu">
+                <li class="header">MAIN NAVIGATION</li>
+                <li class="treeview active">
+                    <a href="#">
+                        <i class="fa fa-folder"></i> <span>diagbot</span>
+                        <span class="pull-right-container">
+              <i class="fa fa-angle-left pull-right"></i>
+            </span>
+                    </a>
+                    <ul class="treeview-menu">
+                        <li class="active"><a href="/push-web/participle/index"><i class="fa fa-circle-o"></i>分词示例</a>
+                        </li>
+                        <li class="active"><a href="/push-web/extract/index"><i class="fa fa-circle-o"></i>提取特征</a></li>
+                        <li class="active"><a href="/push-web/relation/list"><i class="fa fa-circle-o"></i>数据标注</a>
+                        </li>
+                        <li class="active"><a href="/push-web/relation/index"><i class="fa fa-circle-o"></i>关系抽取</a>
+                        </li>
+                        <li class="active"><a href="/push-web/algorithm/index"><i class="fa fa-circle-o"></i>算法分析</a>
+                        </li>
+                    </ul>
+                </li>
+            </ul>
+        </section>
+        <!-- /.sidebar -->
+    </aside>
+
+    <!-- Content Wrapper. Contains page content -->
+    <div class="content-wrapper">
+        <!-- Content Header (Page header) -->
+        <section class="content-header">
+            <h1>
+                <small></small>
+            </h1>
+            <ol class="breadcrumb">
+                <li><a href="#"><i class="fa fa-dashboard"></i>Diagbot</a></li>
+                <li><a href="#">nlp</a></li>
+                <li class="active">分词示例</li>
+            </ol>
+        </section>
+        <!-- Main content -->
+        <section class="invoice">
+            <div class="row">
+                <div class="row">
+                    <div class="col-xs-12">
+                        <button type="button" class="btn btn-success pull-right"
+                                onclick="_ajax()"><i
+                                class="fa fa-credit-card"></i> 开始
+                        </button>
+                        <button type="button" class="btn btn-success pull-right"
+                                onclick="after()"><i
+                                class="fa fa-credit-card"></i> 下一页
+                        </button>
+                        <button type="button" class="btn btn-success pull-right"
+                                onclick="before()"><i
+                                class="fa fa-credit-card"></i> 上一页
+                        </button>
+                    </div>
+                </div>
+                <div class="col-md-12">
+                    <!-- TABLE: LATEST ORDERS -->
+                    <div class="box box-info">
+                        <div class="box-header with-border">
+                            <h3 class="box-title">正样本信息</h3>
+                            <div class="box-tools pull-right">
+                                <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
+                                </button>
+                                <button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
+                            </div>
+                        </div>
+                        <!-- /.box-header -->
+                        <div class="box-body">
+                            <div class="table-responsive">
+                                <table class="table no-margin">
+                                    <thead>
+                                    <tr>
+                                        <th width="90%">样本</th>
+                                        <th width="10%">ID</th>
+                                    </tr>
+                                    </thead>
+                                    <tbody id="symptom_extract_id">
+                                    </tbody>
+                                </table>
+                            </div>
+                            <!-- /.table-responsive -->
+                        </div>
+                    </div>
+                    <!-- /.box -->
+                </div>
+                <!-- ./col -->
+            </div>
+
+
+
+            <script>
+                var pageNum = 0;
+                function before() {
+                    if (pageNum > 0) {
+                        pageNum = pageNum -1;
+                    }
+                    _ajax();
+                }
+
+                function after() {
+                    pageNum = pageNum +1;
+                    _ajax();
+                }
+
+                function _ajax() {
+                    $.support.cors = true;
+                    $.ajax({
+                        url: nlp_web_url + '/relation/list',
+                        data: {"pageNum":pageNum},
+                        dataType: "json",
+                        type: "post",
+                        success: function (data) {
+                            var taggingResults = data.data;
+                            var h = "";
+                            $.each(taggingResults, function (index, taggingResult) {
+                                h += "<tr><td>";
+                                h += taggingResult.sentence;
+                                h += "</td>";
+                                h += "<td>";
+                                    h += taggingResult.sentenceId;
+                                h += "</td></tr>";
+                            });
+
+                            $("#symptom_extract_id").html(h);
+                        }
+                    });
+                };
+            </script>
+    </section>
+    <!-- /.content -->
+    <div class="clearfix"></div>
+</div>
+
+<!-- /.control-sidebar -->
+<!-- Add the sidebar's background. This div must be placed
+     immediately after the control sidebar -->
+<div class="control-sidebar-bg"></div>
+</div>
+<!-- ./wrapper -->
+
+<!-- jQuery 2.2.3 -->
+<script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>
+<!-- Bootstrap 3.3.6 -->
+<script src="../bootstrap/js/bootstrap.min.js"></script>
+<!-- FastClick -->
+<script src="../plugins/fastclick/fastclick.js"></script>
+<!-- AdminLTE App -->
+<script src="../dist/js/app.min.js"></script>
+<!-- AdminLTE for demo purposes -->
+<script src="../dist/js/demo.js"></script>
+
+<script src="../dist/js/push.js"></script>
+</body>
+</html>

+ 2 - 0
push-web/src/main/resources/static/pages/participle/sample.html

@@ -63,6 +63,8 @@
           <ul class="treeview-menu">
             <li class="active"><a href="/push-web/participle/index"><i class="fa fa-circle-o"></i>分词示例</a></li>
             <li class="active"><a href="/push-web/extract/index"><i class="fa fa-circle-o"></i>提取特征</a></li>
+            <li class="active"><a href="/push-web/relation/list"><i class="fa fa-circle-o"></i>数据标注</a>
+            </li>
             <li class="active"><a href="/push-web/relation/index"><i class="fa fa-circle-o"></i>关系抽取</a></li>
             <li class="active"><a href="/push-web/algorithm/index"><i class="fa fa-circle-o"></i>算法分析</a></li>
           </ul>

File diff suppressed because it is too large
+ 315 - 88
push-web/src/main/resources/static/pages/relation/sample.html