از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
پایتون برای NLP: تجزیه و تحلیل احساسات فیلم با استفاده از یادگیری عمیق در Keras
سرفصلهای مطلب
این هفدهمین مقاله از سری مقالات من است روی پایتون برای NLP. در آخرین مقاله، بحث خود را در مورد یادگیری عمیق برای پردازش زبان طبیعی آغاز کردیم.
مقاله قبلی عمدتاً بر روی جاسازی کلمات متمرکز بود، جایی که دیدیم چگونه می توان از جاسازی کلمات برای تبدیل متن به یک بردار متراکم متناظر استفاده کرد، که متعاقباً می تواند به عنوان ورودی برای هر مدل یادگیری عمیق استفاده شود. ما وظایف طبقه بندی اولیه را با استفاده از جاسازی کلمه انجام می دهیم. ما از یک مجموعه داده سفارشی استفاده کردیم که شامل 16 بررسی خیالی درباره فیلم ها بود. علاوه بر این، الگوریتم های طبقه بندی آموزش و آزمایش شدند روی همان داده ها در نهایت، ما فقط از یک شبکه عصبی متصل متراکم برای آزمایش الگوریتم خود استفاده کردیم.
در این مقاله، مفاهیمی را که در مقاله قبلی مورد مطالعه قرار دادیم استوار میکنیم و با استفاده از مجموعه دادههای دنیای واقعی، طبقهبندی را با جزئیات بیشتری مشاهده خواهیم کرد. ما از سه نوع مختلف شبکه عصبی عمیق استفاده خواهیم کرد: شبکه عصبی با اتصال متراکم (شبکه عصبی پایه)، شبکه عصبی کانولوشنال (سی ان ان) و شبکه حافظه کوتاه مدت بلند مدت (LSTM)، که یک نوع از شبکه های عصبی مکرر. علاوه بر این، روش ارزیابی مدل های یادگیری عمیق را خواهیم دید روی داده های کاملاً دیده نشده
توجه داشته باشید: این مقاله از جاسازیهای کلمه Keras Embedding Layer و GloVe برای تبدیل متن به شکل عددی استفاده میکند. مهم است که قبلاً این مفاهیم را درک کرده باشید. در غیر این صورت، شما باید مقاله قبلی من را بخوانید و سپس می توانید برگردید و این مقاله را ادامه دهید.
مجموعه داده
مجموعه داده ای که می توان از این دانلود کرد لینک کاگل.
اگر مجموعه داده را دانلود کنید و فایل فشرده را استخراج کنید، یک فایل CSV خواهید دید. این فایل شامل 50000 رکورد و دو ستون است: بررسی و احساس. ستون بررسی حاوی متنی برای بررسی و ستون احساسات حاوی احساسات برای بررسی است. ستون احساس می تواند دو مقدار داشته باشد یعنی “مثبت” و “منفی” که مشکل ما را به یک مشکل طبقه بندی باینری تبدیل می کند.
واردات کتابخانه های مورد نیاز
اسکریپت زیر کتابخانه های مورد نیاز را وارد می کند:
import pandas as pd
import numpy as np
import re
import nltk
from nltk.corpus import stopwords
from numpy import array
from keras.preprocessing.text import one_hot
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers.core import Activation, Dropout, Dense
from keras.layers import Flatten
from keras.layers import GlobalMaxPooling1D
from keras.layers.embeddings import Embedding
from sklearn.model_selection import train_test_split
from keras.preprocessing.text import Tokenizer
وارد کردن و تجزیه و تحلیل مجموعه داده
حالا بیایید import و مجموعه داده ما را تجزیه و تحلیل کنید. اسکریپت زیر را اجرا کنید:
movie_reviews = pd.read_csv("E:\Datasets\IMDB Dataset.csv")
movie_reviews.isnull().values.any()
movie_reviews.shape
در اسکریپت بالا ما از read_csv()
روش کتابخانه پانداها برای خواندن فایل CSV حاوی مجموعه داده ما. در خط بعدی، بررسی می کنیم که آیا مجموعه داده حاوی مقدار NULL است یا خیر. بالاخره ما print شکل مجموعه داده ما
حالا بیایید print 5 ردیف اول مجموعه داده با استفاده از head()
روش.
movie_reviews.head()
در خروجی دیتافریم زیر را مشاهده خواهید کرد:
بیایید اکنون به هر یک از بررسی ها نگاهی بیندازیم تا ایده ای در مورد متنی که می خواهیم process. به اسکریپت زیر نگاه کنید.
movie_reviews("review")(3)
شما باید بررسی زیر را ببینید:
"Basically there's a family where a little boy (Jake) thinks there's a zombie in his closet & his parents are fighting all the time.<br /><br />This movie is slower than a soap opera... and suddenly, Jake decides to become Rambo and kill the zombie.<br /><br />OK, first of all when you're going to make a film you must Decide if its a thriller or a drama! As a drama the movie is watchable. Parents are divorcing & arguing like in real life. And then we have Jake with his closet which totally ruins all the film! I expected to see a BOOGEYMAN similar movie, and instead i watched a drama with some meaningless thriller spots.<br /><br />3 out of 10 just for the well playing parents & descent dialogs. As for the shots with Jake: just ignore them."
می بینید که متن ما حاوی علائم نگارشی، براکت و چند تگ HTML نیز هست. در بخش بعدی این متن را پیش پردازش خواهیم کرد.
در نهایت، بیایید توزیع احساسات مثبت و منفی را در مجموعه داده خود ببینیم.
import seaborn as sns
sns.countplot(x='sentiment', data=movie_reviews)
خروجی:
از خروجی، مشخص است که مجموعه داده شامل تعداد مساوی بررسی مثبت و منفی است
پیش پردازش داده ها
دیدیم که مجموعه داده ما حاوی علائم نقطه گذاری و تگ های HTML است. در این بخش تابعی را تعریف می کنیم که یک رشته متن را به عنوان پارامتر می گیرد و سپس پیش پردازش را انجام می دهد روی رشته برای حذف کاراکترهای خاص و تگ های HTML از رشته. در نهایت رشته به تابع فراخوانی باز می گردد. به اسکریپت زیر نگاه کنید:
def preprocess_text(sen):
sentence = remove_tags(sen)
sentence = re.sub('(^a-zA-Z)', ' ', sentence)
sentence = re.sub(r"\s+(a-zA-Z)\s+", ' ', sentence)
sentence = re.sub(r'\s+', ' ', sentence)
return sentence
TAG_RE = re.compile(r'<(^>)+>')
def remove_tags(text):
return TAG_RE.sub('', text)
در preprocess_text()
روش گام اول حذف تگ های HTML است. برای حذف تگ های HTML، remove_tags()
تابع تعریف شده است. این remove_tags
عملکرد به سادگی جایگزین هر چیزی بین باز و بسته شدن می شود <>
با فضای خالی
بعد، در preprocess_text
عملکرد، همه چیز حذف می شود به جز حروف بزرگ و کوچک انگلیسی، که منجر به ایجاد نویسه های منفرد می شود که معنی ندارد. به عنوان مثال، هنگامی که یک آپاستروف را از کلمه “Mark’s” حذف می کنید، آپاستروف با یک فضای خالی جایگزین می شود. از این رو، ما با یک شخصیت «s» باقی میمانیم.
در مرحله بعد، تمام کاراکترهای منفرد را حذف می کنیم و با فاصله ای جایگزین می کنیم که چندین فاصله در متن ما ایجاد می کند. در نهایت، فاصله های متعدد را نیز از متن خود حذف می کنیم.
در مرحله بعد، بررسی های خود را از قبل پردازش می کنیم و آنها را در یک لیست جدید ذخیره می کنیم که در زیر نشان داده شده است:
X = ()
sentences = list(movie_reviews('review'))
for sen in sentences:
X.append(preprocess_text(sen))
حالا بیایید دوباره بررسی چهارم را ببینیم:
X(3)
خروجی به شکل زیر است:
'Basically there a family where little boy Jake thinks there a zombie in his closet his parents are fighting all the time This movie is slower than soap opera and suddenly Jake decides to become Rambo and kill the zombie OK first of all when you re going to make film you must Decide if its thriller or drama As drama the movie is watchable Parents are divorcing arguing like in real life And then we have Jake with his closet which totally ruins all the film expected to see BOOGEYMAN similar movie and instead watched drama with some meaningless thriller spots out of just for the well playing parents descent dialogs As for the shots with Jake just ignore them '
از خروجی می بینید که تگ ها، علائم نگارشی و اعداد HTML حذف شده اند. ما فقط با حروف الفبا مانده ایم.
در مرحله بعد، باید برچسب های خود را به رقم تبدیل کنیم. از آنجایی که ما فقط دو برچسب در خروجی داریم یعنی “مثبت” و “منفی”. همانطور که در زیر نشان داده شده است، میتوانیم آنها را با جایگزین کردن «مثبت» با رقم 1 و منفی با رقم 0 به اعداد صحیح تبدیل کنیم:
y = movie_reviews('sentiment')
y = np.array(list(map(lambda x: 1 if x=="positive" else 0, y)))
در نهایت، باید مجموعه داده های خود را به مجموعه های قطار و تست تقسیم کنیم. مجموعه قطار برای آموزش مدل های یادگیری عمیق ما استفاده می شود در حالی که مجموعه تست برای ارزیابی عملکرد مدل ما استفاده می شود.
ما میتوانیم استفاده کنیم train_test_split
روش از sklearn.model.selection
ماژول، همانطور که در زیر نشان داده شده است:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)
اسکریپت بالا داده های ما را به 80% برای مجموعه آموزشی و 20% برای مجموعه تست تقسیم می کند.
حالا بیایید اسکریپت لایه جاسازی خود را بنویسیم. لایه embedding داده های متنی ما را به داده های عددی تبدیل می کند و به عنوان اولین لایه برای مدل های یادگیری عمیق در Keras استفاده می شود.
آماده سازی لایه جاسازی
به عنوان اولین قدم، ما از Tokenizer
کلاس از keras.preprocessing.text
ماژول برای ایجاد فرهنگ لغت کلمه به فهرست. در فرهنگ لغت کلمه به فهرست، هر کلمه در مجموعه به عنوان یک کلید استفاده می شود، در حالی که یک شاخص منحصر به فرد مربوطه به عنوان مقدار کلید استفاده می شود. اسکریپت زیر را اجرا کنید:
tokenizer = Tokenizer(num_words=5000)
tokenizer.fit_on_texts(X_train)
X_train = tokenizer.texts_to_sequences(X_train)
X_test = tokenizer.texts_to_sequences(X_test)
اگر شما مشاهده کنید X_train
متغیر در اکسپلورر متغیر، خواهید دید که شامل 40000 لیست است که هر لیست شامل اعداد صحیح است. هر لیست در واقع با هر جمله در مجموعه آموزشی مطابقت دارد. همچنین متوجه خواهید شد که اندازه هر لیست متفاوت است. این به این دلیل است که طول جملات متفاوت است.
ما حداکثر اندازه هر لیست را 100 تنظیم می کنیم. می توانید اندازه دیگری را امتحان کنید. لیست هایی با اندازه بزرگتر از 100 به 100 کوتاه می شوند. برای لیست هایی که طول آنها کمتر از 100 است، 0 را در انتهای لیست اضافه می کنیم تا به حداکثر طول برسد. این process padding نامیده می شود.
اسکریپت زیر اندازه واژگان را پیدا می کند و سپس padding را انجام می دهد روی هم قطار و هم مجموعه تست
vocab_size = len(tokenizer.word_index) + 1
maxlen = 100
X_train = pad_sequences(X_train, padding='post', maxlen=maxlen)
X_test = pad_sequences(X_test, padding='post', maxlen=maxlen)
حالا اگر شما مشاهده کنید X_train
یا X_test
، خواهید دید که تمام لیست ها دارای طول یکسانی هستند یعنی 100. همچنین، the vocabulary_size
متغیر اکنون حاوی مقدار 92547 است که به این معنی است که مجموعه ما دارای 92547 کلمه منحصر به فرد است.
ما از جاسازی های GloVe برای ایجاد ماتریس ویژگی های خود استفاده خواهیم کرد. در اسکریپت زیر، جاسازیهای کلمه GloVe را بارگذاری میکنیم و فرهنگ لغتی ایجاد میکنیم که حاوی کلمات بهعنوان کلید و فهرست جاسازی متناظر آنها بهعنوان مقادیر باشد.
from numpy import array
from numpy import asarray
from numpy import zeros
embeddings_dictionary = dict()
glove_file = open('E:/Datasets/Word Embeddings/glove.6B.100d.txt', encoding="utf8")
for line in glove_file:
records = line.split()
word = records(0)
vector_dimensions = asarray(records(1:), dtype='float32')
embeddings_dictionary (word) = vector_dimensions
glove_file.close()
در نهایت، یک ماتریس تعبیهسازی ایجاد میکنیم که در آن هر شماره ردیف با شاخص کلمه در بدنه مطابقت دارد. ماتریس دارای 100 ستون خواهد بود که در آن هر ستون حاوی کلمات جاسازی شده GloVe برای کلمات موجود در مجموعه ما خواهد بود.
embedding_matrix = zeros((vocab_size, 100))
for word, index in tokenizer.word_index.items():
embedding_vector = embeddings_dictionary.get(word)
if embedding_vector is not None:
embedding_matrix(index) = embedding_vector
پس از اجرای اسکریپت بالا، آن را خواهید دید embedding_matrix
شامل 92547 ردیف (یک ردیف برای هر کلمه در مجموعه) خواهد بود. اکنون ما آماده ایم تا مدل های یادگیری عمیق خود را ایجاد کنیم.
طبقه بندی متن با شبکه عصبی ساده
اولین مدل یادگیری عمیقی که قرار است توسعه دهیم یک شبکه عصبی عمیق ساده است. به اسکریپت زیر نگاه کنید:
model = Sequential()
embedding_layer = Embedding(vocab_size, 100, weights=(embedding_matrix), input_length=maxlen , trainable=False)
model.add(embedding_layer)
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
در اسکریپت بالا، a را ایجاد می کنیم Sequential()
مدل. بعد، لایه embedding خود را ایجاد می کنیم. لایه جاسازی دارای طول ورودی 100 خواهد بود، بعد بردار خروجی نیز 100 خواهد بود. اندازه واژگان 92547 کلمه خواهد بود. از آنجایی که ما تعبیههای خود را آموزش نمیدهیم و از جاسازی GloVe استفاده نمیکنیم، تنظیم کردیم trainable
به False
و در weights
ماتریس تعبیه شده خود را پاس می کنیم.
سپس لایه embedding به مدل ما اضافه می شود. در مرحله بعد، از آنجایی که لایه جاسازی خود را مستقیماً به لایه ای متراکم متصل می کنیم، لایه جاسازی را صاف می کنیم. در نهایت یک لایه متراکم با اضافه می کنیم sigmoid
عملکرد فعال سازی
برای کامپایل کردن مدل خود، از آن استفاده خواهیم کرد adam
بهینه ساز، binary_crossentropy
به عنوان تابع ضرر ما و accuracy
به عنوان معیارها و سپس ما print خلاصه مدل ما:
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=('acc'))
print(model.summary())
خروجی به شکل زیر است:
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 100, 100) 9254700
_________________________________________________________________
flatten_1 (Flatten) (None, 10000) 0
_________________________________________________________________
dense_1 (Dense) (None, 1) 10001
=================================================================
Total params: 9,264,701
Trainable params: 10,001
Non-trainable params: 9,254,700
از آنجایی که 92547 کلمه در مجموعه ما وجود دارد و هر کلمه به عنوان یک بردار 100 بعدی نشان داده می شود، تعداد پارامترهای قابل آموزش خواهد بود. 92547x100
در لایه جاسازی در لایه مسطح، به سادگی سطرها و ستون ها را ضرب می کنیم. در نهایت در لایه متراکم تعداد پارامترها 10000 (از لایه مسطح) و 1 برای پارامتر بایاس، در مجموع 10001 است.
حال بیایید مدل خود را آموزش دهیم:
history = model.fit(X_train, y_train, batch_size=128, epochs=6, verbose=1, validation_split=0.2)
در اسکریپت بالا از fit
روشی برای آموزش شبکه عصبی ما توجه کنید در حال تمرین هستیم روی فقط مجموعه قطار ما این validation_split
از 0.2 به این معنی است که 20٪ از داده های آموزشی برای یافتن دقت آموزش الگوریتم استفاده می شود.
در پایان آموزش خواهید دید که دقت تمرین در حدود 85.52 درصد است.
برای ارزیابی عملکرد مدل، میتوانیم به سادگی مجموعه تست را به آن پاس کنیم evaluate
روش مدل ما
score = model.evaluate(X_test, y_test, verbose=1)
برای بررسی دقت و از دست دادن تست، اسکریپت زیر را اجرا کنید:
print("Test Score:", score(0))
print("Test Accuracy:", score(1))
وقتی اسکریپت بالا را اجرا کردید، خواهید دید که دقت تست 74.68% بدست می آید. دقت تمرین ما 85.52 درصد بود. این به این معنی است که مدل ما بیش از حد مناسب است روی مجموعه آموزشی اضافه کردن زمانی اتفاق می افتد که مدل شما عملکرد بهتری داشته باشد روی مجموعه آموزشی نسبت به مجموعه تست. در حالت ایده آل، تفاوت عملکرد بین تمرین و مجموعه تست باید حداقل باشد.
بیایید سعی کنیم تفاوت های باخت و دقت را برای مجموعه های آموزشی و تست ترسیم کنیم. اسکریپت زیر را اجرا کنید:
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(('train','test'), loc='upper left')
plt.show()
plt.plot(history.history('loss'))
plt.plot(history.history('val_loss'))
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(('train','test'), loc='upper left')
plt.show()
خروجی:
شما به وضوح می توانید تفاوت های باخت و دقت را بین مجموعه های آموزشی و تست مشاهده کنید.
طبقه بندی متن با شبکه عصبی کانولوشنال
شبکه عصبی کانولوشنال نوعی شبکه است که در درجه اول برای طبقه بندی داده های دو بعدی مانند تصاویر استفاده می شود. یک شبکه کانولوشن سعی می کند ویژگی های خاصی را در یک تصویر در لایه اول پیدا کند. در لایههای بعدی، ویژگیهای شناسایی شده اولیه به یکدیگر متصل میشوند تا ویژگیهای بزرگتری را تشکیل دهند. به این ترتیب کل تصویر شناسایی می شود.
شبکههای عصبی کانولوشنال با دادههای متنی نیز به خوبی کار میکنند. اگرچه دادههای متنی تک بعدی هستند، اما میتوانیم از شبکههای عصبی کانولوشنیک یک بعدی برای استخراج ویژگیها از دادههایمان استفاده کنیم. برای کسب اطلاعات بیشتر در مورد شبکه های عصبی کانولوشن، لطفاً به این مقاله.
بیایید یک شبکه عصبی کانولوشنال ساده با 1 لایه کانولوشن و 1 لایه ادغام ایجاد کنیم. به یاد داشته باشید، کد تا ایجاد لایه embedding یکسان باقی می ماند، پس از ایجاد لایه embedding، کد زیر را اجرا کنید:
model = Sequential()
embedding_layer = Embedding(vocab_size, 100, weights=(embedding_matrix), input_length=maxlen , trainable=False)
model.add(embedding_layer)
model.add(Conv1D(128, 5, activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=('acc'))
در اسکریپت بالا یک مدل متوالی و به دنبال آن یک لایه جاسازی ایجاد می کنیم. این مرحله مشابه کاری است که قبلا انجام داده بودیم. در مرحله بعد، یک لایه کانولوشنیک یک بعدی با 128 ویژگی یا هسته ایجاد می کنیم. اندازه هسته 5 و تابع فعال سازی استفاده شده است sigmoid
. در مرحله بعد، برای کاهش اندازه ویژگی، یک لایه جهانی max pooling اضافه می کنیم. در نهایت یک لایه متراکم با فعال سازی سیگموئید اضافه می کنیم. تالیف process همان است که در بخش قبل بود.
حال بیایید خلاصه مدل خود را ببینیم:
print(model.summary())
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_2 (Embedding) (None, 100, 100) 9254700
_________________________________________________________________
conv1d_1 (Conv1D) (None, 96, 128) 64128
_________________________________________________________________
global_max_pooling1d_1 (Glob (None, 128) 0
_________________________________________________________________
dense_2 (Dense) (None, 1) 129
=================================================================
Total params: 9,318,957
Trainable params: 64,257
Non-trainable params: 9,254,700
می بینید که در مورد بالا نیازی نیست لایه جاسازی خود را صاف کنیم. شما همچنین می توانید متوجه شوید که اندازه ویژگی اکنون با استفاده از لایه ادغام کاهش یافته است.
حال بیایید مدل خود را آموزش دهیم و آن را ارزیابی کنیم روی مجموعه آموزشی این process برای آموزش و آزمایش مدل ما ثابت می ماند. برای این کار می توانیم از fit
و evaluate
روش ها، به ترتیب.
history = model.fit(X_train, y_train, batch_size=128, epochs=6, verbose=1, validation_split=0.2)
score = model.evaluate(X_test, y_test, verbose=1)
اسکریپت زیر نتایج را چاپ می کند:
print("Test Score:", score(0))
print("Test Accuracy:", score(1))
اگر دقت آموزش و تست را با هم مقایسه کنید، خواهید دید که دقت آموزش برای CNN حدود 92 درصد خواهد بود که از دقت آموزش شبکه عصبی ساده بیشتر است. دقت تست برای CNN حدود 82٪ است، که همچنین از دقت تست برای شبکه عصبی ساده که حدود 74٪ بود بیشتر است.
با این حال، مدل CNN ما هنوز بیش از حد مناسب است زیرا تفاوت زیادی بین دقت آموزش و آزمون وجود دارد. بیایید تفاوت از دست دادن و دقت بین مجموعه آموزشی و تست را ترسیم کنیم.
import matplotlib.pyplot as plt
plt.plot(history.history('acc'))
plt.plot(history.history('val_acc'))
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(('train','test'), loc = 'upper left')
plt.show()
plt.plot(history.history('loss'))
plt.plot(history.history('val_loss'))
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(('train','test'), loc = 'upper left')
plt.show()
خروجی:
شما می توانید به وضوح تفاوت از دست دادن و دقت بین قطار و مجموعه تست را ببینید.
بیایید اکنون سومین مدل یادگیری عمیق خود را که یک شبکه عصبی تکراری است آموزش دهیم و ببینیم که آیا میتوانیم از شر بیش از حد برازش خلاص شویم.
طبقه بندی متن با شبکه عصبی تکراری (LSTM)
شبکه عصبی بازگشتی نوعی از شبکه عصبی است که ثابت شده است که با داده های توالی به خوبی کار می کند. از آنجایی که متن در واقع دنباله ای از کلمات است، یک شبکه عصبی تکراری یک انتخاب خودکار برای حل مشکلات مربوط به متن است. در این بخش از LSTM (شبکه حافظه کوتاه مدت بلندمدت) که نوعی از RNN است برای حل مسائل طبقه بندی احساسات استفاده خواهیم کرد.
یک بار دیگر کد را تا قسمت واژه embedding اجرا کنید و پس از آن کد زیر را اجرا کنید.
model = Sequential()
embedding_layer = Embedding(vocab_size, 100, weights=(embedding_matrix), input_length=maxlen , trainable=False)
model.add(embedding_layer)
model.add(LSTM(128))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=('acc'))
در اسکریپت بالا، ما با مقداردهی اولیه یک مدل متوالی و سپس ایجاد لایه embedding شروع می کنیم. بعد، یک لایه LSTM با 128 نورون ایجاد می کنیم (شما می توانید با تعداد نورون ها بازی کنید). مابقی کد همان چیزی است که برای CNN بود.
بیایید خلاصه مدل خود را ترسیم کنیم.
print(model.summary())
خلاصه مدل به این صورت است:
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_3 (Embedding) (None, 100, 100) 9254700
_________________________________________________________________
lstm_1 (LSTM) (None, 128) 117248
_________________________________________________________________
dense_3 (Dense) (None, 1) 129
=================================================================
Total params: 9,372,077
Trainable params: 117,377
Non-trainable params: 9,254,700
قدم بعدی ما آموزش مدل است روی مجموعه آموزشی و ارزیابی عملکرد آن روی مجموعه تست
history = model.fit(X_train, y_train, batch_size=128, epochs=6, verbose=1, validation_split=0.2)
score = model.evaluate(X_test, y_test, verbose=1)
اسکریپت بالا مدل را آموزش می دهد روی مجموعه تست اندازه دسته 128 است در حالی که تعداد دوره ها 6 است. در پایان آموزش خواهید دید که دقت آموزش حدود 85.40 درصد است.
هنگامی که مدل آموزش داده شد، می توانیم نتایج مدل را مشاهده کنیم روی مجموعه تست با اسکریپت زیر:
print("Test Score:", score(0))
print("Test Accuracy:", score(1))
در خروجی خواهید دید که دقت تست ما حدود 85.04 درصد است. دقت تست هم از CNN و هم از شبکه عصبی با اتصال متراکم بهتر است. همچنین، می بینیم که تفاوت بسیار کمی بین دقت تمرین و دقت تست وجود دارد که به این معنی است که مدل ما بیش از حد مناسب نیست.
بیایید تفاوتهای از دست دادن و دقت بین مجموعههای آموزشی و تست را ترسیم کنیم.
import matplotlib.pyplot as plt
plt.plot(history.history('acc'))
plt.plot(history.history('val_acc'))
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(('train','test'), loc='upper left')
plt.show()
plt.plot(history.history('loss'))
plt.plot(history.history('val_loss'))
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(('train','test'), loc='upper left')
plt.show()
خروجی:
خروجی نشان می دهد که تفاوت بین مقادیر دقت برای مجموعه های آموزشی و آزمایشی در مقایسه با شبکه عصبی ساده و CNN بسیار کوچکتر است. به طور مشابه، تفاوت بین مقادیر ضرر نیز ناچیز است، که نشان می دهد مدل ما بیش از حد مناسب نیست. می توانیم نتیجه بگیریم که برای مشکل ما، RNN بهترین الگوریتم است.
در این مقاله به طور تصادفی تعداد لایه ها، نورون ها، پارامترهای هایپر و … را انتخاب کردیم. پیشنهاد می کنم سعی کنید تعداد لایه ها، تعداد نورون ها و توابع فعال سازی را برای هر سه شبکه عصبی مورد بحث در این مقاله تغییر دهید و ببینید کدام یک شبکه عصبی بهترین کار را برای شما دارد.
پیشگویی روی نمونه واحد
این بخش پایانی مقاله است و در اینجا روش پیشبینی را خواهیم دید روی یک نمونه یا احساس واحد. بیایید هر بررسی را از مجموعه خود بازیابی کنیم و سپس سعی کنیم احساسات آن را پیش بینی کنیم.
بیایید ابتدا به طور تصادفی هر بررسی را از مجموعه خود انتخاب کنیم:
instance = X(57)
print(instance)
خروجی:
I laughed all the way through this rotten movie It so unbelievable woman leaves her husband after many years of marriage has breakdown in front of real estate office What happens The office manager comes outside and offers her job Hilarious Next thing you know the two women are going at it Yep they re lesbians Nothing rings true in this Lifetime for Women with nothing better to do movie Clunky dialogue like don want to spend the rest of my life feeling like had chance to be happy and didn take it doesn help There a wealthy distant mother who disapproves of her daughter new relationship sassy black maid unbelievable that in the year film gets made in which there a sassy black maid Hattie McDaniel must be turning in her grave The woman has husband who freaks out and wants custody of the snotty teenage kids Sheesh No cliche is left unturned
شما به وضوح می بینید که این یک بررسی منفی است. برای پیش بینی احساس این بررسی، باید این بررسی را به شکل عددی تبدیل کنیم. ما می توانیم این کار را با استفاده از tokenizer
که در قسمت word embedding ایجاد کردیم. این text_to_sequences
روش جمله را به همتای عددی خود تبدیل می کند.
در مرحله بعد، باید دنباله ورودی خود را مانند پیکره خود اضافه کنیم. در نهایت می توانیم از predict
روش مدل ما و آن را به دنباله ورودی پردازش شده ما ارسال کنید. به کد زیر نگاه کنید:
instance = tokenizer.texts_to_sequences(instance)
flat_list = ()
for sublist in instance:
for item in sublist:
flat_list.append(item)
flat_list = (flat_list)
instance = pad_sequences(flat_list, padding='post', maxlen=maxlen)
model.predict(instance)
خروجی به شکل زیر است:
array(((0.3304276)), dtype=float32)
به یاد داشته باشید، ما خروجی های مثبت را به 1 و خروجی های منفی را به 0 نگاشت کردیم. با این حال، تابع سیگموئید مقادیر شناور بین 0 و 1 را پیش بینی می کند. اگر مقدار کمتر از 0.5 باشد، احساسات منفی در نظر گرفته می شود در حالی که اگر مقدار بیشتر از 0.5 باشد. ، این احساس مثبت در نظر گرفته می شود. مقدار احساسات برای نمونه واحد ما 0.33 است که به این معنی است که احساسات ما منفی پیش بینی می شود، که در واقع همینطور است.
نتیجه
طبقه بندی متن یکی از رایج ترین کارهای پردازش زبان طبیعی است. در این مقاله روش انجام تحلیل احساسات را دیدیم که نوعی طبقه بندی متن با استفاده از کتابخانه یادگیری عمیق Keras است. ما از سه نوع مختلف شبکه عصبی برای طبقه بندی احساسات عمومی در مورد فیلم های مختلف استفاده کردیم. نتایج نشان میدهد که LSTM، که نوعی از RNN است، هم از CNN و هم از شبکه عصبی ساده بهتر عمل میکند.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-21 07:09:03