瀏覽代碼

新增合同签订时间、合同起始时间、合同结束时间字段的提取

znj 1 年之前
父節點
當前提交
aba3e8de64
共有 2 個文件被更改,包括 78 次插入12 次删除
  1. 61 10
      BiddingKG/dl/interface/getAttributes.py
  2. 17 2
      BiddingKG/dl/time/re_servicetime.py

+ 61 - 10
BiddingKG/dl/interface/getAttributes.py

@@ -1550,8 +1550,13 @@ def findAttributeAfterEntity(PackDict,roleSet,PackageList,PackageSet,list_senten
                         if (_subject.label==0 and _object.entity_text in agency_contact ) or (_subject.label==1 and _object.entity_text in tenderee_contact):
                             continue
                         # 角色为中标候选人,排除"质疑|投诉|监督|受理"相关的联系人
-                        if _subject.label in [2,3,4] and re.search("质疑|投诉|监督|受理|项目(单位)?联系",list_sentence[_object.sentence_index].sentence_text[max(0,_object.wordOffset_begin-10):_object.wordOffset_begin]):
+                        if _subject.label in [2,3,4] and re.search("质疑|投诉|监督|受理|项目(单位)?联系|^联系人|请.{0,4}联系",list_sentence[_object.sentence_index].sentence_text[max(0,_object.wordOffset_begin-10):_object.wordOffset_begin]):
                             continue
+                        if _object.sentence_index!=0 and _object.wordOffset_begin<=10:
+                            if _subject.label in [2, 3, 4] and re.search("请.{0,4}联系",
+                                                                         list_sentence[_object.sentence_index-1].sentence_text[-10:]+
+                                                                         list_sentence[_object.sentence_index].sentence_text[0:_object.wordOffset_begin]):
+                                continue
                         # 角色为中标候选人,排除距离过远的联系人
                         if _subject.label in [2, 3, 4] and distance>=40:
                             continue
@@ -1977,6 +1982,11 @@ def findAttributeAfterEntity(PackDict,roleSet,PackageList,PackageSet,list_senten
                                 # 角色为中标候选人,排除"质疑|投诉|监督|受理"相关的联系人
                                 if entity.label in [2, 3, 4] and re.search("质疑|投诉|监督|受理|项目(单位)?联系", list_sentence[after_entity.sentence_index].sentence_text[max(0,after_entity.wordOffset_begin - 10):after_entity.wordOffset_begin]):
                                     break
+                                if after_entity.sentence_index != 0 and after_entity.wordOffset_begin <= 10:
+                                    if entity.label in [2, 3, 4] and re.search("请.{0,5}联系",
+                                                                                 list_sentence[after_entity.sentence_index - 1].sentence_text[-10:] +
+                                                                                 list_sentence[after_entity.sentence_index].sentence_text[0:after_entity.wordOffset_begin]):
+                                        continue
                                 if after_entity.label in [1, 2, 3]:
                                     # distance = (tokens_num_dict[
                                     #                 after_entity.sentence_index] + after_entity.begin_index) - (
@@ -3030,7 +3040,10 @@ def getTimeAttributes(list_entity,list_sentence):
         'time_commencement':[] , #13 开工日期
         'time_completion': [],  # 14 竣工日期
         'time_listingStart': [],  # 15 挂牌开始日期(挂牌时间)
-        'time_listingEnd': []  # 16 挂牌结束日期、挂牌截止日期
+        'time_listingEnd': [],  # 16 挂牌结束日期、挂牌截止日期
+        'time_signContract': [],  # 17 合同签订时间
+        'time_contractStart': [],  # 18 合同开始时间
+        'time_contractEnd': []  # 19 合同结束时间
     }
     last_sentence_index = 0
     last_time_type = ""
@@ -3041,7 +3054,8 @@ def getTimeAttributes(list_entity,list_sentence):
         'time_registrationStart':"time_registrationEnd",
         'time_earnestMoneyStart':"time_earnestMoneyEnd",
         'time_commencement':"time_completion",
-        'time_listingStart':"time_listingEnd"
+        'time_listingStart':"time_listingEnd",
+        'time_contractStart':"time_contractEnd"
     }
     for entity in time_entitys:
         sentence_text = list_sentence[entity.sentence_index].sentence_text
@@ -3172,6 +3186,31 @@ def getTimeAttributes(list_entity,list_sentence):
                     last_sentence_index = entity.sentence_index
                     continue
 
