Beispiel #1
0
 def prediction(self, path_test, path_train, path_bestModel):
     self.hyperpara = Hyperparameter()
     eval_test = Eval()
     ner = NER()
     reader = Reader()
     traininsts = reader.readfiles(path_train)
     testinsts = reader.readfiles(path_test)
     ner.create_alphabet(traininsts)
     self.hyperpara.tag_size = ner.hyperpara.tag_size
     self.hyperpara.embedding_num = ner.hyperpara.embedding_num
     self.model = BiLstm(self.hyperpara)  # BiLstm模型
     if self.hyperpara.loadModel == 1 and\
        self.hyperpara.load_pattern ==  1:
         try:
             self.model.load_state_dict(torch.load(path_bestModel))
         except Exception:
             print('模型参数不匹配')
         else:
             pass
     elif self.hyperpara.loadModel == 1 and\
          self.hyperpara.load_pattern == 0 :
         try:
             self.model = torch.load(path_bestModel)
         except Exception:
             print('模型参数不匹配')
         else:
             pass
     testExamples = ner.change(testinsts)
     for idx in range(len(testExamples)):
         test_list = []
         test_list.append(testExamples[idx])
         x, y = ner.variable(test_list)
         lstm_feats = self.model(x)
         predict = ner.getMaxIndex(lstm_feats)
         predictLabels = []
         for idy in range(len(predict)):
             predictLabels.append(ner.label_AlphaBet.list[predict[idy]])
         testinsts[idx].evalPRF(predictLabels, eval_test)
         a, e = testinsts[idx].extractA_and_E()
         self.Attr.append(a)
         self.Eval.append(e)
Beispiel #2
0
 def getAEOcount(self,path):
     a = 0
     e = 0
     o = 0
     reader = Reader()
     Inst = reader.readfiles(path)
     for i in Inst:
         for j in range(len(i.labels)):   
            if len(i.labels[j]) == 3:
                 if i.labels[j][2] == 'A':
                     a = a+1
                 elif i.labels[j][2] == 'E':
                     e = e+1
            elif i.labels[j] == 'O':
                 o += 1
     return a,e,o
