از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
پایتون برای NLP: مدلسازی موضوع
سرفصلهای مطلب
این ششمین مقاله از سری مقالات من است روی پایتون برای NLP. در مقاله قبلی خود، در مورد چگونگی انجام تجزیه و تحلیل احساسات داده های توییتر با استفاده از کتابخانه Scikit-Learn پایتون صحبت کردم. در این مقاله به بررسی مدل سازی موضوع می پردازیم که یکی دیگر از کاربردهای بسیار مهم NLP است. خواهیم دید که چگونه می توان مدل سازی موضوع را با پایتون انجام داد.
مدلسازی موضوع چیست؟
مدلسازی موضوع یک تکنیک بدون نظارت است که قصد دارد حجم زیادی از دادههای متنی را با خوشهبندی اسناد در گروهها تجزیه و تحلیل کند. در مورد مدلسازی موضوع، دادههای متنی هیچ برچسبی به آن متصل نیستند. در عوض، مدلسازی موضوع سعی میکند اسناد را در خوشهها گروهبندی کند روی ویژگی های مشابه
یک مثال معمولی از مدلسازی موضوع، خوشهبندی تعداد زیادی از مقالات روزنامهای است که به همان دسته تعلق دارند. به عبارت دیگر، اسنادی را که موضوع یکسانی دارند، خوشه بندی کنید. در اینجا ذکر این نکته ضروری است که ارزیابی عملکرد مدل سازی موضوع بسیار دشوار است زیرا پاسخ درستی وجود ندارد. این بستگی به کاربر دارد که ویژگی های مشابهی را بین اسناد یک خوشه بیابد و یک برچسب یا موضوع مناسب به آن اختصاص دهد.
دو رویکرد عمدتا برای مدل سازی موضوع استفاده می شود: تخصیص دیریکله نهفته و فاکتورسازی ماتریس غیر منفی. در بخشهای بعدی، هر دوی این رویکردها را به اختصار بررسی خواهیم کرد و خواهیم دید که چگونه میتوان آنها را برای مدلسازی موضوع در پایتون به کار برد.
تخصیص دیریکله نهفته (LDA)
LDA بر دو فرض کلی استوار است:
- اسنادی که دارای کلمات مشابه هستند معمولاً موضوع یکسانی دارند
- اسنادی که دارای گروههایی از کلمات هستند که اغلب در کنار هم قرار میگیرند، معمولاً موضوع یکسانی دارند.
این مفروضات منطقی هستند زیرا اسنادی که موضوع یکسانی دارند، به عنوان مثال، موضوعات تجاری دارای کلماتی مانند “اقتصاد”، “سود”، “بازار سهام”، “زیان” و غیره خواهند بود. فرض دوم بیان می کند که اگر این موارد کلمات اغلب با هم در چندین سند وجود دارند، آن اسناد ممکن است متعلق به یک دسته باشند.
از نظر ریاضی، دو فرض بالا را می توان به صورت زیر نشان داد:
- اسناد توزیع احتمال بر روی موضوعات پنهان هستند
- موضوعات توزیع احتمال بر روی کلمات هستند
LDA برای مدل سازی موضوع در پایتون
در این بخش خواهیم دید که چگونه می توان از پایتون برای پیاده سازی LDA برای مدل سازی موضوع استفاده کرد. مجموعه داده ها را می توان از کاگل.
مجموعه داده شامل نظرات کاربران برای محصولات مختلف در دسته مواد غذایی است. ما از LDA برای گروه بندی نظرات کاربران در 5 دسته استفاده می کنیم.
اولین قدم، مثل همیشه، این است که import مجموعه داده ها به همراه کتابخانه های مورد نیاز برای این کار اسکریپت زیر را اجرا کنید:
import pandas as pd
import numpy as np
reviews_datasets = pd.read_csv(r'E:\Datasets\Reviews.csv')
reviews_datasets = reviews_datasets.head(20000)
reviews_datasets.dropna()
در اسکریپت بالا ما import مجموعه داده با استفاده از read_csv
روش کتابخانه پانداها مجموعه داده اصلی شامل حدود 500 هزار بررسی است. با این حال، به دلیل محدودیت حافظه، من فقط LDA را انجام خواهم داد روی 20 هزار رکورد اول در اسکریپت بالا ما 20 هزار ردیف اول را فیلتر کرده و سپس مقادیر null را از مجموعه داده حذف می کنیم.
بعد، ما print پنج ردیف اول مجموعه داده با استفاده از head()
عملکرد بازرسی داده های ما:
reviews_datasets.head()
در خروجی داده های زیر را مشاهده خواهید کرد:
ما LDA را اعمال خواهیم کرد روی ستون “متن” از آنجایی که حاوی نظرات است، بقیه ستون ها نادیده گرفته می شوند.
بیایید بررسی شماره 350 را ببینیم.
reviews_datasets('Text')(350)
در خروجی، متن بررسی زیر را مشاهده خواهید کرد:
'These chocolate covered espresso beans are wonderful! The chocolate is very dark and rich and the "bean" inside is a very delightful blend of flavors with just enough caffine to really give it a zing.'
قبل از اینکه بتوانیم LDA را اعمال کنیم، باید واژگانی از تمام کلمات موجود در داده های خود ایجاد کنیم. از مقاله قبلی به یاد داشته باشید، ما میتوانیم این کار را با کمک بردار شمارش انجام دهیم. به اسکریپت زیر نگاه کنید:
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer(max_df=0.8, min_df=2, stop_words='english')
doc_term_matrix = count_vect.fit_transform(reviews_datasets('Text').values.astype('U'))
در اسکریپت بالا ما از CountVectorizer
کلاس از sklearn.feature_extraction.text
ماژول برای ایجاد یک ماتریس سند-ترم. ما مشخص می کنیم که فقط کلماتی را که در کمتر از 80٪ سند ظاهر می شوند و حداقل در 2 سند ظاهر می شوند شامل شود. ما همچنین تمام کلمات توقف را حذف می کنیم زیرا آنها واقعاً به مدل سازی موضوع کمک نمی کنند.
حالا بیایید به ماتریس اصطلاح سند خود نگاه کنیم:
doc_term_matrix
خروجی:
<20000x14546 sparse matrix of type '<class 'numpy.int64'>'
with 594703 stored elements in Compressed Sparse Row format>
هر یک از 20 هزار سند به صورت بردار 14546 بعدی نشان داده می شود، به این معنی که واژگان ما دارای 14546 کلمه است.
در مرحله بعد، از LDA برای ایجاد موضوعات به همراه توزیع احتمال برای هر کلمه در واژگان خود برای هر موضوع استفاده خواهیم کرد. اسکریپت زیر را اجرا کنید:
from sklearn.decomposition import LatentDirichletAllocation
LDA = LatentDirichletAllocation(n_components=5, random_state=42)
LDA.fit(doc_term_matrix)
در اسکریپت بالا ما از LatentDirichletAllocation
کلاس از sklearn.decomposition
کتابخانه برای انجام LDA روی ماتریس سند – مدت ما پارامتر n_components
تعداد دسته ها یا موضوعاتی را مشخص می کند که می خواهیم متن ما به آنها تقسیم شود. پارامتر random_state
(معروف به دانه) روی 42 تنظیم شده است تا نتایجی مشابه من بدست آورید.
بیایید به طور تصادفی کلمات را از دایره لغات خود بیاوریم. می دانیم که count vectorizer تمام کلمات موجود در واژگان ما را شامل می شود. ما می توانیم استفاده کنیم get_feature_names()
روش و شناسه کلمه ای را که می خواهیم واکشی کنیم به آن ارسال کنید.
اسکریپت زیر به طور تصادفی 10 کلمه را از واژگان ما می آورد:
import random
for i in range(10):
random_id = random.randint(0,len(count_vect.get_feature_names()))
print(count_vect.get_feature_names()(random_id))
خروجی به شکل زیر است:
bribe
tarragon
qualifies
prepare
hangs
noted
churning
breeds
zon
chunkier
بیایید 10 کلمه با بیشترین احتمال برای موضوع اول پیدا کنیم. برای دریافت موضوع اول می توانید از components_
ویژگی و یک شاخص 0 را به عنوان مقدار ارسال کنید:
first_topic = LDA.components_(0)
مبحث اول شامل احتمالات 14546 کلمه برای مبحث 1 است. برای مرتب سازی شاخص ها بر اساس مقادیر احتمال، می توانیم از argsort()
تابع. پس از مرتب سازی، 10 کلمه با بالاترین احتمال اکنون به 10 نمایه آخر آرایه تعلق دارند. اسکریپت زیر نمایه های 10 کلمه با بیشترین احتمال را برمی گرداند:
top_topic_words = first_topic.argsort()(-10:)
خروجی:
array((14106, 5892, 7088, 4290, 12596, 5771, 5187, 12888, 7498,
12921), dtype=int64)
سپس می توان از این شاخص ها برای بازیابی ارزش کلمات از قسمت استفاده کرد count_vect
شی، که می تواند به صورت زیر انجام شود:
for i in top_topic_words:
print(count_vect.get_feature_names()(i))
در خروجی باید کلمات زیر را ببینید:
water
great
just
drink
sugar
good
flavor
taste
like
tea
کلمات نشان می دهند که اولین موضوع ممکن است در مورد چای باشد.
اجازه دهید print 10 کلمه با بیشترین احتمال برای هر پنج موضوع:
for i,topic in enumerate(LDA.components_):
print(f'Top 10 words for topic #{i}:')
print((count_vect.get_feature_names()(i) for i in topic.argsort()(-10:)))
print('\n')
خروجی به شکل زیر است:
Top 10 words for topic #0:
('water', 'great', 'just', 'drink', 'sugar', 'good', 'flavor', 'taste', 'like', 'tea')
Top 10 words for topic #1:
('br', 'chips', 'love', 'flavor', 'chocolate', 'just', 'great', 'taste', 'good', 'like')
Top 10 words for topic #2:
('just', 'drink', 'orange', 'sugar', 'soda', 'water', 'like', 'juice', 'product', 'br')
Top 10 words for topic #3:
('gluten', 'eat', 'free', 'product', 'like', 'dogs', 'treats', 'dog', 'br', 'food')
Top 10 words for topic #4:
('cups', 'price', 'great', 'like', 'amazon', 'good', 'br', 'product', 'cup', 'coffee')
خروجی نشان میدهد که مبحث دوم ممکن است حاوی نظراتی درباره شکلاتها و غیره باشد. می بینید که چند کلمه رایج در همه دسته ها وجود دارد. این به این دلیل است که کلمات کمی وجود دارد که تقریباً برای همه موضوعات استفاده می شود. به عنوان مثال “خوب”، “عالی”، “مانند” و غیره.
به عنوان آخرین مرحله، یک ستون به قاب داده اصلی اضافه می کنیم که موضوع را برای متن ذخیره می کند. برای این کار می توانیم استفاده کنیم LDA.transform()
روش و ماتریس سند-ترم خود را ارسال کنید. این روش احتمال تمام موضوعات را به هر سند اختصاص می دهد. به کد زیر نگاه کنید:
topic_values = LDA.transform(doc_term_matrix)
topic_values.shape
در خروجی، (20000، 5) را خواهید دید که به این معنی است که هر یک از سند دارای 5 ستون است که هر ستون با مقدار احتمال یک موضوع خاص مطابقت دارد. برای پیدا کردن شاخص موضوع با حداکثر مقدار، میتوانیم آن را فراخوانی کنیم argmax()
روش و عدد 1 را به عنوان مقدار پارامتر محور ارسال کنید.
اسکریپت زیر یک ستون جدید برای موضوع در قاب داده اضافه می کند و مقدار موضوع را به هر سطر در ستون اختصاص می دهد:
reviews_datasets('Topic') = topic_values.argmax(axis=1)
حال بیایید ببینیم مجموعه داده چگونه به نظر می رسد:
reviews_datasets.head()
خروجی:
شما می توانید یک ستون جدید برای موضوع در خروجی ببینید.
فاکتورسازی ماتریس غیر منفی (NMF)
در بخش قبل، دیدیم که چگونه می توان از LDA برای مدل سازی موضوع استفاده کرد. در این بخش خواهیم دید که چگونه می توان از فاکتورسازی ماتریس غیر منفی برای مدل سازی موضوع استفاده کرد.
فاکتورسازی ماتریس غیر منفی نیز یک تکنیک یادگیری نظارت شده است که خوشه بندی و همچنین کاهش ابعاد را انجام می دهد. می توان از آن در ترکیب با طرح TF-IDF برای انجام مدل سازی موضوع استفاده کرد. در این بخش خواهیم دید که چگونه می توان از پایتون برای انجام فاکتورسازی ماتریس غیر منفی برای مدل سازی موضوع استفاده کرد.
NMF برای مدل سازی موضوع در پایتون
در این قسمت مدل سازی موضوع را انجام می دهیم روی همان مجموعه داده ای که در بخش آخر استفاده کردیم. خواهید دید که مراحل نیز کاملا مشابه هستند.
ما با وارد کردن مجموعه داده ها شروع می کنیم:
import pandas as pd
import numpy as np
reviews_datasets = pd.read_csv(r'E:\Datasets\Reviews.csv')
reviews_datasets = reviews_datasets.head(20000)
reviews_datasets.dropna()
در قسمت قبل از thee count vectorizer استفاده کردیم، اما در این بخش از TFIDF vectorizer استفاده می کنیم زیرا NMF با TFIDF کار می کند. ما یک ماتریس اصطلاح سند با TFIDF ایجاد خواهیم کرد. به اسکریپت زیر نگاه کنید:
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vect = TfidfVectorizer(max_df=0.8, min_df=2, stop_words='english')
doc_term_matrix = tfidf_vect.fit_transform(reviews_datasets('Text').values.astype('U'))
هنگامی که ماتریس اصطلاح سند ایجاد شد، میتوانیم یک ماتریس احتمال ایجاد کنیم که شامل احتمالات همه کلمات در واژگان برای همه موضوعات است. برای این کار می توانیم از NMF
کلاس از sklearn.decomposition
مدول. به اسکریپت زیر نگاه کنید:
from sklearn.decomposition import NMF
nmf = NMF(n_components=5, random_state=42)
nmf.fit(doc_term_matrix )
همانطور که در بخش قبل انجام دادیم، بیایید به طور تصادفی 10 کلمه از واژگان خود را بدست آوریم:
import random
for i in range(10):
random_id = random.randint(0,len(tfidf_vect.get_feature_names()))
print(tfidf_vect.get_feature_names()(random_id))
در خروجی، کلمات زیر را مشاهده خواهید کرد:
safest
pith
ache
formula
fussy
frontier
burps
speaker
responsibility
dive
در مرحله بعد، بردار احتمال کلمات را برای مبحث اول بازیابی می کنیم و شاخص های ده کلمه با بیشترین احتمال را بازیابی می کنیم:
first_topic = nmf.components_(0)
top_topic_words = first_topic.argsort()(-10:)
اکنون می توان این شاخص ها را به tfidf_vect
برای بازیابی کلمات واقعی اعتراض کنید. به اسکریپت زیر نگاه کنید:
for i in top_topic_words:
print(tfidf_vect.get_feature_names()(i))
خروجی به شکل زیر است:
really
chocolate
love
flavor
just
product
taste
great
good
like
کلمات موضوع 1 نشان می دهد که موضوع 1 ممکن است حاوی نظراتی برای شکلات باشد. حالا بیایید print ده کلمه با بیشترین احتمال برای هر یک از موضوعات:
for i,topic in enumerate(nmf.components_):
print(f'Top 10 words for topic #{i}:')
print((tfidf_vect.get_feature_names()(i) for i in topic.argsort()(-10:)))
print('\n')
خروجی اسکریپت بالا به شکل زیر است:
Top 10 words for topic #0:
('really', 'chocolate', 'love', 'flavor', 'just', 'product', 'taste', 'great', 'good', 'like')
Top 10 words for topic #1:
('like', 'keurig', 'roast', 'flavor', 'blend', 'bold', 'strong', 'cups', 'cup', 'coffee')
Top 10 words for topic #2:
('com', 'amazon', 'orange', 'switch', 'water', 'drink', 'soda', 'sugar', 'juice', 'br')
Top 10 words for topic #3:
('bags', 'flavor', 'drink', 'iced', 'earl', 'loose', 'grey', 'teas', 'green', 'tea')
Top 10 words for topic #4:
('old', 'love', 'cat', 'eat', 'treat', 'loves', 'dogs', 'food', 'treats', 'dog')
کلمات مربوط به مبحث 1 نشان می دهد که این موضوع حاوی نظراتی در مورد قهوه است. به طور مشابه، واژههای مبحث 2 نشان میدهد که حاوی نظراتی درباره نوشابهها و آبمیوهها است. موضوع 3 دوباره حاوی نظراتی در مورد نوشیدنی است. در نهایت، مبحث 4 ممکن است حاوی نظراتی در مورد غذای حیوانات باشد زیرا حاوی کلماتی مانند “گربه”، “سگ”، “درمان” و غیره است.
اسکریپت زیر موضوعات را به مجموعه داده اضافه می کند و پنج ردیف اول را نمایش می دهد:
topic_values = nmf.transform(doc_term_matrix)
reviews_datasets('Topic') = topic_values.argmax(axis=1)
reviews_datasets.head()
خروجی کد بالا به شکل زیر است:
همانطور که می بینید به هر بررسی یک موضوع اختصاص داده شده است که با استفاده از روش NMF ایجاد شده است.
نتیجه
مدلسازی موضوع یکی از حوزههای تحقیقاتی بسیار مورد توجه در NLP است. برای گروه بندی حجم زیادی از داده های متنی بدون برچسب استفاده می شود. در این مقاله دو رویکرد برای مدل سازی موضوعی توضیح داده شده است. در این مقاله دیدیم که چگونه می توان از تخصیص دیریکله پنهان و فاکتورسازی ماتریس غیر منفی برای مدل سازی موضوع با کمک کتابخانه های پایتون استفاده کرد.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-23 18:04:03