|
@@ -430,50 +430,50 @@ class CodeNamePredict():
|
|
|
code_set.add(it)
|
|
|
# item['code'].append(it)
|
|
|
if re.search("(项目编号|招标编号):?$", pre_text[h]):
|
|
|
- item['code'].append((it, 0))
|
|
|
+ item['code'].append((it, 0, sentence.sentence_index))
|
|
|
elif re.search('采购(计划)?编号:?$', pre_text[h]):
|
|
|
- item['code'].append((it, 1))
|
|
|
+ item['code'].append((it, 1, sentence.sentence_index))
|
|
|
elif re.search('(询价|合同)编号:?$', pre_text[h]):
|
|
|
- item['code'].append((it, 2))
|
|
|
+ item['code'].append((it, 2, sentence.sentence_index))
|
|
|
else:
|
|
|
- item['code'].append((it, 3))
|
|
|
+ item['code'].append((it, 3, sentence.sentence_index))
|
|
|
elif len(item['code']) > 0:
|
|
|
new_it = item['code'][-1][0] + re.search(',|/|;|、|,', the_code).group(0) + it
|
|
|
if new_it not in code_set:
|
|
|
code_set.add(new_it)
|
|
|
# item['code'][-1] = new_it
|
|
|
if re.search("(项目编号|招标编号):?$", pre_text[h]):
|
|
|
- item['code'][-1] = (new_it, 0)
|
|
|
+ item['code'][-1] = (new_it, 0, sentence.sentence_index)
|
|
|
elif re.search('采购(计划)?编号:?$', pre_text[h]):
|
|
|
- item['code'][-1] = (new_it, 1)
|
|
|
+ item['code'][-1] = (new_it, 1, sentence.sentence_index)
|
|
|
elif re.search('(询价|合同)编号:?$', pre_text[h]):
|
|
|
- item['code'][-1] = (new_it, 2)
|
|
|
+ item['code'][-1] = (new_it, 2, sentence.sentence_index)
|
|
|
else:
|
|
|
- item['code'][-1] = (new_it, 3)
|
|
|
+ item['code'][-1] = (new_it, 3, sentence.sentence_index)
|
|
|
else:
|
|
|
if the_code not in code_set:
|
|
|
code_set.add(the_code)
|
|
|
# item['code'].append(the_code)
|
|
|
if re.search("(项目编号|招标编号):?$", pre_text[h]):
|
|
|
- item['code'].append((the_code, 0))
|
|
|
+ item['code'].append((the_code, 0, sentence.sentence_index))
|
|
|
elif re.search('采购(计划)?编号:?$', pre_text[h]):
|
|
|
- item['code'].append((the_code, 1))
|
|
|
+ item['code'].append((the_code, 1, sentence.sentence_index))
|
|
|
elif re.search('(询价|合同)编号:?$', pre_text[h]):
|
|
|
- item['code'].append((the_code, 2))
|
|
|
+ item['code'].append((the_code, 2, sentence.sentence_index))
|
|
|
else:
|
|
|
- item['code'].append((the_code, 3))
|
|
|
+ item['code'].append((the_code, 3, sentence.sentence_index))
|
|
|
break
|
|
|
elif the_code not in code_set:
|
|
|
code_set.add(the_code)
|
|
|
# item['code'].append(the_code)
|
|
|
if re.search("(项目编号|招标编号):?$", pre_text[h]):
|
|
|
- item['code'].append((the_code, 0))
|
|
|
+ item['code'].append((the_code, 0, sentence.sentence_index))
|
|
|
elif re.search('采购(计划)?编号:?$', pre_text[h]):
|
|
|
- item['code'].append((the_code, 1))
|
|
|
+ item['code'].append((the_code, 1, sentence.sentence_index))
|
|
|
elif re.search('(询价|合同)编号:?$', pre_text[h]):
|
|
|
- item['code'].append((the_code, 2))
|
|
|
+ item['code'].append((the_code, 2, sentence.sentence_index))
|
|
|
else:
|
|
|
- item['code'].append((the_code, 3))
|
|
|
+ item['code'].append((the_code, 3, sentence.sentence_index))
|
|
|
|
|
|
# if the_code not in code_set:
|
|
|
# code_set.add(the_code)
|
|
@@ -573,18 +573,18 @@ class CodeNamePredict():
|
|
|
if othercode != None:
|
|
|
# item['code'].append(othercode.group('code'))
|
|
|
if re.search("(项目编号|招标编号):?$", othercode.group(0)):
|
|
|
- item['code'].append((othercode.group('code'), 0))
|
|
|
+ item['code'].append((othercode.group('code'), 0, sentence.sentence_index))
|
|
|
elif re.search('采购(计划)?编号:?$', othercode.group(0)):
|
|
|
- item['code'].append((othercode.group('code'), 1))
|
|
|
+ item['code'].append((othercode.group('code'), 1, sentence.sentence_index))
|
|
|
elif re.search('(询价|合同)编号:?$', othercode.group(0)):
|
|
|
- item['code'].append((othercode.group('code'), 2))
|
|
|
+ item['code'].append((othercode.group('code'), 2, sentence.sentence_index))
|
|
|
else:
|
|
|
- item['code'].append((othercode.group('code'), 3))
|
|
|
+ item['code'].append((othercode.group('code'), 3, sentence.sentence_index))
|
|
|
# print('规则召回项目编号:', othercode.group('code'))
|
|
|
# item['code'] = [code for code in item['code'] if len(code)<500]
|
|
|
# item['code'].sort(key=lambda x:len(x),reverse=True)
|
|
|
item['code'] = [code for code in item['code'] if len(code[0]) < 500]
|
|
|
- item['code'].sort(key=lambda x: x[1])
|
|
|
+ item['code'].sort(key=lambda x: [x[1],x[2]])
|
|
|
item['code'] = [it[0] for it in item['code']]
|
|
|
result.append(item)
|
|
|
|
|
@@ -703,7 +703,7 @@ class PREMPredict():
|
|
|
text_sen = sentence.sentence_text
|
|
|
b = entity.wordOffset_begin
|
|
|
e = entity.wordOffset_end
|
|
|
- text_list.append((text_sen[max(0, b-13):b], text_sen[b:e], text_sen[e:e+10]))
|
|
|
+ text_list.append((text_sen[max(0, b-13):b], text_sen[b:e], text_sen[e:e+15]))
|
|
|
# item_x = embedding(spanWindow(tokens=sentence.tokens,begin_index=entity.begin_index,end_index=entity.end_index,size=settings.MODEL_ROLE_INPUT_SHAPE[1]),shape=settings.MODEL_ROLE_INPUT_SHAPE)
|
|
|
# item_x = self.model_role.encode(tokens=sentence.tokens,begin_index=entity.begin_index,end_index=entity.end_index,entity_text=entity.entity_text)
|
|
|
item_x = self.model_role.encode_word(sentence_text=text_sen, begin_index=entity.wordOffset_begin, end_index=entity.wordOffset_end, size=30)
|
|
@@ -805,6 +805,9 @@ class PREMPredict():
|
|
|
# print('模型预测角色:', front, entity.entity_text, behind,label, values)
|
|
|
# if label in [0, 1, 2, 3, 4]:
|
|
|
# self.role_file.write("{0}#split#{1}#split#{2}#split#{3}#split#{4}\n".format(front, entity.entity_text, behind,label, entity.doc_id))
|
|
|
+ if re.search('^以\d+[\d,.]+万?元中标', behind) and label != 2: # 优化244261884预测错误 大连长之琳科技发展有限公司以7.63277万元中标
|
|
|
+ label = 2
|
|
|
+ values[label] = 0.8
|
|
|
if label in [0, 1, 2, 3, 4] and values[label] < 0.5: # 小于阈值的设为其他,让后面的规则召回重新判断
|
|
|
# print(' # 小于阈值的设为其他,让后面的规则召回重新判断', values[label])
|
|
|
label = 5
|
|
@@ -884,6 +887,9 @@ class PREMPredict():
|
|
|
label = 5
|
|
|
elif re.search('委托$', front) and re.search('^(抽样|送检|看样)', behind):
|
|
|
label = 5
|
|
|
+ elif re.search('推荐入围的招标代理单位:$', front): # 20240709 修复302505502预测错为代理
|
|
|
+ label = 2
|
|
|
+ values[label] = 0.501
|
|
|
elif label in [3,4]:
|
|
|
if re.search('第[二三]分(公司|店),中标(人|供应商|单位|公司):$', front):
|
|
|
label = 2
|
|
@@ -955,16 +961,16 @@ class PREMPredict():
|
|
|
values[label] = 0.5
|
|
|
elif re.search('[\+=]((中标|成交)(金?额|价格?)|[若如]果?(中标|成交)(金?额|价格?)为?', front): # 处理例如 241561780 如中标金额为 500-1000万元,则代理服务费=100 万元×0.5%+400万元×0.35%+(中标金额-500)万元
|
|
|
values[label] = 0.49
|
|
|
- elif re.search('^(以[上下])?按[\d.%]+收取|^以[上下]|^[()]?[+×*-][\d.%]+', behind):
|
|
|
+ elif re.search('^(以[上下])?按[\d.%]+收取|^及?以[上下]|^[()]?[+×*-][\d.%]+', behind):
|
|
|
values[label] = 0.49
|
|
|
elif re.search('(含|在|包括|[大小等高低]于|达到)$|[\d.%]+[+×*-]$', front):
|
|
|
values[label] = 0.49
|
|
|
elif entity.notes == '单价' and float(entity.entity_text)<5000:
|
|
|
label = 2
|
|
|
elif label ==0: # 错误招标金额处理
|
|
|
- if entity.notes in ["投资", "总投资","工程造价"] or re.search('最低限价:?$', front) or re.search('服务内容:([\d,.]+万?亿?元?-?)$', front):
|
|
|
+ if entity.notes in ["投资", "总投资","工程造价"] or re.search('最低限价:?$|注册资本', front) or re.search('服务内容:([\d,.]+万?亿?元?-?)$', front):
|
|
|
values[label] = 0.49
|
|
|
- elif re.search('^(以[上下])?按[\d.%]+收取|^以[上下]|^[()]?[+×*-][\d.%]+|(含)', behind):
|
|
|
+ elif re.search('^(以[上下])?按[\d.%]+收取|^及?以[上下]|^[()]?[+×*-][\d.%]+|(含)', behind):
|
|
|
values[label] = 0.49
|
|
|
elif re.search('(含|在|包括|[大小等高低]于|如预算金额为)$|[\d.%]+((含))?[+×*-]$', front):
|
|
|
values[label] = 0.49
|
|
@@ -1403,7 +1409,7 @@ class RoleRulePredictor():
|
|
|
"(乙|竞得|受让|买受|签约|施工|供货|供应?|合作|承做|承包|承建|承销|承保|承接|承制|承担|承修|承租((包))?|入围|入选|竞买)(候选|投标)?(人|单位|机构|供应商|方|公司|企业|厂商|商|社会资本方?)(:?单位名称|:?名称|盖章)?[::是为]+$" \
|
|
|
"|(选定单位|指定的中介服务机构|实施主体|中标银行|中标通知书,致|征集结果|选择中介|选择结果|成交对象|勘察人|(,|审计|处置|勘察|设计)服务单位|受托[人方])[::是为]+$" \
|
|
|
"|((评审结果|名次|排名|中标结果)[::]*第?[一1]名?)[::是为]+$|成交供应商信息[,:]?(序号1)?:?|供应商名称$" \
|
|
|
- "|单一来源(采购)?(供应商|供货商|服务商|方式向)$|((中标|成交)(结果|信息))[::是为]+$" \
|
|
|
+ "|单一来源(采购)?(供应商|供货商|服务商|方式向)$|((中标|成交)(结果|信息))[::是为]+$|(中标|成交)供应商、(中标|成交)(金额|价格),$" \
|
|
|
"|现(公布|宣布|公示)中标单位如下:$|现将中标单位(公布|公示)如下:$|现宣布以下(企业|单位|公司)中标:$|经讨论,决定采用$)" # 承办单位:不作为中标 83914772
|
|
|
self.pattern_winTenderer_left_60 = "(?P<winTenderer_left_60>" \
|
|
|
"(,|。|:|^)((中标(投标)?|[拟预]中标|中选|中价|中签|成交)(人|单位|机构|中介(服务)?机构|供应商|客户|方|公司|企业|厂商|商家?|社会资本方?)|(中标候选人)?第?[一1]名|第[一1](中标|中选|成交)?候选人|服务机构)" \
|
|
@@ -1414,7 +1420,7 @@ class RoleRulePredictor():
|
|
|
|
|
|
self.pattern_winTenderer_right = "(?P<winTenderer_right>(^[是为](首选)?((采购|中标|成交)(供应商|供货商|服务商)|(第[一1]|预)?(拟?(中标|中选|中价|成交)(候选|排序)?(人|单位|机构|供应商|公司|企业|厂商)))|" \
|
|
|
"^((报价|价格)最低,|以\w{5,10})?(确定|成|作)?为[\w“”()]{3,25}((成交|中选|中标|服务)(人|单位|供应商|企业|公司)|供货单位|供应商|第一中标候选人)[,。]" \
|
|
|
- "|^:贵公司参与|^:?你方于|^(胜出)?中标。|^取得中标(单位)?资格" \
|
|
|
+ "|^:贵公司参与|^:?你方于|^(胜出)?中标。|^取得中标(单位)?资格|^以\d+[\d,.]+万?元(中标|成交|中选)" \
|
|
|
"|^通过(挂牌|拍卖)方式(以[\d.,]+万?元)?竞得|^[((](中标|成交|承包)人名?称?[))]))" # 去掉 |\w{,20} 修复 460216955 网上公布的与本次采购项目有关的信息视为已送达各响应供应商。 作为中标
|
|
|
self.pattern_winTenderer_whole = "(?P<winTenderer_center>(贵公司|由).{,15}以\w{,15}中标|确定[\w()]{5,20}为[^,。;]{5,50}的?中标单位" \
|
|
|
"|选定报价最低的[“”\w()]{5,25}为[^,。;]{5,50}的?(服务|中标|成交)单位" \
|
|
@@ -2234,10 +2240,11 @@ class RoleGrade():
|
|
|
self.winTenderer_left_9 = "(?P<winTenderer_left_9>(中标|中选|中价|成交|竞得)|第[1一]名|排[名序]:1|名次:1)"
|
|
|
self.winTenderer_left_8 = "(?P<winTenderer_left_8>(入选供应商|供货商|乙方|最[终后]选[择取]))" # 229435497 最后选择西平,县中原彩印有限公司,作为此项目中标供应商,
|
|
|
self.winTenderer_left_6 = "(?P<winTenderer_left_6>(入围|承[接建包修做制担租销]))"
|
|
|
+ self.winTenderer_right_9 = "(?P<winTenderer_right_9>^(为(中标|成交|中选)(人|单位|供应商|公司)|以\d+[\d.,]+万?元中标))"
|
|
|
self.secondTenderer_left_9 = "(?P<secondTenderer_left_9>(第[二2](中标|中选|中价|成交)?候选(人|单位|供应商|公司)|第[二2]名|排[名序]:2|名次:2))"
|
|
|
self.thirdTenderer_left_9 = "(?P<thirdTenderer_left_9>(第[三3](中标|中选|中价|成交)?候选(人|单位|供应商|公司)|第[三3]名|排[名序]:3|名次:3))"
|
|
|
self.pattern_list = [self.tenderee_left_9,self.tenderee_center_8, self.tenderee_left_8,self.tenderee_left_6,self.tenderee_left_5,self.agency_left_9,
|
|
|
- self.winTenderer_left_6, self.winTenderer_left_9,self.winTenderer_left_8, self.secondTenderer_left_9, self.thirdTenderer_left_9]
|
|
|
+ self.winTenderer_left_6, self.winTenderer_left_9,self.winTenderer_left_8, self.winTenderer_right_9, self.secondTenderer_left_9, self.thirdTenderer_left_9]
|
|
|
def predict(self, list_sentences, list_entitys, original_docchannel, span=15, min_prob=0.7):
|
|
|
'''
|
|
|
根据规则给角色分配不同等级概率;分三级:0.9-1,0.8-0.9,0.7-0.8;附件0.7-0.8,0.6-0.7,0.5-0.6
|
|
@@ -3923,7 +3930,7 @@ class DocChannel():
|
|
|
self.type_dic = {
|
|
|
'土地矿产': '供地结果|(土地|用地|宗地|地块|海域|矿)的?(基本信息|基本情况|概况|信息|详情|来源|用途|性质|编号|位置|坐落|使用年限|出让年限)|(土地|山地|农田)(经营权)?(出让|出租|招租|租赁|承包|流转)|流转土地',
|
|
|
'拍卖出让': '(拍卖|变卖|流拍|竞拍)的?(公告|活动|信息|结果|成交|主体|标的|资产|财产|方式|类型|流程|程序|规则|价格|保证金|时间)|(公开|进行|密封)(拍卖|变卖|竞拍)|第[一二三]次拍卖|(资产|司法|网络)拍卖|交易方式.{,2}拍卖|拍卖会',
|
|
|
- '产权交易': '(产权|资产|权证)的?(类型|信息|名称|编号|(基本)?情况)|(经营权|承包权|使用权|租赁权|股权|债权|排污权|化学需氧量|储备量)(挂牌|转让|出让)|竞价销售|销售结果|房屋所有权房产|免租期限|交易期限|(受让|转让|承租|出租)(人|方)|(店面|店铺|商铺|铺位?|门面|门市|食堂|饭堂|校舍|车位|停车场|厂?房|仓?库|馆|资产|物业|房产|房屋|场地|农田|鱼?塘)\w{,4}(处置|招租|出租|续租|租赁|转让)|(出租|转让|产权|资产)(项目|中标|成交|流标|废标)|出租(用途|类型)|转让底价|租赁(标的物|情况)|看样(时间|地[点址]|方式)|最小加价|加价幅度',
|
|
|
+ '产权交易': '(产权|资产|权证)的?(类型|类别|用途|性质|状态|信息|名称|编号|(基本)?情况)|(经营权|承包权|使用权|租赁权|股权|债权|排污权|化学需氧量|储备量)(挂牌|转让|出让)|竞价销售|销售结果|房屋所有权房产|免租期限|交易期限|(受让|转让|承租|出租)(人|方)|(店面|店铺|商铺|铺位?|门面|门市|食堂|饭堂|校舍|车位|停车场|厂?房|仓?库|馆|资产|物业|房产|房屋|场地|农田|鱼?塘)\w{,4}(处置|招租|出租|续租|租赁|转让)|(出租|转让|产权|资产)(项目|中标|成交|流标|废标)|出租(用途|类型)|转让底价|租赁(标的物|情况)|看[样货](时间|地[点址]|方式|仓库|验货)|最小加价|加价[幅梯]度|交易模式[::\s]*延时竞价销售|挂牌(开始|结束)时间',
|
|
|
'采招数据': '(采购|招标)(条件|范围|文件|内容)|(申请人|投标人|供应商|报价人|参选人)的?资格要求;|采购需求清单|最低价排序|竞争性采购方式|采购进行公开竞价|竞价模式[::\s]*一次报价|预算金额' # |变更|答疑|澄清|中标|成交|合同|废标|流标 |(采购|招标|代理)(人|机构|单位)|
|
|
|
}
|
|
|
|
|
@@ -3931,7 +3938,7 @@ class DocChannel():
|
|
|
'土地矿产': '(土地|用地|宗地|荒地|山地|海域|矿)(出让|出租|招租|租赁|承包|流转|使用权|经营权|征收|划拨|中标|成交)|供地结果|矿业权|探矿权|采矿权|(土地|用地|宗地|地块)(使用权)?(终止|中止|网上)?(挂牌|出让|拍卖|招拍|划拨)|征收土地',
|
|
|
'拍卖出让': '(拍卖|变卖|流拍|竞拍)的?(公告|公示)|拍卖|变卖|流拍|竞拍',
|
|
|
'产权交易': '经营权|承包权|使用权|租赁权|股权|债权|排污权|化学需氧量|储备量|竞价销售|销售结果|出租|招租|拍租|竞租|续租|挂牌|出让',
|
|
|
- '采招数据': '(采购|招标|询价|议价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判)的?(公告|公示|中标|成交|结果|$)|工程招标|定点服务|竞价采购|(中标|成交)(结果)?(公告|公示)',
|
|
|
+ '采招数据': '(采购|招标|询价|议价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|征询|调研)的?(公告|公示|中标|成交|结果|$)|工程招标|定点服务|竞价采购|(设备|服务)采购|网上超市采购|定点采购',
|
|
|
# |竞价 采招/产权都有竞价方式 # 意向|需求|预公?告|报建|总承包|工程|施工|设计|勘察|代理|监理 |变更|答疑|澄清|中标|成交|合同|废标|流标
|
|
|
'新闻资讯': '(考试|面试|笔试)成绩|成绩的?(公告|公示|公布)|公开招聘|招聘(公告|简章|启事|合同制)|疫情防控\s{,5}(通知|情况|提示)|行政审批结果'
|
|
|
}
|
|
@@ -3939,22 +3946,22 @@ class DocChannel():
|
|
|
'采购意向': '采购意向|招标意向|选取意向|意向公告|意向公示',
|
|
|
'采购意向neg': '发布政府采购意向|采购意向公告已于',
|
|
|
'招标预告': '(预计|计划)(采购|招标)(时间|日期)|采购(计划编号|需求方案|预告|预案)|(预|需求)公示|需求(方案|信息|论证|公告|公示)',
|
|
|
- '招标公告': '(采购|招标|竞选|报名)条件|报名(时间|流程|方法|要求|\w{,5}材料)[:\s]|[^\w]成交规则|参加竞价采购交易资格|(申请人|投标人|供应商|报价人|参选人)的?资格要求|获取(采购|招标|询价|议价|竞价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|竞谈|应答)文件|(采购|招标|询价|议价|竞价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|竞谈|应答)文件的?(获取|领取)',
|
|
|
+ '招标公告': '(采购|招标|竞选|报名)条件|报名(时间|流程|方法|要求|\w{,5}材料)[:\s]|[^\w]成交规则|参加竞价采购交易资格|(申请人|投标人|供应商|报价人|参选人)的?资格要求|获取(采购|招标|询价|议价|竞价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|竞谈|应答)文件|(采购|招标|询价|议价|竞价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|竞谈|应答)文件的?(获取|领取)|评选方式:?\s*价格最低',
|
|
|
'资审结果': '资审及业绩公示|资审结果及业绩|资格后审情况报告|资格(后审|预审|审查)结果(公告|公示)|(预审|审查)工作已经?结束|未通过原因', #|资格
|
|
|
'招标答疑': '现澄清(为|如下)|答疑补遗|澄清内容如下|第[0-9一二三四五]次澄清|答疑澄清|(最高(投标)?限价|控制价|拦标价)公示', # |异议的回复
|
|
|
'公告变更': '第[\d一二]次变更|(更正|变更)(公告|公示|信息|内容|事项|原因|理由|日期|时间|如下)|原公告((主要)?(信息|内容)|发布时间)|(变更|更正)[前后]内容|现?在?(变更|更正|修改|更改)(内容)?为|(公告|如下|信息|内容|事项|结果|文件|发布|时间|日期)(更正|变更)',
|
|
|
'公告变更neg': '履约变更内容',
|
|
|
'候选人公示': '候选人公示|评标结果公示|中标候选人名单公示|现将中标候选人(进行公示|公[示布]如下)|(中标|中选)候选人(信息|情况)[::\s]',
|
|
|
'候选人公示neg': '中标候选人公示期|中标候选人公示前',
|
|
|
- '中标信息': '供地结果信息|采用单源直接采购的?情况说明|[特现]?将\w{,4}(成交|中标|中选|选定结果|选取结果|入围结果|竞价结果)\w{,4}(进行公示|公[示布]如下)|(询价|竞价|遴选)(成交|中标|中选)(公告|公示)|(成交|中标|中选|选定|选取|入围|询价)结果(如下|公告|公示)|(中标|中选)(供应商|承包商|候选人|入围单位)如下|拟定供应商的情况|((中标|中选)(人|成交)|成交)\w{,3}(信息|情况)[::\s]',
|
|
|
- '中标信息2': '\s(成交|中标|中选)(信息|日期|时间|总?金额|价格)[::\s]|(采购|招标|成交|中标|中选|评标)结果|单一来源(采购|招标)?的?(中标|成交|结果)|项目已结束|中标公示 ', # |单一来源采购原因|拟采取单一来源方式采购|单一来源采购公示
|
|
|
+ '中标信息': '供地结果信息|采用单源直接采购的?情况说明|[特现]?将\w{,4}(成交|中标|中选|选定结果|选取结果|入围结果|竞价结果)\w{,4}(进行公示|公[示布]如下)|(询价|竞价|遴选)?(成交|中标|中选)(公告|公示)|(成交|中标|中选|选定|选取|入围|询价)结果(如下|公告|公示)|(中标|中选)(供应商|承包商|候选人|入围单位)如下|拟定供应商的情况|((中标|中选)(人|成交)|成交)\w{,3}(信息|情况)[::\s]',
|
|
|
+ '中标信息2': '\s(成交|中标|中选)(信息|日期|时间|总?金额|价格)[::\s]|(成交|中标|中选)价格\s*[\d.,]+(?万?元|(采购|招标|成交|中标|中选|评标)结果|单一来源(采购|招标)?的?(中标|成交|结果)|项目已结束|中标公示 ', # |单一来源采购原因|拟采取单一来源方式采购|单一来源采购公示
|
|
|
'中标信息3': '(中标|中选|成交|拟定|拟选用|最终选定的?|受让)(供应商|供货商|服务商|机构|企业|公司|单位|候选人|人)(信息[,:]?)?(名称)?[::\s]|[、\s](第一名|(拟定|推荐|入围)?(供应商|供货商)|(中选|中标|供货)单位|中选人)[::\s]|确定[\w()]{6,25}为中标人', # |唯一
|
|
|
- '中标信息neg': '按项目控制价下浮\d%即为成交价|成交原则|不得确定为(中标|成交)|招标人按下列原则选择中标人|评选成交供应商:|拟邀请供应商|除单一来源采购项目外|单一来源除外|(各.{,5}|尊敬的)(供应商|供货商)[:\s]|竞拍起止时间:|询价结果[\s\n::]*不公开|本项目已具备招标条件|现对该项目进行招标公告|发布\w{2}结果后\d天内送达|本次\w{2}结果不对外公示|供应商\s*资格要求|成交情况:\s*[流废]标|中标单位:本次招标拟?中标单位\d家|通知中标单位|影响(成交|中标)结果',
|
|
|
+ '中标信息neg': '按项目控制价下浮\d%即为成交价|成交原则|不得确定为(中标|成交)|招标人按下列原则选择中标人|评选成交供应商:|拟邀请供应商|除单一来源采购项目外|单一来源除外|(各.{,5}|尊敬的)(供应商|供货商)[:\s]|竞拍起止时间:|询价结果[\s\n::]*不公开|本项目已具备招标条件|现对该项目进行招标公告|发布\w{2}结果后\d天内送达|本次\w{2}结果不对外公示|供应商\s*资格要求|成交情况:\s*[流废]标|中标单位:本次招标拟?中标单位\d家|通知中标单位|影响(成交|中标)结果|确定为成交供应商|(成交|中标|中选)公[告示](发布|\w{,2})后|竞价成交后', # 503076535 按照服务方案的优劣 确定为成交供应商
|
|
|
# |确定成交供应商[:,\s]
|
|
|
'合同公告': '合同(公告|公示|信息|内容)|合同(编号|名称|主体|基本情况|完成(日期|时间))|(供应商乙方|乙方供应商):|合同总?金额|履约信息',
|
|
|
'废标公告': '(终止|中止|废标|流标|流采|失败|作废|异常|撤销)(结果)?(公告|公示|招标|采购|竞价)|(谈判结果为|结果类型):?废标|((本|该)(项目|标段|合同|合同包|采购包|次)\w{,5})((失败|终止|流标|废标)|予以废标|(按|做|作)?(流标|废标|废置)处理)|(采购|招标|询价|议价|竞价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|竞谈|应答|项目)(终止|中止|废标|流标|失败|作废|异常|撤销)',
|
|
|
'废标公告2': '(无效|中止|终止|废标|流标|失败|作废|异常|撤销)的?(原因|理由)|本项目因故取消|本(项目|次)(公开)?\w{2}失败|已终止\s*原因:|(人|人数|供应商|单位)(不足|未达\w{,3}数量)|已终止|不足[3三]家|无(废标)|成交情况:\s*[流废]标|现予以废置',
|
|
|
- '废标公告neg': '超过此报价将作为[废流]标处理|否则按[废流]标处理|终止规则:|成交规则:|视为流标|竞价失败的一切其他情形|是否废标:否'
|
|
|
+ '废标公告neg': '超过此报价将作为[废流]标处理|否则按[废流]标处理|终止规则:|成交规则:|视为流标|竞价失败的一切其他情形|是否废标:否|若不足三家公司参与|供应商数量:?\s*报名供应商不足三家|有效报价不足三家,\s*系统自动废标' # 503076535 供应商数量: 报名供应商不足三家。
|
|
|
}
|
|
|
self.title_life_dic = {
|
|
|
'采购意向': '采购意向|招标意向|选取意向|意向公告|意向公示|意向公开',
|
|
@@ -3963,8 +3970,8 @@ class DocChannel():
|
|
|
'招标答疑': '质疑|澄清|答疑(文件)?|补遗书?|(最高(投标)?限价|控制价|拦标价)(公示|公告|$)',
|
|
|
'废标公告': '(终止|中止|废标|废除|废置|流标|失败|作废|异常|撤销|撤回|取消成?交?|流拍)(结果|竞价|项目)?的?(公告|公示|$)|(终止|中止)(采购|招标|询价|议价|竞价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|拍卖|招租|交易|出让)|关于废置',
|
|
|
'合同公告': '(合同(成交|变更)?)(公告|公示|信息|公式|公开|签订)|合同备案|合同书|合同$', # |(履约|验收)(结果)?
|
|
|
- '候选人公示': '候选人(变更)?公示|评标(结果)?公示|中标前?公示|中标预公示',
|
|
|
- '中标信息': '(中标|中选|中价|中租|成交|入选|确认)(候选人|人|供应商|记录|结果|变更)?(公告|公示|结果)|未?入围(公示|公告)|(遴选|采购|招标|竞价|议价|比选|询比?价|评选|谈判|邀标|邀请|洽谈|约谈|评标|发包|遴选|交易)\w{,2}结果|单一来源(采购|招标)?的?(中标|成交|结果)|中标通知书|中标$', # |开标(记录|信息|情况)
|
|
|
+ '候选人公示': '候选人(变更)?公示|评标(结果)?公示|中标前?公示|中标预公示|评审结果',
|
|
|
+ '中标信息': '(中标|中选|中价|中租|成交|入选|确认)(候选人|人|供应商|记录|结果|变更)?(公告|公示|结果)|未?入围(公示|公告)|(遴选|采购|招标|竞价|议价|比选|询比?价|评选|谈判|邀标|邀请|洽谈|约谈|评标|发包|遴选|交易)\w{,2}结果|单一来源(采购|招标)?的?(中标|成交|结果)|中标通知书|中标$|项目中标', # |开标(记录|信息|情况)
|
|
|
'资审结果': '((资格|资质)(审查|预审|后审|审核)|资审)结果(公告|公示)?|(资质|资格)(预审|后审)公示|资审及业绩公示',
|
|
|
'招标公告': '(采购|招标|询价|议价|竞价|比价|比选|遴选|邀请|邀标|磋商|洽谈|约谈|谈判|拍卖|招租|交易|出让)的?(公告|公示|$)|公开(采购|招标|招租|拍卖|挂牌|出让)|(资审|预审|后审)公告',
|
|
|
'开标记录': '开标记录|截标信息|评委名单公示|开标安排|开标数据表|开标信息|开标情况|开标一览表|开标结果|开标会',
|
|
@@ -4368,7 +4375,7 @@ class DocChannel():
|
|
|
elif '验收合同' in life_kw_title:
|
|
|
return '验收合同', msc
|
|
|
elif '候选人公示' in life_kw_title or '候选人公示' in life_list:
|
|
|
- if '招标公告' in life_kw_title and life_score.get('招标公告', 0) > 3:
|
|
|
+ if '招标公告' in life_kw_title and '候选人公示' not in life_kw_title: # and life_score.get('招标公告', 0) > 3
|
|
|
return '招标公告', msc
|
|
|
elif '废标公告' in life_kw_title or life_score.get('废标公告', 0) > 5:
|
|
|
return '废标公告', msc
|
|
@@ -4381,8 +4388,7 @@ class DocChannel():
|
|
|
return '合同公告', msc
|
|
|
|
|
|
elif '中标信息' in life_kw_title or '中标信息' in life_list:
|
|
|
- if '招标公告' in life_kw_title and life_score.get('招标公告',
|
|
|
- 0) > 2: # (life_score.get('招标公告', 0)>2 or life_score.get('中标信息', 0)<4) 0.7886409793924245
|
|
|
+ if '招标公告' in life_kw_title and '中标信息' not in life_kw_title and life_score.get('招标公告',0) >= life_score.get('中标信息',0): # (life_score.get('招标公告', 0)>2 or life_score.get('中标信息', 0)<4) 0.7886409793924245
|
|
|
return '招标公告', msc
|
|
|
elif '废标公告' in life_kw_title or life_score.get('废标公告', 0) > 5:
|
|
|
return '废标公告', msc
|
|
@@ -4504,8 +4510,7 @@ class DocChannel():
|
|
|
|
|
|
if result['docchannel']['doctype'] in ['产权交易', '土地矿产', '拍卖出让'] and origin_dic.get(
|
|
|
original_docchannel, '') not in ['产权交易', '土地矿产', '拍卖出让'] \
|
|
|
- and re.search('产权|转让|受让|招租|招商|出租|承租|资产|挂牌|出让|拍卖|招拍|划拨|销售', title) == None\
|
|
|
- and re.search('(采购|招投?标|投标)(信息|内容|项目|公告|数量|人|单位|方式)|(建设|工程|服务|施工|监理|勘察|设计)项目|(%s)'%self.type_dic['采招数据'], text):
|
|
|
+ and (re.search(self.title_type_dic['采招数据'], title) or re.search('工程|服务|采购|询价|磋商', title) or re.search('(采购|招投?标|投标)(信息|内容|项目|公告|数量|人|单位|方式)|(建设|工程|服务|施工|监理|勘察|设计)项目|(%s)'%self.type_dic['采招数据'], text)):
|
|
|
result['docchannel']['doctype'] = '采招数据'
|
|
|
msc += ' 最终规则修改:预测为非采招数据,原始为采招数据且有招标关键词,返回采招数据'
|
|
|
elif result['docchannel']['doctype'] in ['土地矿产'] and origin_dic.get(original_docchannel, '') in ['拍卖出让', '产权交易']:
|
|
@@ -4561,8 +4566,8 @@ class DocChannel():
|
|
|
return {'docchannel': {'docchannel': '', 'doctype': not_extract_dic[original_docchannel], 'life_docchannel': origin_dic.get(original_docchannel, '原始类别')}}, '公告类别不在提取范围'
|
|
|
if web_source_no in ['02104-7', '04733', 'DX007628-6']: # 这些数据源无法识别
|
|
|
return {'docchannel': {'docchannel': '', 'doctype': '采招数据', 'life_docchannel': origin_dic.get(original_docchannel, '原始类别')}}, '此数据源公告分类不明确,返回数据源类别'
|
|
|
- if original_docchannel == 303 or (re.search('处罚|投诉|失信', title) and re.search(self.title_type_dic['采招数据'], title)==None):
|
|
|
- return {'docchannel': {'docchannel': '处罚公告', 'doctype': '处罚公告', 'life_docchannel': '处罚公告'}}, "处罚公告只判断标题和源类别"
|
|
|
+ if original_docchannel == 303:
|
|
|
+ return {'docchannel': {'docchannel': '处罚公告', 'doctype': '处罚公告', 'life_docchannel': '处罚公告'}}, "源类别为处罚公告"
|
|
|
|
|
|
title = re.sub('[^\u4e00-\u9fa5]+|出租车', '', title)
|
|
|
if len(title) > 50:
|
|
@@ -4582,9 +4587,9 @@ class DocChannel():
|
|
|
# print('channel正则预测结果:', result)
|
|
|
msc = '正则结果:类型:%s, 关键词:%s, 周期:%s, 关键词:%s'%(doc_type, type_kw,doc_life, life_kw)+'\n'+'模型结果:'
|
|
|
# print('类型:%s, 关键词:%s, 周期:%s, 关键词:%s'%(doc_type, type_kw,doc_life, life_kw))
|
|
|
- if doc_type == "" or doc_life == "":
|
|
|
+ if doc_type == "" or doc_life == "" or (doc_type != '采招数据' and origin_dic.get(original_docchannel, '原始类别') in ['招标公告', '中标信息', '招标预告', '采购意向']):
|
|
|
array_content, array_title, text_len, title_len, content = get_model_inputs(list_sentence)
|
|
|
- if doc_type =="":
|
|
|
+ if doc_type =="" or (doc_type != '采招数据' and origin_dic.get(original_docchannel, '原始类别') in ['招标公告', '中标信息', '招标预告', '采购意向']):
|
|
|
type_id, type_prob = type_model_predict()
|
|
|
type_model = self.id2type[type_id]
|
|
|
if type_model == '新闻资讯' and doc_life!='': # 修复bug 78584245 "docchannel": "合同公告", "doctype": "新闻资讯",
|
|
@@ -5305,8 +5310,8 @@ class IndustryPredictor():
|
|
|
text = text.replace('(', '(').replace(')', ')')
|
|
|
text = re.sub(
|
|
|
'(废标|终止|综?合?评审|评标|开标|资审|履约|验收|成交|中标人?|中选人?|单一来源|合同|候选人|结果|变更|更正|答疑|澄清|意向|需求|采购|招标|询比?价|磋商|谈判|比选|比价|竞价|议价)的?(公告|预告|公示)?|关于为?|选取|定点|直接|邀请函?|通知书?|备案|公开|公示|公告|记录|竞争性',
|
|
|
- '', text)
|
|
|
- text = text.replace(tenderee, '')
|
|
|
+ ' ', text)
|
|
|
+ text = text.replace(tenderee, ' ')
|
|
|
text = ' ' if text=="" else text
|
|
|
words_docs_list = selffool.cut(text)
|
|
|
words_docs_list = [[it for it in l if re.search('^[\u4e00-\u9fa5]+$', it)][-maxSententLen:] for l in words_docs_list]
|
|
@@ -5339,6 +5344,7 @@ class IndustryPredictor():
|
|
|
product = product if product else ''
|
|
|
|
|
|
text_ind = (doctitle + project_name + product).replace(tenderee, '')
|
|
|
+ text_ind = text_ind.replace('墙面粉刷', '墙面 粉刷')
|
|
|
text_com = win_tenderer
|
|
|
|
|
|
length_ind_text = len(text_ind) + 1
|
|
@@ -6788,7 +6794,8 @@ class CandidateExtractor(object):
|
|
|
"third_tenderer": "第三名|第三(中标|成交)?候选人",
|
|
|
}
|
|
|
'''非表格候选人正则'''
|
|
|
- self.p = '((候选|入围|入选|投标)(供应商库)?的?(人|人?单位|机构|供应商|供货商|服务商|投标人|(中标)?公司|(中标)?企业)|(通过)?名单)(名称|名单|全称|\d)?:$'
|
|
|
+ # self.p = '((候选|入围|入选|投标)(供应商库)?的?(人|人?单位|机构|供应商|供货商|服务商|投标人|(中标)?公司|(中标)?企业|应答人)|(通过)?名单)(名称|名单|全称|\d)?:$'
|
|
|
+ self.p = '((候选|入围|入选|投标|报价|成交|中标|中选|供[货应]|应答)(人|方|人?单位|机构|厂?商|商家|服务商|公司|企业)|(通过|入围)名单)(名称|名单|全称|\d)?:?$'
|
|
|
self.tb = TableTag2List()
|
|
|
with open(os.path.dirname(__file__)+'/header_set.pkl', 'rb') as f:
|
|
|
self.headerset = pickle.load(f)
|
|
@@ -6927,7 +6934,7 @@ class CandidateExtractor(object):
|
|
|
package = uniform_package_name(package) if package !="" else "Project"
|
|
|
if candidate:
|
|
|
if win_or_not and re.search('否|未入围', win_or_not):
|
|
|
- pass
|
|
|
+ candidate_set.add(candidate)
|
|
|
elif re.search('^((建议|推荐)(中标|成交)|是)$', win_or_not) and win_sort in ['', '参与投标单位及排名'] and win_tenderer=='':
|
|
|
win_sort = '第一名'
|
|
|
candidate_set.add(candidate)
|
|
@@ -6945,8 +6952,7 @@ class CandidateExtractor(object):
|
|
|
if type not in role_dic:
|
|
|
role_dic[type] = dict()
|
|
|
role_dic[type]['role_text'] = text
|
|
|
- if type in ['second_tenderer', 'third_tenderer']:
|
|
|
- candidate_set.add(text)
|
|
|
+ candidate_set.add(text)
|
|
|
|
|
|
elif re.search('投标报价|报价$', df.loc[i, 0]) or re.search('投标报价|报价$', df.loc[i, 1]):
|
|
|
findmoney = True
|
|
@@ -7103,7 +7109,7 @@ class CandidateExtractor(object):
|
|
|
e = ent.wordOffset_end
|
|
|
if ent.label in [2,3,4]: # 直接加实体预测的候选人, 否则规则检查是否为候选人
|
|
|
candidates.add(ent.entity_text)
|
|
|
- elif isinstance(b, int) and isinstance(e, int):
|
|
|
+ elif isinstance(b, int) and isinstance(e, int) and ent.label in [5]:
|
|
|
foreword = text[max(0, b - 10):b]
|
|
|
if re.search(self.p, foreword):
|
|
|
candidates.add(ent.entity_text)
|
|
@@ -7126,8 +7132,8 @@ class CandidateExtractor(object):
|
|
|
if prem == {} and richText:
|
|
|
prem, candidate_set = self.get_prem(richText)
|
|
|
in_attachment = True
|
|
|
- if prem == {} and candidate_set == set():
|
|
|
- candidate_set = self.get_candidates_from_text(list_sentences, list_entitys)
|
|
|
+ candidate_set2 = self.get_candidates_from_text(list_sentences, list_entitys)
|
|
|
+ candidate_set.update(candidate_set2)
|
|
|
return prem, {'candidate': ','.join(candidate_set)}, in_attachment
|
|
|
|
|
|
def role_special_predictor(web_source_name, content, nlp_enterprise):
|