Эта статья возникла из личного публичного аккаунта:TechFlow
В предыдущей статье мы представилиОсновы наивных байесовских моделей.
Основная суть наивного байесовского подхода состоит в том, чтобы предположить, что переменные в выборкеподчиняться распределению, чтобы использовать условную вероятность для расчета вероятности принадлежности выборки к определенной категории. Вообще говоря, выборка часто содержит много признаков, и эти признаки, скорее всего, коррелируют. Для упрощения модели используется наивная байесовская модель.Предположим, что эти переменные независимы. Таким образом, мы можем легко рассчитать вероятность выборки.
Студенты, которые хотят ознакомиться с деталями, могут щелкнуть ссылку, чтобы вернуться к предыдущей статье:
Основы машинного обучения — позвольте вам изучить наивные байесовские модели
В процессе изучения алгоритмов, если мы будем смотреть только на принципы и теории модели, всегда будет какое-то ощущение поверхностности на бумаге. Во многих случаях правда проста, но когда вы действительно хотите начать, вы все равно будете в замешательстве. Либо вы с трудом можете это сделать, но в процессе всегда будете сталкиваться с различными неожиданными проблемами того или иного рода. С одной стороны, нашей практической практики недостаточно, а с другой стороны, наше понимание недостаточно глубоко.
Сегодня в этой статье мы собственно реализуем модель, а вреальный набор данныхЗапустите его и посмотрите, как работает наша модель.
Наивный Байес и классификация текстов
В общем, мы думаемузкое событиеРезультат события должен быть конечным, т. е. результатом события должно бытьдискретное значениевместо непрерывных значений. Поэтому ранняя байесовская модель, до введения идеи гауссовской смешанной модели, также нацелена на дискретнозначные выборки (сомнительно, размышляет автор). Итак, давайте сначала отложим в сторону сценарий с непрерывными функциями, а давайте посмотрим на практическое применение наивной байесовской модели в дискретных выборках.
Среди широкого спектра сценариев применения машинного обучения есть очень классический сценарий приложения, его образцы должны быть дискретными, этообработка естественного языка(Обработка естественного языка). В языке, на каком бы языке он ни был, будь то предложение или фрагмент текста, его наименьшая единица — это либо слово, либо слово. Эти единицыдискретный, так что это естественное соответствие модели наивного Байеса.
Модель, которую мы делаем на этот раз, нацелена на сцену.Идентификация спама, которая должна быть функцией, с которой мы часто соприкасаемся в нашей жизни. Текущий почтовый ящик в основном имеет функцию определения спама, если он оказывается спамом, то часто напрямую блокируется и не будет отображаться пользователям. Ранние функции спама и идентификации спама были реализованы Naive Bayes.
В этом эксперименте мы использовалиUCIнабор данных. Наборы данных машинного обучения Университета UCI очень хорошо известны, и многие учебники и учебники используют их наборы данных в качестве примеров. Мы можем загрузить их данные прямо из Интернета, и данные в наборе данных UCI бесплатны.
После завершения загрузки давайте выберем несколько из них, чтобы увидеть:
ham Go until jurong point, crazy.. Available only in bugis n great world la e buffet... Cine there got amore wat...
ham Ok lar... Joking wif u oni...
spam Free entry in 2 a wkly comp to win FA Cup final tkts 21st May 2005. Text FA to 87121 to receive entry question(std txt rate)T&C's apply 08452810075over18's
ham U dun say so early hor... U c already then say...
Эти данные сохраняются в файле типа txt.Первое слово каждой строки текста представляет категорию текста, где ham означает нормальный, а spam означает спам.
Мы сначала читаем файл, и сначала читаем содержимое файла в список, что удобно для нашей последующей обработки.
def read_file(filename):
file = open(filename, 'r')
content = []
for line in file.readlines():
content.append(line)
return content
Давайте посмотрим на первые три части данных:
Можно обнаружить, что категория и текст разделены \t (табуляция), и мы можем напрямую разделить категорию и текст с помощью метода разделения Python. Категория — это результат, который мы хотим, чтобы модель изучила, который в обучении с учителем называется меткой. Текстовая часть также является основой для модели, позволяющей делать прогнозы, называемые функциями. В сценарии классификации текстаХарактеристики представляют собой текстовую информацию.
Разделяем этикетку и текст:
labels = []
data = []
for i in smsTxt:
row = i.split('\t')
if len(row) == 2:
labels.append(row[0])
data.append(row[1])
фильтр пунктуации
После отделения текста от метки нам нужно обработать текст. Перед обработкой возьмем для проверки случайный кусок данных, здесь выбираем первый:
'Go until jurong point, crazy.. Available only in bugis n great world la e buffet... Cine there got amore wat...\n'
Это очень типичный необработанный текст, в котором перемешаны не только прописные и строчные буквы, но и некоторые специальные символы. Таким образом, первым шагом в обработке текста является перевод всех букв в нижний регистр и удаление знаков препинания.
Это сложнее сказать, но пока мы используем регулярные выражения, мы можем легко добиться:
import re
# 只保留英文字母和数字
rule = re.compile("[^a-zA-Z\d ]")
for i in range(len(data)):
data[i] = re.sub("[^a-zA-Z\d ]", '', data[i].lower())
Окончательный результат выглядит следующим образом:
go until jurong point crazy available only in bugis n great world la e buffet cine there got amore wat
Регулярное выражение здесь очень простое, то есть сохраняются только английские буквы и цифры и пробелы, а все остальное фильтруется. Мы делаем преобразование регистра при передаче и преобразуем все прописные буквы в строчные. На данный момент обработаны все специальные символы, после чего можно выполнять сегментацию слов.
Сегментация английских слов очень проста, мы можем напрямую разделить по пробелу. Если это сегментация китайских слов, вы можете использовать некоторые сторонние библиотеки для ее завершения, которые были представлены в предыдущей статье, поэтому я не буду здесь вдаваться в подробности.
установить нлтк
В следующей обработке текста нам нужно использовать библиотеку инструментов обработки естественного языка под названием nltk. Он объединяет много очень полезных инструментов NLP.Как и предыдущую библиотеку инструментов, мы можем установить ее напрямую с помощью pip:
pip3 install nltk
Здесь настоятельно рекомендуется использовать Python3, так как Python2 больше не поддерживается. После этого шага просто установите библиотеку nltk, в nltk есть много других файлов ресурсов, которые нам нужно скачать. Мы можем скачать напрямую через python:
import nltk
nltk.download()
После вызова этого кода появится окно загрузки:
Мы можем выбрать все и щелкнуть для загрузки, но этот источник данных находится за границей, и прямая загрузка в Китае может быть очень медленной. В дополнение к научному доступу в Интернет есть еще один метод — загрузить соответствующие данные ресурсов прямо в github:GitHub.com/стремиться расширить/стремиться расширить_'s…
Следует отметить, что данные должны быть размещены в указанном месте.Для конкретного места установки вы можете вызвать метод загрузки и отметить путь в красном поле. Или вы также можете использовать зеркальный источник Университета Цинхуа, используя команду:
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple/nltk
После скачивания выполняем его на Python:
fron nltk.book import *
Установка завершена, если появятся следующие результаты:
удалить стоп-слова
После установки nltk первая предварительная обработка, которую нам нужно сделать, это удалить стоп-слова.
Стоп-слова — это стоп-слова в английском языке, которые относятся к словам в тексте, которые не важны с точки зрения семантики. Содержит общие служебные слова, вспомогательные слова, предлоги и т. д. Большинство этих слов являются лишь модификаторами и не играют решающей роли в смысловом содержании текста. Поэтому в области NLP его можно фильтровать, чтобы уменьшить объем вычислений и повысить точность модели.
Nltk предоставляет список стоп-слов для распространенных основных языков (за исключением китайского). Мы передаем указанный язык, и он возвращает список стоп-слов. Мы можем фильтровать по списку стоп-слов после сегментации слов.
Мы можем распечатать все стоп-слова на английском языке и посмотреть, большинство из них — это какие-то служебные и вспомогательные слова, которые могут встречаться во всех контекстах и вряд ли помогут нам классифицировать текст.
нормализация части речи
Как мы все знаем, слова в английском языкемного форм. Например, существительные имеют формы единственного и множественного числа, а некоторые специальные существительные имеют очень разные формы множественного числа. Глаголы имеют три времени: прошедшее, настоящее и будущее, а также совершенное время и простое время от третьего лица и т. д., и есть много изменений.
Например, глагол do порождает в тексте много маленьких слов. Такие, как делает, делал, делал, делал и т. д. Хотя это разные слова, но означают они совершенно одно и то же. Поэтому, создавая английскую модель НЛП,Необходимо восстановить слова в этих временах до их самых основных времен., что называется нормализацией частей речи.
Изначально это была очень сложная работа, но теперь, когда у нас есть nltk, эта работа стала намного проще. Чтобы выполнить нормализацию слов, нам нужно использовать два инструмента в nltk.
Первый метод называетсяpos_tag, который получает на вход список слов. Возврат также представляет собой список кортежей, каждый кортеж содержит два значения, одно — само слово, а второй параметр — часть речи, которую мы хотим.
Например:
Мы передаем список только с одним словом яблоко, кроме яблока в возвращаемом результате есть дополнительный NN, который означает, что яблоко является существительным существительным.
Что касается возвращаемого объяснения части речи, желающие могут самостоятельно ознакомиться с описанием официального документа.
Нам не нужно различать так тонко здесь, нам нужно только различать наиболее часто используемыеглагол, существительное, прилагательное, наречиеВ принципе достаточно.
Мы можем сделать простое утверждение, непосредственно основанное на первой букве возвращаемого результата.карта:
from nltk import word_tokenize, pos_tag
from nltk.corpus import wordnet
from nltk.stem import WordNetLemmatizer
# 获取单词的词性
def get_wordnet_pos(tag):
if tag.startswith('J'):
return wordnet.ADJ
elif tag.startswith('V'):
return wordnet.VERB
elif tag.startswith('N'):
return wordnet.NOUN
elif tag.startswith('R'):
return wordnet.ADV
else:
return None
Через метод pos_tag мы легко можем получить часть речи слова, но этого недостаточно, нам нужно еще и восстановить ее до самого основного вида. На этот раз вам нужно использовать другой инструмент:WordNetLemmatizer
его использованиеВозвращает наиболее общую форму слова на основе слова и его части речи., что является операцией нормализации.
Например:
Мы передаем форму множественного числа коробки: коробки и существительное, соответствующее ящику, и результат, который он возвращает, — это именно тот ящик, который нам нужен.
Мы можем завершить нормализацию слов, комбинируя только что реализованный метод опроса частей речи.
Пока о текстеинициализацияДаже если он почти закончился. В дополнение к тому, что только что было упомянуто, nltk также содержит много других очень удобных библиотек инструментов. Из-за ограниченного объема мы не можем исчерпать их все, и заинтересованные студенты могут изучить их самостоятельно.
Затем мы используем несколько методов предварительной обработки текста, которые только что были представлены вместе.Предварительно обработайте все SMS-сообщения:
for i in range(len(data)):
data[i] = re.sub("[^a-zA-Z ]", '', data[i].lower())
tokens = data[i].split(' ') # 分词
tagged_sent = pos_tag([i for i in tokens if i and not i in stopwords.words('english')]) # 获取单词词性
wnl = WordNetLemmatizer()
lemmas_sent = []
for tag in tagged_sent:
wordnet_pos = get_wordnet_pos(tag[1]) or wordnet.NOUN
lemmas_sent.append(wnl.lemmatize(tag[0], pos=wordnet_pos))
data[i] = lemmas_sent
С помощью библиотеки инструментов nltk нам нужно всего несколько строк кода для завершения сегментации текста, фильтрации стоп-слов и нормализации частей речи.
Далее мы можем реализовать модель Наивного Байеса.обучение и предсказание.
Во-первых, нам нужно найтифоновая вероятность. Так называемая фоновая вероятность относится к вероятности естественного спама в информации в данной выборке без учета каких-либо особенностей.
На самом деле это очень просто, нам просто нужно разделить количество обычных писем и спам-писем и разделить их на общее количество:
def base_prob(labels):
pos, neg = 0.0, 0.0
for i in labels:
if i == 'ham':
neg += 1
else:
pos += 1
return pos / (pos + neg), neg / (pos + neg)
Запустим и проверим результаты:
Вероятность увидеть спам составляет всего 13%, а большинство писем обычные. Это тоже соответствует нашему жизненному опыту, ведь спам в меньшинстве.
Далее нам нужноНайти вероятность того, что каждое слово принадлежит каждой категории, то есть требуется таблица вероятностей слова. Этот код немного сложнее, но не слишком громоздкий:
def word_prob(data, labels):
n = len(data)
# 创建词表
word_dict = {}
for i in range(n):
lab = labels[i]
# 先转set再转list,去除重复的常规操作
dat = list(set(data[i]))
for word in dat:
# 单词不在dict中的时候创建dict,默认从1开始计数,为了防止除0
if word not in word_dict:
word_dict[word] = {'ham' : 1, 'spam': 1} # 拉普帕斯平滑避免除0
word_dict[word][lab] += 1
# 将数量转化成概率
for i in word_dict:
dt = word_dict[i]
ham = dt['ham']
spam = dt['spam']
word_dict[i]['ham'] = ham / float(ham + spam)
word_dict[i]['spam'] = spam / float(ham + spam)
return word_dict
Опять же, давайте запустим тест, чтобы увидеть результаты:
После того, как все это на месте, это является основным моментом прогноза. Здесь следует отметить, что в соответствии с нашей формулой выше, когда мы предсказываем вероятность текста, мы будем использовать умножение нескольких вероятностей. Поскольку числа с плавающей запятой имеют ограничения по точности, мы не можем вычислить произведение напрямую, а вместо этогоПреобразовать в логарифмическое сложение, так что вместо умножения на сложение мы можемИзбегайте проблем с точностью, вызванных непрерывным умножением.
import math
def predict(samples, word_prob, base_p, base_n):
ret = []
for sam in samples:
neg = math.log(base_n)
pos = math.log(base_p)
for word in sam:
if word not in word_prob:
continue
neg += math.log(word_prob[word]['spam'])
pos += math.log(word_prob[word]['ham'])
ret.append('ham' if pos > neg else 'spam')
return ret
Метод прогнозирования также очень прост: мы вычисляем вероятность того, что текст относится к спаму и ветке соответственно, а затем выбираем тот, который имеет более высокую вероятность, в качестве конечного результата.
Мы разделяем исходные данные на обучающий набор и набор прогнозов и вызываем алгоритм, который мы только что написали, чтобы получить прогнозы:
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(data, labels, test_size=0.25)
base_p, base_n = base_prob(y_train)
word_dt = word_prob(x_train, y_train)
ret = predict(x_test, word_dt, base_p, base_n)
Наконец, мы вызываем метод classification_report в sklearn дляПолучите прогнозируемую производительность байесовской модели:
Судя по приведенному выше рисунку, эффект предсказания байесовской модели все еще хорош. Точность распознавания ненужного текста составляет 90 %, но, к сожалению, показатель отзыва немного ниже, что указывает на то, что некоторые нечеткие ненужные тексты не были распознаны. Это тоже одна из сложностей в текущей ситуации, но в целом принцип байесовской модели прост, но эффект хороший, и по этой причине она актуальна и сегодня.
НЛП — один из самых сложных и трудоемких сценариев применения в области машинного обучения на сегодняшний день, в нем много операций по предобработке текста, выбору и оптимизации модели. В этой статье перечислены только самые простые и часто используемые детали.
На этом практика Наивного Байеса закончилась. Я думаю, должно быть очень увлекательно писать рабочую модель с нуля вручную. Но наивная байесовская модель еще не закончилась, в ней еще много деталей, о которых все должны подумать, а также много расширенных знаний. Хотя модель проста, она все же достойна нашего искреннего опыта.
Сегодняшняя статья здесь,Отсканируйте код, чтобы следоватьМой официальный аккаунт, смотрите больше статей, ваша поддержка - моя самая большая мотивация.