+            # 2023/9/13 新增合同相关时间
+            if re.search("合同|服务|履[约行]", entity_left2):
+                if len(extract_time) == 1:
+                    if re.search("(合同.{,2}签[订定署].{,2}|签[订定署].{,2}合同.{,2})(?:时间|日期)", entity_left2):
+                        dict_time['time_signContract'].append((extract_time[0], 0.5, in_attachment))
+                        last_time_type = 'time_signContract'
+                    elif re.search("(?:合同|服务|履约|(合同|服务)履行)(?:期限?|有效期)|(?:服务|履约|(合同|服务)履行)(?:时间|日期|周期)|服务[时年]限|合同周期", entity_left2):
+                        if re.search("到|至|-|截[至止]",entity_left) or re.search("前|止|截止",entity_right) or re.search("前",entity_text[-2:]):
+                            dict_time['time_contractEnd'].append((extract_time[0], 0.5, in_attachment))
+                            last_time_type = 'time_contractEnd'
+                        else:
+                            dict_time['time_contractStart'].append((extract_time[0], 0.5, in_attachment))
+                            last_time_type = 'time_contractStart'
+                    elif re.search("(合同|服务|履约|(合同|服务)履行).{,2}(?:起始|开始)(?:时间|日期)", entity_left2):
+                        dict_time['time_contractStart'].append((extract_time[0], 0.55, in_attachment))
+                        last_time_type = 'time_contractStart'
+                    elif re.search("(合同|服务|履约).{,2}(?:完成|截止|结束)(?:时间|日期|时限)", entity_left2):
+                        dict_time['time_contractEnd'].append((extract_time[0], 0.55, in_attachment))
+                        last_time_type = 'time_contractEnd'
+                else:
+                    if re.search("(?:合同|服务|履约|(合同|服务)履行)(?:期限?|有效期)|(?:服务|履约|(合同|服务)履行)(?:时间|日期|周期)|服务[时年]限|合同周期", entity_left2):
+                        dict_time['time_contractStart'].append((extract_time[0], 0.6, in_attachment))
+                        dict_time['time_contractEnd'].append((extract_time[1], 0.6, in_attachment))
+                        last_time_type = ''
+
             if re.search("至|到", entity_left):
                 if entity.sentence_index == last_sentence_index:
                     time_type = last_time_index.get(last_time_type)
@@ -3347,8 +3386,9 @@ def getOtherAttributes(list_entity):
                 dict_other["moneysource"] = entity.entity_text
                 last_moneysource_prob = entity.prob
         elif entity.entity_type=='serviceTime':
-            if list_serviceTime and entity.in_attachment:
-                continue
+            # print(entity.entity_text)
+            # if list_serviceTime and entity.in_attachment:
+            #     continue
             if re.search("[^之]日|天|年|月|周|星期", entity.entity_text) or re.search("\d{4}[\-\./]\d{1,2}", entity.entity_text):
                 list_serviceTime.append(entity)
         elif entity.entity_type=="person" and entity.label ==4:
@@ -3359,11 +3399,22 @@ def getOtherAttributes(list_entity):
             dict_other["total_tendereeMoney"] = str(Decimal(entity.entity_text))
             dict_other["total_tendereeMoneyUnit"] = entity.money_unit
     if list_serviceTime:
-        list_serviceTime.sort(key=lambda x:x.prob,reverse=True)
-        max_prob = list_serviceTime[0].prob
-        max_prob_serviceTime = [ent for ent in list_serviceTime if ent.prob==max_prob]
-        max_prob_serviceTime.sort(key=lambda x:(x.sentence_index,x.begin_index))
-        dict_other["serviceTime"] = max_prob_serviceTime[0].entity_text
+        list_serviceTime_inAtt = [serviceTime for serviceTime in list_serviceTime if serviceTime.in_attachment==1]
+        list_serviceTime = [serviceTime for serviceTime in list_serviceTime if serviceTime.in_attachment==0]
+        if not list_serviceTime:
+            list_serviceTime = list_serviceTime_inAtt
+        list_serviceTime.sort(key=lambda x: (x.prob,-x.sentence_index,-x.begin_index), reverse=True)
+        for _serviceTime in list_serviceTime:
+            # 优先取具体时间
+            if re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}",_serviceTime.entity_text):
+                dict_other["serviceTime"] = _serviceTime.entity_text
+                break
+        if not dict_other["serviceTime"]:
+            max_prob = list_serviceTime[0].prob
+            max_prob_serviceTime = [ent for ent in list_serviceTime if ent.prob==max_prob]
+            max_prob_serviceTime.sort(key=lambda x:(x.sentence_index,x.begin_index))
+            dict_other["serviceTime"] = max_prob_serviceTime[0].entity_text
+
     if dict_other['moneysource']:
         dict_other['moneysource'] = turnMoneySource(dict_other['moneysource'])
     # dict_other["product"] = list(set(dict_other["product"])) # 已在添加时 顺序去重保留