Beispiel #3
0
    def train(self, path_train, path_dev, path_test, path_PRF, path_model,
              path_bestModel):
        #读取训练集、测试集、开发集 并 建立字典
        reader = Reader()
        traininsts = reader.readfiles(path_train)
        devinsts = reader.readfiles(path_dev)
        testinsts = reader.readfiles(path_test)
        print('Training Instance:', len(traininsts))
        print('Dev Instance:', len(devinsts))
        print('Test Instance:', len(testinsts))
        self.create_alphabet(traininsts)

        #字符串转成ID
        trainExamples = self.change(traininsts)  # e_train
        devExamples = self.change(devinsts)
        testExamples = self.change(testinsts)

        self.model = BiLstm(self.hyperpara)  # BiLstm模型
        # 加载模型
        if self.hyperpara.loadModel == 1 and\
           self.hyperpara.load_pattern ==  1:
            try:
                self.model.load_state_dict(torch.load(path_bestModel))
            except Exception:
                print('模型参数不匹配')
            else:
                pass
        elif self.hyperpara.loadModel == 1 and\
             self.hyperpara.load_pattern == 0 :
            try:
                self.model = torch.load(path_bestModel)
            except Exception:
                print('模型参数不匹配')
            else:
                pass
        optimizer = torch.optim.Adam(self.model.parameters(),
                                     lr=self.hyperpara.lr)  # 优化器
        total_num = len(trainExamples)
        for epoch in range(1, self.hyperpara.epochs):
            print("————————第{}轮迭代,共{}轮————————".format(epoch,
                                                       self.hyperpara.epochs))
            total = 0
            random.shuffle(trainExamples)  # 随机打乱训练集顺序,能有效提高准确率
            try:
                part = total_num // self.hyperpara.batch
                if total_num % self.hyperpara.batch != 0:
                    part += 1
            except ZeroDivisionError:
                print('batch数为0,除0错误')
            else:

                #开始训练
                self.model.train()
                for idx in range(part):
                    begin = idx * self.hyperpara.batch
                    end = (idx + 1) * self.hyperpara.batch
                    if end > total_num:
                        end = total_num
                    batch_list = []
                    #             batch_list_len = []
                    for idy in range(begin, end):
                        batch_list.append(trainExamples[idy])

    #                  batch_list_len.append(len(trainExamples[idy].wordIndexs))
                    optimizer.zero_grad()
                    x, y = self.variable(batch_list)
                    lstm_feats = self.model(x)
                    loss = F.cross_entropy(lstm_feats, y)
                    total += 1
                    loss.backward()
                    optimizer.step()
                    print('current:', total, ", loss:", loss.data[0])
            #开发集测试效果
            eval_dev = Eval()
            eval_dev_A = Eval()
            eval_dev_E = Eval()
            for idx in range(len(devExamples)):
                dev_list = []
                dev_list.append(devExamples[idx])
                x, y = self.variable(dev_list)
                lstm_feats = self.model(x)
                predict = self.getMaxIndex(lstm_feats)
                predictLabels = []
                for idy in range(len(predict)):
                    predictLabels.append(
                        self.label_AlphaBet.list[predict[idy]])
                gold_ent, predict_ent = devinsts[idx].evalPRF(
                    predictLabels, eval_dev)
                gold_ent_A, gold_ent_E, predict_ent_A, predict_ent_E = devinsts[
                    idx].getAE(gold_ent, predict_ent)
                devinsts[idx].evalAEPRF(gold_ent_A, predict_ent_A, eval_dev_A)
                devinsts[idx].evalAEPRF(gold_ent_E, predict_ent_E, eval_dev_E)
            line = ''
            print('Dev: ', end="")
            d_precision, d_recall, d_fscore = eval_dev.getFscore()
            line = line + str(epoch) + '.dev:\nP:' + (
                '%.2f' % (d_precision * 100)) + ' R:' + (
                    '%.2f' %
                    (d_recall * 100)) + ' F:' + ('%.2f' %
                                                 (d_fscore * 100)) + '\n'
            print("precision:", d_precision * 100, ", recall: ",
                  d_recall * 100, ", fscore:", d_fscore * 100)
            d_precision, d_recall, d_fscore = eval_dev_A.getFscore()
            line = line + 'A_P:' + ('%.2f' % (d_precision * 100)) + ' A_R:' + (
                '%.2f' %
                (d_recall * 100)) + ' A_F:' + ('%.2f' %
                                               (d_fscore * 100)) + '\n'
            print("precision:", d_precision * 100, ", recall: ",
                  d_recall * 100, ", fscore:", d_fscore * 100)
            d_precision, d_recall, d_fscore = eval_dev_E.getFscore()
            line = line + 'E_P:' + ('%.2f' % (d_precision * 100)) + ' E_R:' + (
                '%.2f' %
                (d_recall * 100)) + ' E_F:' + ('%.2f' %
                                               (d_fscore * 100)) + '\n'
            print("precision:", d_precision * 100, ", recall: ",
                  d_recall * 100, ", fscore:", d_fscore * 100)
            #测试集测试效果
            eval_test = Eval()
            eval_test_A = Eval()
            eval_test_E = Eval()
            for idx in range(len(testExamples)):
                test_list = []
                test_list.append(testExamples[idx])
                x, y = self.variable(test_list)
                lstm_feats = self.model(x)
                predict = self.getMaxIndex(lstm_feats)
                predictLabels = []
                for idy in range(len(predict)):
                    predictLabels.append(
                        self.label_AlphaBet.list[predict[idy]])
                gold_ent, predict_ent = testinsts[idx].evalPRF(
                    predictLabels, eval_test)
                gold_ent_A, gold_ent_E, predict_ent_A, predict_ent_E = testinsts[
                    idx].getAE(gold_ent, predict_ent)
                testinsts[idx].evalAEPRF(gold_ent_A, predict_ent_A,
                                         eval_test_A)
                testinsts[idx].evalAEPRF(gold_ent_E, predict_ent_E,
                                         eval_test_E)
            print('Test: ', end="")
            t_precision, t_recall, t_fscore = eval_test.getFscore()
            line = line + 'test:\nP:' + (
                '%.2f' % (t_precision * 100)) + ' R:' + (
                    '%.2f' %
                    (t_recall * 100)) + ' F:' + ('%.2f' %
                                                 (t_fscore * 100)) + '\n'
            print("precision:", t_precision * 100, ", recall: ",
                  t_recall * 100, ", fscore:", t_fscore * 100)
            t_precision, t_recall, t_fscore = eval_test_A.getFscore()
            line = line + 'A_P:' + ('%.2f' % (t_precision * 100)) + ' A_R:' + (
                '%.2f' %
                (t_recall * 100)) + ' A_F:' + ('%.2f' %
                                               (t_fscore * 100)) + '\n'
            print("precision:", t_precision * 100, ", recall: ",
                  t_recall * 100, ", fscore:", t_fscore * 100)
            t_precision, t_recall, t_fscore = eval_test_E.getFscore()
            line = line + 'E_P:' + ('%.2f' % (t_precision * 100)) + ' E_R:' + (
                '%.2f' %
                (t_recall * 100)) + ' E_F:' + ('%.2f' %
                                               (t_fscore * 100)) + '\n'
            print("precision:", t_precision * 100, ", recall: ",
                  t_recall * 100, ", fscore:", t_fscore * 100)
            #保存模型
            if self.hyperpara.save_pattern == 0:
                torch.save(self.model.state_dict(),
                           path_model + str(epoch) + '.pkl')
            elif self.hyperpara.save_pattern == 1:
                torch.save(self.model, path_model + str(epoch) + '.pkl')
            try:
                file = open(path_PRF, 'a+', encoding='utf-8')
            except IOError:
                print('文件读取异常')
            else:
                file.write(line)
                file.close()