Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.
1. Анализ задачи и вывод формулы
Чем лучше результат тегирования части речи, то есть вероятность результата тегирования наибольшая, в соответствии с моделью зашумленного канала:
из которыхприговор,является частью речи слова в предложении;Может рассматриваться как Translate Model,Можно рассматривать как языковую модель.
Разделите выражение вверх:
Согласно гипотезе Маркова, предполагая, что слова независимы друг от друга, текущее слово связано только с текущей частью речи:
Чтобы значение результата не было слишком маленьким, в сочетании со строго возрастающей характеристикой логарифмической функции получается логарифм вероятности:
Предполагать:
Пусть N будет количеством слов, M будет количеством тегов, A представляет вероятность появления каждого слова под данным тегом (частью речи), а размер матрицы равен M * N,
B представляет собой матрицу преобразования между тегами, размер матрицы M*M,
Pi представляет вероятность появления тега в начале предложения, а размер матрицы равен 1*M.
два,Используйте алгоритм Витерби (алгоритм динамического программирования), чтобы найти максимальное значение формулы
Среди них: dp[i,j] означает, будетназначить тегиВ случае наилучший путь от начала до i (т.е. наибольшая вероятность), преобразующий его во множество подзадач, тогда:
три,код
(1) Данные
(2) Создайте словарь и таблицу тегов
# 构建词汇表和tag表
# maps tag to id . tag2id:{"VB":0,"NNP":1...},id2tag:{0:"VB",1:"NNP"} tag2id ,id2tag = {},{} # maps word to id
word2id ,id2word = {},{}
for line in open("./data/08/traindata.txt"): i
tems = line.split("/")
# 获取每一行的单词和词性,rstrip():删除末尾指定字符,默认为空格
word,tag = items[0],
items[1].rstrip()
if word not in word2id:
word2id[word]=len(word2id)
id2word[len(id2word)] = word
if tag not in tag2id: tag2id[tag] = len(tag2id)
id2tag[len(id2tag)] = tag
(3) Рассчитать параметры модели
#计算模型的参数:A,B,Pi矩阵
N = len(word2id) # N: 词典的大小、# of words in dictionary M = len(tag2id) # M: 词性的种类个数 # of tags in tag set
# A[i][j]: 给定tag i, 出现单词j的概率。 N: # of tags M: # of words in dictionary
A = np.zeros(M,N)
# B[i][j]: 之前的状态是i, 之后转换成转态j的概率 N: # of tags
B = np.zeros(M,M)
# 每个词性出现在句子中第一个位置的概率, N: # of tags pi[i]: tag i出现在句子中第一个位置的概率
Pi = np.zeros(M)
prev_tag = ""
for line in open("./data/08/traindata.txt"):
items = line.split('/')
wordId,tagId = word2id[items[0]],tag2id[items[1]]
if prev_tag == "":#表示是句子开头
Pi[tagId] += 1
A[tagId][wordId] += 1
else:
A[tagId][wordId] += 1
B[tag2id[prev_tag]][tagId] += 1
if items[0] == ".":
prev_tag = ""
else:
prev_tag = items[1].rstrip()
# 标准化
Pi = Pi/sum(Pi)
for i in range(M):
A[i] /= sum(A[i])
B[i] /= sum(B[i])