Compare commits

..

11 Commits
lab_4 ... main

Author SHA1 Message Date
426c79e4b8 Merge pull request 'lab_8' (#7) from lab_8 into main
Reviewed-on: #7
2025-03-21 20:38:36 +04:00
82544a9f49 fix variable name 2025-03-02 19:01:00 +04:00
bbd493c975 fix train function 2025-03-02 18:54:38 +04:00
097eb0c680 Reduce file weight 2025-03-02 18:30:00 +04:00
6040af3aee lab 8 done 2025-03-02 17:54:23 +04:00
2efcd657ab Merge pull request 'lab_7' (#6) from lab_7 into main
Reviewed-on: #6
2025-02-15 09:23:35 +04:00
d08bba642d add requirements 2025-02-08 22:29:02 +04:00
2ed1523e1c lab 7 done 2025-02-08 22:19:23 +04:00
2efd29af3b Merge pull request 'lab_5' (#5) from lab_5 into main
Reviewed-on: #5
2024-11-30 09:33:26 +04:00
1799992082 5 lab done 2024-11-26 15:42:15 +04:00
d6d9dd3785 Merge pull request 'lab_4' (#4) from lab_4 into main
Reviewed-on: #4
2024-11-16 09:14:49 +04:00
6 changed files with 3129 additions and 0 deletions

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

Binary file not shown.

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

Binary file not shown.

641
lab_8/lab8.ipynb Normal file
View 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

Binary file not shown.