role_labeling.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. # DEPRECATED(Phase1): 本文件中的 PostgreSQL 硬编码连接(host=192.168.*,
  2. # password=postgres 等)将在后续 training/ Phase 迁移到 BiddingKG.dl.infra.db。
  3. # 迁移完成前可临时使用:from BiddingKG.dl.infra.db import get_connection;
  4. # conn = get_connection("<dbname>")
  5. # 详见 ARCHITECTURE.md 第 11 章 Phase 1 与 REFACTOR_LOG.md。
  6. import psycopg2
  7. import codecs
  8. import xlwt
  9. import xlrd
  10. import os
  11. import re
  12. from xlutils.copy import copy
  13. from BiddingKG.dl.common.Utils import *
  14. import pandas as pd
  15. import math
  16. def getData(t="final_label_role"):
  17. '''
  18. '''
  19. conn = psycopg2.connect(dbname="BiddingKM_test_10000",user="postgres",password="postgres",host="192.168.2.101")
  20. cursor = conn.cursor()
  21. select_sql = " select A.doc_id,C.entity_id,C.label,case when C.label=0 then '招标人' when C.label=1 then '招标代理' when C.label=2 then '中标人/第一候选' when C.label=3 then '第二' when C.label=4 then '第三' else '无' end as 再标注,case when D.label=0 then '招标人' when D.label=1 then '招标代理' when D.label=2 then '中标人/第一候选' when D.label=3 then '第二' when D.label=4 then '第三' else '无' end as 原标注,B.entity_text,A.tokens[B.begin_index-10:B.begin_index],A.tokens[B.begin_index+1:B.end_index+1],A.tokens[B.end_index+2:B.end_index+12] "
  22. group_sql = " group by A.doc_id,C.entity_id,C.label,D.label,B.entity_text,B.begin_index,B.end_index,A.tokens,A.sentence_index "
  23. sql = select_sql+" from sentences A,entity_mention B,"+t+" C,label_guest_role D where A.doc_id=B.doc_id and A.sentence_index=B.sentence_index and B.entity_id=C.entity_id and C.entity_id=D.entity_id and C.label!=D.label "+group_sql+"order by A.doc_id,A.sentence_index asc,D.label asc"
  24. cursor.execute(sql)
  25. result = []
  26. rows = cursor.fetchall()
  27. for row in rows:
  28. item = []
  29. for column in row:
  30. item.append(column)
  31. result.append(item)
  32. conn.close()
  33. return result
  34. def labeling(datas):
  35. '''
  36. @summary:标注数据
  37. @param:
  38. datas:待标注数据,包括doc_id,entity_id,标注值,上下文
  39. '''
  40. sum = 0
  41. row_index = 0
  42. begin_doc_id = str(input("开始文章是:"))
  43. begin_index = 0
  44. end_index = len(datas)-1
  45. find_flag = False
  46. while(row_index<len(datas)):
  47. row = datas[row_index]
  48. if begin_doc_id!="" and begin_index==0:
  49. if row[0]==begin_doc_id:
  50. begin_index = row_index
  51. else:
  52. row_index += 1
  53. continue
  54. find_flag = True
  55. print(row[0])
  56. print(row[3],row[4],row[5])
  57. print("before",row[6])
  58. print("entity",row[7])
  59. print("after",row[8])
  60. while(True):
  61. l = str(input("标签为:"))
  62. if l in ["0","1","2","3","4","5","","8","9"]:
  63. break
  64. if l=="0":
  65. row[2] = 0
  66. elif l=="1":
  67. row[2] = 1
  68. elif l=="2":
  69. row[2] = 2
  70. elif l=="3":
  71. row[2] = 3
  72. elif l=="4":
  73. row[2] = 4
  74. elif l=="5":
  75. row[2] = 5
  76. elif l=="":
  77. pass
  78. elif l=="8":
  79. row_index -= 1
  80. sum -= 1
  81. continue
  82. elif l=="9":
  83. end_index = row_index-1
  84. break
  85. sum += 1
  86. row_index += 1
  87. print("sum:",sum)
  88. if find_flag:
  89. with codecs.open("relabel.txt","a",encoding="utf8") as f:
  90. for row in datas[begin_index:end_index+1]:
  91. f.write(str(row[1]))
  92. f.write("\t")
  93. f.write(str(row[2]))
  94. f.write("\n")
  95. f.flush()
  96. f.close()
  97. #设置表格样式
  98. def set_style(name,height,bold=False):
  99. style = xlwt.XFStyle()
  100. font = xlwt.Font()
  101. font.name = name
  102. font.bold = bold
  103. font.color_index = 4
  104. font.height = height
  105. style.font = font
  106. return style
  107. def getDatasToExcel():
  108. '''
  109. @summary:取出待标注数据到excel中
  110. '''
  111. roles = ["0_招标人","1_招标代理","2_中标第一候选","3_第二候选","4_第三候选","5_无"]
  112. conn = psycopg2.connect(dbname="BiddingKM_test_10000",user="postgres",password="postgres",host="192.168.2.101")
  113. cursor = conn.cursor()
  114. nums = 3
  115. for role in roles:
  116. select_sql = " select C.entity_id,C.label,A.tokens[B.begin_index-10:B.begin_index],A.tokens[B.begin_index+1:B.end_index+1],A.tokens[B.end_index+2:B.end_index+12],case when C.label=0 then '招标人' when C.label=1 then '招标代理' when C.label=2 then '中标人/第一候选' when C.label=3 then '第二候选' when C.label=4 then '第三候选' else '无' end as 再标注 "
  117. sql = select_sql+" from sentences A,entity_mention B,final_label_role C where C.label="+role.split("_")[0]+" and A.doc_id=B.doc_id and A.sentence_index=B.sentence_index and B.entity_id=C.entity_id and not exists(select 1 from relabel where C.entity_id=relabel.entity_id) order by C.label asc,A.doc_id,A.sentence_index asc limit 20000"
  118. print(sql)
  119. cursor.execute(sql)
  120. rows = cursor.fetchall()
  121. parts = len(rows)//3
  122. for nums_i in range(nums):
  123. file = xlwt.Workbook()
  124. sheet = file.add_sheet("标注"+role,cell_overwrite_ok=True)
  125. row_head = ["entity_id","标注id","实体前","实体","实体后","角色","正确?(1-正确,0-错误)"]
  126. row_index = 0
  127. style = set_style('Times New Roman',220,True)
  128. for i in range(len(row_head)):
  129. sheet.write(row_index,i,row_head[i],style)
  130. row_index += 1
  131. if nums_i<nums-1:
  132. for row in rows[nums_i*parts:(nums_i+1)*parts]:
  133. for i in range(len(row)):
  134. sheet.write(row_index,i,row[i],style)
  135. row_index += 1
  136. else:
  137. for row in rows[nums_i*parts:]:
  138. for i in range(len(row)):
  139. sheet.write(row_index,i,row[i],style)
  140. row_index += 1
  141. file.save("标注"+role.split("_")[1]+str(nums_i)+".xls")
  142. conn.close()
  143. def getDatasFromExcel():
  144. '''
  145. @summary:从已经标注的excel中取出标注数据
  146. '''
  147. home = "./label/role_done/"
  148. col_entity_id = 0
  149. col_label = 1
  150. col_flag = 6
  151. table = "hand_label_role"
  152. conn = psycopg2.connect(dbname="BiddingKM_test_10000",user="postgres",password="postgres",host="192.168.2.101")
  153. cursor = conn.cursor()
  154. cursor.execute(" select to_regclass('"+table+"') is null ")
  155. notExists = cursor.fetchall()[0][0]
  156. if notExists:
  157. cursor.execute(" create table "+table+" (entity_id text,label int)")
  158. else:
  159. cursor.execute(" delete from "+table)
  160. conn.commit()
  161. for file in os.listdir(home):
  162. if os.path.isfile(home+file):
  163. book = xlrd.open_workbook(home+file)
  164. sheet = book.sheet_by_index(0)
  165. for row_index in range(1,sheet.nrows):
  166. print(row_index,file)
  167. if len(str(sheet.cell_value(row_index,col_flag)))>0 and (int(sheet.cell_value(row_index,col_flag))>0):
  168. sql = " insert into "+table+"(entity_id,label) values('"+str(sheet.cell_value(row_index,col_entity_id))+"',"+str(int(sheet.cell_value(row_index,col_label)))+")"
  169. cursor.execute(sql)
  170. conn.commit()
  171. conn.close()
  172. def selectWrongDatasFromExcel():
  173. '''
  174. @summary:取出标注为错误的数据
  175. '''
  176. home = "./label/role_done/"
  177. data = []
  178. toExcel_file = "../../dl_dev/role/label/role_done/候选中因序号标错到无.xls"
  179. toExcel = xlwt.Workbook()
  180. toExcel_sheet = toExcel.add_sheet("错误标注到无",cell_overwrite_ok=True)
  181. row_head = ["entity_id","标注id","实体前","实体","实体后","角色","正确?(1-正确,0-错误)"]
  182. row_index_toExcel = 0
  183. style = set_style('Times New Roman',220,True)
  184. for i in range(len(row_head)):
  185. toExcel_sheet.write(row_index_toExcel,i,row_head[i],style)
  186. row_index_toExcel += 1
  187. for file in os.listdir(home):
  188. if os.path.isfile(home+file):
  189. if re.search(re.compile("第[一二三]"),file) is not None:
  190. book = xlrd.open_workbook(home+file)
  191. sheet = book.sheet_by_index(0)
  192. changeBook = copy(book)
  193. changeSheet = changeBook.get_sheet(0)
  194. for row_index in range(0,sheet.nrows):
  195. if re.search(re.compile("排名|排序|名次|第[123一二三]|(中标|成交)(人|单位|供应商)|成交情况"),str(sheet.cell_value(row_index,2))) is None:
  196. if re.search(re.compile("序号[::][123]"),str(sheet.cell_value(row_index,4))) is not None:
  197. print(file,sheet.row_values(row_index))
  198. changeSheet.write(row_index,6,0)
  199. row = sheet.row_values(row_index)
  200. row[1] = 5
  201. row[5] = "无"
  202. row[6] = 1
  203. for i in range(len(row)):
  204. toExcel_sheet.write(row_index_toExcel,i,row[i],style)
  205. row_index_toExcel += 1
  206. changeBook.save(home+"".join(file.split(".")[:-1])+"修改序号.xls")
  207. toExcel.save(toExcel_file)
  208. def exportHandLabelData():
  209. conn = psycopg2.connect(dbname="BiddingKM_test_10000",user="postgres",password="postgres",host="192.168.2.101")
  210. cursor = conn.cursor()
  211. sql = '''
  212. select A.entity_id,A.entity_text,A.begin_index,A.end_index,C.label,B.tokens
  213. from entity_mention A,sentences B ,hand_label_role C
  214. where A.doc_id=B.doc_id and A.sentence_index=B.sentence_index and A.entity_id=C.entity_id
  215. and A.entity_type in ('org','company')
  216. order by C.label
  217. '''
  218. cursor.execute(sql)
  219. rows = cursor.fetchall()
  220. list_entity_id = []
  221. list_before = []
  222. list_after = []
  223. list_text = []
  224. list_label = []
  225. repeat = set()
  226. for row in rows:
  227. entity_id = row[0]
  228. entity_text = row[1]
  229. begin_index = row[2]
  230. end_index = row[3]
  231. label = int(row[4])
  232. tokens = row[5]
  233. beforeafter = spanWindow(tokens, begin_index, end_index, 10)
  234. if ("".join(beforeafter[0]),entity_text,"".join(beforeafter[1])) in repeat:
  235. continue
  236. if str(label)!="5":
  237. continue
  238. repeat.add(("".join(beforeafter[0]),entity_text,"".join(beforeafter[1])))
  239. list_entity_id.append(entity_id)
  240. list_before.append("".join(beforeafter[0]))
  241. list_after.append("".join(beforeafter[1]))
  242. list_text.append(entity_text)
  243. list_label.append(label)
  244. print("len",len(list_entity_id))
  245. parts = 1
  246. parts_num = len(list_entity_id)//parts
  247. for i in range(parts-1):
  248. data = {"entity_id":list_entity_id[i*parts_num:(i+1)*parts_num],"list_before":list_before[i*parts_num:(i+1)*parts_num],"list_after":list_after[i*parts_num:(i+1)*parts_num],"list_text":list_text[i*parts_num:(i+1)*parts_num],"list_label":list_label[i*parts_num:(i+1)*parts_num]}
  249. df = pd.DataFrame(data)
  250. df.to_excel("原先标注数据_role_"+str(i)+".xls",columns=["entity_id","list_before","list_text","list_after","list_label"])
  251. i = parts - 1
  252. data = {"entity_id":list_entity_id[i*parts_num:],"list_before":list_before[i*parts_num:],"list_after":list_after[i*parts_num:],"list_text":list_text[i*parts_num:],"list_label":list_label[i*parts_num:]}
  253. df = pd.DataFrame(data)
  254. df.to_excel("角色无数据_role_"+str(i)+".xls",columns=["entity_id","list_before","list_text","list_after","list_label"])
  255. def selectWithRule(source,filter,target):
  256. assert target not in filter
  257. assert source!=target
  258. dict_source = pd.read_excel(source)
  259. set_filter = set()
  260. for filt in filter:
  261. set_filter = set_filter | set(pd.read_excel(filt)["entity_id"])
  262. list_entity_id = []
  263. list_before = []
  264. list_text = []
  265. list_after = []
  266. list_label = []
  267. for id,before,text,after,label in zip(dict_source["entity_id"],dict_source["list_before"],dict_source["list_text"],dict_source["list_after"],dict_source["list_label"]):
  268. if id in set_filter:
  269. continue
  270. if re.search("",str(before)) is not None:
  271. list_entity_id.append(id)
  272. list_before.append(before)
  273. list_text.append(text)
  274. list_after.append(after)
  275. list_label.append(label)
  276. data = {"entity_id":list_entity_id,"list_before":list_before,"list_text":list_text,"list_after":list_after,"list_label":list_label}
  277. columns = ["entity_id","list_before","list_text","list_after","list_label"]
  278. df = pd.DataFrame(data)
  279. df.to_excel(target,index=False,columns=columns)
  280. def importreHandLabelData():
  281. conn = psycopg2.connect(dbname="BiddingKM_test_10000",user="postgres",password="postgres",host="192.168.2.101")
  282. cursor = conn.cursor()
  283. table = "hand_label_role_0409"
  284. files = ["待检测原先标注数据_role_11.xls","待检查原先标注数据_role_00.xls","批量.xls"]
  285. for file in files:
  286. df = pd.read_excel(file)
  287. for entity_id,label,turn in zip(df["entity_id"],df["list_label"],df["turn"]):
  288. new_label = label
  289. #print(entity_id)
  290. if not math.isnan(turn):
  291. new_label = turn
  292. sql = " insert into "+table+"(entity_id,label) values('"+entity_id+"',"+str(new_label)+") "
  293. cursor.execute(sql)
  294. conn.commit()
  295. conn.close()
  296. def dumpData():
  297. conn = psycopg2.connect(dbname="BiddingKM_test_10000",user="postgres",password="postgres",host="192.168.2.101")
  298. cursor = conn.cursor()
  299. sql = " select B.entity_id,A.tokens,B.entity_text,B.begin_index,B.end_index,C.label from sentences A,entity_mention_copy B,hand_label_role_0409 C where B.entity_type in ('org','company') and A.doc_id=B.doc_id and A.sentence_index=B.sentence_index and B.entity_id=C.entity_id "
  300. cursor.execute(sql)
  301. rows = cursor.fetchall()
  302. save(rows,"id_token_text_begin_end_label.pk")
  303. conn.close()
  304. def relabel():
  305. pkfiles = ["id_token_text_begin_end_label.pk","id_token_text_begin_end_label.pk1"]
  306. list_id = []
  307. list_before = []
  308. list_text = []
  309. list_after = []
  310. list_label = []
  311. for file in pkfiles:
  312. for row in load(file):
  313. id = row[0]
  314. token = row[1]
  315. text = row[2]
  316. begin = int(row[3])
  317. end = int(row[4])
  318. label = int(row[5])
  319. span = spanWindow(token, begin, end, size=10, center_include=True, word_flag=True)
  320. before = span[0]
  321. center = span[1]
  322. after = span[2]
  323. if re.search("中标人.{,3}$",before) is not None:
  324. list_id.append(id)
  325. list_before.append(before)
  326. list_text.append(center)
  327. list_after.append(after)
  328. list_label.append(label)
  329. df = pd.DataFrame({"list_id":list_id,"list_before":list_before,"list_text":list_text,"list_after":list_after,"list_label":list_label})
  330. df.to_excel("rule1.xls",columns=["list_id","list_before","list_text","list_after","list_label"],index=False)
  331. def importAfterrelabel():
  332. conn = psycopg2.connect(dbname="BiddingKM_test_10000",user="postgres",password="postgres",host="192.168.2.101")
  333. cursor = conn.cursor()
  334. conn_1 = psycopg2.connect(dbname="article_label",user="postgres",password="postgres",host="192.168.2.101")
  335. cursor_1 = conn_1.cursor()
  336. df = pd.read_excel("rule1.xls")
  337. list_id = df["list_id"]
  338. list_label = df["list_label"]
  339. count = 0
  340. for id,label in zip(list_id,list_label):
  341. if re.search("比地",id) is not None:
  342. sql = " update turn_label set new_label='"+str(int(label))+"' where entity_id='"+id+"' "
  343. cursor_1.execute(sql)
  344. else:
  345. sql = " update hand_label_role_0409 set label="+str(int(label))+" where entity_id='"+id+"' "
  346. cursor.execute(sql)
  347. count += 1
  348. print("done",count)
  349. conn.commit()
  350. conn_1.commit()
  351. conn.close()
  352. conn_1.close()
  353. if __name__=="__main__":
  354. pass
  355. #labeling()
  356. #getDatasToExcel()
  357. #getDatasFromExcel()
  358. #selectWrongDatasFromExcel()
  359. #exportHandLabelData()
  360. #selectWithRule("角色无数据_role_0.xls",["批量.xls"],"公告公示.xls")
  361. #importreHandLabelData()
  362. #dumpData()
  363. #relabel()
  364. #importAfterrelabel()