محاسبه مشابهت متن با Gensim — راهنمای کاربردی

۴۸۴ بازدید
آخرین به‌روزرسانی: ۳۱ خرداد ۱۴۰۲
زمان مطالعه: ۲۳ دقیقه
محاسبه مشابهت متن با Gensim — راهنمای کاربردی

«ژنیسم» (Gensim) یک کتابخانه «زبان برنامه‌نویسی پایتون» (Python Programming Language) برای مدل‌سازی موضوعی، اندیس‌گذاری اسناد و «بازیابی مشابهت» (Similarity Retrieval) است. مخاطبان هدف این کتابخانه پایتون، افرادی هستند که به زمینه‌های «پردازش زبان طبیعی» (Natural Language Processing | NLP) و یا «بازیابی اطلاعات» (Information Retrieval | IR) علاقه‌مند و در آن‌ها مشغول به فعالیت هستند. در این مطلب، روش محاسبه مشابهت متن با Gensim مورد بررسی قرار گرفته است.

کتابخانه Gensim

همانطور که پیش از این نیز بیان شد، Gensim یک کتابخانه برای زبان برنامه‌نویسی پایتون است. این کتابخانه «متن‌باز» (Open Source) برای پردازش زبان طبیعی و بازیابی اطلاعات مورد استفاده قرار می‌گیرد. Gensim ساخته شده است تا به طور خودکار «موضوعات معنایی» (Semantic Topics) را از اسناد، تا حد ممکن به صورت کارا (کامپیوتر-آگاه) و بدون سختی (انسان-آگاه)، خارج کند.

در واقع، کتابخانه Gensim ساخته شده تا داده‌های دیجیتال خام و ساختار نیافته (Plain Text) را پردازش کند. در ادامه، برخی از مهم‌ترین ویژگی‌های کتابخانه پایتون Gensim بیان شده است.

  • همه الگوریتم‌های موجود در کتابخانه Gensim، با توجه به اندازه «بدنه متن» (Corpus)، «مستقل از حافظه» (Memory Independant) هستند. در واقع، ورودی فرایند می‌تواند از RAM بیشتر، جریانی و خارج از هسته باشد.
  • وارد کردن بدنه متن و یا جریان داده مورد نظر کاربر به این کتابخانه آسان است (رابط برنامه‌نویسی کاربردی برای استریم کردن).
  • امکان گسترش دادن این کتابخانه با استفاده از دیگر الگوریتم‌های فضای برداری آسان است (رابط برنامه‌نویسی کاربردی برای تبدیل)
  • پیاده‌سازی کارا و چند هسته‌ای الگوریتم‌های محبوبی مانند «آنالیز پنهان مفهومی» (Latent Semantic Analysis | در فارسی به آن آنالیز مفاهیم نهفته نیز گفته می‌شود) به صورت آنلاین (شامل الگوریتم‌های LSI ،LSA و SVD)، «تخصیص پنهان دیریکله» (Latent Dirichlet Allocation | LDA)، «تصویر تصادفی» (Random Projection | RP)، «فرایند دیریکله سلسله‌مراتبی» (Hierarchical Dirichlet Process | HDP) یا «یادگیری عمیق word2vec» در این کتابخانه پایتون ویژه پردازش زبان طبیعی و بازیابی اطلاعات، وجود دارد.
  • امکان انجام کارها با رویکرد محاسبات توزیع شده (Distributed Computing) وجود دارد. در واقع، می‌توان الگوریتم‌های آنالیز پنهان مفهومی و تخصیص پنهان دیریکله را روی خوشه‌ای از کامپیوترها پیاده‌سازی کرد.
  • راهنماهای گسترده و همچنین، راهنماهای «ژوپیتر نوت‌بوک» (Jupyter Notebook) برای کتابخانه پایتون Gensim وجود دارد.

آنچه بیان شد، تنها برخی از ویژگی‌ها و مزایای قابل توجه کتابخانه پردازش زبان طبیعی و بازیابی اطلاعات Gensim محسوب می‌شود.

روش نصب کتابخانه Gensim

این کتابخانه، وابسته به کتابخانه‌های «نام‌پای» (NumPy) و «سای‌پای» (SciPy) است. دو کتابخانه یاد شده، از بسته‌های (Packages) علمی پایتون برای محاسبات علمی محسوب می‌شوند. کاربر برای استفاده از کتابخانه Gensim، ابتدا باید حتما دو کتابخانه مذکور را نصب داشته باشد.

