train_znj.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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 sys
  7. from keras.models import Model
  8. from keras.layers import Input, LSTM, Dense
  9. import numpy as np
  10. import pandas as pd
  11. from matplotlib import pyplot
  12. import random
  13. import json
  14. import psycopg2
  15. from BiddingKG.dl.common.models import *
  16. from sklearn.metrics import classification_report
  17. from BiddingKG.dl.interface.predictor import h5_to_graph
  18. input_shape = (2, 20, 128)
  19. output_shape = [5]
  20. def get_new_data():
  21. conn = psycopg2.connect(dbname="iepy", user="postgres", password="postgres", host="192.168.2.101")
  22. sql = "SELECT A.human_identifier,A.sentences,A.tokens,A.offsets_to_text,B.value,A.edituser " \
  23. "FROM corpus_iedocument A,brat_bratannotation B " \
  24. "WHERE A.human_identifier = B.document_id " \
  25. "and A.edittime > '2021-01-01' " \
  26. "and A.edittime < '2021-04-01' " \
  27. "and B.value like '%person%' " \
  28. "and A.edituser is not null " \
  29. "and A.jump_signal = 0 "
  30. db_data = []
  31. cur1 = conn.cursor()
  32. cur1.execute(sql)
  33. db_data.extend(cur1.fetchall())
  34. cur1.close()
  35. conn.close()
  36. columns = ['document_id','sentences','tokens','offsets_to_text','value','edituser']
  37. df = pd.DataFrame(db_data, columns=columns)
  38. drop1 = df[df['value'].str.contains('rel_person')]
  39. df = df.drop(index=drop1.index)
  40. df = df.reset_index(drop=True)
  41. print(len(df))
  42. person_label = df['value'].str.split(expand=True)
  43. person_label.columns = ['_', 'label_type', 'begin_index', 'end_index', 'entity_text']
  44. person_label = person_label.drop('_', axis=1)
  45. df = pd.concat([df, person_label], axis=1)
  46. print(df.info())
  47. # df['tokens'] = [token[2:-2].split("', '") for token in df['tokens']]
  48. # df['sentences'] = [sentence[1:-1].split(", ") for sentence in df['sentences']]
  49. # df['sentences'] = [[int(s) for s in sentence] for sentence in df['sentences']]
  50. # df['offsets_to_text'] = [offset[1:-1].split(", ") for offset in df['offsets_to_text']]
  51. # df['offsets_to_text'] = [[int(o) for o in offset] for offset in df['offsets_to_text']]
  52. df.to_csv("C:/Users/Administrator/Desktop/person_data/Person_new_data.csv")
  53. # save(df,'db_person_data.pk')
  54. def new_data_process():
  55. data = pd.read_csv("C:/Users/Administrator/Desktop/person_data/Person_new_data.csv",index_col=0)
  56. # test_users = ['test1','test7','test8','test17']
  57. label_dict = dict({
  58. "person":0,
  59. "person_tendereePerson":1,
  60. "person_agencyPerson":2,
  61. "person_person":3,
  62. "person_review":4
  63. }
  64. )
  65. data = data[data['edituser'].str.contains('test1$|test7$|test8$|test17$')]
  66. print(len(data))
  67. data['tokens'] = [token[2:-2].split("', '") for token in data['tokens']]
  68. data['offsets_to_text'] = [offset[1:-1].split(", ") for offset in data['offsets_to_text']]
  69. data['offsets_to_text'] = [[int(o) for o in offset] for offset in data['offsets_to_text']]
  70. data['label'] = [label_dict[_type] for _type in data['label_type']]
  71. # data = data[:1]
  72. word_list = []
  73. left_context = []
  74. right_context = []
  75. for tokens,offsets,begin,end,entity_text in zip(data['tokens'],data['offsets_to_text'],data['begin_index'],data['end_index'],data['entity_text']):
  76. begin = int(begin)
  77. end = int(end)
  78. if begin in offsets and end in offsets:
  79. b_index = offsets.index(begin)
  80. e_index = offsets.index(end)
  81. word = tokens[b_index:e_index]
  82. word = "".join(word)
  83. # print(word)
  84. context = spanWindow(tokens=tokens,begin_index=b_index,end_index=e_index,size=20)
  85. # print(context[0])
  86. word_list.append(word)
  87. left_context.append(context[0])
  88. right_context.append(context[1])
  89. else:
  90. word_list.append("&*$#")
  91. left_context.append("&*$#")
  92. right_context.append("&*$#")
  93. data['word'] = word_list
  94. data['left_context'] = left_context
  95. data['right_context'] = right_context
  96. data = data[data['entity_text']==data['word']]
  97. data.drop(columns=['tokens','offsets_to_text','sentences'],inplace=True)
  98. data.to_csv("C:/Users/Administrator/Desktop/person_data/Person_new_data_process.csv")
  99. def getBiGRU_Dropout():
  100. '''
  101. @summary: 获得模型
  102. '''
  103. L_input = layers.Input(shape=input_shape[1:], dtype="float32")
  104. R_input = layers.Input(shape=input_shape[1:], dtype="float32")
  105. lstm_0 = layers.Bidirectional(layers.GRU(32, dropout=0.4, recurrent_dropout=0.4, return_sequences=True))(L_input)
  106. avg_0 = layers.GlobalAveragePooling1D()(lstm_0)
  107. lstm_2 = layers.Bidirectional(layers.GRU(32, dropout=0.4, recurrent_dropout=0.4, return_sequences=True))(R_input)
  108. avg_2 = layers.GlobalAveragePooling1D()(lstm_2)
  109. concat = layers.merge([avg_0, avg_2], mode="concat")
  110. output = layers.Dense(output_shape[0], activation="softmax")(concat)
  111. model = models.Model(inputs=[L_input, R_input], outputs=output)
  112. model.compile(optimizer=optimizers.Adam(lr=0.0002), loss=losses.binary_crossentropy, metrics=[precision, recall, f1_score])
  113. return model
  114. def train():
  115. '''
  116. @summary: 训练模型
  117. '''
  118. train_x, train_y,test_x, test_y = getData(isTrain=True,add_data=True)
  119. model = getBiGRU_Dropout()
  120. model.summary()
  121. model_file = "model_person_classify_fjs.model.hdf5"
  122. # 回调checkpoint,保存loss最小的模型
  123. epochs = 150
  124. batch_size = 256
  125. checkpoint = ModelCheckpoint(model_file, monitor="val_loss", verbose=1, save_best_only=True, mode='min')
  126. history_model = model.fit(x=[train_x[0], train_x[1]], class_weight='auto',
  127. y=train_y, validation_data=([test_x[0], test_x[1]], test_y),
  128. epochs=epochs, batch_size=batch_size, shuffle=True, callbacks=[checkpoint])
  129. plotTrainTestLoss(history_model)
  130. def plotTrainTestLoss(history_model):
  131. pyplot.plot(history_model.history['loss'])
  132. pyplot.plot(history_model.history['val_loss'])
  133. pyplot.title('model train vs validation loss')
  134. pyplot.ylabel('loss')
  135. pyplot.xlabel('epoch')
  136. pyplot.legend(['train', 'validation'], loc='upper right')
  137. pyplot.show()
  138. val_loss = list(history_model.history['val_loss'])
  139. min_val_loss = min(val_loss)
  140. print("min_val_loss:",min_val_loss)
  141. print("min_epoch:",val_loss.index(min_val_loss))
  142. def getData(isTrain = True,add_data = False):
  143. '''
  144. :return:返回训练数据或测试数据的词嵌入,分前后两个句子,不包含中心词
  145. '''
  146. x_list = []
  147. y_list = []
  148. if isTrain and not add_data:
  149. data = pd.read_csv("C:/Users/Administrator/Desktop/person_data/Person_Sentence_Notest_new111-20.csv")
  150. elif not isTrain:
  151. data = pd.read_csv("C:/Users/Administrator/Desktop/person_data/test2000_new-20.csv")
  152. elif add_data:
  153. print("add data!")
  154. data = pd.read_csv("C:/Users/Administrator/Desktop/person_data/Person_Sentence_Notest_new111-20.csv")
  155. data_add = pd.read_csv("C:/Users/Administrator/Desktop/person_data/add_data.csv")
  156. data_add['left_context'] = [left[2:-2].split("', '") for left in data_add['left_context']]
  157. data_add['right_context'] = [right[2:-2].split("', '") for right in data_add['right_context']]
  158. for left, right, label in zip(data_add['left_context'], data_add['right_context'], data_add['re_label']):
  159. y = np.zeros(output_shape)
  160. y[label] = 1
  161. if label == 4:
  162. if '。' in left:
  163. i = left.index('。')
  164. left[i] = ','
  165. context = [left, right]
  166. x = embedding(context, shape=input_shape)
  167. x_list.append(x)
  168. y_list.append(y)
  169. pingsheng = re.compile("专家|评标委员|评委|评审小组|评审委员")
  170. # new_data
  171. new_data = pd.read_csv("C:/Users/Administrator/Desktop/person_data/Person_new_data_process-20.csv")
  172. new_data['left_context'] = [left[2:-2].split("', '") for left in new_data['left_context']]
  173. new_data['right_context'] = [right[2:-2].split("', '") for right in new_data['right_context']]
  174. for left, right, re_label,label,left4read in zip(new_data['left_context'], new_data['right_context'],
  175. new_data['re_label'],new_data['label'],new_data['left4read']):
  176. if label in [1,2]:
  177. y = np.zeros(output_shape)
  178. y[re_label] = 1
  179. context = [left, right]
  180. x = embedding(context, shape=input_shape)
  181. x_list.append(x)
  182. y_list.append(y)
  183. elif label==4 and re.search(pingsheng,left4read):
  184. y = np.zeros(output_shape)
  185. y[re_label] = 1
  186. context = [left, right]
  187. x = embedding(context, shape=input_shape)
  188. x_list.append(x)
  189. y_list.append(y)
  190. new_data2 = pd.read_csv("C:/Users/Administrator/Desktop/person_data/same_data-20.csv")
  191. new_data2['left_context'] = [left[2:-2].split("', '") for left in new_data2['left_context']]
  192. new_data2['right_context'] = [right[2:-2].split("', '") for right in new_data2['right_context']]
  193. for left, right, re_label,label in zip(new_data2['left_context'], new_data2['right_context'],
  194. new_data2['re_label'],new_data2['label']):
  195. if label in [0,3]:
  196. y = np.zeros(output_shape)
  197. y[re_label] = 1
  198. context = [left, right]
  199. x = embedding(context, shape=input_shape)
  200. x_list.append(x)
  201. y_list.append(y)
  202. # print(len(data))
  203. # data = data.drop_duplicates(subset=['left_context','right_context'])
  204. # print(len(data))
  205. data['left_context'] = [left[2:-2].split("', '") for left in data['left_context']]
  206. data['right_context'] = [right[2:-2].split("', '") for right in data['right_context']]
  207. for left, right, label in zip(data['left_context'], data['right_context'], data['re_label']):
  208. y = np.zeros(output_shape)
  209. y[label] = 1
  210. if label==4:
  211. if '。' in left:
  212. i = left.index('。')
  213. left[i] = ','
  214. context = [left, right]
  215. x = embedding(context, shape=input_shape)
  216. x_list.append(x)
  217. y_list.append(y)
  218. x_list, y_list = (np.array(x_list), np.array(y_list))
  219. data_len = len(x_list)
  220. print("数据总量:",data_len)
  221. test_len = int(data_len * 0.1)
  222. indices = np.random.permutation(data_len) # 生成随机数列
  223. indices = list(indices)
  224. x_list = x_list[indices]
  225. y_list = y_list[indices]
  226. x_train = x_list[test_len:]
  227. y_train = y_list[test_len:]
  228. # x_train = x_list
  229. # y_train = y_list
  230. x_test = x_list[:test_len]
  231. y_test = y_list[:test_len]
  232. # x_train, y_train = (np.array(x_train), np.array(y_train))
  233. # x_test, y_test = (np.array(x_test), np.array(y_test))
  234. x_train = np.transpose(x_train, (1, 0, 2, 3))
  235. x_test = np.transpose(x_test, (1, 0, 2, 3))
  236. return x_train, y_train,x_test, y_test
  237. def predict():
  238. model1 = models.load_model("model_person_classify_fjs.model.hdf5",custom_objects={'precision':precision,'recall':recall,'f1_score':f1_score})
  239. # data_load = pd.read_csv("C:/Users/Administrator/Desktop/person_data/test2000_new-20.csv", index_col=0)
  240. data_load = pd.read_csv("C:/Users/Administrator/Desktop/person_data/Person_Sentence_Notest_new111-20.csv", index_col=0)
  241. # data_load = pd.read_csv("C:/Users/Administrator/Desktop/person_data/Person_new_data_process-20.csv")
  242. data_load['left_context'] = [left[2:-2].split("', '") for left in data_load['left_context']]
  243. data_load['right_context'] = [right[2:-2].split("', '") for right in data_load['right_context']]
  244. test_x = []
  245. test_y = []
  246. for left, right, label in zip(data_load['left_context'], data_load['right_context'], data_load['re_label']):
  247. y = np.zeros(output_shape)
  248. y[label] = 1
  249. if label==4:
  250. if '。' in left:
  251. i = left.index('。')
  252. left[i] = ','
  253. context = [left, right]
  254. x = embedding(context, shape=input_shape)
  255. test_x.append(x)
  256. test_y.append(y)
  257. test_x = np.transpose(np.array(test_x), (1, 0, 2, 3))
  258. pre_y = model1.predict([test_x[0],test_x[1]])
  259. data_load['pre'] = [np.argmax(item) for item in pre_y]
  260. data_load['prob'] = [np.max(item) for item in pre_y]
  261. data_load.to_csv("C:/Users/Administrator/Desktop/person_data/test_result1_20.csv")
  262. # data_load.to_csv("C:/Users/Administrator/Desktop/person_data/new_data_predict_20.csv")
  263. error_data = data_load[data_load['re_label']!=data_load['pre']]
  264. # same_data = data_load[data_load['re_label']==data_load['pre']]
  265. error_data.to_csv("C:/Users/Administrator/Desktop/person_data/error1-20.csv")
  266. # same_data.to_csv("C:/Users/Administrator/Desktop/person_data/same_data-20.csv")
  267. def hdf52savemodel():
  268. filepath = 'model_person_classify_fjs.model.hdf5'
  269. with tf.Graph().as_default() as graph:
  270. model = models.load_model(filepath, custom_objects={'precision': precision, 'recall': recall, 'f1_score': f1_score})
  271. with tf.Session() as sess:
  272. sess.run(tf.global_variables_initializer())
  273. h5_to_graph(sess, graph, filepath)
  274. tf.saved_model.simple_save(sess,
  275. "./person_savedmodel_new/",
  276. inputs={"input0":model.input[0],
  277. "input1":model.input[1]},
  278. outputs={"outputs":model.output})
  279. if __name__ == '__main__':
  280. # train()
  281. # predict()
  282. # get_new_data()
  283. # new_data_process()
  284. hdf52savemodel()
  285. pass