শব্দের সিমিলারিটি, কাছাকাছি অর্থ, লাইকলিহুড - সঙ্গে ফাস্টটেক্সট এবং ওয়ার্ড২ভেক
যেহেতু ভাষা একটা ‘কমপ্লেক্স’ জিনিস, সেকারণে ডিপ লার্নিং অ্যাপ্লিকেশনে এই এই কমপ্লেক্সিটির সমস্যাগুলোকে কাটিয়ে ওঠার জন্য এই জিনিসটা আমাদের কাজের একটা ভালো ক্যান্ডিডেট। প্রতিটা শব্দের সাথে আরেকটা শব্দের সম্পর্ক এবং তার সিমিলারিটি অথবা সেই শব্দের সাথে কাছাকাছি শব্দগুলো কোন ডাইমেনশনে আছে সেটাও একটা ভালো দেখার বিষয়। যখন ‘ন্যাচারাল ল্যাঙ্গুয়েজ প্রসেসিং’ বোঝা শুরু করলাম, তখন বাংলায় এই ব্যাপারটা একদম অনুপস্থিত ছিল। বাংলায় এখনো কাজ দেখা কঠিন। এর পাশাপাশি শব্দ সিমিলারিটি অথবা কোন শব্দের কাছাকাছি কতগুলো শব্দ কাজ করছে, অথবা লিংক প্রেডিকশন - সেগুলো দেখার মত সেরকম রিসোর্স এখনো কম। তবে ডিপ লার্নিং অ্যাপ্লিকেশন আসার পর থেকে দু বাংলায় আমাদের ভাষা নিয়ে কাজ শুরু হয়েছে। কিছু রিসার্চ পেপার পাওয়া যায় তবে সেগুলোর ডাটাসেট সেভাবে উন্মুক্ত নয়। কেউ যদি কোনো কাজ শুরু করতে চায়, তাকে কেঁচে গণ্ডূষ করে শুরু করতে হবে। সে দিক থেকে আমাদের জন্য এই প্রি-ট্রেইনড মডেলই ভালো।
পাইথনের জন্য ‘স্পেসি’ এর মতো খুব ভালো দুটো এপ্লিকেশন আছে আমাদের হাতে। সেখানে ‘এনএলটিকে’ পুরনো হলেও ‘স্পেসি’ বেশ কাজের। তবে এ মুহূর্তে ‘স্পেসি’ এর বাংলা মডিউলটা আপডেট না থাকাতে সেটা কিছুটা কম্প্যাটিবিলিটি সমস্যায় আছে। সে কারণে আমরা ফিরে যাচ্ছি ওয়ার্ল্ড২ভেক এবং ফাস্টটেক্সটে। দুটো মডেল অবাক করার মতো। এ দুটো প্রি-ট্রেইনড মডেল অনেক বড় হলেও এর কাজকে দেখানোর জন্য বেশ কিছু ‘প্রি-প্রসেসিং’ আগে থেকে করে রাখা হয়েছে। ‘প্রি-প্রসেসিং’ একাই একটা আলাদা জগত, তবে সেটা ‘ডিপ লার্নিং’ এর মত ততটা কমপ্লেক্স নয়। আমি ধারণা করি কাজ করতে করতে প্রি-প্রসেসিং শিখে যাবেন আপনি।
আমরা যেহেতু অল্প সল্প ন্যাচারাল ল্যাংগুয়েজ প্রসেসিং নিয়ে কাজ করছি, শব্দগুলোর ‘সিমিলারিটি’ এবং কাছাকাছি অর্থ এবং রিপ্রেজেন্টেশন পাশাপাশি হওয়াতে আমরা কিছু কাজ দেখাতে পারি। আমাদের একটা টার্গেট শব্দ থাকলে ওই শব্দটাকে ঘিরে যে পাশাপাশি একই ধরনের শব্দগুলো আছে সেগুলোকে খালি চোখে দেখলে কিন্তু বিশ্বাস হবে। নিউরাল নেটওয়ার্কের হিডেন লেয়ারগুলো যেহেতু আমাদের শব্দ রিপ্রেজেন্টেশনকে এনকোড করে, সে কারণে আমরা এই ন্যাচারাল ল্যাংগুয়েজ প্রসেসিং অ্যাপ্লিকেশনকে অনেকটাই ছেড়ে দিচ্ছি নিউরাল নেটওয়ার্কের ওপর। এই দুটোকে আবার কনভার্জ করার জন্য দরকার কিছু বিশেষায়িত ফ্রেমওয়ার্ক। এর জন্য একটা ভালো ফ্রেমওয়ার্ক হচ্ছে ‘জেনসিম’। আসলেইএকটা অসাধারণ ফ্রেমওয়ার্ক। তবে, শুরুতেই ‘ওয়ার্ড২ভেক’। মানে ওয়ার্ড টু ভেক্টর।
চিত্রঃ কাছাকাছি অর্থ এবং রিপ্রেজেন্টেশন
স্কিপ-গ্রাম
বেশি কমপ্লেক্সিটিতে না যেয়ে বলতে পারি ওয়ার্ড২ভেক দুভাবে কাজ করে। একটাকে আমরা বলি স্কিপ-গ্রাম, মানে যার কাজ হচ্ছে বাক্যের কনটেক্সট প্রেডিক্ট করে শব্দ নিয়ে কাজ করা। এদিকে আরেকটা হচ্ছে ‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডস’। স্কিপ-গ্রাম এ আমাদের টার্গেট শব্দ যখন ইনপুট হিসেবে দেওয়া হয় - তখন তার আশেপাশের টার্গেট শব্দগুলো হচ্ছে আউটপুট। উদাহরণ হিসেবে বলা যায় একটা বাক্য, - “আমি এখন বই পড়ছি”, এর ইনপুট শব্দ যদি “বই” হয়, তাহলে তার আউটপুট হবে “আমি” “এখন”, এবং “পড়ছি”। আমাদের এখানে উইন্ডো সাইজ হচ্ছে ৪। এখানে ইনপুট এবং আউটপুট ডাটা একই ডাইমেনশনে থাকবে, অবশ্যই ‘ওয়ান হট এনকোডিং’ এ থাকবে। এই নেটওয়ার্কে একটা হিডেন লেয়ার যার ডাইমেনশন সমান হবে ‘এম্বেডিং সাইজ এর উপর, - যা আসলে ইনপুট এবং আউটপুট ভেক্টর সাইজের ছোট হবে। আউটপুট লেয়ার এর শেষে একটা ‘সফটম্যাক্স’ অ্যাক্টিভেশন ফাংশন প্রতিটা আউটপুট ফ্যাক্টরের এলিমেন্ট গুলোর উপর অ্যাপ্লাই করা থাকবে যাতে প্রবাবিলিটি ডিস্ট্রিবিউশনে ‘লাইকলিহুড’ মানে কন্টেক্সটুয়ালের কাছাকাছি শব্দগুলো আসবে এখানে।
চিত্রঃ ইনপুট লেয়ার থেকে আউটপুট লেয়ারে
আবার, আমাদের স্কিপ-গ্রামে ভোকাবুলারি সাইজ থেকে তার রিপ্রেজেন্টেশন ডাইমেনশন কমে আসে হিডেন লেয়ারে। পাশাপাশি আমাদের ভেক্টরগুলো অনেকটাই অর্থবহ হয় যখন শব্দগুলোর মধ্যে অংকের রিলেশনশিপ বা সম্পর্ককে ঠিকমতো বুঝতে পারি। একটা শব্দ থেকে আরেকটা শব্দকে যোগ অথবা বিয়োগ এব্যাপারগুলো বোঝা যাবে যখন আমরা সেগুলো এখন হাতে কলমে দেখব। এখানে একটা ছবি দেখুন।
‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডস’
ওয়ার্ড২ভেক এর আরেকটা ধারণা হচ্ছে ‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডস’, যা অনেকটাই স্কিপ-গ্রাম এর মত তবে এটা ইনপুট এবং আউটপুটকে পাল্টে দেয়। ব্যাপারটা এরকম, আমরা একটা ‘কন্টেক্সট’ দেবো সেখানে আমরা জানতে চাইব কোন শব্দটার সবচেয়ে বেশি ‘লাইকলিহুড’ অথবা ‘প্রবাবিলিটি’ থাকবে সবার আগে আসার। এই দুটো সিস্টেমের মধ্যে সবচেয়ে বড় পার্থক্য হচ্ছে যেভাবে শব্দের ভেক্টরগুলো জেনারেট হয়। ‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডে’ টার্গেট শব্দের সব উদাহরণগুলো নেটওয়ার্কে ফিড করানো হয় যা আসলে সেগুলোর গড় করে হিডেন লেয়ার থেকে এক্সট্রাক্ট করে। আমাদের সব ধরনের বাক্যের মধ্যে কিভাবে গড় করা যায় সেটা বের করা খুব একটা সমস্যা নয়। একটা ছবি দেখি।
চিত্রঃ ইনপুট লেয়ার থেকে আউটপুট লেয়ারে কমে আসছে
এগুলো না বুঝলে সমস্যা নেই, কারণ সবকিছুই দেখব হাতে-কলমে সামনে। শুরুতে বেশকিছু প্রি-প্রসেসিং ব্যবহার করে যতিচিহ্ন, ইমোজি, ম্যাপ সিম্বল, স্পেশাল ক্যারেক্টার, ফেলে দেয়া হয়েছে ভালোভাবে বোঝার জন্য। এগুলো রেগুলার এক্সপ্রেশন এর কাজ।
আমাদের এই টেক্সট ফাইলটা দেখে নিতে পারেন। প্রতিটা লাইনে একটা করে বাংলা বাক্য আছে। বাংলা উইকিপিডিয়া থেকে নেয়া। প্রি-প্রসেসিং করে নিয়েছি আগেই। এখানে সহায়তা দিয়েছেন তারেক আল মুনতাসির।
lines_from_file = []withopen(preprocessed_text_file_path, encoding='utf8')as text_file:for line in text_file: lines_from_file.append(line)
কতগুলো লাইন আছে এই ফাইলে?
len(lines_from_file)
1363435
আমাদের জেনসিম ওয়ার্ড২ভেক এবং ফাস্টটেক্সট শব্দের লিস্ট আশা করে একেকটা বাক্য/প্রতিটা লাইনে। যেমন, [["আমি", "এখন", "বইটি", "পরছি"],["বইটি", "অনেক", "ভাল"]]
tokenized_lines = []for single_line in lines_from_file: tokenized_lines.append(single_line.split())
print('এখানে কোন শব্দটা যাচ্ছে না বাকিদের সাথে?')model.wv.doesnt_match("ঢাকা রাজশাহী রংপুর নজরুল".split())
এখানে কোন শব্দটা যাচ্ছে না বাকিদের সাথে?
'নজরুল'
print(model.wv.similarity('শিক্ষা', 'শিক্ষিত'))
0.42382157
semantically_similar_words ={words: [item[0]for item in model.wv.most_similar([words], topn=5)]for words in ['বাংলা','মাতা','একুশে','ভাষা','আনন্দ','আকাশ']}for k,v in semantically_similar_words.items():print(k+":"+str(v))
semantically_similar_words ={words: [item[0]for item in fasttext_model.wv.most_similar([words], topn=5)]for words in ['বাংলা','মাতা','একুশে','ভাষা','আনন্দ','আকাশ']}for k,v in semantically_similar_words.items():print(k+":"+str(v))
# একটা ছবি আঁকবো যেখানে কাছাকাছি শব্দগুলো কোথায় আছে দেখাবেfrom sklearn.decomposition import PCAall_similar_words =sum([[k] + v for k, v in semantically_similar_words.items()], [])print(all_similar_words)print(type(all_similar_words))print(len(all_similar_words))