همچنین، توصیه می‌شود تا کاربران کتابخانه سریع BLAS را نیز پیش از نصب نام‌پای، نصب داشته باشند. انجام این کار اختیاری است؛ اما استفاده از یک BLAS بهینه مانند ATLAS یا OpenBLAS راهکاری برای ارتقای کارایی است. در سیستم‌عامل OS X، کتابخانه نام‌پای به طور پیش‌فرض همراه با BLAS ارائه می‌شود، بنابراین نیازی به انجام کار خاصی در این راستا نیست. روش نصب کتابخانه پایتون Gensim بسیار ساده است و در ادامه به طور کامل بیان شده است. در این راستا، کافی است دستور زیر در شل وارد شود.

1pip install -U gensim

یا اگر کاربر از قبل فایل کتابخانه Gensim را دانلود و ازحالت زیپ خارج کرده باشد، می‌تواند از دستورات زیر برای نصب استفاده کند.

1python setup.py test
2python setup.py install

برای حالت‌های جایگزین نصب (بدون نیاز به دسترسی ریشه، نصب توسعه، ویژگی‌های اختیاری نصب)، مطالعه مستندات این کتابخانه توصیه می‌شود. این کتابخانه هم با پایتون ۲ و هم پایتون ۳ کار می‌کند.

دلایل سرعت و کارایی بالای کتابخانه Gensim

بسیاری از الگوریتم‌های علمی را می‌توان با عملیات ماتریسی توصیف کرد. کتابخانه Gensim با کتابخانه‌های سطح پایینی مانند BLAS رقابت می‌کند، زیرا وابسته به نام‌پای است. بنابراین، با وجود آنکه بسیاری از کدهای سطح بالای آن پایتون هستند، اما در واقع کد C/فرترن بسیار بهینه‌ای را در پس پرده اجرا می‌کند که شامل «چندریسمانی» (چندریسگی | چند نخی | Multithreading) می‌شود.

Gensim حافظه-آگاه (Memory-Wise) استفاده‌های قابل توجهی از «مولدها» (Generators) و «تکرارگرهای» (Iterators) برای پردازش داده‌های جریانی دارد. کارایی بالای حافظه یکی از اهداف اصلی ضمن طراحی کتابخانه پردازش زبان طبیعی و بازیابی اطلاعات Gensim بوده است و ویژگی کلیدی این کتابخانه محسوب می‌شود.

روش ارجاع به کتابخانه Gensim

همانطور که پیش از این بیان شد، کتابخانه Gensim متن‌باز است. این کتابخانه با گواهینامه گنو LGPLv2.1 منتشر می‌شود. به این کتابخانه می‌توان به صورت زیر ارجاع داد.