+ 17 - 2
BiddingKG/dl/time/re_servicetime.py

@@ -242,10 +242,24 @@ def re_service_time(text):
     index2word = []
     for i in range(len(all_text_index_list)):
         word = text[all_text_index_list[i][0]:all_text_index_list[i][1]]
+        # print(word,text,all_text_index_list[i][0],all_text_index_list[i][1])
         if i != len(all_text_index_list)-1:
             word = word + " "
         index2word.append(word)
 
+        # 补充“服务期限12个月,自2022年10月1日至2023年9月30日。”类似数据
+        word2 = re.search("^[^。]{,8}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?.{,4}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",text[all_text_index_list[i][1]:])
+        if not re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}",word) and word2:
+            word2 = word2.group()
+            word2 = re.search("20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?.{,4}20\d{2}[年/.\-]\d{1,2}[月/.\-]\d{1,2}日?",word2).group()
+            begin = all_text_index_list[i][1] + text[all_text_index_list[i][1]:].index(word2)
+            end = begin + len(word2)
+            # print(text[begin:end],"|",word2)
+            all_text_index_list.append([begin,end])
+            index2word.append(word2)
+
+
+    # print(index2word, all_text_index_list, prob)
     if TEST_MODE:
         print("index2word all_text_index_list", index2word, all_text_index_list)
     return index2word, all_text_index_list, prob
@@ -355,8 +369,9 @@ def test_from_str():
     # """
     # s = "5元/年 服务期:交付使用之日起三年; 承诺服务等级"
     # s = "交货,1.交货时间:7天,2.交货地点:广东清远市清城区飞来峡镇人民政府高田应急安置点"
-    s = ''',莆田市财政局走廊及卫生间吊顶改造工程中标结果公告,莆田市财政局走廊及卫生间吊顶改造工程,工程预算价236878元,发包价194240元,招标编号为:宏福莆招字【2020】H001号,该项目招标方式为:邀请招标。2020年04月07日开标,2020年04月07日评标完成,中标主要结果公示如下:中标人名称,福建省东海伟业建设有限公司,中标价:194240元,评标办法,随机抽取法,资格评审结果,注册建造师:合格:余爱华(注册编号:闽235141578763),履约保证金(元):合格:合同金额的10%,施工工期:14日历天,工程质量,备注,被确定为废标、无效标的投标人及原因:合格:无废标,资格审查小组:合格:王宗仙、林慧灵、谢淑青,根据评标结果确定福建省东海伟业建设有限公司为中标人,现在莆田市财政局网上(http://czj.putian.gov.cn/)公示。中标公示期自2020年04月08日至2020年04月10日。投标人对中标结果有异议或认为评标活动存在违法违规行为,可在公示期内向相关主管部门投诉,招标单位:招标代理机构:莆田市财政局,福建省宏福工程管理有限公司,联系电话:0594-2694413,联系电话:15160467775,2020年04月08日,2020年04月08日,
-'''
+    s = "本项目服务期限12个月,自2022年10月1日至2023年9月30日。"
+#     s = ''',莆田市财政局走廊及卫生间吊顶改造工程中标结果公告,莆田市财政局走廊及卫生间吊顶改造工程,工程预算价236878元,发包价194240元,招标编号为:宏福莆招字【2020】H001号,该项目招标方式为:邀请招标。2020年04月07日开标,2020年04月07日评标完成,中标主要结果公示如下:中标人名称,福建省东海伟业建设有限公司,中标价:194240元,评标办法,随机抽取法,资格评审结果,注册建造师:合格:余爱华(注册编号:闽235141578763),履约保证金(元):合格:合同金额的10%,施工工期:14日历天,工程质量,备注,被确定为废标、无效标的投标人及原因:合格:无废标,资格审查小组:合格:王宗仙、林慧灵、谢淑青,根据评标结果确定福建省东海伟业建设有限公司为中标人,现在莆田市财政局网上(http://czj.putian.gov.cn/)公示。中标公示期自2020年04月08日至2020年04月10日。投标人对中标结果有异议或认为评标活动存在违法违规行为,可在公示期内向相关主管部门投诉,招标单位:招标代理机构:莆田市财政局,福建省宏福工程管理有限公司,联系电话:0594-2694413,联系电话:15160467775,2020年04月08日,2020年04月08日,
+# '''
     print(extract_servicetime(s))
     print(re.findall('(\d{2,4}[-.年/]|\d{1,2}[-.月/]|\d{1,2}[日号]?)+[-~~起至到—]+\d{2,4}[-.年/]', s))