Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
426c79e4b8 | |||
82544a9f49 | |||
bbd493c975 | |||
097eb0c680 | |||
6040af3aee | |||
2efcd657ab | |||
d08bba642d | |||
2ed1523e1c | |||
2efd29af3b | |||
1799992082 | |||
d6d9dd3785 |
1490
lab_5/lab5.ipynb
Normal file
1490
lab_5/lab5.ipynb
Normal file
File diff suppressed because one or more lines are too long
BIN
lab_5/requirements.txt
Normal file
BIN
lab_5/requirements.txt
Normal file
Binary file not shown.
998
lab_7/lab7.ipynb
Normal file
998
lab_7/lab7.ipynb
Normal file
File diff suppressed because one or more lines are too long
BIN
lab_7/requirements.txt
Normal file
BIN
lab_7/requirements.txt
Normal file
Binary file not shown.
641
lab_8/lab8.ipynb
Normal file
641
lab_8/lab8.ipynb
Normal file
@ -0,0 +1,641 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Лабораторная работа 8\n",
|
||||||
|
"\n",
|
||||||
|
"Выбранный датасет: ТЗ и статьи по ИТ (кластеризация, классификация).\n",
|
||||||
|
"\n",
|
||||||
|
"Выбранный метод машинного обучения: классификация.\n",
|
||||||
|
"\n",
|
||||||
|
"Задача анализа текстов: разработка модели, которая сможет автоматически определять категорию, к которой относится текст (в данном случае, ТЗ или статья)."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Импорт библиотеки и инициализация модуля для анализа текста:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import spacy\n",
|
||||||
|
"\n",
|
||||||
|
"sp = spacy.load(\"ru_core_news_lg\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Загрузка текстов из файлов с расширением .docx в датафрейм:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" doc \\\n",
|
||||||
|
"15 tz_16.docx \n",
|
||||||
|
"16 tz_17.docx \n",
|
||||||
|
"17 tz_18.docx \n",
|
||||||
|
"18 tz_19.docx \n",
|
||||||
|
"19 tz_20.docx \n",
|
||||||
|
"20 Архитектура, управляемая модель.docx \n",
|
||||||
|
"21 Введение в проектирование ИС.docx \n",
|
||||||
|
"22 Встроенные операторы SQL.docx \n",
|
||||||
|
"23 Методологии разработки программного обеспечени... \n",
|
||||||
|
"24 Методологии разработки программного обеспечени... \n",
|
||||||
|
"\n",
|
||||||
|
" text type \n",
|
||||||
|
"15 2.2\\tТехническое задание\\n2.2.1\\tОбщие сведени... 0 \n",
|
||||||
|
"16 2.2 Техническое задание.\\n2.2.1 Общие сведения... 0 \n",
|
||||||
|
"17 2.2. Техническое задание\\nОбщие сведения:\\nПол... 0 \n",
|
||||||
|
"18 2.2. Техническое задание\\n2.2.1. Наименование ... 0 \n",
|
||||||
|
"19 2.2. Техническое задание\\n2.2.1. Общие сведени... 0 \n",
|
||||||
|
"20 Архитектура, управляемая модель\\nАббревиатура ... 1 \n",
|
||||||
|
"21 1. ВВЕДЕНИЕ В ПРОЕКТИРОВАНИЕ ИНФОРМАЦИОННЫХ СИ... 1 \n",
|
||||||
|
"22 Встроенные операторы SQL. \\nКак было отмечено ... 1 \n",
|
||||||
|
"23 Методологии разработки программного обеспечени... 1 \n",
|
||||||
|
"24 Методологии разработки программного обеспечени... 1 \n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"from docx import Document\n",
|
||||||
|
"import os\n",
|
||||||
|
"\n",
|
||||||
|
"def read_docx(file_path):\n",
|
||||||
|
" doc = Document(file_path)\n",
|
||||||
|
" full_text = []\n",
|
||||||
|
" for paragraph in doc.paragraphs:\n",
|
||||||
|
" full_text.append(paragraph.text)\n",
|
||||||
|
" return \"\\n\".join(full_text)\n",
|
||||||
|
"\n",
|
||||||
|
"def load_docs(dataset_path):\n",
|
||||||
|
" df = pd.DataFrame(columns=[\"doc\", \"text\"])\n",
|
||||||
|
" for file_path in os.listdir(dataset_path):\n",
|
||||||
|
" if file_path.startswith(\"~$\"):\n",
|
||||||
|
" continue\n",
|
||||||
|
" text = read_docx(dataset_path + file_path)\n",
|
||||||
|
" df.loc[len(df.index)] = [file_path, text]\n",
|
||||||
|
" return df\n",
|
||||||
|
"\n",
|
||||||
|
"df = load_docs(\"../../static/tz_itdocs/\")\n",
|
||||||
|
"df[\"type\"] = df.apply(\n",
|
||||||
|
" lambda row: 0 if str(row[\"doc\"]).startswith(\"tz_\") else 1, axis=1\n",
|
||||||
|
")\n",
|
||||||
|
"df.sort_values(by=[\"doc\"], inplace=True)\n",
|
||||||
|
"\n",
|
||||||
|
"print(df.iloc[15:25])"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### В первую очередь будут использованы методы для предобработки текста.\n",
|
||||||
|
"\n",
|
||||||
|
"Трансформация:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import re\n",
|
||||||
|
"import emoji\n",
|
||||||
|
"from num2words import num2words\n",
|
||||||
|
"\n",
|
||||||
|
"# Функция для преобразования эмоджи в слова\n",
|
||||||
|
"def emojis_words(text):\n",
|
||||||
|
" \n",
|
||||||
|
" # Модуль emoji: преобразование эмоджи в их словесные описания\n",
|
||||||
|
" text = emoji.demojize(text, delimiters=(\" \", \" \"))\n",
|
||||||
|
" \n",
|
||||||
|
" # Редактирование текста путём замены \":\" и\" _\", а так же - путём добавления пробела между отдельными словами\n",
|
||||||
|
" text = text.replace(\":\", \"\").replace(\"_\", \" \")\n",
|
||||||
|
" \n",
|
||||||
|
" return text\n",
|
||||||
|
"\n",
|
||||||
|
"def transform_text(text):\n",
|
||||||
|
" # Удаление из текста всех HTML-тегов\n",
|
||||||
|
" text = re.sub(r'<[^<]+?>', '', text)\n",
|
||||||
|
" \n",
|
||||||
|
" # Удаление из текста всех URL и ссылок\n",
|
||||||
|
" text = re.sub(r'http\\S+', '', text)\n",
|
||||||
|
"\n",
|
||||||
|
" # Преобразование эмоджи в текст\n",
|
||||||
|
" text = emojis_words(text)\n",
|
||||||
|
"\n",
|
||||||
|
" # Приведение к нижнему регистру\n",
|
||||||
|
" text = text.lower()\n",
|
||||||
|
"\n",
|
||||||
|
" # Удаление лишних пробелов\n",
|
||||||
|
" text = re.sub(r'\\s+', ' ', text) \n",
|
||||||
|
" \n",
|
||||||
|
" # Преобразование \"ё\" в \"е\"\n",
|
||||||
|
" text = text.replace(\"ё\", \"е\")\n",
|
||||||
|
"\n",
|
||||||
|
" # Удаление всех специальных символов\n",
|
||||||
|
" text = re.sub(r'[^a-zA-Zа-яА-Я0-9\\s]', '', text)\n",
|
||||||
|
"\n",
|
||||||
|
" # Преобразование чисел в слова\n",
|
||||||
|
" words: list[str] = text.split()\n",
|
||||||
|
" words = [num2words(word, lang=\"ru\") if word.isdigit() else word for word in words]\n",
|
||||||
|
" text = \" \".join(words)\n",
|
||||||
|
"\n",
|
||||||
|
" # Удаление из текста всех знаков препинания\n",
|
||||||
|
" text = re.sub(r'[^\\w\\s]', '', text)\n",
|
||||||
|
"\n",
|
||||||
|
" return text\n",
|
||||||
|
"\n",
|
||||||
|
"df[\"preprocessed_text\"] = df[\"text\"].apply(transform_text)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Для токенизации, выделения частей речи (POS tagging), нормализации (в данном случае была выбрана лемматизация) и фильтрации используем библиотеку spaCy. На этапе фильтрации для сокращения пространства признаков используем словарь стоп-слов, а также удалим все слова длиной больше 20 символов:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 4,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"двадцать_NUM_Case=Nom технический_ADJ_Case=Nom|Degree=Pos|Gender=Neut|Number=Sing задание_NOUN_Animacy=Inan|Case=Nom|Gender=Neut|Number=Sing двести_NUM_Case=Nom двадцать_NUM_Case=Nom общий_ADJ_Case=Nom|Degree=Pos|Number=Plur сведение_NOUN_Animacy=Inan|Case=Nom|Gender=Neut|Number=Plur полный_ADJ_Case=Nom|Degree=Pos|Gender=Neut|Number=Sing наименование_NOUN_Animacy=Inan|Case=Acc|Gender=Neut|Number=Sing система_NOUN_Animacy=Inan|Case=Gen|Gender=Fem|Number=Sing\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from nltk.corpus import stopwords\n",
|
||||||
|
"\n",
|
||||||
|
"stop_words = set(stopwords.words('russian'))\n",
|
||||||
|
"\n",
|
||||||
|
"def preprocess_text(text):\n",
|
||||||
|
" doc = sp(text)\n",
|
||||||
|
" \n",
|
||||||
|
" filtered_tokens = [\n",
|
||||||
|
" f\"{token.lemma_}_{token.pos_}_{token.morph}\" # Формирование строки с нужным форматом\n",
|
||||||
|
" for token in doc\n",
|
||||||
|
" if token.text not in stop_words and len(token.text) <= 20 # Фильтрация \n",
|
||||||
|
" ]\n",
|
||||||
|
" \n",
|
||||||
|
" return \" \".join(filtered_tokens)\n",
|
||||||
|
"\n",
|
||||||
|
"df[\"preprocessed_text\"] = df[\"preprocessed_text\"].apply(preprocess_text)\n",
|
||||||
|
"\n",
|
||||||
|
"# Выведем 10 токенов из первого текста\n",
|
||||||
|
"first_text_tokens = df[\"preprocessed_text\"].iloc[0].split()[:10]\n",
|
||||||
|
"print(\" \".join(first_text_tokens))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Теперь перейдем к этапу формирования N-грамм:\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" doc \\\n",
|
||||||
|
"15 tz_16.docx \n",
|
||||||
|
"16 tz_17.docx \n",
|
||||||
|
"17 tz_18.docx \n",
|
||||||
|
"18 tz_19.docx \n",
|
||||||
|
"19 tz_20.docx \n",
|
||||||
|
"20 Архитектура, управляемая модель.docx \n",
|
||||||
|
"21 Введение в проектирование ИС.docx \n",
|
||||||
|
"22 Встроенные операторы SQL.docx \n",
|
||||||
|
"23 Методологии разработки программного обеспечени... \n",
|
||||||
|
"24 Методологии разработки программного обеспечени... \n",
|
||||||
|
"\n",
|
||||||
|
" text type \\\n",
|
||||||
|
"15 2.2\\tТехническое задание\\n2.2.1\\tОбщие сведени... 0 \n",
|
||||||
|
"16 2.2 Техническое задание.\\n2.2.1 Общие сведения... 0 \n",
|
||||||
|
"17 2.2. Техническое задание\\nОбщие сведения:\\nПол... 0 \n",
|
||||||
|
"18 2.2. Техническое задание\\n2.2.1. Наименование ... 0 \n",
|
||||||
|
"19 2.2. Техническое задание\\n2.2.1. Общие сведени... 0 \n",
|
||||||
|
"20 Архитектура, управляемая модель\\nАббревиатура ... 1 \n",
|
||||||
|
"21 1. ВВЕДЕНИЕ В ПРОЕКТИРОВАНИЕ ИНФОРМАЦИОННЫХ СИ... 1 \n",
|
||||||
|
"22 Встроенные операторы SQL. \\nКак было отмечено ... 1 \n",
|
||||||
|
"23 Методологии разработки программного обеспечени... 1 \n",
|
||||||
|
"24 Методологии разработки программного обеспечени... 1 \n",
|
||||||
|
"\n",
|
||||||
|
" preprocessed_text \\\n",
|
||||||
|
"15 двадцать_NUM_Case=Nom технический_ADJ_Case=Nom... \n",
|
||||||
|
"16 двадцать_NUM_Case=Nom технический_ADJ_Case=Nom... \n",
|
||||||
|
"17 двадцать_NUM_Case=Nom технический_ADJ_Case=Nom... \n",
|
||||||
|
"18 двадцать_NUM_Case=Nom технический_ADJ_Case=Nom... \n",
|
||||||
|
"19 двадцать_NUM_Case=Nom технический_ADJ_Case=Nom... \n",
|
||||||
|
"20 архитектура_NOUN_Animacy=Inan|Case=Nom|Gender=... \n",
|
||||||
|
"21 введение_NOUN_Animacy=Inan|Case=Nom|Gender=Neu... \n",
|
||||||
|
"22 встроенные_ADJ_Case=Nom|Degree=Pos|Number=Plur... \n",
|
||||||
|
"23 методология_NOUN_Animacy=Inan|Case=Nom|Gender=... \n",
|
||||||
|
"24 методология_NOUN_Animacy=Inan|Case=Nom|Gender=... \n",
|
||||||
|
"\n",
|
||||||
|
" bigrams \\\n",
|
||||||
|
"15 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"16 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"17 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"18 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"19 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"20 [(архитектура_NOUN_Animacy=Inan|Case=Nom|Gende... \n",
|
||||||
|
"21 [(введение_NOUN_Animacy=Inan|Case=Nom|Gender=N... \n",
|
||||||
|
"22 [(встроенные_ADJ_Case=Nom|Degree=Pos|Number=Pl... \n",
|
||||||
|
"23 [(методология_NOUN_Animacy=Inan|Case=Nom|Gende... \n",
|
||||||
|
"24 [(методология_NOUN_Animacy=Inan|Case=Nom|Gende... \n",
|
||||||
|
"\n",
|
||||||
|
" trigrams \n",
|
||||||
|
"15 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"16 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"17 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"18 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"19 [(двадцать_NUM_Case=Nom, технический_ADJ_Case=... \n",
|
||||||
|
"20 [(архитектура_NOUN_Animacy=Inan|Case=Nom|Gende... \n",
|
||||||
|
"21 [(введение_NOUN_Animacy=Inan|Case=Nom|Gender=N... \n",
|
||||||
|
"22 [(встроенные_ADJ_Case=Nom|Degree=Pos|Number=Pl... \n",
|
||||||
|
"23 [(методология_NOUN_Animacy=Inan|Case=Nom|Gende... \n",
|
||||||
|
"24 [(методология_NOUN_Animacy=Inan|Case=Nom|Gende... \n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from nltk.util import ngrams\n",
|
||||||
|
"from nltk.tokenize import word_tokenize\n",
|
||||||
|
"\n",
|
||||||
|
"def generate_ngrams(text: str, n: int = 2) -> list[tuple]:\n",
|
||||||
|
" tokens: list[str] = word_tokenize(text, language=\"russian\")\n",
|
||||||
|
" \n",
|
||||||
|
" n_grams: list[tuple] = list(ngrams(tokens, n))\n",
|
||||||
|
" return n_grams\n",
|
||||||
|
"\n",
|
||||||
|
"# Пример для биграмм (N=2)\n",
|
||||||
|
"df[\"bigrams\"] = df[\"preprocessed_text\"].apply(lambda x: generate_ngrams(x, n=2))\n",
|
||||||
|
"\n",
|
||||||
|
"# Пример для триграмм (N=3)\n",
|
||||||
|
"df[\"trigrams\"] = df[\"preprocessed_text\"].apply(lambda x: generate_ngrams(x, n=3))\n",
|
||||||
|
"\n",
|
||||||
|
"print(df.iloc[15:25])"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Также применим методы для векторизации текста.\n",
|
||||||
|
"\n",
|
||||||
|
"Мешок слов:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" поручить_verb_aspect попадание_noun_animacy интерфейс_noun_animacy \\\n",
|
||||||
|
"15 0 0 2 \n",
|
||||||
|
"16 0 0 2 \n",
|
||||||
|
"17 0 0 7 \n",
|
||||||
|
"18 0 0 2 \n",
|
||||||
|
"19 0 0 1 \n",
|
||||||
|
"20 0 0 6 \n",
|
||||||
|
"21 0 0 1 \n",
|
||||||
|
"22 0 0 0 \n",
|
||||||
|
"23 0 0 6 \n",
|
||||||
|
"24 0 0 5 \n",
|
||||||
|
"25 0 0 0 \n",
|
||||||
|
"\n",
|
||||||
|
" анатолиевич_propn_animacy столкнуться_verb_aspect скрытие_noun_animacy \\\n",
|
||||||
|
"15 2 0 0 \n",
|
||||||
|
"16 0 0 0 \n",
|
||||||
|
"17 0 0 0 \n",
|
||||||
|
"18 0 0 0 \n",
|
||||||
|
"19 0 0 0 \n",
|
||||||
|
"20 0 0 0 \n",
|
||||||
|
"21 0 1 0 \n",
|
||||||
|
"22 0 0 0 \n",
|
||||||
|
"23 0 1 0 \n",
|
||||||
|
"24 0 0 0 \n",
|
||||||
|
"25 0 0 2 \n",
|
||||||
|
"\n",
|
||||||
|
" распространенной_adj_case текстовый_adj_animacy pipes_x_foreign \\\n",
|
||||||
|
"15 0 0 0 \n",
|
||||||
|
"16 0 0 0 \n",
|
||||||
|
"17 0 1 0 \n",
|
||||||
|
"18 0 0 0 \n",
|
||||||
|
"19 0 0 0 \n",
|
||||||
|
"20 0 0 0 \n",
|
||||||
|
"21 0 0 0 \n",
|
||||||
|
"22 0 0 0 \n",
|
||||||
|
"23 0 0 0 \n",
|
||||||
|
"24 0 0 0 \n",
|
||||||
|
"25 0 0 0 \n",
|
||||||
|
"\n",
|
||||||
|
" руководствоваться_verb_aspect \n",
|
||||||
|
"15 0 \n",
|
||||||
|
"16 0 \n",
|
||||||
|
"17 0 \n",
|
||||||
|
"18 0 \n",
|
||||||
|
"19 0 \n",
|
||||||
|
"20 0 \n",
|
||||||
|
"21 2 \n",
|
||||||
|
"22 0 \n",
|
||||||
|
"23 0 \n",
|
||||||
|
"24 0 \n",
|
||||||
|
"25 0 \n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from scipy import sparse\n",
|
||||||
|
"from sklearn.feature_extraction.text import CountVectorizer\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"\n",
|
||||||
|
"counts_vectorizer = CountVectorizer()\n",
|
||||||
|
"counts_matrix = sparse.csr_matrix(counts_vectorizer.fit_transform(df[\"preprocessed_text\"]))\n",
|
||||||
|
"counts_df = pd.DataFrame(\n",
|
||||||
|
" counts_matrix.toarray(),\n",
|
||||||
|
" columns=counts_vectorizer.get_feature_names_out(),\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"random_columns = np.random.choice(counts_df.columns, size=10, replace=False)\n",
|
||||||
|
"\n",
|
||||||
|
"print(counts_df.loc[15:25, random_columns]) "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Либо же можно использовать частотный портрет:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
" поручить_verb_aspect попадание_noun_animacy интерфейс_noun_animacy \\\n",
|
||||||
|
"15 0.0 0.0 0.033439 \n",
|
||||||
|
"16 0.0 0.0 0.028513 \n",
|
||||||
|
"17 0.0 0.0 0.044900 \n",
|
||||||
|
"18 0.0 0.0 0.043194 \n",
|
||||||
|
"19 0.0 0.0 0.023228 \n",
|
||||||
|
"20 0.0 0.0 0.038113 \n",
|
||||||
|
"21 0.0 0.0 0.007355 \n",
|
||||||
|
"22 0.0 0.0 0.000000 \n",
|
||||||
|
"23 0.0 0.0 0.026442 \n",
|
||||||
|
"24 0.0 0.0 0.028079 \n",
|
||||||
|
"25 0.0 0.0 0.000000 \n",
|
||||||
|
"\n",
|
||||||
|
" анатолиевич_propn_animacy столкнуться_verb_aspect скрытие_noun_animacy \\\n",
|
||||||
|
"15 0.101196 0.000000 0.000000 \n",
|
||||||
|
"16 0.000000 0.000000 0.000000 \n",
|
||||||
|
"17 0.000000 0.000000 0.000000 \n",
|
||||||
|
"18 0.000000 0.000000 0.000000 \n",
|
||||||
|
"19 0.000000 0.000000 0.000000 \n",
|
||||||
|
"20 0.000000 0.000000 0.000000 \n",
|
||||||
|
"21 0.000000 0.017215 0.000000 \n",
|
||||||
|
"22 0.000000 0.000000 0.000000 \n",
|
||||||
|
"23 0.000000 0.022169 0.000000 \n",
|
||||||
|
"24 0.000000 0.000000 0.000000 \n",
|
||||||
|
"25 0.000000 0.000000 0.040551 \n",
|
||||||
|
"\n",
|
||||||
|
" распространенной_adj_case текстовый_adj_animacy pipes_x_foreign \\\n",
|
||||||
|
"15 0.0 0.000000 0.0 \n",
|
||||||
|
"16 0.0 0.000000 0.0 \n",
|
||||||
|
"17 0.0 0.035675 0.0 \n",
|
||||||
|
"18 0.0 0.000000 0.0 \n",
|
||||||
|
"19 0.0 0.000000 0.0 \n",
|
||||||
|
"20 0.0 0.000000 0.0 \n",
|
||||||
|
"21 0.0 0.000000 0.0 \n",
|
||||||
|
"22 0.0 0.000000 0.0 \n",
|
||||||
|
"23 0.0 0.000000 0.0 \n",
|
||||||
|
"24 0.0 0.000000 0.0 \n",
|
||||||
|
"25 0.0 0.000000 0.0 \n",
|
||||||
|
"\n",
|
||||||
|
" руководствоваться_verb_aspect \n",
|
||||||
|
"15 0.000000 \n",
|
||||||
|
"16 0.000000 \n",
|
||||||
|
"17 0.000000 \n",
|
||||||
|
"18 0.000000 \n",
|
||||||
|
"19 0.000000 \n",
|
||||||
|
"20 0.000000 \n",
|
||||||
|
"21 0.037685 \n",
|
||||||
|
"22 0.000000 \n",
|
||||||
|
"23 0.000000 \n",
|
||||||
|
"24 0.000000 \n",
|
||||||
|
"25 0.000000 \n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
||||||
|
"\n",
|
||||||
|
"tfidf_vectorizer = TfidfVectorizer(sublinear_tf=True)\n",
|
||||||
|
"tfidf_matrix = sparse.csr_matrix(tfidf_vectorizer.fit_transform(df[\"preprocessed_text\"]))\n",
|
||||||
|
"tfidf_df = pd.DataFrame(\n",
|
||||||
|
" tfidf_matrix.toarray(),\n",
|
||||||
|
" columns=tfidf_vectorizer.get_feature_names_out(),\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"print(tfidf_df.loc[15:25, random_columns]) "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Обучение модели и проверка ее качества:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 8,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"### TF-IDF Model ###\n",
|
||||||
|
"Accuracy: 0.8889\n",
|
||||||
|
"Precision: 0.7500\n",
|
||||||
|
"Recall: 1.0000\n",
|
||||||
|
"F1 Score: 0.8571\n",
|
||||||
|
"ROC AUC: 0.9167\n",
|
||||||
|
"Cross-validated F1 Score: 1.0000\n",
|
||||||
|
"\n",
|
||||||
|
"### Count Vectorizer Model ###\n",
|
||||||
|
"Accuracy: 1.0000\n",
|
||||||
|
"Precision: 1.0000\n",
|
||||||
|
"Recall: 1.0000\n",
|
||||||
|
"F1 Score: 1.0000\n",
|
||||||
|
"ROC AUC: 1.0000\n",
|
||||||
|
"Cross-validated F1 Score: 0.8933\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV\n",
|
||||||
|
"from sklearn.ensemble import RandomForestClassifier\n",
|
||||||
|
"from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score\n",
|
||||||
|
"\n",
|
||||||
|
"def train_and_evaluate(X, y, test_size=0.2, cv=5, optimize=False):\n",
|
||||||
|
" X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=9)\n",
|
||||||
|
"\n",
|
||||||
|
" if optimize:\n",
|
||||||
|
" param_grid = {\n",
|
||||||
|
" \"n_estimators\": [10, 20, 30, 40, 50, 100, 150, 200, 250, 500],\n",
|
||||||
|
" \"max_features\": [\"sqrt\", \"log2\", 2],\n",
|
||||||
|
" \"max_depth\": [2, 3, 4, 5, 6, 7, 8, 9, 10],\n",
|
||||||
|
" \"criterion\": [\"gini\", \"entropy\", \"log_loss\"],\n",
|
||||||
|
" \"class_weight\": [\"balanced\", \"balanced_subsample\"]\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" grid_search = GridSearchCV(RandomForestClassifier(random_state=9), param_grid, scoring=\"f1\", cv=cv, n_jobs=-1)\n",
|
||||||
|
" grid_search.fit(X_train, y_train)\n",
|
||||||
|
" model = grid_search.best_estimator_\n",
|
||||||
|
" print(f\"Лучшие параметры: {grid_search.best_params_}\")\n",
|
||||||
|
" else:\n",
|
||||||
|
" model = RandomForestClassifier(n_estimators=100, random_state=9)\n",
|
||||||
|
" model.fit(X_train, y_train)\n",
|
||||||
|
"\n",
|
||||||
|
" y_pred = model.predict(X_test)\n",
|
||||||
|
"\n",
|
||||||
|
" accuracy = accuracy_score(y_test, y_pred)\n",
|
||||||
|
" precision = precision_score(y_test, y_pred)\n",
|
||||||
|
" recall = recall_score(y_test, y_pred)\n",
|
||||||
|
" f1 = f1_score(y_test, y_pred)\n",
|
||||||
|
" roc_auc = roc_auc_score(y_test, y_pred)\n",
|
||||||
|
"\n",
|
||||||
|
" print(f\"Accuracy: {accuracy:.4f}\")\n",
|
||||||
|
" print(f\"Precision: {precision:.4f}\")\n",
|
||||||
|
" print(f\"Recall: {recall:.4f}\")\n",
|
||||||
|
" print(f\"F1 Score: {f1:.4f}\")\n",
|
||||||
|
" print(f\"ROC AUC: {roc_auc:.4f}\")\n",
|
||||||
|
"\n",
|
||||||
|
" scores = cross_val_score(model, X_train, y_train, cv=cv, scoring='f1')\n",
|
||||||
|
" f1_cv = scores.mean()\n",
|
||||||
|
" print(f\"Cross-validated F1 Score: {f1_cv:.4f}\")\n",
|
||||||
|
"\n",
|
||||||
|
" return model\n",
|
||||||
|
"\n",
|
||||||
|
"X_tfidf = tfidf_df\n",
|
||||||
|
"X_counts = counts_df\n",
|
||||||
|
"y = df[\"type\"]\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"### TF-IDF Model ###\")\n",
|
||||||
|
"model_tfidf = train_and_evaluate(X_tfidf, y)\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"\\n### Count Vectorizer Model ###\")\n",
|
||||||
|
"model_counts = train_and_evaluate(X_counts, y)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Как можно заметить, обе модели показывают очень хорошие результаты, а вторая модель даже практически идеальные. Возможно это связано с малым количеством данных в выборке (всего 41 документ), которые модель просто запомнила и в итоге переобучилась. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Кроме того, согласно заданию, попробуем оценить решение, используя другие гиперпараметры модели машинного обучения (подберем их методом поиска по сетке):"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"### TF-IDF Model (Optimized) ###\n",
|
||||||
|
"Лучшие параметры: {'class_weight': 'balanced', 'criterion': 'gini', 'max_depth': 2, 'max_features': 'sqrt', 'n_estimators': 10}\n",
|
||||||
|
"Accuracy: 1.0000\n",
|
||||||
|
"Precision: 1.0000\n",
|
||||||
|
"Recall: 1.0000\n",
|
||||||
|
"F1 Score: 1.0000\n",
|
||||||
|
"ROC AUC: 1.0000\n",
|
||||||
|
"Cross-validated F1 Score: 1.0000\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"print(\"### TF-IDF Model (Optimized) ###\")\n",
|
||||||
|
"model_tfidf = train_and_evaluate(X_tfidf, y, optimize=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Можно сделать вывод о том, что в данном случае имееется возможность подобрать модель с такими гиперпараметрами, которая согласно метрикам покажет даже идеальный результат"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "aimenv",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.12.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
BIN
lab_8/requirements.txt
Normal file
BIN
lab_8/requirements.txt
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user