1@inproceedings{rehurek_lrec,
2      title = {{Software Framework for Topic Modelling with Large Corpora}},
3      author = {Radim {\v R}eh{\r u}{\v r}ek and Petr Sojka},
4      booktitle = {{Proceedings of the LREC 2010 Workshop on New
5           Challenges for NLP Frameworks}},
6      pages = {45--50},
7      year = 2010,
8      month = May,
9      day = 22,
10      publisher = {ELRA},
11      address = {Valletta, Malta},

مفاهیم کلیدی مورد نیاز ضمن کار با کتابخانه Gensim

بدنه متن (Corpus) برای آموزش دادن یک مدل یادگیری ماشین در Gensim مورد استفاده قرار می‌گیرد. مدل‌ها از بدنه متن برای مقداردهی اولیه پارامترها برای مدل، استفاده می‌کنند.

مدل فضای برداری (Vector Space Model)

هر سندی با یک آرایه از ویژگی‌هل ارائه می‌شود و می‌توان به ویژگی‌ها به عنوان یک جفت پرسش و پاسخ نگریست. مثالی از یک ویژگی به صورت زیر است:

کلمه «happy» چند بار در سند متنی ظاهر شده است؟ سه بار.

(How many times does the word “happy” appear in the text document? Three.)

پرسش با شناسه و یا همان ID آن (عدد صحیح | Integer) مشخص می‌شود و بنابراین ارائه متن به صورت یک سری از جفت‌ها مانند (2,4.0)، (3,6.0)، (4,5.0) انجام می‌شود. این سری را می‌توان یک «بردار» (Vector) در نظر گرفت. اگر بردارهای دو سند مشابه باشند، سندها نیز باید مشابه باشند.

بردار خلوت (Sparse Vector)

سندها در Gensim با استفاده از «بردارهای خلوت» (Sparse Vector | بردار اسپارس) نمایش داده می‌شوند. کتابخانه Gensim، همه بردارهای دارای مقدار ۰.۰ را حذف می‌کند و هر بردار یک جفت از (شناسه ویژگی، مقدار ویژگی) یا همان (feature_id, feature_value) است.

مدل (Model)

یک مدل را می‌توان به عنوان تبدیلی از یک فضای برداری به فضای برداری دیگر در نظر گرفت. با آموزش دادن بدنه، پارامترهای این تبدیل، یاد گرفته می‌شوند.

محاسبه مشابهت متن با Gensim

در ادامه، مثال ساده‌ای از کد پایتون پیاده شده با کتابخانه Gensim ارائه شده است. این کد، مشابهت متن‌هایی که به آن ورودی به آن داده شده است را تعیین می‌کند.

در اینجا، jieba  ماژول پایتون برای قطعه‌بندی متن، برای شکستن کلمات در قطعات، برای ساده کردن تحلیل‌های مشابهت متنی است که روی متن انجام خواهد شد.

1from gensim import corpora, models, similarities
2import jieba
3texts = ['I love reading Japanese novels. My favorite Japanese writer is Tanizaki Junichiro.', 'Natsume Soseki is a well-known Japanese novelist and his Kokoro is a masterpiece.', 'American modern poetry is good. ']
4keyword = 'Japan has some great novelists. Who is your favorite Japanese writer?'
5texts = [jieba.lcut(text) for text in texts]
6dictionary = corpora.Dictionary(texts)
7feature_cnt = len(dictionary.token2id)
8corpus = [dictionary.doc2bow(text) for text in texts]
9tfidf = models.TfidfModel(corpus) 
10kw_vector = dictionary.doc2bow(jieba.lcut(keyword))
11index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features = feature_cnt)
12sim = index[tfidf[kw_vector]]
13for i in range(len(sim)):
14    print('keyword is similar to text%d: %.2f' % (i + 1, sim[i]))

خروجی نتایج قطعه کد بالا، به صورت زیر است.

keyword is similar to text1: 0.50
keyword is similar to text2: 0.02
keyword is similar to text3: 0.00

توضیح چگونگی کدنویسی با Gensim

در ادامه، روش کد نویسی با کتابخانه پردازش زبان طبیعی و بازیابی اطلاعات Gensim به صورت گام به گام، همراه با ارائه توضیحاتی پیرامون عملکرد هر قطعه کد، آموزش داده می‌شود.

گام اول: قطعه‌بندی کلمه با استفاده از Jieba

