【机器学习+NER】手把手教你用机器学习CRF模型构建NER系统(CCL2021)
【機(jī)器學(xué)習(xí)+NER】手把手教你用機(jī)器學(xué)習(xí)CRF模型構(gòu)建NER系統(tǒng)(CCL2021)
數(shù)據(jù)集來源:2021年中文計算語言學(xué)研究大會的智能對話診療評測比賽
任務(wù):利用機(jī)器學(xué)習(xí)CRF模型構(gòu)建NER系統(tǒng),得到下圖所示的評估指標(biāo)
原始數(shù)據(jù)處理參考:醫(yī)療命名體識別之?dāng)?shù)據(jù)預(yù)處理(處理.json文件)
文章目錄
- 【機(jī)器學(xué)習(xí)+NER】手把手教你用機(jī)器學(xué)習(xí)CRF模型構(gòu)建NER系統(tǒng)(CCL2021)
- 一、環(huán)境搭建
- 二、數(shù)據(jù)類型處理
- 三、訓(xùn)練模型
- 四、結(jié)果分析
- 五、完整源碼
一、環(huán)境搭建
此處機(jī)器學(xué)習(xí)CRF模型主要使用sklearn_crfsuite庫調(diào)用CRF進(jìn)行搭建;
可以通過:
pip install sklearn_crfsuite安裝sklearn_crfsuite庫
二、數(shù)據(jù)類型處理
三、訓(xùn)練模型
四、結(jié)果分析
從評估結(jié)果可以看出,模型對精準(zhǔn)率的宏平均值macro avg=0.90,加權(quán)平均值weighted avg=0.97。由此可以得出模型預(yù)測的正樣本中精確率達(dá)到90%以上;
模型對于召回率recall的宏平均值macro avg=0.89,加權(quán)平均值weighted avg=0.97,因而模型對于正樣本的分類準(zhǔn)確率能達(dá)到89%%,加權(quán)平均值weighted avg=0.97說明大部分正樣本的分類準(zhǔn)確率為97%。
模型對于F1-score的宏平均值macro avg=0.89,加權(quán)平均值weighted avg=0.97,說明模型的召回率和精準(zhǔn)率都很高,模型對于正樣本的預(yù)測效果和正樣本預(yù)測中的準(zhǔn)確性都很好。
五、完整源碼
import sklearn_crfsuite from sklearn.metrics import classification_reportchar_vocab_path = "./data/char_vocabs.txt" # 字典文件 train_data_path = "./data/train_data.txt" # 訓(xùn)練測試數(shù)據(jù) special_words = ['<PAD>', '<UNK>'] # 特殊詞表示 # CCL2021數(shù)據(jù)標(biāo)簽: label2idx = {'O': 0,'B-Symptom': 1, 'I-Symptom': 2,'B-Drug_Category': 3, 'I-Drug_Category': 4,'B-Drug': 5, 'I-Drug': 6,'B-Medical_Examination': 7, 'I-Medical_Examination': 8,'B-Operation': 9, 'I-Operation': 10}# 索引和BIO標(biāo)簽對應(yīng) idx2label = {idx: label for label, idx in label2idx.items()} # print(idx2label)# 讀取字符詞典文件 with open(char_vocab_path, "r", encoding="utf8") as fo:char_vocabs = [line.strip() for line in fo] char_vocabs = special_words + char_vocabs # print(char_vocabs)# 字符和索引編號對應(yīng) idx2vocab = {idx: char for idx, char in enumerate(char_vocabs)} vocab2idx = {char: idx for idx, char in idx2vocab.items()} # print(idx2vocab) # print(idx2vocab)# 讀取訓(xùn)練語料 def read_corpus(corpus_path, vocab2idx, label2idx, flag):datas, labels = [], []with open(corpus_path, encoding='utf-8') as fr:lines = fr.readlines()sent_, tag_ = [], []if flag == "train":lines = lines[:int(len(lines) * 0.7)]else:lines = lines[int(len(lines) * 0.7):]for line in lines:if line != '\n':[char, label] = line.strip().split()sent_.append(char)tag_.append(label)else:sent_ids = [vocab2idx[char] if char in vocab2idx else vocab2idx['<UNK>'] for char in sent_]tag_ids = [label2idx[label] if label in label2idx else 0 for label in tag_]datas.append(sent_ids)labels.append(tag_ids)sent_, tag_ = [], []return datas, labels# 加載訓(xùn)練集 7成 train_datas, train_labels = read_corpus(train_data_path, vocab2idx, label2idx, flag="train") # 加載測試集 3成 test_datas, test_labels = read_corpus(train_data_path, vocab2idx, label2idx, flag="test")# 輸出看數(shù)據(jù)是否對應(yīng)上了,"嘔吐" # print(train_datas[8]) # print([idx2vocab[idx] for idx in train_datas[8]]) # print(train_labels[8]) # print([idx2label[idx] for idx in train_labels[8]])# 得到訓(xùn)練數(shù)據(jù)、訓(xùn)練數(shù)據(jù)標(biāo)簽 labels = [] datas = [] for i in range(len(train_labels)):datas.append([idx2vocab[idx] for idx in train_datas[i]])train_datas = datas # print(train_datas)for i in range(len(train_labels)):labels.append([idx2label[idx] for idx in train_labels[i]])train_labels = labels # print(train_labels)# 得到測試數(shù)據(jù)、測試數(shù)據(jù)標(biāo)簽 labels = [] datas = [] for i in range(len(test_labels)):datas.append([idx2vocab[idx] for idx in test_datas[i]])test_datas = datasfor i in range(len(test_labels)):labels.append([idx2label[idx] for idx in test_labels[i]])test_labels = labels# 訓(xùn)練 crf = sklearn_crfsuite.CRF(algorithm='lbfgs',c1=0.1,c2=0.1,max_iterations=100,all_possible_transitions=True )crf.fit(train_datas, train_labels)labels = list(crf.classes_) # labels.remove('O')# 預(yù)測 test_pred = crf.predict(test_datas)sorted_labels = sorted(labels,key=lambda name: (name[1:], name[0]) )# 轉(zhuǎn)換成一維數(shù)組 label = [] pred = [] for i in range(len(test_labels)):for j in range(len(test_labels[i])):label.append(test_labels[i][j])test_labels = labelfor i in range(len(test_pred)):for j in range(len(test_pred[i])):pred.append(test_pred[i][j])test_pred = predprint(classification_report(test_labels, test_pred, target_names=sorted_labels ))總結(jié)
以上是生活随笔為你收集整理的【机器学习+NER】手把手教你用机器学习CRF模型构建NER系统(CCL2021)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Boxx:一个旨在提高 Python 代
- 下一篇: VM安装windows10操作系统