محاسبه شباهت معنایی بین دو متن نوشتاری با PyTorch و SentenceTransformers
شباهت معنایی یا شباهت معنایی نوشتاری یکی از مسائل حوزهی پردازش زبان طبیعی یا NLP است. در این نوع مسائل، با استفاده از یک معیار مشخص ارتباط بین متون یا اسناد اندازهگیری میشود. شباهت معنایی در موارد گوناگون از جمله بازیابی اطلاعات ، خلاصهسازی متون ، و تجزیه و تحلیل عواطف ، کاربرد دارد.
رویکردهای زیادی برای محاسبهی شباهت معنایی وجود دارند. سادهترین و کارآمدترین آنها روشی است که از یک مدل قدرتمند مبدل برای رمزگذاری جملات و ثبت تعبیههای آنها استفاده میکند و سپس برمبنای یک معیار شباهت (شباهت کسینوسی ) مقدار شباهت بین دو متن را محاسبه میکند. شباهت یا تفاوت بین دو متن برمبنای این مقدار شباهت مشخص میشود. در این نوشتار قصد داریم به کاربرد مبدلها در محاسبهی شباهت معنایی بپردازیم. مبدلها از معماریهای قدرتمند حوزهی NLP هستند که امکان دستیابی به عملکردی عالی و بیسابقه در بسیاری از مسائل NLP را فراهم کردهاند.
نصب وابستگیها
کتابخانهی اصلی که اینجا برای محاسبهی شباهت معنایی به کار میبریم، SentenceTransformers (لینک Github) است. این کتابخانهی ساده، برای محاسبهی بازنمایی بردارهای متراکم (تعبیهها) در متون، روشی آسان ارائه میدهد. این کتابخانه مدلهای جدیدی دارد که برای کاربردهای مختلف به صورت دقیق تنظیم شدهاند. یکی از مسائل مهمی که این کتابخانه پشتیبانی میکند، شباهت معنایی نوشتاری است.
برای نصب SentenceTransformers باید ابتدا وابستگیهای Pytorch و Transformers را نصب کنید.
نصب Pytorch
وارد وبسایت رسمی Pytorch شوید و دستورالعملهای مربوط به نصب را دنبال کنید.
نصب Transformers
برای نصب Transformers، این دستور را اجرا کنید:
pip install transformers
نصب SentenceTransformers
حال که Pytorch و Transformers را نصب کردهاید میتوانید SentenceTransformers را با استفاده از این دستور نصب کنید:
pip install sentence-transformers
نکته: SentenceTransformers استفاده از Python 3.6 یا بالاتر، Pytorch 1.6.0 یا بالاتر و transformers v3.1.0 را به کاربران پیشنهاد میکند.
[irp posts=”23211″]انتقال کتابخانه
بعد از نصب موفقیتآمیز SentenceTransformers و وابستگیهای آن، میتوانیم از آن استفاده کنیم. برای انتقال کتابخانه این دستور را به کار میبریم:
from sentence_transformers import SentenceTransformer, util import numpy as np
انتخاب و مقداردهی اولیه مدل
SentenceTransformers از مدلهای زیادی پشتیبانی میکند که از پیش آموزش دیدهاند و برای مسائل گوناگون به صورت دقیق تنظیم شدهاند. در این لینک فهرستی از مدلهایی را مشاهده میکنید که برای مسئلهی شباهت معنایی، بهینه شدهاند.
در حال حاضر، stsb-roberta-large که از ROBERTA-large به عنوان مدل پایه و mean-pooling استفاده میکند، بهترین مدل برای مسئلهی شباهت معنایی به شمار میرود. به همین دلیل در این نوشتار از آن استفاده میکنیم.
بعد از انتخاب مدل، میتوانیم بدین صورت آن را تعریف کنیم:
model = SentenceTransformer('stsb-roberta-large')
محاسبهی شباهت معنایی بین دو جمله
بعد از تعریف مدل، میتوانیم مقدار شباهت بین دو جمله را مشخص کنیم. همانطور که در قسمت مقدمه توضیح دادیم، در این رویکرد با استفاده از مدل مبدل، دو جمله رمزگذاری میشوند و سپس شباهت کسینوسی تعبیهی آن جملات محاسبه میشود. نتیجهی نهایی مدل، مقدار شباهت معنایی خواهد بود.
در کل میتوانیم از فرمولهای مختلفی (ضرب ماتریسی، Jaccard، و غیره) برای محاسبهی مقدار شباهت نهایی استفاده کنیم. اما با توجه به ویژگیهایی که اینجا در دست داریم، از شباهت کسینوسی استفاده میکنیم. عامل مهمتر، تعبیههایی هستند که توسط مدل تولید میشوند. پس مهم است که یک مدل رمزگذار مناسب به کار ببریم.
برای محاسبهی مقدار شباهت معنایی با استفاده از رویکرد مذکور، میتوانیم این کد را اجرا کنیم:
sentence1 = "I like Python because I can build AI applications" sentence2 = "I like Python because I can do data analytics"# encode sentences to get their embeddings embedding1 = model.encode(sentence1, convert_to_tensor=True) embedding2 = model.encode(sentence2, convert_to_tensor=True)# compute similarity scores of two embeddings cosine_scores = util.pytorch_cos_sim(embedding1, embedding2)print("Sentence 1:", sentence1) print("Sentence 2:", sentence2) print("Similarity score:", cosine_scores.item())
ابتدا دو جملهی مدنظر را تعریف میکنیم (sentence1 و sentence2). سپس با استفاده از مدلی که از پیش تعریف کردهایم آنها را رمزگذاری میکنیم. تعبیههای نهایی خود را به تنسور تبدیل میکنیم تا GPU بتواند سریعتر آنها را پردازش کند. البته این گام زمانی که با مقدار کمی داده سروکار داریم (همچون مورد کاربرد ما) ضروری نیست.
سپس میتوانیم با استفاده از تابع pytorch_cos_sim (که در بخش util پیادهسازی کردیم)، به راحتی مقدار شباهت کسینوسی بین دو تعبیه را به دست آوریم.
همانطور که مشاهده میکنید، مقدار شباهت sentence1 و sentence2 نزدیک به 1 است، یعنی این دو جمله شباهت زیادی به هم دارند.
محاسبهی شباهت معنایی بین دو لیست از جملات
اگر بخواهید جملات بیشتری را با هم مقایسه کنید، میتوانید جملات را در دو لیست قرار دهید و از همان کد قبلی برای محاسبهی مقدار شباهت بین آنها استفاده کنید. نتیجهی نهایی، یک ماتریس از مقادیر شباهت است که مؤلفهی i, j در آن نشاندهندهی مقدار شباهت بین جملهی i در لیست 1 و جملهی j در لیست 2 است. برای محاسبهی مقدار شباهت بین دو لیست، این کد را اجرا کنید:
sentences1 = ["I like Python because I can build AI applications", "The cat sits on the ground"] sentences2 = ["I like Python because I can do data analytics", "The cat walks on the sidewalk"]# encode list of sentences to get their embeddings embedding1 = model.encode(sentences1, convert_to_tensor=True) embedding2 = model.encode(sentences2, convert_to_tensor=True)# compute similarity scores of two embeddings cosine_scores = util.pytorch_cos_sim(embedding1, embedding2)for i in range(len(sentences1)): for j in range(len(sentences2)): print("Sentence 1:", sentences1[i]) print("Sentence 2:", sentences2[j]) print("Similarity Score:", cosine_scores[i][j].item()) print()
همانطور که مشاهده میکنید این دو جفت جمله («من Python را دوست دارم چون میتوانم برنامههای کاربردی هوش مصنوعی بسازم»، «من Python را دوست دارم چون میتوانم به تجزیه و تحلیل داده بپردازم») و («گربه روی زمین نشسته است»، «گربه در پیادهرو راه میرود») به هم شبیه هستند. بنابراین مقدار شباهتی که به عنوان خروجی مدل تولید میشود نیز بالاتر خواهد بود. از سوی دیگر، جملات مربوط به Python از جملات مربوط به گربه خیلی متفاوت هستند؛ بنابراین مقدار شباهت بین دو جفت دیگر از این جملات، کمتر خواهد بود.
[irp posts=”3143″]بازیابی K مورد از شبیهترین جملات از پیکرهی متنی
یکی از کاربردهای محبوب شباهت معنایی مربوط به پیدا کردن مرتبطترین جملات در یک پیکره بر مبنای یک کوئری است. به این مسئله، جستجوی معنایی نیز میگویند. برای انجام جستجوی معنایی، نیاز به یک پیکرهی متنی و یک جمله داریم که نقش کوئری (جملهی پرسشی) را ایفا میکند. میتوانیم پیکره و آن کوئری را به همان شیوهی قبلی رمزگذاری کنیم. در آخر top_k یعنی K مورد از شبیهترین جملات را بر اساس top_k یا k مورد از بالاترین مقادیر شباهت پیدا میکنیم.
corpus = ["I like Python because I can build AI applications", "I like Python because I can do data analytics", "The cat sits on the ground", "The cat walks on the sidewalk"]# encode corpus to get corpus embeddings corpus_embeddings = model.encode(corpus, convert_to_tensor=True)sentence = "I like Javascript because I can build web applications"# encode sentence to get sentence embeddings sentence_embedding = model.encode(sentence, convert_to_tensor=True)# top_k results to return top_k=2# compute similarity scores of the sentence with the corpus cos_scores = util.pytorch_cos_sim(sentence_embedding, corpus_embeddings)[0]# Sort the results in decreasing order and get the first top_k top_results = np.argpartition(-cos_scores, range(top_k))[0:top_k]print("Sentence:", sentence, "\n") print("Top", top_k, "most similar sentences in corpus:") for idx in top_results[0:top_k]: print(corpus[idx], "(Score: %.4f)" % (cos_scores[idx]))
در مثال این مقاله، پیکرهی متنی ما 4 جمله دارد. ما top-k را روی 2 تنظیم کردیم تا 2 جمله که بیشترین شباهت را با کوئری دارند بازیابی کنیم. جملهی کوئری ما این بود: «من Javascript را دوست دارم چون میتوانم برنامههای کاربردی شبکه بسازم» و مدل دو جملهی مربوط به پایتون را به ما برگرداند، چون Javascript به Python شباهت بیشتری دارد (نسبت به گربهها).
جمعبندی
اکنون میدانید چطور شباهت معنایی بین جملات و فهرست جملات را محاسبه کنید و شبیهترین دادههای موجود در یک پیکرهی متنی را بازیابی کنید.