ابتدا، نگاهی به چگونگی کار کردن jieba انداخته می‌شود. در اینجا، هدف قطعه‌بندی یک جمله از رمان «نائومی» (Naomi | عشق پلید) است که توسط نویسنده محبوب ژاپنی به نام «جون‌ایچیرو تانیزاکی» (Jun'ichirō Tanizaki) نوشته شده است.

1import jieba 
2text = ‘I wanted to boast to everyone. This woman is mine. Take a look at my treasure.3words = jieba.lcut(text)
4print(words)

خروجی قطعه کد بالا، به صورت زیر است.

[‘I’, ‘wanted’, ‘to’, ‘boast’, ‘to’, ‘everyone’, ‘.’, ‘This’, ‘woman’, ‘is’, ‘mine’, ‘.’, ‘Take’, ‘a’, ‘look’, ‘at’, ‘my’, ‘treasure’, ‘.’]

گام دوم: به دست آوردن تعداد ویژگی‌ها بر اساس dictionary

corpora.Dictionary یک دیکشنری می‌سازد. len(dictionary.token2id)‎ تعداد کلمات موجود در دیکشنری را نشان می‌دهد. مثالی از این مورد در ادامه آمده است.

1from gensim import corpora
2import jieba
3
4text1 = ‘痴人の愛’
5text2 = ‘よく世間では「女が男を欺す」と云います。’
6texts = [text1, text2]
7# Generate a word list for the text set
8texts = [jieba.lcut(text) for text in texts]
9print(‘Text set:, texts)
10#Build a dictionary based on a text set
11dictionary = corpora.Dictionary(texts)
12print(‘dictionary:, dictionary)
13# Extract dictionary features
14feature_cnt = len(dictionary.token2id)
15print(‘Dictionary feature number: %d’ % feature_cnt)

خروجی قطعه کد بالا به صورت زیر است.

Text set: [['痴人', 'の', '愛'], ['よ', 'く', '世間', 'で', 'は', '「', '女', 'が', '男', 'を', '欺', 'す', '」', 'と', '云', 'い', 'ま', 'す', '。']]
dictionary: Dictionary(21 unique tokens: ['の', '愛', '痴人', '。', '「']...)
Dictionary feature number: 21

گام سوم: به دست آوردن بدنه متن بر اساس دیکشنری

با استفاده از قطعه کد زیر‌، می‌توان بدنه متن را بر اساس دیکشنری به دست آورد.

1from gensim import corpora
2import jieba
3text1 = 'I love Tokyo'
4text2 = 'Tokyo, Tokyo, Tokyo'
5texts = [text1, text2]
6texts = [jieba.lcut(text) for text in texts]
7dictionary = corpora.Dictionary(texts)
8corpus = [dictionary.doc2bow(text) for text in texts]
9print('Dictionary (dictionary):', dictionary.token2id)
10print('Corpus: ', corpus)

خروجی قطعه کد بالا، به صورت زیر است.

Dictionary (dictionary): {' ': 0, 'Come': 1, 'Tokyo': 2, 'cuisine': 3, 'for': 4, 'to': 5, ',': 6}
Corpus: [[(0, 5), (1, 1), (2, 2), (3, 1), (4, 1), (5, 1)], [(0, 2), (2, 3), (6, 2)]]

در اینجا، تابع، بردار خلوت (Sparse Vector) را تولید می‌کند.

گام چهارم: استفاده از مدل TF-IDF  برای پردازش بدنه و به دست آوردن اندیس

در ادامه، قطعه کدی با استفاده از TF-IDF به عنوان نمونه‌ای از چگونگی کد نویسی با آن، ارائه شده است.

1tfidf = models.TfidfModel(corpus)
2index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features = feature_cnt)

گام پنجم: تبدیل کلمات جستجو به بردار خلوت

قطعه کد زیر، کلمات جستجو را به بردار خلوت (Sparse Vectors) تبدیل می‌کند.

1from gensim import corpora
2import jieba
3text1 = ‘Tanizaki Junichiro writes good stories’ 
4text2 = ‘Naomi is a story written by Tanizaki’
5texts = [text1, text2]
6texts = [jieba.lcut(text) for text in texts]
7dictionary = corpora.Dictionary(texts)
8# Use [Dictionary] to convert [search word] to [sparse vector]
9keyword = ‘good stories’
10kw_vector = dictionary.doc2bow(jieba.lcut(keyword))
11print(kw_vector)

خروجی قطعه کدهای بالا به صورت زیر است.

[(0, 1), (3, 1), (4, 1)]

گام ششم: یکپارچه‌سازی کد و محاسبه مشابهت

در ادامه، قطعه کدهایی که در بخش‌های پیشین آموزش داده شده‌اند یکپارچه شده و کار محاسبه مشابهت با استفاده از آن انجام می‌شود.

1texts = [jieba.lcut(text) for text in texts]
2dictionary = corpora.Dictionary(texts)
3feature_cnt = len(dictionary.token2id)
4corpus = [dictionary.doc2bow(text) for text in texts]
5tfidf = models.TfidfModel(corpus)
6kw_vector = dictionary.doc2bow(jieba.lcut(keyword))
7index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features = feature_cnt)
8sim = index[tfidf[kw_vector]]
9for i in range(len(sim)):
10    print('keyword is similar to text%d: %.2f' % (i + 1, sim[i]))

استفاده از Gensim در پروژه مقایسه فیلم

پس از یادگیری مبانی استفاده از Gensim، یه کاربرد جالب و خلاقانه از این کتابخانه در این بخش از مطلب بیان خواهد شد. در ادامه، از کتابخانه پردازش زبان طبیعی و بازیابی اطلاعات Gensim برای مقایسه فیلم و تلویزیون استفاده شده است.

ابتدا، ورودی‌های اولیه که دو شیت اکسل دریافت می‌شود که حاوی فیلم‌ها و خصیصه‌های تلویزیون هستند. سرآیند (Heading) فرم به صورت زیر است.

