1. Принцип ИРК
1.1 Пример CRF
CRF просто означает, удовлетворяют ли соседние переменные на карте вероятностей характеристической функцииМодель , такая как пример ниже, представляет собой CRF-приложение для идентификации продавца. Для ввода адреса продавца, ключевых слов имени, сферы деятельности и другой информации используйте метод маркировки BIOS, отмеченный следующим образом:
-
Функция передаточной характеристики:
-
Функция функции состояния:
-
Характеристическая функция перехода (t) принимает четыре параметра, а характеристическая функция состояния (s) принимает три параметра:
- , предложение обозначить частью речи
- , используется для представления i-го слова в предложении s
- , указывающий на часть речи тега i-го слова
- , представляющий часть речи тега i-1-го слова
Его выходное значение равно 0 или 1, 0 указывает, что оцениваемая последовательность меток не соответствует этому признаку, 1 указывает, что оцениваемая последовательность меток соответствует этому признаку,- веса функции признаков перехода t и функции признаков состояния s соответственно.
1.2 В приведенной выше задаче идентификации продавца
-
За ключевым словом бизнеса следует сфера бизнеса, мы можем дать положительную оценку и передать характеристическую функцию: (I-KEYWORDS B-BUSINESS)
= 1;
-
отметить мега какKEYWORDS , мы можем дать положительную оценку функции признаков состояния:
1.3 Параметризация вышеуказанного процесса
Вероятностный (с использованием функции softmax):
Объедините функцию функции перехода и функцию функции состояния, и параметрыозначает, что приведенную выше формулу можно записать в виде:
Среди них,используется для нормализации,
2. Построение функции CRF
В модели CRF задействованы следующие два типа шаблонов объектов:
2.1 функции базового класса, то есть часто используемые функции в модели CRF, включая следующие 4 категории:
-
это число
-
Будь то английские цифры: 1-10
-
Китайские цифры: «один», «два», «три», «четыре», «пять», «шесть», «семь», «восемь», «девять», «десять».
-
Традиционные китайские числа: «A», «B», «C», «D», «Wu», «Ji», «Geng», «Xin», «Ren», «Kui».
-
-
верхний регистр Нижний регистр
-
Начинается ли текст / заканчивается ли текст
-
Является ли первое соседнее слово строчным/прописным; является ли второе соседнее слово строчным/прописным
2.2 Возможности класса Ngrams
Сам Ngram также относится к набору, состоящему из N слов или слов, каждое слово или слово имеет последовательность, и они не обязаны отличаться друг от друга
3. Применение CRF в NER
CRF широко используется для маркировки последовательностей Пакет sklearn-crfsuite используется ниже для реализации модели маркировки последовательностей CRF с четырех аспектов: импорт данных, создание признаков, обучение и оценка. Код можно запускать напрямую
3.1 Подготовка данных
импортировать зависимости
import sklearn
import scipy.stats
import sklearn_crfsuite
from sklearn_crfsuite import scorers
from sklearn_crfsuite import metrics
Загрузите данные CoNLL 2002 с помощью nltk
import nltk
nltk.download('conll2002')
----------------- # 分割线下是输出,不是代码
>>> [nltk_data] Downloading package conll2002 to /root/nltk_data...
[nltk_data] Package conll2002 is already up-to-date!
True
Загрузить данные conll2002
%%time
train_sents = list(nltk.corpus.conll2002.iob_sents('esp.train'))
test_sents = list(nltk.corpus.conll2002.iob_sents('esp.testb'))
Просмотр фрагмента данных
train_sents[0]
----------------- # 分割线下是输出,不是代码
>>> [('Melbourne', 'NP', 'B-LOC'),
('(', 'Fpa', 'O'),
('Australia', 'NP', 'B-LOC'),
(')', 'Fpt', 'O'),
(',', 'Fc', 'O'),
('25', 'Z', 'O'),
('may', 'NC', 'O'),
('(', 'Fpa', 'O'),
('EFE', 'NC', 'B-ORG'),
(')', 'Fpt', 'O'),
('.', 'Fp', 'O')]
Обычно наши данные имеют только текст и аннотации NER, поэтому мы берем только текст вышеуказанных данных и аннотации в формате BIOS и просматриваем часть данных.
train_sents_ner = [[(i[0], i[2]) for i in row] for row in train_sents]
test_sents_ner = [[(i[0], i[2]) for i in row] for row in test_sents]
train_sents_ner[0]
----------------- # 分割线下是输出,不是代码
>>> [('Melbourne', 'B-LOC'),
('(', 'O'),
('Australia', 'B-LOC'),
(')', 'O'),
(',', 'O'),
('25', 'O'),
('may', 'O'),
('(', 'O'),
('EFE', 'B-ORG'),
(')', 'O'),
('.', 'O')]
3.2 Генерация признаков
Создавайте шаблоны, используя функции из официальной документации
def word2features(sent, i):
word = sent[i][0]
postag = sent[i][1]
features = {
'bias': 1.0,
'word.lower()': word.lower(),
'word[-3:]': word[-3:],
'word[-2:]': word[-2:],
'word.isupper()': word.isupper(),
'word.istitle()': word.istitle(),
'word.isdigit()': word.isdigit()
}
if i > 0:
word1 = sent[i-1][0]
features.update({
'-1:word.lower()': word1.lower(),
'-1:word.istitle()': word1.istitle(),
'-1:word.isupper()': word1.isupper()
})
else:
features['BOS'] = True
if i < len(sent)-1:
word1 = sent[i+1][0]
features.update({
'+1:word.lower()': word1.lower(),
'+1:word.istitle()': word1.istitle(),
'+1:word.isupper()': word1.isupper()
})
else:
features['EOS'] = True
return features
def sent2features(sent):
return [word2features(sent, i) for i in range(len(sent))]
def sent2labels(sent):
return [label for token, label in sent]
def sent2tokens(sent):
return [token for token, label in sent]
Посмотрите, как выглядит преобразованный элемент
sent2features(train_sents_ner[0])[2]
# 第一条训练数据中,第3个单词(Australia)的特征如下
----------------- # 分割线下是输出,不是代码
>>>{'+1:word.istitle()': False,
'+1:word.isupper()': False,
'+1:word.lower()': ')',
'-1:word.istitle()': False,
'-1:word.isupper()': False,
'-1:word.lower()': '(',
'bias': 1.0,
'word.isdigit()': False,
'word.istitle()': True,
'word.isupper()': False,
'word.lower()': 'australia',
'word[-2:]': 'ia',
'word[-3:]': 'lia'}
Преобразование как обучающих данных, так и тестовых данных в их представления функций
X_train = [sent2features(s) for s in train_sents_ner]
y_train = [sent2labels(s) for s in train_sents_ner]
X_test = [sent2features(s) for s in test_sents_ner]
y_test = [sent2labels(s) for s in test_sents_ner]
3.3 Обучение модели
%%time
crf = sklearn_crfsuite.CRF(
algorithm='lbfgs',
c1=0.1,
c2=0.1,
max_iterations=100,
all_possible_transitions=True)
crf.fit(X_train, y_train)
----------------- # 分割线下是输出,不是代码
>>> CPU times: user 35 s, sys: 21.8 ms, total: 35.1 s
Wall time: 35.1 s
3.4 Предсказание модели
labels = list(crf.classes_)
labels.remove('O')
labels
----------------- # 分割线下是输出,不是代码
>>> ['B-LOC', 'B-ORG', 'B-PER', 'I-PER', 'B-MISC', 'I-ORG', 'I-LOC', 'I-MISC']
y_pred = crf.predict(X_test)
metrics.flat_f1_score(y_test, y_pred, average='weighted', labels=labels)
----------------- # 分割线下是输出,不是代码
>>> 0.7860514251609507
# group B and I results
sorted_labels = sorted(labels,key=lambda name: (name[1:], name[0]))
print(metrics.flat_classification_report(
y_test, y_pred, labels=sorted_labels, digits=3
))
----------------- # 分割线下是输出,不是代码
>>> precision recall f1-score support
B-LOC 0.800 0.778 0.789 1084
I-LOC 0.672 0.631 0.651 325
B-MISC 0.721 0.534 0.614 339
I-MISC 0.686 0.582 0.630 557
B-ORG 0.804 0.821 0.812 1400
I-ORG 0.846 0.776 0.810 1104
B-PER 0.832 0.865 0.849 735
I-PER 0.884 0.935 0.909 634
micro avg 0.803 0.775 0.789 6178
macro avg 0.781 0.740 0.758 6178
weighted avg 0.800 0.775 0.786 6178