Скрытые марковские причастия

задняя часть алгоритм глубокое обучение NLP
Скрытые марковские причастия

предисловие

Хотя многие задачи nlp были разработаны для использования моделей рекуррентных нейронных сетей глубокого обучения и моделей внимания, нам также необходимо понимать традиционные модели. Вот как можно использовать скрытую марковскую модель (HMM) для сегментации слов.

Скрытая марковская модель

Скрытая марковская модель представляет собой модель ориентированного графа.Модель графа может явно выражать вероятность корреляции между переменными.Модель общего графа также имеет условное случайное поле.Узлы представляют переменные, а связь между узлами представляет вероятность корреляции между два. Модель HMM описывается следующими определениями:

Пусть множество всех возможных состояний системы естьS = \{s_1,s_2,...s_n\}, набор всех наблюдаемых объектовV=\{v_1,v_2,...v_m\}, то всего имеется n скрытых состояний и m явных состояний.

Затем установите последовательность состояний в общей сложности T разE = (e_1,e_2,...e_T), соответствующий последовательности наблюдений с T моментамиO = (o_1,o_2,...o_T), эти два слова легко понять. Тег части речи, соответствующий nlp, представляет собой предложение, а тег части речи этого предложения, например, «я/есть/китаец/человек» и «местоимение/глагол/ существительное/существительное».

Скрытые марковские модели в основном имеют три группы вероятностей: вероятность перехода, вероятность наблюдения и вероятность начального состояния.

Существует вероятность перехода между состояниями системы, и задана матрица переходаA = [a_{ij}]_{n \times n}, потому что есть n скрытых состояний, поэтому это n строк и n столбцов. Формула для расчета вероятности:

a_{ij} = P(e_{t+1} = s_j | e_t =s_i) ,\quad  1 \le i,j \le n

Это означает, что состояние в любой момент времени ts_i, то состояние в следующий момент будетs_jВероятность , то есть вероятность перехода двух состояний в любой момент времени.

Матрица вероятности наблюденияB = [b_{ij}]_{n \times m}b_{ij} = P(o_t=v_j|e_t=s_i), \quad 1 \le i\le n,1 \le j\le m, который используется для представления того, что в любой момент времени t, если состояниеs_i, то генерируется наблюдаемое состояниеv_kВероятность.

Кроме того, существует вероятность начального состояния\pi =(\pi_1,\pi_2,...,\pi_n), который используется для представления вероятности появления каждого состояния в начальный момент, где\pi_i=P(e_1=s_i),\quad i=1,2,...,n, то есть состояние в момент времени t=1 равноs_iВероятность.

Подводя итоги, можно использовать скрытую модель Маркова с\lambda = [A,B,\pi]описывать.

image

тег последовательности

Для маркировки обучающих данных можно указать четыре типа меток: BMES. Где B обозначает начало слова, M — середину слова, E — конец слова, а S — слово, состоящее из одного слова. Например, следующее

农B业E生B产E再B次E获B得E好S的S收B成E

После завершения метки получаются последовательность наблюдений и последовательность состояний, а также два из пяти элементов скрытой марковской модели.Через эти два элемента можно получить матрицу переходных вероятностей, матрицу вероятностей наблюдений и вероятность начального состояния. быть рассчитаны.

код реализации

Сначала определите функцию чтения обучающего файла, где слово и метка начинаются с\tПроцесс сегментации и чтения подсчитывает набор объектов наблюдения и состояние, установленное между ними.

def read_data(filename):
    sentences = []
    sentence = []
    with open(filename, 'r', encoding='utf-8') as f:
        for line in f.readlines():
            word_label = line.strip().split('\t')
            if len(word_label) == 2:
                observation_set.add(word_label[0])
                state_set.add(word_label[1])
                sentence.append(word_label)
            else:
                sentences.append(sentence)
                sentence = []
    return sentences

Определение функции обучения, после прочтения через все приговоры обучения корпусов, матрица вероятностей статистической наблюденияobservation_matrix, статистическая вероятность начального состоянияpi_state, матрица статистической вероятности переходаtransition_matrix, здесь мы сначала считаем число, а затем нормализуем его, чтобы получить реальную вероятность. Следовательно, можно видеть, что матрица вероятности перехода, матрица вероятности наблюдения и начальное состояние нормированы соответственно.