محاسبه مشابهت متن با Gensim -- راهنمای کاربردی

ستون‌های name و summary مهم‌ترین دارایی‌هایی هستند که می‌توان از آن‌ها برای مقایسه استفاده کرد، زیرا به شکل جمله/پاراگراف هستند. از این رو، در اینجا از jieba استفاده می‌شود. پس از استفاده از کتابخانه پایتون «پانداس» (Pandas) برای استخراج همه داده‌ها از دو شیت اکسل و ذخیره‌سازی آن‌ها در «چارچوب‌های داده» (Data Frames)، می‌توان نام و خلاصه را به طور جداگانه در دیکشنری‌ها ذخیره کرد. این کار به نشان دادن ID دارایی‌ها (Assets) و خصیصه‌های متناظر آن‌ها کمک می‌کند. قطعه کد مربوط به این کار، در ادامه آمده است.

1df = pd.read_excel ("YOUR LOCAL FILE ADDRESS", sheetname = 'Sheet1')
2df2 = pd.read_excel("YOUR LOCAL FILE ADDRESS", sheetname = "Sheet1")
3# This is the first excel file
4ccms_title = {}
5for i in range(len(df[‘assets_id’])):
6 name = df[‘assets_name’][i]
7 iD = str(df[‘assets_id’][i])
8 ccms_title[iD] = name
9# This is the second excel file
10douban_title = {}
11for i in range(len(df2[‘assets_id’])):
12 name = df2[‘assets_name’][i]
13 iD = str(df2[‘assets_id’][i])
14 douban_title[iD] = name
15ccms_summary = {}
16for i in range(len(df['assets_id'])):
17    name = df['assets_name'][i]
18    iD = str(df['summary'][i])
19    ccms_summary[iD] = name
20douban_summary = {}
21for i in range(len(df2['assets_id'])):
22    name = df2['assets_name'][i]
23    iD = str(df2['summary'][i])
24    douban_summary[iD] = name

در ادامه، یک تابع ساخته می‌شود که از Gensim برای محاسبه رتبه مشابهت بین عنوان‌ها و خلاصه استفاده می‌کند.

1def gensimCalculation(d1, d2):
2  new_dict = {}
3  for x in d1:
4    text1 = d1[x]
5    texts = [jieba.lcut(d2[y]) for y in d2] 
6    dictionary = corpora.Dictionary(texts)
7    feature_cnt = len(dictionary.token2id)
8    corpus = [dictionary.doc2bow(text) for text in texts]
9    tfidf = models.TfidfModel(corpus)
10    new_vec = dictionary.doc2bow(jieba.lcut(text1))
11    index = similarities.SparseMatrixSimilarity(tfidf[corpus],     num_features = feature_cnt)
12    sim = index[tfidf[new_vec]]
13    new_dict[x] = max(sim) 
14 print(new_dict)
15 return
16print(gensimCalculation(ccms_summary, douban_summary))

تابعی که در بالا با استفاده از زبان برنامه‌نویسی پایتون و کتابخانه Gensim پیاده‌سازی شده است، خلاصه یک دارایی (Asset) را در excel1 با هر «خلاصه» (Summary) دیگری در excel2 مقایسه و مشابه‌ترین خلاصه‌ها را پیدا می‌کند. خروجی، یک دیکشنری با ID دارایی‌ها و ID دارایی دارای بیشترین مشابهت با شبیه‌ترین خلاصه به آن است. دیگر محاسبات مشابه مانند محاسبه عنوان‌ها را نیز می‌توان بدین شکل انجام داد.

خلاصه

Gensim یک کتابخانه پردازش زبان طبیعی و بازیابی اطلاعات ویژه پایتون است که با نسخه‌های ۲ و ۳ پایتون سازگار است. این کتابخانه مبتنی بر کتابخانه‌های پایتون نام‌پای و سای‌پای است و پیش از نصب آن، باید دو کتابخانه مذکور نصب شده باشند. با استفاده از این کتابخانه، ضمن پردازش متن، می‌توان بهتر و بیشتر روی ورودی و خروجی متمرکز شد. به کمک jieba که ماژول قطعه‌بندی کلمات موجود در پایتون است، می‌توان به سادگی مشابهت متن را استخراج کرد.

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۰ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
pypiMedium
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *