Большой Бесплатный Курс по NLP (Обработке Естественного Языка): Часть 1 – Предобработка

Аве Кодер!
В этом уроке мы будем осваивать механику предобработки текста для задач обработки естественного языка.
Мы разберем такие концепты как: базовая токенизация, работа с регулярными выражениями для очистки строк, работа с библиотекой nltk, пунктуация, стемминг, лемматизация, n-gram, векторизация, а также инжинерию признаков.

Расшифровка видео
0:00
а выкодер и добро пожаловать на курс по основам обработки естественного языка
0:05
прежде чем вы напишите ваш собственный чат gpt важно понимать механизмы
0:10
взаимодействия кода и естественного языка то есть того на котором говорим мы
0:16
люди а затем следующим шагом мы можем переходить уже к более продвинутым
0:21
концептам например к моделям Трансформеров по которым я записал отдельный курс ссылка в описании где мы
0:27
проходим буквально с нуля и до наших больших языковых моделей которые мы
0:34
будем строить и обучать сами Ну а пока давай посмотрим как работают базовые механизмы взаимодействия кода и нашего
0:41
языка в этом прекрасном курсе ставь этому видео императорский палец вверх подписывайся на канал ты в колокол чтобы
0:48
не пропустить еще больше такой вкуснятины и давай начинать Я буду работать в джупетер о том как его
0:54
устанавливать на канале есть видео просто вбейте в поиск по видео jupiter
0:59
оно там есть но вы также можете использовать коллап или Tata spell или что-то еще начнем с
1:05
установки библиотеки ltk через восклицательный знак пип Install nlk
1:10
напомню что поскольку это вводный урок в обработку естественного языка то мы
1:16
постараемся при помощи такого остального так как nlk понять как работают эти
1:22
алгоритмические библиотеки Перед тем как мы Надеемся на Трансформеры у меня библиотека уже установлена поэтому
1:28
скорее всего мне вернется что требованием уже удовлетворено но в вашем случае если вы никогда не
1:34
устанавливались скорее всего вас ожидает лесенка установки после того как библиотека установлена по канону Поэтому
1:40
нам нужно ее импортировать что мы сделаем в следующей ячейке после того
1:46
как мы импортировали библиотеку в наш ноутбук нам также нужно подгрузить различные инструменты
1:53
пакеты и прочее Что содержится в этой чудесной библиотеке и мы делаем это через nlk
1:59
там лот это функция нажимаем Shift Enter запускаем ячейку и у нас откроется новое
2:06
окно где нас попросят Уточнить что именно Мы хотим подгрузить Если вы
2:12
знаете что вы хотите вы можете выбирать отдельные пакеты через Control и
2:17
загружать их но мы можем данном случае просто выбрать пол То есть все И нажать
2:23
там вот внизу вы также можете указать в какой директории вы хотите все это
2:28
подгрузить и После нажатия заветной кнопки там вот вы увидите как поле
2:33
статус меняется с not installs на стол после того как все что нам нужно было
2:41
загрузить окрасилась зеленым и мы видели статус installs мы можем спокойно закрыть это окно и начать исследовать
2:49
Что именно в этой библиотеке мы сейчас подгрузили для этого следующие чеки
2:55
внутри функции мы укажем и Запусти ячейку мы увидим все атрибуты функции
3:02
методы которые в этом инструментарии содержатся естественно большинство из
3:07
этих атрибутов методов и функции нам понадобится чуть чаще чем никогда Кроме
3:13
того С развитием Трансформеров Я бы действительно относился к этой библиотеке как некому учебному самолету
3:20
и совершенно не запарился выучивать наизусть то что есть в этом списке просто знаете что через функцию Dr можно
3:28
все это посмотреть в принципе старую добрую документацию никто не отменял примеру через From
3:35
nlk.corpus мы можем посмотреть на так называемые стоп слова импортируем или
3:41
еще называют шумовые слова это всякие суффиксы префиксы местоимения междометия
3:47
и прочее В общем все что может засорять нам скажем поиск по ключевым словам после этого через
3:53
stopos.weets мы можем скобках указать язык на самом деле там достаточно много языков
3:59
для примера и Скажем мы хотим посмотреть на первые 10 слов потому что там их на
4:05
самом деле очень много и мы видим здесь местоимение я мне моё и так далее Мы
4:11
также можем немного изменить наш слайс Если вы помните как они работают первая цифра это Старт потом через двоеточие
4:18
это Стоп то есть где мы останавливаемся и еще через двоеточие это степлер и Шаг в данном случае мы проходим от нулевого
4:24
до 500 С шагом 25 Кто забыл или хочет уточнить подробнее У меня есть видео про
4:31
numpi где эту тему разбираю довольно подробно Это был пример шумовых слов в котором мы еще Вернемся сейчас перейдем
4:38
непосредственно к практике на реальном датасете этот известный dataset посвященный спам в текстовых сообщениях
4:44
Мы возьмем из не менее известного академического репозитории Задача будет следующая основываясь на
4:51
тексте в сообщении мы будем определять является ли она спамом или так
4:57
называемым то есть ветчиной такая питоновская шутка то есть не содержит
5:02
спама и в принципе нормально и можно его пропускать иными словами мы с вами создадим некий фильтр который будет
5:09
задерживать сообщения содержащие спам Итак здесь я предлагаю сразу два способа как мы можем подгрузить этот dataset и
5:17
затем его посмотреть и уже с ним работать если у вас возникают какие-то трудности с тем механикой джипетр Я
5:24
рекомендую на канале У меня есть видео как раз про джипер Если же вас некоторые проблемки с подгрузкой наборов данных то
5:31
Я рекомендую опять же есть замечательная целый плейлист про введение в дата сайленс где мы неоднократно этим
5:38
занимаемся на самом деле оба этих подхода суть есть одно и то же и ведут они к одному и тому же исходу Давайте
5:46
взглянем на содержание документа как мы видим у нас просто очень длинная строка
5:51
и мы видим что местами мелькает хам местами спам и отделено все это обратным
5:57
слешем T то есть это или разделитель между лейблом или меткой и собственно телом то
6:04
есть непосредственно неким текстом положительно это текстовое сообщение которое помечено вот этой меткой И также
6:11
у нас присутствует помимо обратного слэша T обратный слэш N это как вы знаете разделитель переноса строки то
6:18
есть обратный слэш N помещен на конец вот этой пары метка и текст Что
6:24
символизирует собственно разделение в этом датасете по строкам опять же мы не
6:29
использовали пандас поэтому мы считаем все это в сыром формате Несмотря на то что пандас это действительно очень
6:35
полезная библиотека весь Челлендж состоит в том чтобы показать как можно справиться и без неё например мы можем
6:42
заменить все обратные слэша ти на обратные слышим Что даст нам хорошая по
6:48
строковое разделение для этого после метода Place с двумя параметрами Первое это что мы заменяем второе это на что мы
6:56
заменяем Мы также применяем метод с у того по чему именно мы будем производить
7:02
разделение например по backslash N то есть Перенос строки вводим Все это на экран Ну давайте Не все а скажем Первое
7:09
первые пять строчек и мы увидим что у нас метки Хам и текст уже раздельно на
7:17
новых строчках дальше нас снова хам снова текст вам Ну и так далее То есть мы получили какую-никакую но структуру и
7:24
теперь что можем сделать мы можем например про парсить все это дело и
7:30
вытащить оттуда скажем каждый второй элемент для этого мы берем наш ПАЗ Data
7:35
и проворачиваем старый трюк со Старт Стоп и степ то есть шаг значение разделены двоеточиями то есть 0 это наш
7:42
Старт мы ничего не указываем в нашем стопе то есть мы проходим по всему массиву данных и далее указываем 2 как
7:49
шаг то есть Каждая вторая строчка То есть если мы начинаем с нулевой позиции и далее мы вытаскиваем каждую вторую
7:56
строчку то это будут наши метки что мы сохраня аналогичным образом если мы начинаем с
8:02
индекса 1 и вытаскиваем каждый второй это наш собственно текст и мы сохраняем
8:08
это в текст далее при помощи двух принтов я выведу лейблест и текст ибо
8:15
природа джипитера такова что если написать просто лейблест или текст он выдаст результат
8:21
который Самый Нижний последний в ячейке А я хочу их вместе и опять же я не хочу
8:27
все поэтому вывожу только первые пять строк поэтому использую слайс от 0 до 5
8:32
как мы видим у нас теперь два списка наши метки отдельно Наш текст отдельно теперь можем подумать о том как это все
8:39
комбинировать Для дальнейшего анализа и на этом этапе можно уже по-доброму подключить библиотеку пандас для этого
8:47
мы сначала импортируем ее все очень стандартно импорт Панда если вам интересно как библиотека
8:54
работает и вы раньше в ней не работали У меня есть отличное видео по пандам за час Ну в принципе покрываем и уже после
9:01
импорта мы можем создать dataframe в которой мы поместим наши данные при этом
9:07
мы будем использовать словарь то есть давайте выведем сейчас длину нашего лейблест на всякий случай и длину нашего
9:15
чтобы увидеть Сколько у нас всего там данных также это альтернативный способ
9:20
помимо и знал посмотреть где у нас не хватает Или же Аналогично Вполне
9:26
возможно что у нас наоборот чего-то есть лишнее поэтому Давайте выведем последние 5 элементов сначала нашего списка меток
9:35
и посмотрим не затесалась ли туда пустое значение это опять же в принте я выберу
9:41
лейблест и на этот раз я буду двигаться с конца То есть -5 это будет 5 элементов
9:47
с конца и как мы видим У нас есть одно пустое значение которое мы собственно обрежем И на самом деле мы можем
9:54
использовать еще один трюк уже в пандас из того чтобы как-то отдельно надо
10:00
обрезать мы можем создать дата фрейм и скажем у нас будет представлен виде словаря где ключами будут будущие
10:07
наименования столбцов а значениями будут собственно наши списки
10:13
лейблест и textles но в плане лейбла есть поскольку мы знаем что там есть лишнее значение мы можем сказать что мы
10:19
возьмем не весь лист целиком весь список целиком а до -1 элемента то есть до
10:25
предпоследнего и это решит нашу проблему с этим лишним элементом Иначе мы получим
10:31
ошибку что наши массивы наши списки не являются одинаковой длины Давайте покажу
10:38
что имею в виду и уберу нашу конструкцию с лейблест и попробуем запустить всё это
10:45
дело мы увидим Ту самую ошибку что рейс маски То есть все наши пассивы или списки
10:52
должны быть одинаковой длины вернем конструкцию запустим и мы видим что все нормально Теперь если мы возьмем наш
10:58
фулл корпус и используем метод то есть мы выведем первые 5 строчек то мы увидим
11:05
в принципе довольно чистый dataset репрезентацию нашего дата Сета мы видим
11:10
столбец метки мы видим текст и это гораздо лучше всего того месиво с
11:15
которым мы в принципе начинали И заранее отвечу мальчикам и девочкам несостоявшимся как выдающийся
11:22
специалисты которые вместо того чтобы учить что-то новое почему-то ходят по базовым курсам и поднимают свою
11:30
самооценку упавших Да нельзя на работе тем что пишет что можно было
11:35
сделать это гораздо проще да Можно например вот так как только мы замечаем
11:41
что есть обратный слэштит то есть что в данных датасете присутствует
11:47
табулятивный разделитель мы можем просто все это взять в пандас соорудить метод
11:53
выйти сет указать что разделитель то есть это
11:59
ты слеш ты и указать что нам не нужны заголовки то есть не надо размечать нам
12:05
наши столбцы выводим и мы видим что у нас вместо
12:10
лейбла и Бады нас просто 0 единицы чтобы показать какой у нас первый какой второй
12:15
столбец то есть вот вам еще один вариант и дабы передушить всех душнил давайте сейчас зайдем в ассемблер и сделаем это
12:22
в ассемблере шутка но Давайте все-таки будем последовательны и поскольку наш фрейм называется Full corpus Давайте
12:29
переименуем все с dataset на Full корпус Кроме того если Вы заметили у нас нет
12:34
как таковых наименований столбцов вместо этого 0 и единичка Давайте это исправим
12:39
и определим наименование столбцов как лейбл и более текст Для этого нам
12:45
Достаточно воспользоваться методом Холмс на нашем время Full корпус и внутри
12:51
квадратных скобок мы укажем два стринга первый будет а второй через запятую
12:57
соответственно более Ну или Главное чтобы было поле после перезапуска ячейки
13:03
мы увидим что у нас появились наименования колонок нашим Data Frame и
13:09
мы можем двигаться дальше далее мы можем провести некие анализ нашего текста
13:14
сколько текста отмечены метками хам сколько спам Какова форма или размер
13:20
нашего дата Сета и если у нас какие-то пробелы в этом сайте то есть Может быть
13:25
у нас отсутствует какие-то значения Это поможет нам принятие решений для дальнейшей предопроводки наших данных И
13:34
для этого подготавливаем сначала Принт где при помощи формата мы уже будем подставлять нужные значения люблю когда
13:41
все в одном месте сначала Давайте попробуем определить Сколько у нас всего строк и столбцов наши датасете Я в курсе
13:48
что их всего два но это очень чистый dataset а работать Вы скорее всего будете с грязными данными Так что это
13:54
вам пригодится Итак наша строка говорит что настолько то строк и столько столбцов куда мы подставляем две функции
14:01
LAN в первом случае это длина нашего всего дата Сета а во втором случае это
14:06
наш досет и через точку соответственно Столбцы Итак я вижу что у нас
14:11
5572 строки и ожидаемо два столбца далее У нас в наших данных две метки это Хам и
14:19
спам и Давайте почитаем сколько у нас меток Хам и соответственно сколько меток
14:24
спам наша строка говорит что у нас столько-то строчек помечено как спам и
14:30
столько-то как хам Итак первое значение говорит нам Сколько у нас всего строк то
14:35
есть опять же мы будем использовать формат и внутри первая у нас подставное значение будет длина всего нашего
14:43
корпуса то есть всех наших данных это даст нам общее количество строк далее мы
14:48
используем переход на новую строку и уже через Лен и корпус мы отфильтруем чтобы
14:56
у нас остались только метки нам для этого мы указываем Full корпус далее
15:02
опять же внутри уже скобок Мы указываем корпус И говорим что Label или метка То
15:09
есть это наш первый столбец с данными так Вот метка должна быть равна спам это
15:16
даст нам второе подставное значение Сколько строк у нас помечены как спам и
15:21
аналогичную технику мы применяем уже к хам То есть фактически я копирую
15:27
предыдущую строчку то есть корпус далее мы фильтруем фулл корпус опять же по
15:32
метке по лейблу и она у нас уже должна быть равна не спам а соответственно
15:38
после того как мы закончим печатать мы просто запускаем эту ячейку и мы увидим
15:44
опять же то же самое число 5572 общего количества строк 747 строк у
15:52
нас с меткой спам и 4800 25 с меткой хам
15:57
если у вас получились немножко другие цифры Не пугайтесь датасет мог быть к тому времени изменен главное что мы
16:04
получили важную информацию что меток Хан то есть строк в которых У нас есть метка
16:09
хам значительно больше чем строк с меткой спам и это мы будем учитывать
16:15
будущем к этому вопросу мы вернемся чуть позже когда уже будем заниматься фичами
16:20
давайте сейчас посмотрим сколько у нас строк пустых то есть где у нас есть
16:25
какие-то пропущенные данные то есть в этой строке мы будем подставлять значения которые мы найдем следующим
16:31
образом возьмем столбец лейбл нашего дата фрейма Full corpus и мы применим к
16:37
нему функцию и знал которая вернет false если у нас строки имеется значение и
16:44
True если оно отсутствует и сюда же мы присоединим функцию сам которая считает
16:50
или просумирует вместе сколько у нас таких отсутствующих значений То есть те
16:56
случаи когда функция и знал верну Таким образом мы поймем если у нас пропущенное
17:02
значение И сколько их и мы видим что у нас 0 пропущенных значений что
17:07
собственно хорошо Таким образом мы проверили отсутствует или присутствует у нас метки теперь Давайте проверим наш
17:14
boreless то есть отсутствие или присутствия текста иными словами вместо
17:19
лейбл мы поместим сюда более лест и опять же подсчитаем сколько у нас строк где отсутствует именно текст и у нас
17:27
таких также 0 Что также хорошо давайте далее рассмотрим такую тему как использование регулярных выражений для
17:34
работы с текстом месяц кстати целый курс по Python где мы тщательно рассматриваем эти регулярные выражения с кучей
17:41
примеров и практики Так что ссылка в описании начнем Итак для начала Давайте импортируем модуль отвечающий за
17:47
регулярные выражения а именно и соорудим три учебных предложения 3 строки первая
17:54
у нас будет тест и здесь мы будем использовать знаменитую английскую скороговорку She is Sells сейшелспады
18:02
О как и это будет наш Эталон чистого текста в этом примере тогда как две
18:09
другие будут носить некие изменения то есть мы внесем некий мусор в них
18:16
специально чтобы научиться его потом чистить поэтому второй у нас называется rejects Test mess и это будет та же
18:23
скороговорка только с увеличенными пробелами между словами чтобы Мы
18:28
научились работать как раз с пробелами и третья строка у нас будет jax Test
18:35
mess 2 и сюда мы опять же возьмем Ту же самую скороговорку только поместим
18:41
различные мусор типа дефисов слэшей точек Ну всего понемножку так все это
18:49
выглядит и теперь Давайте приступим к обработке этого текста при помощи регулярных выражений мы рассмотрим всего
18:56
несколько приемов но они могут вам будущем пригодится давайте рассмотрим на практике Как работает базовая
19:02
токенизация то есть разбиение предложения на слова таким образом грубо говоря мы покажем Поэтому с чем мы будем
19:10
оперировать то есть словами для этого мы будем использовать функцию splat с двумя аргументами первый это обратный слэш с и
19:18
второй собственное предложение которое мы собираемся разбивать обратный слэш с Это то же самое что и одинарный пробел
19:25
Теперь мы наблюдаем что у нас вместо строки список состоящий из отдельных слов отдельных строк которые когда-то
19:33
составляли целое предложение Но если мы используем аналогичный подход ко второму предложению то мы увидим несколько
19:39
другую картину поскольку во втором предложении использовался тройной пробел то мы видим что у нас полно всяких
19:46
символов которые нам не нужны то есть дополнительные пробелы Как там это исправить мы можем немножко изменить
19:53
наше регулярное выражение добавив плюсик и теперь она будет забирать не только одинарный пробел но и фактически это
19:59
означает один или несколько пробелов И как мы видим благодаря такой модификации у нас результат аналогичный результат в
20:06
первом случае следующее предложение у нас содержит много мусора то есть каких-то символов которые фактически не
20:12
являются буквами как Мы поступим в этом случае если мы применим тоже регулярное
20:17
выражение к нашей грязной строке то у нас принципе ничего не получится потому что пробелов там походу и нет но есть
20:23
различные мусор но на самом деле есть регулярное выражение и Для таких случаев например обратный слэш за главное
20:31
Плюс То есть оно будет искать символы 1 или больше которые не являются буквами и
20:38
это как раз как нельзя лучше подходит для нашего случая Несмотря на то что это очень базовые регулярные выражения все
20:44
равно они могут решить многие проблемы Но естественно мы можем строить гораздо более сложные регулярное выражение Если
20:51
хотите погрузиться в эту тему опять же ссылка в описании но как мы видим нашу третью строку разложила снова на слова
20:59
то есть весь мусор был оттуда убран но мы можем быть гибкими и в выборе функции
21:04
то есть вместо того чтобы использовать функцию Сплит разделение и искать то что разделяет слова мы можем использовать
21:10
другую функцию например искать сами слова для этого будем использовать обратный слэш за главную с плюс И как мы
21:18
видим результат у нас идентичный здесь мы использовали новый подход на самой первой строке где слова были разделены
21:25
одинарным пробелом но мы также можем применить такой подход и второй строке
21:30
где пробелы были до трех между словами Все работает отлично но в третьей строке
21:36
пробелы отсутствует По сути она разделена слова в этой строке разделены
21:41
мусором и это выглядит как одна сплошная строка поэтому такой подход немножко
21:47
нужно изменить Иначе если мы используем этот подход на нашей третьей мусорной строке то есть Найди мне все слова в
21:54
этой строке это вернет нам всю строку целиком потому что опять же там нет разделяющих пробелов то есть по сути
22:01
заглавная с ищет все символы которые не являются пробелами но здесь мы можем
22:06
немного изменить наше регулярное выражение и вместо заглавной с мы
22:11
поставим строчную W то есть регулярных выражениях заглавные и строчные буквы в
22:16
этих паттернах являются фактически инверсии то есть заглавная W ищет не буквенные символы строчные наоборот
22:23
буквенные символы поэтому мы можем разделить их на слова то есть нашу
22:28
мусорную строку достаточно просто При помощи W плюс давайте рассмотрим другие
22:34
дополнительные методы применения регулярных выражений и здесь у нас снова три предложения которые содержат некое
22:40
пояснение Что такое лед 9 или Ice Nine из книжки Курта ванигута колыбель для
22:47
кошки но в некоторых предложениях закралась ошибка лет 9 стал лед 8 и
22:52
прочие Метаморфозы попробуем выстроить процесс чтобы найти и исправить ошибки то есть найти сначала места в которых
22:59
Эти ошибки могут произойти для этого будем использовать функцию find All первый паттерн который мы испытаем Это
23:06
от А до Z То есть все строчные буквы латинского алфавита одна или больше и
23:13
дальше мы подаем уже какое предложение Мы хотим пропустить через этот паттерн и
23:18
мы видим что нам вернулись в принципе все слова только обратить внимание что и
23:24
Курт его не Гуд без заглавных букв если мы поменяем паттерн на заглавные буквы
23:29
от то мы видим что все заглавные буквы в том числе слово Ice без цифры и те самые
23:36
пропущенные в первом случае заглавной буквы из скажем Курта ванигута и что
23:42
можем сделать чтобы получить и числа и буквы это ожидаемо добавить паттерн с
23:48
нуля до 9 опять же с плюсом Таким образом мы получаем собственно слова связки которые содержат и буквы и цифры
23:55
в нашем случае это лет 9 в случае второго стринга это лёд 8 и в случае
24:01
Давайте попробуем третьего стринга Мы также получаем неправильно написанный лет 9 теперь давайте рассмотрим Как
24:07
работает функция Sub которую мы будем использовать для того чтобы под Сток мы нашли нужный нам паттерн Мы можем
24:14
заменить его на что-то другое к примеру мы можем найти в предложении лед 9 написанной как Ice Nine при помощи того
24:22
паттерна который мы уже использовали То есть все заглавные буквы и все числа то есть то что мы ищем и через запятую мы
24:29
можем утвердить то на что Давайте заменим тот паттерн который мы нашли например на собственно выражение в
24:36
буквенном виде лед 9 то есть Ice Nine и где мы будем это делать и как мы видим у
24:42
нас произошла замена вместо Ice девятка у нас именно словами написано лед 9
24:48
Аналогично мы можем провести замену во втором предложении то есть где был лед 8
24:53
теперь словами написано лед 9 и в третьем предложении где у нас было неправильно написано лед 9 но также
25:01
теперь все исправлено в этом есть сила регулярных выражений что как только мы нашли паттерн мы можем применить
25:06
какое-то действие вообще ко всему чему подходят от паттерн мы рассмотрели базовые операции при помощи регулярных
25:13
выражений И для этого курса нам может больше и не понадобиться И теперь мы можем приступить к предотработке наших
25:20
данных то есть текста Мы возвращаемся к датасету которую мы разбирали ранее посвященный фильтру от спама
25:27
Единственное что после того как импортировал библиотеку пандас я за хардкодил символов которые будут
25:33
отображать до фрейм в строке чтобы мы увидели немножко больше далее Мы считываем наш набор данных ранее
25:39
показывал несколько способов как это сделать утверждаем название наших колонок наших столбцов
25:46
лейбл и Body Text и считываем первые 5 строк Итак это знакомый нам еще не
25:53
очищенный набор данных с различными мусорными значениями внутри например с
25:58
пунктуацией которая нам не нужна и мы сейчас от нее избавимся далее мы уберем стоп слова которые не несут не придают
26:05
особого значения предложению типа предлогов и прочего и токенизируем текст все это мы будем делать поэтапно Так что
26:12
начнем мы с пунктуации Так и запишем но для начала нам нужно показать поэтому Что такое пунктуация что она из себя
26:19
представляет и для этих целей мы импортируем модуль string в котором есть много чего для нас полезно частности он
26:26
содержит себе пунктуационный набор которым можем вызвав просто вызов метод пу на собственно стринге Так выглядит
26:34
пунктуационный набор и отсюда мы уже можем отталкиваться Почему удаление пунктуационных символов из набора данных
26:40
вообще имеет какой-то смысл Давайте я вам проиллюстрирую Дело в том что мы люди воспринимаем рукописный текст не
26:47
так как его воспринимает интерпретатор Например если я наберу фразу что-то вроде Я люблю поэтому с восклицательным
26:55
знаком на конце то Для меня она будет примерно той же самой что если бы я сказал поэтому только без этого
27:01
восклицательного знака Но для пайтона они совершенно разные фразы то есть мы их сравним то нам вернется false может
27:08
быть восклицательный знак не лучше пример но Представьте что там точка результат будет такой же самый то есть
27:14
по той же логике для Python это могли быть фразой Я люблю питон и я ненавижу и
27:20
дабы не допустить таких разнотолков мы как раз пунктуацию и убираем Давайте следующие ячейки определим нашу функцию
27:27
которая будет заниматься очисткой текста от пунктуации и внутри мы поместим
27:32
следующую логику мы будем использовать генератор списков который пройдет по тексту и если символ не находится в этом
27:40
пунктуационном наборе string.punktration то он его естественно оставит если нет
27:45
то в финальный текст он не попадет и если расшифровать это выражение буквально то получится следующее возьми
27:52
текст который эта функция получает на вход и для каждого символа в этом тексте
27:57
сделать следующее если Этот символ не находится в пунктуационном списке то
28:03
есть то сохранила в наш список текст но пант
28:08
и это косвенно указывает на продолжение этой логики что если символ таки присутствует в этом пунктуационном
28:15
наборе то в список текст но пакт он не попадет и в конце наша функция
28:21
возвращает результат этой операции то есть список текст Но для того чтобы
28:26
применить эту функцию к нашему набору данных мы будем использовать так называемую за функциями чтобы сохранить
28:33
результат работы этой ламп до функции Мы возьмем наш набор данных Data и организуем новый столбец парень
28:40
Он будет содержать текст из столбца боритекс того же набора данных то есть 3
28:46
которому через функцию пандас apply то есть применить мы применим нашу Land
28:52
функцию с вызовом функции которую мы я напомню описали чуть выше и
28:59
она возвращает тот же текст только без пунктуации далее Мы выведем первые пять
29:04
строчек нашего набора данных Tata с новым столбцом поле Text Clean В нем мы
29:11
видим список из индивидуальных букв или символов и это вполне ожидаемо потому
29:17
что именно такой порядок мы использовали в нашем генераторе списка то есть Мы проверяли каждый символ и добавляли его
29:24
в наш список текст и потом его возвращали но такая репрезентация нам не подходит потому это
29:31
немножко тупенька и чтобы все это пофиксить мы можем воспользоваться функцией Join то есть обернуть наш
29:39
генератор списков в эту функцию Join И если мы соединим это все по пробелу то у
29:44
нас получится примерно следующее то есть вся наша символы в разделенные пробелом что тоже немножко не комильфо что нам
29:51
нужно сделать так это соединить их буквально по ничему для этого мы сдвигаем кавычки вместе И у нас
29:57
получается связанный текст То есть все символы будут приклеены друг другу Разумеется пробелы будут сохранены Ну
30:05
что ж теперь у нас есть Наш текст без пунктуации с которым мы можем работать
30:10
дальше А дальше мы будем применять к нему токенизацию Итак токенизация мы
30:17
пойдем достаточно базовым простым путем и разобьем наше предложение на слова
30:23
которые будем называть токенами на самом деле есть много различных подходов токенизации и более подробно и
30:30
углубленно давайте рассмотрим на курсе посвященном трансформерам опять же ссылка в описании А здесь мы рассмотрим
30:37
базовый механизм токенизации для начала импортируем модуль с регулярными выражениями и определим функцию которая
30:44
будет заниматься токенизацией мы будем использовать функцию splat с которой мы уже работали с паттерном обратный слеш
30:51
заглавная W + то есть мы будем искать один или более символов которые не
30:56
являются текстовыми и применять мы это все будем к нашему тексту и наша функция будет возвращать список
31:03
talkings в котором мы сохраняем этот результат то есть простым языком мы будем делить Наш текст по пробелам
31:09
специальным символом и все в таком роде далее опять же организуем новый столбец
31:15
текст мы возьмем наш столбец текст где
31:21
данные то есть текст уже свободный от пунктуации и применим через функцию
31:27
с вызовом нашей самописной функции Единственное что потому что Python
31:34
чувствительный к регистру нам при вызове функции Talking Eyes надо поместить каждый
31:40
символ в нижний регистр потому что мы не хотим плодить дубликаты грубо говоря
31:45
далее Давайте выведем первые пять строк нашего дата фрейма Tata при помощи
31:50
функции Head и мы можем заметить новые столбец который будет называться более
31:56
текст в нем наше предложение уже без пунктуации и разбито на слова то есть
32:03
токенизирован следующий этап которым мы можем перейти это избавление нашего текста Вот так называемых стоп слов То
32:11
есть грубо говоря это некие слова которые не несут смысловой нагрузки для модели для улучшения качества ее работы
32:18
но тем не менее забирают ресурсы Сейчас я покажу что я имею ввиду мы будем использовать библиотеку или Скорее это
32:26
даже набор библиотек мы устанавливали в самом начале курса и в нее уже на список
32:32
таких стоп-слов на различных языках Для этого нам нужно обратиться к nltk корпус
32:38
stopwords и дальше уайтс и внутри мы указываем язык нас будет интересовать
32:43
английский и теперь когда мы определили список этих стоп-слов Давайте в следующей ячейке определим нашу функцию
32:50
назовем ее стопс которая будет получать некий текст который мы уже очистили от
32:56
пунктуации и токенизировали и использовать генератор списков опять же который будет практически идентично тому
33:04
что мы использовали при очистке от пунктуации логика будет аналогичная только теперь вместо проверки
33:10
присутствия какого-то символа в пунктуационном списке мы проверяем присутствует ли
33:17
токен в списке стоп слов если нет то мы добавляем его в список текст который
33:22
функция и возвращает и как и в предыдущих примерах ниже мы будем использовать Land функцию мы организуем
33:31
Новую колонку Но столпец которые назовем как-нибудь Стоп это будет все в нашем наборе данных
33:40
столбец опять же наш Вот это Сета где мы уже очистили текст от пунктуации и
33:46
токенизировали его называется и через функцию
33:51
мы применим к нему который уже будет содержать вызов к
33:57
нашей самописной функции и Давайте выведем первые пять строчек
34:05
нашего дата фрейман при помощи функции и мы увидим что у нас теперь добавлена
34:10
новая колонка паре текст нос стоп и сравнив токены в ней с нашим
34:16
первоначальным текстом в Body Text вы сможете заметить что у нас пропали некоторые слова из текста которые нам в
34:24
принципе для моделей не будут нужны если вам интересно Вы хотите посмотреть на список вот этих стоп слов которые были
34:30
удалены из текста Вы можете в следующей ячейке буквально напечатать 100 порт
34:35
который хранит этот список и вывести посмотреть что это такое следующий этап
34:41
обработки текста известен как стемпинг это процесс приведения слова к его
34:46
основе или корню То есть например слова бегать бежит бегал могут быть приведены к одному корню бег если кратко то
34:54
стэминг помогает снизить сложность понимания текста нашей моделью и в nlk
34:59
есть так называемый стеммер портера один из самых известных степлеров которые используют набор эвристических правил
35:06
для отсечения окончаний и префиксов слов с целью получить их с тем или основу или корень давайте рассмотрим пример скажем
35:13
у нас есть несколько однокоренных слов которые мы прогоним через этот стеммер Первое это Старт то есть начинается
35:20
обратить внимание Я использую принты потому что иначе и джу Петер и коллаб печатает только последний второй это
35:26
Starting И третье это старт и мы видим что они все были сокращены до их корня
35:32
Старт Теперь место хранения векторов для трех разных слов мы фактически будем хранить один но с Темир естественно не
35:40
идеальные и бывают и казусы рассмотрим следующий пример первое слово belts это строить то есть действия белдер это
35:48
Строитель то есть профессия и билдинг это вообще здание то есть построенное строителем И как мы видим стеммер
35:54
обработал только первые И третье слово оставив второе таким как есть потому что понял что оно относится к другой
36:01
категории что неплохо Однако если в случае когда мы все привели в нижний регистр мы подаем слово болгарка то
36:08
Вполне вероятно он сократит это до их корня Несмотря на то что это может быть как инструмент так и национальность
36:15
можете проверить сами отписать мне в комментариях что получилось Далее по традиции мы определяем функцию которая
36:21
будет заниматься стемпингом мы будем опять использовать генератор списков и получать эта функция будет текст из
36:28
нашего последнего обработанного столбца Бари текст Обратите внимание что функция
36:33
Stem которая принимает слово из этого предложения напрямую участвует генераторе списков и возвращает уже
36:41
обработанный текст далее мы организуем новый столбец в
36:47
нашем дата-фрейме назовем ее как-нибудь падает и после знака равно все будет по канону
36:53
возьмем столбец но стоп из того же дата фрейма и при помощи функции мы применим
37:00
Ланды функцию с вызовом нашей функции
37:06
и опять же по традиции выведем первые пять строк нашего дата фрейма Теперь мы
37:12
можем заметить что в новом столбце крайне правом слова были приведены к их
37:17
корню по мере возможностей стэмера единственная должен предупредить что ошибки могут быть то есть таймер не
37:24
всегда может адекватно справляться с скажем сленгом или аббревиатурами но
37:29
впереди нас ждет еще один этап предбработки известный как климатизация климатизация это процесс приведения
37:36
слова к его лемме Посмотрите на досуге что это такое или словарной форме в
37:42
отличие от стаминга алиматизация учитывает контекст и часть речи слово что позволяет быть более точным Например
37:49
если прогнать через таймер слово вышло то мы получим вышел то очевидно не
37:54
является словарной формой этого слова Однако при климатизации мы получим выйти
37:59
Что является корректной словарной формы и монетизация важна потому что она позволяет сводить разные формы одного же
38:07
слово к одной базовой форме что упрощает анализ и обработку текста возьмем к примеру популярный или монетизатор
38:13
wordnet и рассмотрим следующий пример возьмем к примеру два слова MT то есть пустой и эмтинг то есть опустошать это
38:21
разные части речи Давайте кстати пойдем еще дальше и слово пустой MT сделаем то
38:27
есть пустота если мы прогоним их через стеммер то мы увидим достаточно странный
38:33
результат то есть таймер решил что у этих слов разный корень Несмотря на то что если мы поменяем сна просто MT и
38:41
перезапустим ячейку то мы видим что у них одинаковый корень и почему-то он
38:46
заканчивается на ай поэтому Есть объяснение Но это как пример работы с темиром А теперь давайте посмотрим на
38:52
пример работы лимонтизатора опять же это будет те же самые два слова что были в
38:58
начале пустота и то есть опустошать поскольку
39:04
данные лимонтизатор обучен на синонимов которые он потом может использовать для
39:10
того чтобы группировать слова под вопросом как те которые имеют какое-то одинаковое значение Мы видим что он
39:17
возвращает нам те же самые слова в первозданном виде не изменяя их проблема в том что пытаясь привести какое-то
39:23
слово к его словарной формы и не имея данное слово в словаре он возвращает его нетронутым такое же самое может
39:30
происходить если слово так и записано в этом словаре Давайте разберем еще пример возьмем слово мышь Маус и майс то есть
39:39
множественное от мыши мы видим что стеммер отрубил букву и из слова Маус то
39:45
есть остался моус а майс осталось нетронутым Ну давайте посмотрим что произойдет если мы поместим оба этих
39:51
слова в климатизатор вкратце его алгоритм увидит что слово Маус является каноничным словом мышь А майс это всего
39:59
лишь его множественное число поэтому приведет слово Найс в каноничной
40:04
словарный вид единственного числа то есть мышь то есть смысл использования такого ароматизатора будет в том что
40:10
вместо нескольких разных слов которые на самом деле обозначают примерно одно и то
40:16
же относится к одному и тому же значению и поэтому будет тратить естественно на них ресурсы мы можем привести их к
40:22
одному скажем слову которое будет обозначать примерно то же самое но естественно поэтому не будет больше
40:28
тратить ресурсы на множество подобных слов То есть нас оптимизация так сказать
40:34
функция климатизации похожа на нашу предыдущую функцию со степлером только теперь место с таймером мы используем
40:40
приматизаторы и Мы возвращаем также текст результат проведения операции или
40:46
мотивации далее мы добавляем дополнительный столбец наш татар фрейм который мы назовем Бори текст
40:53
и по той же схеме Мы возьмем текст из колонки или столбца более текст но устав
41:01
из того же самого дата фрейма и при помощи функции apply мы применим это
41:06
функцию с вызовом нашей функции и затем Мы выведем первые пять строчек
41:13
нашего датасета Мы видим что у нас появилась новый столбец bore текст и
41:19
Обратите внимание на то как слова представлены в нем опять же сленг и сокращением этот климатизатор понимает
41:26
плохо но вы можете увидеть как некоторые слова были приведены в базовую словарную
41:31
форму следующим этапом мы рассмотрим векторизацию векторизация поскольку компьютеры в отличие от человеков
41:38
понимают только Циферки мы этим и будем здесь заниматься мы будем переводить
41:43
текст в его числовую векторную репрезентацию то есть Вектор с числами
41:49
мы будем рассматривать несколько способов векторизации и начнем с простейшего а именно викторизации
41:55
методом подсчёта такой векторизатор будет создавать так называемую матрицу документ термин в которой каждая ячейка
42:02
представляет собой количество раз когда какое-то слово встречается в в каком-то документе нашем случае мы будем
42:08
использовать все тот же dataset со спамом и Мы также его уже почистили этот код я предпогрузил для урока для начала
42:15
мы импортируем этот викторизатор из библиотеки saker до этого мы пишем skiller fitcher extraction и далее текст
42:24
и уже после этого импорт и Count vactories После этого мы можем инициализировать наш объект или
42:32
инстанцировать и добавить некие операционные параметры Давайте сохраним
42:37
наш объект в аккаунт и мы инициализируем наш аккаунт
42:44
с параметром в сам мы подадим нашу функцию текст
42:51
чтобы мы могли и очищать Наш текст и векторизировать его одновременно то есть
42:57
по сути лазер является гиперпараметром нашего аккаунта мы можем вообще ничего
43:03
не указывать тогда все останется по умолчанию шагом Мы применим наш аккаунт vact к
43:09
корпусу то есть телу нашего тотасета для этого мы будем использовать функцию fitchensform Потому что если мы будем
43:16
использовать просто Fit то наш векторизатор вместо собственно викторизации наших данных просто изучит
43:23
какие у нас там есть данные подадим туда текстовый столбец нашего дата Сета дейта
43:28
и сохраним все это в xcounts который будет хранить наши викторизированные данные при помощи xcomesshape мы можем
43:36
увидеть сколько у нас текстовых сообщений и сколько в них уникальных слов То есть по сути наша Матрица
43:41
которая состоит из этих векторов имеет 5570 одну строку и 817 столбцов далее на
43:49
нашем векторизаторе мы можем вызвать функцию Get фича names которая покажет
43:55
наименование всех столбцов это будут Наши фичи или свойства теперь когда мы
44:01
увидели как выглядит наш набор данных целиком и чтобы не утонуть во всем этом
44:06
Давайте применим Ту же самую технику к более маленькому набору данных нам не
44:11
обязательно импортировать новый набор данных мы можем просто взять 20 сэмплов то есть 20 текстовых сообщений или строк
44:18
из нашего текущего набора данных для этого мы используем слайс от 0 до 20 на
44:24
наборе данных Tata и опять же будем использовать Count vect trizer с киберпараметром которым мы присвоим
44:32
функцию Clean Text Но сохранимся это раз в аккаунт сампу далее когда объект
44:38
инициализирован мы вызовем на нем все ту же функцию fitch for опять же все то же
44:44
самое только на этот раз в неё мы подадим уже наш сэмпл то есть 20 первых
44:49
строчек которые будут взяты опять же из столбца боли текст и Мы также сохраним
44:55
все это в xcounts но на этот раз сэмпл и Аналогично мы выведем
45:02
чтобы посмотреть сколько у нас уникальных слов И сколько у нас строк
45:08
нашим тетасете у нас 20 строк и 206 уникальных слова чуть ниже наименование
45:15
столбцов кстати можно без принта джипитер отлично справляется с одинарными выдачами принты нужны если вы
45:23
выполняете вывод нескольких строк сразу в одной ячейке и тут мы наглядно видим
45:28
что у нас выборка гораздо меньше и с ней уже можно работать несомненно мы можем работать и с нашим полным дата сетом Но
45:35
поскольку это обучающее видео Я бы хотел иллюстрировать для вас наглядно весь
45:40
механизм обработки текста Единственное что хотел бы сказать это то что мы получаем на выходе из этого
45:46
викторизатора является по сути разряженной матрицей то есть грубо говоря это Матрица с превалирующим
45:52
количеством в ней нулевых значений давайте сейчас в этом попробуем разобраться То есть вы можете заметить
45:58
что если мы запустим ячейку просто сэмпл то мы увидим выдачи ее размерность
46:04
и также указано разряжена Матрица а выдача ячейки выше
46:09
мы видели только не нулевые элементы Потому что так эффективнее их хранить чтобы увидеть полную матрицу с нулями
46:16
нам придется воспользоваться библиотекой пандас и загнать все это в Data Frame Сохранить все это в xcounts.df и
46:24
использовать функцию на нашей матрице и когда мы запустим эту ячейку мы увидим стройные ряды нулей и
46:33
мы увидим единицы там где содержится собственно значение это и есть наглядно
46:38
Что такое разряженная матрица здесь все представлено в виде чисел Вы можете заметить что здесь нет слов именно так
46:46
собственно и будет воспринимать текст Ну а для себя для наглядности Давайте попробуем преобразовать эти Столбцы в
46:53
словах которые они представляют для этого мы будем использовать Comes на
46:59
то есть по сути мы говорим Тайна наименования столбцов такими какими их
47:05
возвращает names как мы видели ранее и опять же
47:10
выведем на печать xcomes TF и посмотрим теперь у нас будет Матрица состоящая из
47:16
тех самых нулей единиц но наименование колонок будут представлять те самые слова которые мы викторизировали ранее
47:23
Ну или не слова числа или числа и буквы вперемешку В общем это зависит от набора
47:29
данных то есть наглядно поскольку у нас строки представляют наши сообщения вы можете увидеть присутствует ли
47:35
определенное слово в нашем сообщении то есть наименование столбцам если оно присутствует эта единица Если нет то это
47:42
0 Аналогично и с числами То есть вы можете заметить что в десятом сообщении есть число 100 Теперь давайте перейдем к
47:50
следующей теме алгоритму грамм который по сути разбивает текст на последовательности из N подряд идущих
47:57
слов или символов для использования в статистическом анализе и предсказаниях
48:02
текста по сути может быть любым числом токенов которые мы решим объединять обычно выделяют униграммы То есть это
48:09
один токен биграммы 2 3 грамма 3 ну и так далее вы поняли нам придется
48:14
немножко изменить нашу функцию Clean Text потому что engram алгоритм будет ожидать собственно
48:20
строку для того чтобы потом разбить это самостоятельно на отдельные куски и
48:25
посмотреть какие слова какие токены попадают вместе для этого мы возьмем последнюю строку перед термином где Мы
48:31
работали со стоп словами и добавим просто функцию Join по пробелу иными словами вместо списка этих токенов в
48:39
самом конце мы собираем из них строку которую и ожидает наш алгоритм и затем
48:44
все что нам осталось сделать это организовать новые столбец в нашем датасете назовем текст и добавим к нему
48:53
колонку или столбец более Text с примененным к нему через функцию ламда
48:59
функцию на этот раз если мы при помощи функции выведем первые пять стро вы увидите что
49:06
у нас есть наш тетарейн но последний столбец содержит в себе целый строки
49:13
Подготовительная часть закончена можно переходить непосредственно к реализации самого алгоритма для алгоритма энграм на
49:20
всё-таки потребуется аккаунт Back to Riser потому что алгоритм тоже нужно подсчитывать сколько раз он встречает
49:27
какие-то токены или если бы эти ещё точнее отсчитывать повторение словарных групп далее Нам необходимо инициировать
49:34
наш объект Count vectryser на этот раз без анализатора но здесь мы будем
49:39
использовать параметр emgrange установленный на значение от двух до
49:45
двух то есть мы говорим что у нас будет интересовать только биграммы и сохраняем это все в emg и далее как и в предыдущем
49:53
случае мы захотим применить наш к нашим данным и трансформировать их для
50:00
этого мы укажем столбец текст и сохраним все это в counts и
50:07
после того как мы закончим заполнять эту ячейку ниже нам останется при помощи функции Print вывести сначала форму
50:15
нашего xcounts для этого внутри функции Print мы пишем
50:20
xcounts.shape и получив результат мы можем сравнить его с результатом Count Back triser вы заметите что у нас строк
50:28
Примерно осталось столько же Но количество столбцов увеличилось многократно почти в три раза или даже в
50:36
4 Ну почти то есть по сути у нас стало свыше 30 тысяч уникальных комбинаций
50:42
двух слов далее Давайте выведем грамм фичи и либо признаки при помощи функции
50:48
Get фича names дабы воочию увидеть эти бегранные или двухсловные комбинации И
50:56
если мы откроем наш вывод Мы видим что в принципе у нас здесь все по парам давайте как и в прошлый раз мы займемся
51:02
визуализацией работы нашего алгоритма более скромной выборки то есть для этого мы сделаем выборку из первых 20 наших
51:11
текстовых сообщений для этого мы опять же укажем слайс от нуля до 20 на Data и
51:18
далее мы можем просто взять наш код для полной выборки и начать перепечатывать
51:23
его здесь с некоторыми изменениями Мы также будем использовать пиграммы в нашем Count vect trizer engrand Range но
51:31
мы сохраним это все в sample потому что это все-таки небольшая выборка далее Мы возьмем наш эндром vect
51:38
sample следующей строке и применим и трансформируем данные но опять же данные
51:43
у нас будет усечены до 21 текстовых сообщением и мы все это сохраняем в
51:49
xcounts sample естественно и далее мы принтами выводим форму нашего sample и
51:56
также получаем название наших признаков или фичей при помощи Get fitchenames
52:05
наш вывод здесь намного скромнее чем в прошлый раз но вы все еще можете заметить что он больше чем когда мы
52:12
пользовались униграммами И если бы мы использовали Emgrand Range от единицы до
52:18
2 то есть и у неграммы и биграммы то соответственно фичей здесь Было бы намного больше И как мы видели в
52:24
предыдущем примере на выходе мы получим разряженную матрицу поэтому Давайте переопределим ее в dataframe и добавим
52:32
название столбцов для этого мы используем куда мы помещаем наши X counce sample и
52:40
далее мы Превращаем это в массив то есть и сохраняем результат в xcounts затем мы
52:47
возьмем атрибут collems на и присвоим название столбцам при помощи
52:54
sample то есть будет название наших признаков в виде названия наших столбцов
53:00
и все что нам остается это вывести наш дата фрейм и наслажда является
53:05
результатом Для этого просто напишем X counts.tf и запустим ячейку здесь я
53:10
напомню строки Это наши текстовые сообщения нули означает что какой-то биграмм не присутствует в текстовом
53:17
сообщении а единица что присутствует и любой другое значение отличное от нуля Вы можете сами отследить Какие биграммы
53:24
повторяются например более чем одном текстовом сообщении плюс алгоритм том
53:29
что он предоставляет модели больше контекста чем простой аккаунт actriser а
53:35
следующий алгоритм который мы рассмотрим называется tfidf расшифровывается он как
53:42
является статической мерой используемой для оценки важности слова в документе
53:47
которое увеличивается пропорционально количеству появлений слов в документе но с учетом частоты появления того самого
53:54
слова в других документах коллекции или корпуса формула Вы можете загуглить но
54:01
фактически она означает что важность какого-то слова определяется его весом или по крайней мере через этот вес
54:07
вычисляется если совсем на пальцах то чем уникальнее и реже слово встречается
54:12
тем соответственно будет его вес больше потому что оно является определяющим здесь мы скопировали и оставили прежним
54:20
нашу функцию Clean Text и импортировали tfdfiser
54:26
iskiller extraction и текст далее как и прежде нам нужно сначала инициировать
54:32
объектыв adfiser мы подаем в него параметр и присваиваем ему значение
54:40
нашей функции Clean Text сохраняем все это в tfidfects и далее Мы на этом
54:48
выполнен в который мы опять же подадим нашу колонку наш столбец из нашего дата
54:56
фрейма и сохраним все это в xtf это уже стало практически нашим шаблоном и
55:03
Наверное вы догадались что произойдет дальше а именно мы будем использовать функции Print для того чтобы сначала
55:10
вывести форму TF A DF xtf arif при помощи функции Shape и после того как мы
55:17
запустим ячейку xt-fi DF Shape мы заметим что значение в кортеже
55:23
аналогичны тому что выдал нам когда-то аккаунт vactricer принтом следующие чеки
55:28
мы выведем фичи или признаки при помощи функции Get фича names на TF adf и
55:37
Аналогично с аккаунт vactryser когда мы запустим эту ячейку мы увидим целый
55:42
набор чисел вперемешку с какими-то словами или даже просто буквами и на
55:48
секунду даже может показаться что разница с аккаунт vactryser вообще отсутствует ну давайте применим нашу
55:56
старую тактику и возьмем небольшую выборку для этого мы возьмем первые 20 строк из нашего дата фрейма Data то есть
56:03
первые 20 наших текстовых и сохраним все это в три то сампл и ниже мы повторим
56:08
код который мы использовали для всей выборки он этот раз мы будем использовать sample например TF A DF
56:15
vect sample далее Все принципе останется аналогичным опять же с анализатором и Clean Text
56:24
далее мы сохраняем в X TF сампл и уже к TF adf Сампо мы применяем Fit и вместо
56:32
столбца со всеми данными Мы применяем наш сэмпл то есть 20 наших первых
56:38
сообщений или строк после того как ячейка будет заполнена мы ее запустим Shift Enter и далее новые чеки мы Для
56:47
начала естественно выведем форму чтобы убедиться что мы действительно
56:53
взяли небольшую выборку и впоследствии Мы также вводим TF adf сампл но уже фича
57:02
names теперь наших признаков стало меньше и мы можем в них разобраться для этого мы
57:09
опять же будем создавать фрейм состоящий из разряженных матриц и наших признаков
57:16
в виде наименования столбцов запустив ячейку мы заметим что
57:22
наполнение нашего Data Frame то есть сами наши разряженные матрицы перестали
57:28
быть наполнены интеджерами как это было здесь теперь это числа с плавающей
57:33
точкой и теперь можем заметить что они отражают не отсутствие присутствия какого-то слова в каком-то сообщении а
57:42
скорее важность его то есть вес иначе говоря мы теперь можем сравнить какие-то
57:47
слова по важности по весу то есть по их наполнению после точки Чем выше там
57:55
число тем собственно слово будет иметь больший вес опять же Это не все алгоритмы векторизации на самом деле их
58:02
полно Но это одни из самых популярных и к тому же их можно использовать комбинации друг с другом но теперь когда
58:09
мы разобрали эти важные этапы пред обработки текста мы можем приступить к фича engineering или это переводится как
58:16
инженерия признаков Ну что ж Давайте посмотрим что еще полезного мы можем выжить из наших данных чтобы помочь
58:23
нашей модели быть еще точнее возьмем все тот же набор данных но мы возьмем его в
58:29
сыром виде то есть мы не будем применять не стеммер ни весь прочие при процессинг
58:34
которым мы занимались до этого и вы увидите Почему так поступаем продолжая смотреть этот урок до конца первый
58:40
признак на котором мы сконцентрируемся будет длина сообщения Наша задача подтвердить либо же опровергнуть
58:47
гипотезу о том что спам сообщение То есть продающие сообщения они по своей
58:52
сути длиннее чем те сообщения которые мы обычно общаемся друг с другом для этого мы возьмем столбец и применим к нему
59:00
Ланда функцию которая будет замерять длину каждого сообщения результат мы будем сохранять в новый столбец более и
59:08
надо также не забыть от длинные сообщения отнять количество пробелов потому что текст сырой мы его от
59:15
пробелов еще не очищали для этого мы будем использовать функцию Count которую качестве аргумента мы подадим пробел
59:22
итак по сути Barry Land Это наш Новый признак Давайте выведем первые пять
59:28
наших сообщений в dataframe и мы видим что у нас добавилось новая колонка новый
59:34
столбец pory Land который содержит число токенов то есть длину нашего текста
59:39
минус пробелы следующие наши гипотезой будет то что спам сообщение содержит
59:44
больше знаков препинания для этого мы импортируем модуль string и определим
59:49
функцию Count punkt то есть посчитать пунктуацию которую мы подаем текст опять
59:54
же в процессе очистки прошлый раз мы вытравили всю пунктуацию собственно поэтому мы используем сырой текст мы
1:00:01
будем использовать генератор списков внутри функции сам то есть сам будет складывать вместе то что будет
1:00:07
возвращать генераторы списков а возвращать он будет единицу Каждый раз когда он будет находить токен либо
1:00:13
символ который находится внутри пунктуационного списка модуля То есть
1:00:19
если симво скажем запятой то функции сам передается единица затем еще одна
1:00:25
забитая это еще одна единица у нас уже два Ну и так далее мы возвращаем каунт то есть счет который будет содержать
1:00:31
результат вот этого прохода по всему тексту и суммированию внутри функции сам
1:00:37
то есть функция сам у нас выступает неким числовым агрегатором Но что будет
1:00:42
еще лучше это если мы вернем не просто количество знаков пунктуации в тексте а
1:00:48
процент который вот это число занимает от всего текста для этого мы берем
1:00:53
значение Count то есть число символов пунктуации и делим на разность длинные
1:01:00
текста и количество в нем пробелов то есть От длины текста мы отнимаем число
1:01:05
пробелов все это мы округляем до трех знаков после запятой при помощи функции раунд то есть вся эта математическая
1:01:12
операция будет первым аргументом в функции раунд а трешка будет вторым И
1:01:19
после этого для того чтобы сделать нашу жизнь немного легче мы умножаем все это на 100 Теперь мы увидим это в процентном
1:01:25
соотношении вместо неудобной длины десятичной дроби следующим этапом Мы
1:01:31
возьмем столбец porritext применим к нему через функцию lamba нашу самописную
1:01:36
функцию Count пункт и сохраним все это в новый столбец признаков
1:01:42
процент И разумеется для визуальной оценки выведем первые 5 записей на экран
1:01:47
опять же весь смысл всех этих экзорцизов найти какие-то признаки какие-то фичи
1:01:53
которые могут явно или не явно помочь нашей модели быть лучше в своем
1:01:58
предсказании Является ли это нормальным сообщением или же является спамом естественно мы могли бы продолжать
1:02:05
писать эти признаки и урок бы только по признакам длился 6 часов Но это
1:02:11
ознакомительный урок поэтому мы приступим к оценке этих двух признаков которые мы написали для визуальной
1:02:18
оценки наших признаков мы будем использовать библиотеку мат плот либ если кто не знает как ей пользоваться я
1:02:25
оставил ссылку в описании Посмотрите из неё мы импортируем piploat нам также
1:02:30
понадобится библиотека нам пай которую мы импортируем ниже и еще один момент после запуска ячейки матплаклип имеет
1:02:38
особенность отображать графики в новом окне которое всплывает поверх для того
1:02:43
чтобы графики отображались Свободном пространстве под ячейкой Нам нужно будет применить магический метод мат ли инлайн
1:02:51
с вот таким знаком процента для начала мы воспользуемся способом отображения наших данных известных как гистограмма и
1:03:00
это позволит нам увидеть распределение наших текстов наших сообщений по длине
1:03:06
или относительно длины между метками спам и хам мы можем вызвать отображение
1:03:12
этих гистограмм при помощи функции которые мы подадим колонку или столбец
1:03:20
Body Line и отфильтруем ее сначала по метке или лейблу спам второй параметр
1:03:26
функции hist – это параметр binds который по умолчанию равен NAN но если
1:03:33
мы его укажем просто через запятую он будет зачислен Итак что такое Benz это
1:03:38
фактически некие условные секции на которые делятся наши данные мы будем использовать функцию Link Space из и мы
1:03:46
говорим что по длине сообщений символов нас интересует сообщением от 0 до 100
1:03:52
символов и у нас будет 40 таких бинов то есть 40 делений наших данных следующий
1:03:58
параметр Альфа отвечает за некую прозрачность наших Instagram Если хотите это просто визуальный некий эффект чтобы
1:04:05
лучше их отделять друг от друга и дальше Мы также указываем метку далее мы
1:04:10
скопировали эту строчку и уже поменяем саму метку на Хам и также фильтры мы
1:04:16
поменяем спам на хам теперь нам осталось добавить Легенду к нашему графику и при
1:04:22
помощи значения upper Left для параметра Lock мы можем указать где это легенда будет
1:04:29
относительно этой фигуры или конструкции В общем относительно графика Хотя
1:04:35
Давайте на самом деле поместим привычным prom верхнем углу и для того чтобы все это такие отобразилось нашим ноутбуке
1:04:41
Нам нужно будет применить в конце функцию Shell Теперь давайте запускать ячейку и отображать наши чудесный график
1:04:49
Мы также можем заметить что хам у нас значительно больше по размеру нашего спама потому что я забыл применить
1:04:56
нормализацию Вы можете сделать это самостоятельно но мы также можем заметить что принципе наши гипотеза
1:05:02
оправдана по иксу которая у нас отображает длину по символам мы можем
1:05:07
заметить что спам значительно смещен вправо Так что Да действительно спам содержит больше наших любимых символов
1:05:15
но а мы пока что давайте быстренько сделаем то же самое для нашего
1:05:20
до следующего признака это пунктуация поскольку у нас там все в процентах Давайте поменяем наш верхний рубеж
1:05:26
скажем на 50 процентов Мы также поменяем наш Body Line на punkt и знак процента
1:05:35
Почему я выбрал 50 процентов как верхнюю границу потому что я предполагаю что нормальное сообщение не может содержать
1:05:41
более 50 процентов своего объема чисто знаков пунктуации или в любом случае
1:05:47
сообщение которые будут доказывать мне это релевантный признак или нет на графике можем видеть что наш признак
1:05:53
посвященный пунктуации показывает наложение буквально для спама и хама то
1:05:59
есть накладывается друг на друга имеет в принципе похожее распределение поэтому можем
1:06:05
заключить что для нашей модели этот конкретно признак не поможет ей лучше
1:06:11
разбираться и отделять спам от хама в отличие от длины сообщений то есть наша
1:06:18
первая гипотеза наша догадка в длину символов спам сообщениях и нормальных
1:06:23
сообщениях она подтверждается а вторая гипотеза не подтверждается Поэтому в принципе можем ее впоследствии и
1:06:30
отбросить почему бы нет И вот таким образом мы подошли к финальной части подготовки нашего корпуса текста
1:06:36
называемой трансформации опять же это большая тема здесь мы коснемся достаточно поверхностном и вот на каком
1:06:43
этапе Мы закончили наше прошлое преобразование наших признаков следующий
1:06:48
чеки мы снова будем использовать гистограмму для отображения наших признаков но на этот раз мы будем искать
1:06:54
какие-то отклонения скажем перекос в одну или другую сторону либо огромное количество выбросов скажем и мы начнем с
1:07:01
признака отвечающего за длину текста то есть Бари лэн который мы отобразим на небольшой Инстаграме и это гистограмма
1:07:08
будет немного отличаться от той что Я использовал ранее в частности я не буду использовать метод линдспейс я также не
1:07:15
буду использовать гистограмму отображения относительно меток спам Меня
1:07:20
интересует отображение этого признака по всем данным и вот как это выглядит Если
1:07:27
же к примеру Вас не устраивает такое в отображение как мы видим у нас есть и
1:07:32
второй параметр бизнес мы можем скопировать эти самые бедносы из прошлого примера линдспейс и переделать
1:07:40
их для наших нужд у нас получится примерно та же гистограмма Хотя для нашего примера Вы действительно сможете
1:07:47
заметить что репрезентация стала более четкой то есть мы можем заметить что
1:07:52
здесь две вершины то есть некая биомодальность присутствует длина текста У нас отображена по оси X Если вы
1:07:59
помните то первая вершина Это примерно где находится все не спам сообщения а
1:08:05
вторая вершина это как раз Где находится основная часть спам сообщений нашем случае ось Y отвечает за количество
1:08:12
сэмплов либо за количество сообщений Это не самый лучший кандидат на
1:08:17
трансформацию потому что у нас скажем нет явного перекоса в одну или другую сторону Давайте попробуем с пунктуацией
1:08:24
опять же все примерно то что мы уже делали Просто в этот раз мы смотрим на
1:08:29
всю эту историю немножко под другим углом в частности мы смотрим на гистограмму на отображение вот этого
1:08:35
признака и думаем Нужна ли этому признаку трансформация Потому что если мы оставим его как он есть то скорее
1:08:43
всего он может как-то навредить предсказаниям модели в частности в плане пунктуации Мы видим что у нас есть
1:08:49
хороший перекос У нас есть длинный хвост и куча выбросов То есть если мы подадим
1:08:54
его в нынешнем виде в модель то мы можем предположить что это явно навредит
1:09:00
предсказаниям модели то есть модель будет думать из-за Вот этого перекоса из-за выбросов неправильно и Для этого
1:09:07
нам нужно провести трансформацию то есть Нам нужно привести дистрибьюцию этих данных в Такую форму чтобы они буквально
1:09:14
не обманывали модель в частности мы будем использовать достаточно популярный метод трансформация бок Кокса оно
1:09:21
идеально подходит для нашего случая Когда у нас есть асимметричное
1:09:26
распределение у преобразования бокса Кокса которая кстати в полное имя Звучит как степенное преобразование бокса Кокса
1:09:33
у него есть отдельная формула которую можете посмотреть в интернете но мы ее
1:09:39
сейчас выразим в коде если совсем коротко то мы пытаемся фактически стабилизировать дисперсию то есть
1:09:46
степень разброса значений наши данных и по возможности приблизить форму распределения наших данных как можно
1:09:53
ближе к нормальной для этого мы будем преобразовывать наши исходные данные с помощью этой степенной функции То есть
1:10:00
как вы видите внутри функции hist Мы берем наши данные по пунктуации наш последний признак и применяем к нему вот
1:10:07
эту степенную трансформацию то есть сам цикл for проходит по списку от 1 до 5 то
1:10:13
есть это наши положительные экспоненты I представляет собой знаменатель степени в
1:10:18
которую эти экспоненты они будут подставляться и Мы также будем выводить небольшую подсказку На каком этапе
1:10:25
трансформации мы находимся то есть на какой экспоненте то есть первый итерации у нас будет степень 1 то есть единица
1:10:32
фактически то же самое число во второй итерации у нас будет степень 1 2 То есть
1:10:37
фактически квадратный корень Этого числа Ну и так далее Надеюсь вы поняли идею и у нас будет 5 графиков с пятью разными
1:10:44
экспонентами то есть пятью разными трансформациями и вы можете воочию увидеть что они себя представляют и вы
1:10:51
видите что последние два графика представляет из себя вполне уже нормальное распределение Если Вы
1:10:56
заметили палку слева то это просто нули То есть те текстовые сообщения в которых отсутствует пунктуация что досмотрел до
1:11:03
конца тот молодец и увидимся в следующей части А с вами был Вий проверяйте ссылки
1:11:09
в описании и до связи

Поделиться: