Troyanov Daniil 6 дней назад
Родитель a1882005e2
Сommit e63b79b0d8

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

@ -0,0 +1,451 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "gz18QPRz03Ec"
},
"source": [
"### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "mr9IszuQ1ANG"
},
"outputs": [],
"source": [
"# импорт модулей\n",
"import os\n",
"\n",
"from tensorflow import keras\n",
"from tensorflow.keras import layers\n",
"from tensorflow.keras.models import Sequential\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FFRtE0TN1AiA"
},
"source": [
"### 2) Загрузили набор данных IMDb, содержащий оцифрованные отзывы на фильмы, размеченные на два класса: позитивные и негативные. При загрузке набора данных параметр seed выбрали равным значению (4k – 1)=3, где k=1 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Ixw5Sp0_1A-w"
},
"outputs": [],
"source": [
"# загрузка датасета\n",
"import ssl\n",
"ssl._create_default_https_context = ssl._create_unverified_context\n",
"\n",
"from keras.datasets import imdb\n",
"\n",
"vocabulary_size = 5000\n",
"index_from = 3\n",
"\n",
"(X_train, y_train), (X_test, y_test) = imdb.load_data(\n",
" path=\"imdb.npz\",\n",
" num_words=vocabulary_size,\n",
" skip_top=0,\n",
" maxlen=None,\n",
" seed=3,\n",
" start_char=1,\n",
" oov_char=2,\n",
" index_from=index_from\n",
" )\n",
"\n",
"# вывод размерностей\n",
"print('Shape of X train:', X_train.shape)\n",
"print('Shape of y train:', y_train.shape)\n",
"print('Shape of X test:', X_test.shape)\n",
"print('Shape of y test:', y_test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "aCo_lUXl1BPV"
},
"source": [
"### 3) Вывели один отзыв из обучающего множества в виде списка индексов слов. Преобразовали список индексов в текст и вывели отзыв в виде текста. Вывели длину отзыва. Вывели метку класса данного отзыва и название класса (1 – Positive, 0 – Negative)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "9W3RklPcZyH0"
},
"outputs": [],
"source": [
"# создание словаря для перевода индексов в слова\n",
"# загрузка словаря \"слово:индекс\"\n",
"word_to_id = imdb.get_word_index()\n",
"# уточнение словаря\n",
"word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}\n",
"word_to_id[\"<PAD>\"] = 0\n",
"word_to_id[\"<START>\"] = 1\n",
"word_to_id[\"<UNK>\"] = 2\n",
"word_to_id[\"<UNUSED>\"] = 3\n",
"# создание обратного словаря \"индекс:слово\"\n",
"id_to_word = {value:key for key,value in word_to_id.items()}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Nu-Bs1jnaYhB"
},
"outputs": [],
"source": [
"print(X_train[26])\n",
"print('len:',len(X_train[26]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "JhTwTurtZ6Sp"
},
"outputs": [],
"source": [
"review_as_text = ' '.join(id_to_word[id] for id in X_train[26])\n",
"print(review_as_text)\n",
"print('len:',len(review_as_text))\n",
"\n",
"# вывод метки класса и названия класса\n",
"print('Label:', y_train[26])\n",
"print('Class:', 'Positive' if y_train[26] == 1 else 'Negative')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4hclnNaD1BuB"
},
"source": [
"### 4) Вывели максимальную и минимальную длину отзыва в обучающем множестве."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "xJH87ISq1B9h"
},
"outputs": [],
"source": [
"print('MAX Len: ',len(max(X_train, key=len)))\n",
"print('MIN Len: ',len(min(X_train, key=len)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7x99O8ig1CLh"
},
"source": [
"### 5) Провели предобработку данных. Выбрали единую длину, к которой будут приведены все отзывы. Короткие отзывы дополнили спецсимволами, а длинные обрезали до выбранной длины."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "lrF-B2aScR4t"
},
"outputs": [],
"source": [
"# предобработка данных\n",
"from tensorflow.keras.utils import pad_sequences\n",
"max_words = 500\n",
"X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')\n",
"X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HL2_LVga1C3l"
},
"source": [
"### 6) Повторили пункт 4."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "81Cgq8dn9uL6"
},
"outputs": [],
"source": [
"print('MAX Len: ',len(max(X_train, key=len)))\n",
"print('MIN Len: ',len(min(X_train, key=len)))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KzrVY1SR1DZh"
},
"source": [
"### 7) Повторили пункт 3. Сделали вывод о том, как отзыв преобразовался после предобработки."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "vudlgqoCbjU1"
},
"outputs": [],
"source": [
"print(X_train[26])\n",
"print('len:',len(X_train[26]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "dbfkWjDI1Dp7"
},
"outputs": [],
"source": [
"review_as_text = ' '.join(id_to_word[id] for id in X_train[26])\n",
"print(review_as_text)\n",
"print('len:',len(review_as_text))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mJNRXo5TdPAE"
},
"source": [
"#### В результате предобработки данных все отзывы были приведены к единой длине 500 токенов. Для отзывов, исходная длина которых была меньше 500, в начало последовательности были добавлены специальные токены заполнения <PAD> (со значением 0). Это обеспечило единообразие входных данных для нейронной сети и позволило эффективно обрабатывать последовательности различной длины."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YgiVGr5_1D3u"
},
"source": [
"### 8) Вывели предобработанные массивы обучающих и тестовых данных и их размерности."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "7MqcG_wl1EHI"
},
"outputs": [],
"source": [
"# вывод данных\n",
"print('X train: \\n',X_train)\n",
"print('X test: \\n',X_test)\n",
"\n",
"# вывод размерностей\n",
"print('Shape of X train:', X_train.shape)\n",
"print('Shape of X test:', X_test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "amaspXGW1EVy"
},
"source": [
"### 9) Реализовали модель рекуррентной нейронной сети, состоящей из слоев Embedding, LSTM, Dropout, Dense, и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Добились качества обучения по метрике accuracy не менее 0.8."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ktWEeqWd1EyF"
},
"outputs": [],
"source": [
"embed_dim = 32\n",
"lstm_units = 64\n",
"\n",
"model = Sequential()\n",
"model.add(layers.Embedding(input_dim=vocabulary_size, output_dim=embed_dim, input_length=max_words, input_shape=(max_words,)))\n",
"model.add(layers.LSTM(lstm_units))\n",
"model.add(layers.Dropout(0.5))\n",
"model.add(layers.Dense(1, activation='sigmoid'))\n",
"\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "CuPqKpX0kQfP"
},
"outputs": [],
"source": [
"# компилируем и обучаем модель\n",
"batch_size = 64\n",
"epochs = 3\n",
"model.compile(loss=\"binary_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
"model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "hJIWinxymQjb"
},
"outputs": [],
"source": [
"test_loss, test_acc = model.evaluate(X_test, y_test)\n",
"print(f\"\\nTest accuracy: {test_acc}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mgrihPd61E8w"
},
"source": [
"### 10) Оценили качество обучения на тестовых данных:\n",
"### - вывели значение метрики качества классификации на тестовых данных\n",
"### - вывели отчет о качестве классификации тестовой выборки \n",
"### - построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Rya5ABT8msha"
},
"outputs": [],
"source": [
"#значение метрики качества классификации на тестовых данных\n",
"print(f\"\\nTest accuracy: {test_acc}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "2kHjcmnCmv0Y"
},
"outputs": [],
"source": [
"#отчет о качестве классификации тестовой выборки\n",
"y_score = model.predict(X_test)\n",
"y_pred = [1 if y_score[i,0]>=0.5 else 0 for i in range(len(y_score))]\n",
"\n",
"from sklearn.metrics import classification_report\n",
"print(classification_report(y_test, y_pred, labels = [0, 1], target_names=['Negative', 'Positive']))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Kp4AQRbcmwAx"
},
"outputs": [],
"source": [
"#построение ROC-кривой и AUC ROC\n",
"from sklearn.metrics import roc_curve, auc\n",
"\n",
"fpr, tpr, thresholds = roc_curve(y_test, y_score)\n",
"plt.figure(figsize=(8, 6))\n",
"plt.plot(fpr, tpr)\n",
"plt.grid()\n",
"plt.xlabel('False Positive Rate')\n",
"plt.ylabel('True Positive Rate')\n",
"plt.title('ROC')\n",
"plt.savefig('roc_curve.png', dpi=150, bbox_inches='tight')\n",
"plt.show()\n",
"print('AUC ROC:', auc(fpr, tpr))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MsM3ew3d1FYq"
},
"source": [
"### 11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста. "
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xxFO4CXbIG88"
},
"source": [
"Таблица1:"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xvoivjuNFlEf"
},
"source": [
"| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |\n",
"|----------|-------------------------------------|---------------------------|-----------------------------------------|\n",
"| Рекуррентная | 184 897 | 3 | accuracy:0.8659 ; loss:0.3207 ; AUC ROC:0.9386 |\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YctF8h_sIB-P"
},
"source": [
"#### Анализируя полученные результаты применения рекуррентной нейронной сети для классификации тональности текстовых отзывов, можно констатировать успешное выполнение поставленной задачи. Достигнутый уровень точности accuracy = 0.8659 существенно превосходит минимально необходимый порог 0.8, что свидетельствует о надежности разработанной модели. Показатель AUC ROC = 0.9386, превышающий значение 0.9, демонстрирует отличную дискриминационную способность модели в различении позитивных и негативных отзывов. Сбалансированные метрики precision и recall (0.87 для обоих классов) указывают на отсутствие значимого смещения в сторону одного из классов, что подтверждает корректность работы алгоритма классификации."
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"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.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 0
}

@ -0,0 +1,343 @@
# Отчёт по лабораторной работе №4
**Троянов Д.С., Чернов Д.Е. — А-01-22**
---
## Задание 1
### 1) В среде Google Colab создали новый блокнот (notebook). Импортировали необходимые для работы библиотеки и модули. Настроили блокнот для работы с аппаратным ускорителем GPU.
```python
# импорт модулей
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab4')
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
import numpy as np
```
```python
import tensorflow as tf
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))
```
```
Found GPU at: /device:GPU:0
```
### 2) Загрузили набор данных IMDb, содержащий оцифрованные отзывы на фильмы, размеченные на два класса: позитивные и негативные. При загрузке набора данных параметр seed выбрали равным значению (4k – 1)=3, где k=1 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных.
```python
# загрузка датасета
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
from keras.datasets import imdb
vocabulary_size = 5000
index_from = 3
(X_train, y_train), (X_test, y_test) = imdb.load_data(
path="imdb.npz",
num_words=vocabulary_size,
skip_top=0,
maxlen=None,
seed=3,
start_char=1,
oov_char=2,
index_from=index_from
)
# вывод размерностей
print('Shape of X train:', X_train.shape)
print('Shape of y train:', y_train.shape)
print('Shape of X test:', X_test.shape)
print('Shape of y test:', y_test.shape)
```
```
Shape of X train: (25000,)
Shape of y train: (25000,)
Shape of X test: (25000,)
Shape of y test: (25000,)
```
### 3) Вывели один отзыв из обучающего множества в виде списка индексов слов. Преобразовали список индексов в текст и вывели отзыв в виде текста. Вывели длину отзыва. Вывели метку класса данного отзыва и название класса (1 – Positive, 0 – Negative).
```python
# создание словаря для перевода индексов в слова
# загрузка словаря "слово:индекс"
word_to_id = imdb.get_word_index()
# уточнение словаря
word_to_id = {key:(value + index_from) for key,value in word_to_id.items()}
word_to_id["<PAD>"] = 0
word_to_id["<START>"] = 1
word_to_id["<UNK>"] = 2
word_to_id["<UNUSED>"] = 3
# создание обратного словаря "индекс:слово"
id_to_word = {value:key for key,value in word_to_id.items()}
```
```python
print(X_train[26])
print('len:',len(X_train[26]))
```
```
[1, 37, 1388, 4, 2739, 495, 94, 96, 143, 49, 2, 875, 551, 19, 195, 2210, 5, 1698, 8, 401, 4, 65, 24, 64, 1728, 21, 400, 642, 45, 77, 6, 137, 237, 207, 258, 141, 6, 1562, 1301, 1562, 737, 22, 10, 10, 4, 22, 9, 1490, 3862, 4, 744, 19, 307, 1385, 5, 2, 2, 4, 2, 2656, 2, 1669, 19, 4, 1074, 200, 4, 55, 406, 55, 3048, 5, 246, 55, 1451, 105, 688, 8, 4, 321, 177, 32, 677, 7, 4, 678, 1850, 26, 1669, 221, 5, 3921, 10, 10, 13, 386, 37, 1388, 4, 2739, 45, 6, 66, 163, 20, 15, 304, 6, 3049, 168, 33, 4, 4352, 15, 75, 70, 2, 23, 257, 85, 5, 4, 2789, 878, 21, 1305, 2, 1773, 7, 2]
len: 130
```
```python
review_as_text = ' '.join(id_to_word[id] for id in X_train[26])
print(review_as_text)
print('len:',len(review_as_text))
# вывод метки класса и названия класса
print('Label:', y_train[26])
print('Class:', 'Positive' if y_train[26] == 1 else 'Negative')
```
```
<START> who loves the sun works its way through some <UNK> subject matter with enough wit and grace to keep the story not only engaging but often hilarious it's been a while since i've found such a thoroughly touching thoroughly enjoyable film br br the film is gorgeous drawing the eye with beautiful scenery and <UNK> <UNK> the <UNK> imagery <UNK> wonderfully with the tension between the very human very flawed and yet very likable characters due to the excellent cast all five of the major players are wonderfully interesting and dynamic br br i recommend who loves the sun it's a really funny movie that takes a poignant look at the hurts that we can <UNK> on each other and the amazingly difficult but equally <UNK> process of <UNK>
len: 738
Label: 1
Class: Positive
```
### 4) Вывели максимальную и минимальную длину отзыва в обучающем множестве.
```python
print('MAX Len: ',len(max(X_train, key=len)))
print('MIN Len: ',len(min(X_train, key=len)))
```
```
MAX Len: 2494
MIN Len: 11
```
### 5) Провели предобработку данных. Выбрали единую длину, к которой будут приведены все отзывы. Короткие отзывы дополнили спецсимволами, а длинные обрезали до выбранной длины.
```python
# предобработка данных
from tensorflow.keras.utils import pad_sequences
max_words = 500
X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')
X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')
```
### 6) Повторили пункт 4.
```python
print('MAX Len: ',len(max(X_train, key=len)))
print('MIN Len: ',len(min(X_train, key=len)))
```
```
MAX Len: 500
MIN Len: 500
```
### 7) Повторили пункт 3. Сделали вывод о том, как отзыв преобразовался после предобработки.
```python
print(X_train[26])
print('len:',len(X_train[26]))
```
```
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 4 78
46 304 39 2 7 968 2 295 209 101 147 65 10 10
2643 2 497 8 30 6 147 284 5 996 174 10 10 11
4 130 4 2 4979 11 2 10 10 2]
len: 500
```
```python
review_as_text = ' '.join(id_to_word[id] for id in X_train[26])
print(review_as_text)
print('len:',len(review_as_text))
```
```
<PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <START> the bad out takes from <UNK> of fire <UNK> together without any real story br br dean <UNK> tries to be a real actor and fails again br br in the end the <UNK> quit in <UNK> br br <UNK>
len: 2947
```
#### В результате предобработки данных все отзывы были приведены к единой длине 500 токенов. Для отзывов, исходная длина которых была меньше 500, в начало последовательности были добавлены специальные токены заполнения <PAD> (со значением 0). Это обеспечило единообразие входных данных для нейронной сети и позволило эффективно обрабатывать последовательности различной длины.
### 8) Вывели предобработанные массивы обучающих и тестовых данных и их размерности.
```python
# вывод данных
print('X train: \n',X_train)
print('X test: \n',X_test)
# вывод размерностей
print('Shape of X train:', X_train.shape)
print('Shape of X test:', X_test.shape)
```
```
X train:
[[ 0 0 0 ... 12 38 76]
[ 0 0 0 ... 33 4 130]
[ 0 0 0 ... 437 7 58]
...
[ 0 0 0 ... 1874 1553 422]
[ 0 0 0 ... 18 1552 234]
[ 0 0 0 ... 7 87 1090]]
X test:
[[ 0 0 0 ... 6 194 717]
[ 0 0 0 ... 30 87 292]
[ 0 0 0 ... 495 55 73]
...
[ 0 0 0 ... 7 12 908]
[ 0 0 0 ... 61 477 2302]
[ 0 0 0 ... 5 68 4580]]
Shape of X train: (25000, 500)
Shape of X test: (25000, 500)
```
### 9) Реализовали модель рекуррентной нейронной сети, состоящей из слоев Embedding, LSTM, Dropout, Dense, и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Добились качества обучения по метрике accuracy не менее 0.8.
```python
embed_dim = 32
lstm_units = 64
model = Sequential()
model.add(layers.Embedding(input_dim=vocabulary_size, output_dim=embed_dim, input_length=max_words, input_shape=(max_words,)))
model.add(layers.LSTM(lstm_units))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))
model.summary()
```
**Model: "sequential"**
| Layer (type) | Output Shape | Param # |
| ----------------------- | --------------- | ------: |
| embedding_4 (Embedding) | (None, 500, 32) | 160,000 |
| lstm_4 (LSTM) | (None, 64) | 24,832 |
| dropout_4 (Dropout) | (None, 64) | 0 |
| dense_4 (Dense) | (None, 1) | 65 |
**Total params:** 184,897 (722.25 KB)
**Trainable params:** 184,897 (722.25 KB)
**Non-trainable params:** 0 (0.00 B)
```python
# компилируем и обучаем модель
batch_size = 64
epochs = 3
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2)
```
```
Epoch 1/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 108s 338ms/step - accuracy: 0.7596 - loss: 0.4853 - val_accuracy: 0.8086 - val_loss: 0.4447
Epoch 2/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 85s 273ms/step - accuracy: 0.8680 - loss: 0.3281 - val_accuracy: 0.8228 - val_loss: 0.3993
Epoch 3/3
313/313 ━━━━━━━━━━━━━━━━━━━━ 84s 267ms/step - accuracy: 0.8818 - loss: 0.3008 - val_accuracy: 0.8714 - val_loss: 0.3097
```
```python
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"\nTest accuracy: {test_acc}")
```
```
782/782 ━━━━━━━━━━━━━━━━━━━━ 54s 69ms/step - accuracy: 0.8659 - loss: 0.3207
Test accuracy: 0.865880012512207
```
### 10) Оценили качество обучения на тестовых данных:
### - вывели значение метрики качества классификации на тестовых данных
### - вывели отчет о качестве классификации тестовой выборки
### - построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC)
```python
#значение метрики качества классификации на тестовых данных
print(f"\nTest accuracy: {test_acc}")
```
```
Test accuracy: 0.865880012512207
```
```python
#отчет о качестве классификации тестовой выборки
y_score = model.predict(X_test)
y_pred = [1 if y_score[i,0]>=0.5 else 0 for i in range(len(y_score))]
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred, labels = [0, 1], target_names=['Negative', 'Positive']))
```
```
precision recall f1-score support
Negative 0.87 0.87 0.87 12500
Positive 0.87 0.86 0.87 12500
accuracy 0.87 25000
macro avg 0.87 0.87 0.87 25000
weighted avg 0.87 0.87 0.87 25000
```
```python
#построение ROC-кривой и AUC ROC
from sklearn.metrics import roc_curve, auc
fpr, tpr, thresholds = roc_curve(y_test, y_score)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr)
plt.grid()
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC')
plt.savefig('roc_curve.png', dpi=150, bbox_inches='tight')
plt.show()
print('AUC ROC:', auc(fpr, tpr))
```
![ROC-кривая](roc_curve.png)
```
AUC ROC: 0.9386348447999999
```
### 11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста.
Таблица1:
| Модель | Количество настраиваемых параметров | Количество эпох обучения | Качество классификации тестовой выборки |
|----------|-------------------------------------|---------------------------|-----------------------------------------|
| Рекуррентная | 184 897 | 3 | accuracy:0.8659 ; loss:0.3207 ; AUC ROC:0.9386 |
#### Анализируя полученные результаты применения рекуррентной нейронной сети для классификации тональности текстовых отзывов, можно констатировать успешное выполнение поставленной задачи. Достигнутый уровень точности accuracy = 0.8659 существенно превосходит минимально необходимый порог 0.8, что свидетельствует о надежности разработанной модели.
#### Показатель AUC ROC = 0.9386, превышающий значение 0.9, демонстрирует отличную дискриминационную способность модели в различении позитивных и негативных отзывов. Сбалансированные метрики precision и recall (0.87 для обоих классов) указывают на отсутствие значимого смещения в сторону одного из классов, что подтверждает корректность работы алгоритма классификации.

Двоичные данные
labworks/LW4/roc_curve.png

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 35 KiB

Загрузка…
Отмена
Сохранить