def train():
    print('begin training......')
    sentences = read_data(data_path)
    for sentence in sentences:
        pre_label = -1
        for word, label in sentence:
            observation_matrix[label][word] = observation_matrix.setdefault(label, {}).setdefault(word, 0) + 1
            if pre_label == -1:
                pi_state[label] = pi_state.setdefault(label, 0) + 1
            else:
                transition_matrix[pre_label][label] = transition_matrix.setdefault(pre_label, {}).setdefault(label,
                                                                                                             0) + 1
            pre_label = label

    for key, value in transition_matrix.items():
        number_total = 0
        for k, v in value.items():
            number_total += v
        for k, v in value.items():
            transition_matrix[key][k] = 1.0 * v / number_total
    for key, value in observation_matrix.items():
        number_total = 0
        for k, v in value.items():
            number_total += v
        for k, v in value.items():
            observation_matrix[key][k] = 1.0 * v / number_total

    number_total = sum(pi_state.values())
    for k, v in pi_state.items():
        pi_state[k] = 1.0 * v / number_total

    print('finish training.....')
    save_model()

Сохраните параметры модели в файл после обучения и загрузите модель указанного файла при прогнозировании.

def load_model():
    print('loading model...')
    with open(model_path, 'rb') as f:
        model = pickle.load(f)
    return model

def save_model():
    print('saving model...')
    model = [transition_matrix, observation_matrix, pi_state, state_set, observation_set]
    with open(model_path, 'wb') as f:
        pickle.dump(model, f)

После завершения обучения получаются параметры модели, а затем определяется функция прогнозирования. Наш прогноз на самом деле является проблемой декодирования HMM. Как правило, можно использовать алгоритм Витерби. Подробности см. в предыдущей статье "Алгоритм декодирования Vititerbi для скрытых моделей Маркова".

С течением времени каждый узел сохраняет подпуть от всех узлов в предыдущий момент до оптимального значения узла, и оптимальное значение оценивается путем умножения кумулятивной вероятности на узле в предыдущий момент на вероятность в текущий момент. момент. Возможный путь узла в текущий момент — это путь от всех узлов к узлу в предыдущий момент, но мы оставляем только один из оптимальных путей. После вычисления всех шагов по очереди оптимальный путь всего процесса окончательно получается путем возврата.

def predict():
    text = '我在图书馆看书'
    min_probability = -1 * float('inf')
    words = [{} for _ in text]
    path = {}
    for state in state_set:
        words[0][state] = 1.0 * pi_state.get(state, default_probability) * observation_matrix.get(state, {}).get(
            text[0],
            default_probability)
        path[state] = [state]
    for t in range(1, len(text)):
        new_path = {}
        for state in state_set:
            max_probability = min_probability
            max_state = ''
            for pre_state in state_set:
                probability = words[t - 1][pre_state] * transition_matrix.get(pre_state, {}).get(state,
                                                                                                 default_probability) \
                              * observation_matrix.get(state, {}).get(text[t], default_probability)
                max_probability, max_state = max((max_probability, max_state), (probability, pre_state))
            words[t][state] = max_probability
            tmp = copy.deepcopy(path[max_state])
            tmp.append(state)
            new_path[state] = tmp
        path = new_path
    max_probability, max_state = max((words[len(text) - 1][s], s) for s in state_set)
    result = []
    p = re.compile('BM*E|S')
    for i in p.finditer(''.join(path[max_state])):
        start, end = i.span()
        word = text[start:end]
        result.append(word)
    print(result)

Приблизительно опишите процесс декодирования.В начальном состоянии для четырех состояний максимальная вероятность «Я» равна S, далее вычисляется отдельно вероятность четырех состояний «Я» к четырем состояниям «бытия». равно S; продолжайте вычислять вероятности четырех состояний «бытия» до четырех состояний «графа» соответственно, и наибольшее из них равно B; пока четыре состояния «гуань» до четырех состояний «видеть» не станут рассчитывается соответственно вероятность, максимальная вероятность отличается;

'M': ['S']
'B': ['S']
'E': ['S']
'S': ['S']
......
'M': ['S', 'S', 'B', 'M', 'E', 'B', 'M']
'B': ['S', 'S', 'B', 'M', 'E', 'S', 'B']
'E': ['S', 'S', 'B', 'M', 'E', 'B', 'E']
'S': ['S', 'S', 'B', 'M', 'E', 'S', 'S']

github

GitHub.com/sea-boateng/где…

------------- Рекомендуем прочитать ------------

Краткое изложение моих проектов с открытым исходным кодом (машинное и глубокое обучение, НЛП, сетевой ввод-вывод, AIML, протокол mysql, чат-бот)

Зачем писать «Анализ проектирования ядра Tomcat»

Резюме моей статьи за 2017 год — машинное обучение

Краткое изложение моих статей за 2017 год — Java и промежуточное ПО

Резюме моих статей 2017 года — глубокое обучение

Краткое изложение моих статей за 2017 год — исходный код JDK

Резюме моей статьи за 2017 год — обработка естественного языка

Резюме моих статей 2017 года — Java Concurrency


Поговори со мной, задай мне вопросы:

Добро пожаловать, чтобы следовать: