শব্দের সিমিলারিটি, কাছাকাছি অর্থ, লাইকলিহুড - সঙ্গে 'ফাস্টটেক্সট' এবং 'ওয়ার্ড২ভেক'

(পুরো চ্যাপ্টার একটা নোটবুক)

আমরা বই পড়ছি, নোটবুক কেন পড়বো?

যেহেতু গিটবুকে নোটবুক ঠিকমতো রেন্ডার হয়না, সেকারণে গুগল কোলাব এবং গিটহাবে দেখা উচিৎ। নোটবুক সবসময় আপডেটেড থাকে। গিটহাব লিংক: https://github.com/raqueeb/TensorFlow2/blob/master/similarity.ipynb অথবা https://nbviewer.jupyter.org/github/raqueeb/TensorFlow2/blob/master/similarity.ipynb এবং গুগল কোলাব লিংক: https://colab.research.google.com/github/raqueeb/TensorFlow2/blob/master/similarity.ipynb

শব্দের সিমিলারিটি, কাছাকাছি অর্থ, লাইকলিহুড - সঙ্গে ফাস্টটেক্সট এবং ওয়ার্ড২ভেক

যেহেতু ভাষা একটা ‘কমপ্লেক্স’ জিনিস, সেকারণে ডিপ লার্নিং অ্যাপ্লিকেশনে এই এই কমপ্লেক্সিটির সমস্যাগুলোকে কাটিয়ে ওঠার জন্য এই জিনিসটা আমাদের কাজের একটা ভালো ক্যান্ডিডেট। প্রতিটা শব্দের সাথে আরেকটা শব্দের সম্পর্ক এবং তার সিমিলারিটি অথবা সেই শব্দের সাথে কাছাকাছি শব্দগুলো কোন ডাইমেনশনে আছে সেটাও একটা ভালো দেখার বিষয়। যখন ‘ন্যাচারাল ল্যাঙ্গুয়েজ প্রসেসিং’ বোঝা শুরু করলাম, তখন বাংলায় এই ব্যাপারটা একদম অনুপস্থিত ছিল। বাংলায় এখনো কাজ দেখা কঠিন। এর পাশাপাশি শব্দ সিমিলারিটি অথবা কোন শব্দের কাছাকাছি কতগুলো শব্দ কাজ করছে, অথবা লিংক প্রেডিকশন - সেগুলো দেখার মত সেরকম রিসোর্স এখনো কম। তবে ডিপ লার্নিং অ্যাপ্লিকেশন আসার পর থেকে দু বাংলায় আমাদের ভাষা নিয়ে কাজ শুরু হয়েছে। কিছু রিসার্চ পেপার পাওয়া যায় তবে সেগুলোর ডাটাসেট সেভাবে উন্মুক্ত নয়। কেউ যদি কোনো কাজ শুরু করতে চায়, তাকে কেঁচে গণ্ডূষ করে শুরু করতে হবে। সে দিক থেকে আমাদের জন্য এই প্রি-ট্রেইনড মডেলই ভালো।

পাইথনের জন্য ‘স্পেসি’ এর মতো খুব ভালো দুটো এপ্লিকেশন আছে আমাদের হাতে। সেখানে ‘এনএলটিকে’ পুরনো হলেও ‘স্পেসি’ বেশ কাজের। তবে এ মুহূর্তে ‘স্পেসি’ এর বাংলা মডিউলটা আপডেট না থাকাতে সেটা কিছুটা কম্প্যাটিবিলিটি সমস্যায় আছে। সে কারণে আমরা ফিরে যাচ্ছি ওয়ার্ল্ড২ভেক এবং ফাস্টটেক্সটে। দুটো মডেল অবাক করার মতো। এ দুটো প্রি-ট্রেইনড মডেল অনেক বড় হলেও এর কাজকে দেখানোর জন্য বেশ কিছু ‘প্রি-প্রসেসিং’ আগে থেকে করে রাখা হয়েছে। ‘প্রি-প্রসেসিং’ একাই একটা আলাদা জগত, তবে সেটা ‘ডিপ লার্নিং’ এর মত ততটা কমপ্লেক্স নয়। আমি ধারণা করি কাজ করতে করতে প্রি-প্রসেসিং শিখে যাবেন আপনি।

আমরা যেহেতু অল্প সল্প ন্যাচারাল ল্যাংগুয়েজ প্রসেসিং নিয়ে কাজ করছি, শব্দগুলোর ‘সিমিলারিটি’ এবং কাছাকাছি অর্থ এবং রিপ্রেজেন্টেশন পাশাপাশি হওয়াতে আমরা কিছু কাজ দেখাতে পারি। আমাদের একটা টার্গেট শব্দ থাকলে ওই শব্দটাকে ঘিরে যে পাশাপাশি একই ধরনের শব্দগুলো আছে সেগুলোকে খালি চোখে দেখলে কিন্তু বিশ্বাস হবে। নিউরাল নেটওয়ার্কের হিডেন লেয়ারগুলো যেহেতু আমাদের শব্দ রিপ্রেজেন্টেশনকে এনকোড করে, সে কারণে আমরা এই ন্যাচারাল ল্যাংগুয়েজ প্রসেসিং অ্যাপ্লিকেশনকে অনেকটাই ছেড়ে দিচ্ছি নিউরাল নেটওয়ার্কের ওপর। এই দুটোকে আবার কনভার্জ করার জন্য দরকার কিছু বিশেষায়িত ফ্রেমওয়ার্ক। এর জন্য একটা ভালো ফ্রেমওয়ার্ক হচ্ছে ‘জেনসিম’। আসলেইএকটা অসাধারণ ফ্রেমওয়ার্ক। তবে, শুরুতেই ‘ওয়ার্ড২ভেক’। মানে ওয়ার্ড টু ভেক্টর।

স্কিপ-গ্রাম

বেশি কমপ্লেক্সিটিতে না যেয়ে বলতে পারি ওয়ার্ড২ভেক দুভাবে কাজ করে। একটাকে আমরা বলি স্কিপ-গ্রাম, মানে যার কাজ হচ্ছে বাক্যের কনটেক্সট প্রেডিক্ট করে শব্দ নিয়ে কাজ করা। এদিকে আরেকটা হচ্ছে ‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডস’। স্কিপ-গ্রাম এ আমাদের টার্গেট শব্দ যখন ইনপুট হিসেবে দেওয়া হয় - তখন তার আশেপাশের টার্গেট শব্দগুলো হচ্ছে আউটপুট। উদাহরণ হিসেবে বলা যায় একটা বাক্য, - “আমি এখন বই পড়ছি”, এর ইনপুট শব্দ যদি “বই” হয়, তাহলে তার আউটপুট হবে “আমি” “এখন”, এবং “পড়ছি”। আমাদের এখানে উইন্ডো সাইজ হচ্ছে ৪। এখানে ইনপুট এবং আউটপুট ডাটা একই ডাইমেনশনে থাকবে, অবশ্যই ‘ওয়ান হট এনকোডিং’ এ থাকবে। এই নেটওয়ার্কে একটা হিডেন লেয়ার যার ডাইমেনশন সমান হবে ‘এম্বেডিং সাইজ এর উপর, - যা আসলে ইনপুট এবং আউটপুট ভেক্টর সাইজের ছোট হবে। আউটপুট লেয়ার এর শেষে একটা ‘সফটম্যাক্স’ অ্যাক্টিভেশন ফাংশন প্রতিটা আউটপুট ফ্যাক্টরের এলিমেন্ট গুলোর উপর অ্যাপ্লাই করা থাকবে যাতে প্রবাবিলিটি ডিস্ট্রিবিউশনে ‘লাইকলিহুড’ মানে কন্টেক্সটুয়ালের কাছাকাছি শব্দগুলো আসবে এখানে।

আবার, আমাদের স্কিপ-গ্রামে ভোকাবুলারি সাইজ থেকে তার রিপ্রেজেন্টেশন ডাইমেনশন কমে আসে হিডেন লেয়ারে। পাশাপাশি আমাদের ভেক্টরগুলো অনেকটাই অর্থবহ হয় যখন শব্দগুলোর মধ্যে অংকের রিলেশনশিপ বা সম্পর্ককে ঠিকমতো বুঝতে পারি। একটা শব্দ থেকে আরেকটা শব্দকে যোগ অথবা বিয়োগ এব্যাপারগুলো বোঝা যাবে যখন আমরা সেগুলো এখন হাতে কলমে দেখব। এখানে একটা ছবি দেখুন।

‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডস’

ওয়ার্ড২ভেক এর আরেকটা ধারণা হচ্ছে ‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডস’, যা অনেকটাই স্কিপ-গ্রাম এর মত তবে এটা ইনপুট এবং আউটপুটকে পাল্টে দেয়। ব্যাপারটা এরকম, আমরা একটা ‘কন্টেক্সট’ দেবো সেখানে আমরা জানতে চাইব কোন শব্দটার সবচেয়ে বেশি ‘লাইকলিহুড’ অথবা ‘প্রবাবিলিটি’ থাকবে সবার আগে আসার। এই দুটো সিস্টেমের মধ্যে সবচেয়ে বড় পার্থক্য হচ্ছে যেভাবে শব্দের ভেক্টরগুলো জেনারেট হয়। ‘কন্টিনিউয়াস ব্যাগ অফ ওয়ার্ডে’ টার্গেট শব্দের সব উদাহরণগুলো নেটওয়ার্কে ফিড করানো হয় যা আসলে সেগুলোর গড় করে হিডেন লেয়ার থেকে এক্সট্রাক্ট করে। আমাদের সব ধরনের বাক্যের মধ্যে কিভাবে গড় করা যায় সেটা বের করা খুব একটা সমস্যা নয়। একটা ছবি দেখি।

এগুলো না বুঝলে সমস্যা নেই, কারণ সবকিছুই দেখব হাতে-কলমে সামনে। শুরুতে বেশকিছু প্রি-প্রসেসিং ব্যবহার করে যতিচিহ্ন, ইমোজি, ম্যাপ সিম্বল, স্পেশাল ক্যারেক্টার, ফেলে দেয়া হয়েছে ভালোভাবে বোঝার জন্য। এগুলো রেগুলার এক্সপ্রেশন এর কাজ।

import re
import os
import glob
import string

## দুটো মডেল দেখি 'জেনসিম' ফ্রেমওয়ার্ক দিয়ে
from gensim.models import Word2Vec
from gensim.models import FastText

আমাদের এই টেক্সট ফাইলটা দেখে নিতে পারেন। প্রতিটা লাইনে একটা করে বাংলা বাক্য আছে। বাংলা উইকিপিডিয়া থেকে নেয়া। প্রি-প্রসেসিং করে নিয়েছি আগেই। এখানে সহায়তা দিয়েছেন তারেক আল মুনতাসির।

!wget https://media.githubusercontent.com/media/raqueeb/datasets/master/bnwiki-texts.zip
--2019-11-04 05:36:51--  https://media.githubusercontent.com/media/raqueeb/datasets/master/bnwiki-texts.zip
Resolving media.githubusercontent.com (media.githubusercontent.com)... 151.101.0.133, 151.101.64.133, 151.101.128.133, ...
Connecting to media.githubusercontent.com (media.githubusercontent.com)|151.101.0.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 61696513 (59M) [application/zip]
Saving to: ‘bnwiki-texts.zip’

bnwiki-texts.zip    100%[===================>]  58.84M   272MB/s    in 0.2s    

2019-11-04 05:36:53 (272 MB/s) - ‘bnwiki-texts.zip’ saved [61696513/61696513]
!ls -al
total 60268
drwxr-xr-x 1 root root     4096 Nov  4 05:36 .
drwxr-xr-x 1 root root     4096 Nov  4 05:28 ..
-rw-r--r-- 1 root root 61696513 Nov  4 05:36 bnwiki-texts.zip
drwxr-xr-x 1 root root     4096 Oct 30 15:14 .config
drwxr-xr-x 1 root root     4096 Oct 25 16:58 sample_data
!unzip bnwiki-texts.zip
Archive:  bnwiki-texts.zip
  inflating: bnwiki-texts-preprocessed.txt  
# বাড়তি ওয়ার্নিং ফেলে দিচ্ছি, আপনাদের কাজের সময় লাগবে না 
import warnings
warnings.filterwarnings("ignore")
preprocessed_text_file_path = 'bnwiki-texts-preprocessed.txt'
lines_from_file = []
with open(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(len(tokenized_lines))
1363435
print(tokenized_lines[0])
['বাংলা', 'ভাষা', 'বাংলা', 'ভাষা', 'বাংলা', 'ভাষা', 'বাঙলা', 'বাঙ্গলা', 'তথা', 'বাঙ্গালা', 'নামগুলোতেও', 'পরিচিত', 'একটি', 'ইন্দো', 'আর্য', 'ভাষা', 'যা', 'দক্ষিণ', 'এশিয়ার', 'বাঙালি', 'জাতির', 'প্রধান', 'কথ্য', 'ও', 'লেখ্য', 'ভাষা']
# শুরুর মডেল ওয়ার্ড২ভেক, ৫ থেকে ১০ মিনিট লাগতে পারে

model = Word2Vec(tokenized_lines, size=200, window=5, min_count=10)
# পরের মডেল ফাস্টটেক্সট, এখানে একই সময় বা কিছুটা বেশি

fasttext_model = FastText(tokenized_lines, size=200, window=5, min_count=10)
# model.wv মানে মডেলের ওয়ার্ড ভেক্টর 
# ('বাংলা') এর বিশাল ডাইমেনশন
vector_a = fasttext_model.wv.get_vector('বাংলা')
print(vector_a)
[ 1.8380678  -1.737327   -1.6529522  -0.05112945 -1.4894909   3.4011111
  1.0885216  -2.4271836   0.19299157 -1.0932925   1.886907    2.999732
 -2.9732215  -0.9777463  -0.59138757  1.8506116  -1.6718992  -1.3437958
 -2.2993226   0.45145312 -2.90154     1.1796347   1.6372478  -0.93732387
  0.72269    -1.322812    0.67488265 -0.2553197  -2.8221207   0.47853807
 -1.5825214  -2.1237967  -1.5468056   0.1645597  -1.5666918  -2.5121124
  0.4718851   1.9257733   1.0192246  -0.5849877   2.9909644  -1.3063627
  0.07828262  0.0643187  -0.7692331   0.9448936   1.3949028  -1.4649616
 -2.4863896  -0.5425281  -1.793619   -0.35042384  0.39558363  2.3599637
  2.7777758  -1.4054934  -1.5487274   0.3328513  -0.28340796 -2.8430948
 -0.9327644   0.6999147  -2.5343878   0.15494218 -0.32586184  0.43889606
 -0.7882917  -0.4681618  -1.2403862   1.0631973   2.0079184  -1.2068993
  0.63529813 -2.3808987  -0.21832123 -0.1363634   0.5281479  -0.8373488
 -0.7986035   1.1935729   1.8801188  -0.8939522   0.10725019  3.359753
  0.18458065  2.8922195   0.4494454  -1.1680351  -1.8834859  -0.47471508
 -2.299536   -1.0242549   2.0759318   1.8685932  -0.67739034  3.2573614
 -0.07207203  0.2520941   0.02710792  1.3210536   0.32546476 -0.7708636
 -1.09866    -1.7296993   0.6173729   1.434288    4.261316   -2.4087427
  1.6940347   0.85209745 -2.866548    1.0885146   0.6289169   1.7201374
 -3.1261926   0.018237    1.4338254   0.62128395  0.90603215  1.6419231
 -0.05130844  1.1806359  -0.67010105  1.391549   -2.6299393  -1.6637585
 -0.3983475   0.391457   -2.3544602  -0.9600407   0.98992515 -1.6733301
 -1.2692964   2.5725243  -1.5650218  -2.6259742  -1.7402183   2.9217744
 -0.3244911  -2.9336858  -0.12844542 -1.0526279   1.8202819   0.25130072
 -0.32681054  0.21771958  1.9753587   1.0004528  -0.95577466 -0.65698856
  2.0067844   1.8537936   0.60692596 -2.7763276  -4.9803243   0.4838089
 -0.317778   -0.903118   -1.8661584   3.3285487   1.9113973   0.38437128
  0.2213238  -0.7238308   2.1565232  -1.8264067  -1.2468721   2.6072626
 -0.38030598 -0.80289626  0.7144853  -3.0035698  -1.3464603  -0.5746161
  1.0932914  -0.90437824 -3.6043286  -0.79489917  0.7052763   1.9433672
 -0.02424396 -0.7372106  -0.09772991 -0.5390308  -2.9160385  -1.2839049
 -0.13066147  1.5703335   0.86464065 -2.25375    -0.84863985  2.2709577
 -1.1551499  -0.5558198   0.02305196 -2.9795911  -3.1850455   1.1013148
  1.0400853  -0.0465611 ]
# শুরুতে ওয়ার্ড২ভেক ব্যবহার করছি, model এসেছে  ওয়ার্ড২ভেক
print("ছেলে শব্দটার সবচেয়ে কাছাকাছি শব্দ কি?")
model.wv.most_similar('ছেলে', topn=5)
ছেলে শব্দটার সবচেয়ে কাছাকাছি শব্দ কি?

[('মেয়ে', 0.8692359328269958),
 ('বোন', 0.7766759991645813),
 ('ভাই', 0.7698346376419067),
 ('কন্যা', 0.7464115023612976),
 ('সন্তান', 0.7114760279655457)]

আমার পছন্দ ফাস্টটেক্সট, দেখি তাদের রেজাল্ট।

print("ফাস্টটেক্সট উদাহরণ: ছেলে শব্দটার সবচেয়ে কাছাকাছি শব্দ কি?")
fasttext_model.wv.most_similar('ছেলে', topn=5)
ফাস্টটেক্সট উদাহরণ: ছেলে শব্দটার সবচেয়ে কাছাকাছি শব্দ কি?

[('ছেলেমেয়ে', 0.8634185791015625),
 ('মেয়ে', 0.8008948564529419),
 ('ছেলেরাই', 0.8006002902984619),
 ('ছেলেটা', 0.7696641087532043),
 ('বোন', 0.767594039440155)]
print("এখানে দেখি, বাবা + মেয়ে - ছেলে =?")
model.wv.most_similar(positive=['বাবা', 'মেয়ে'], negative=['ছেলে'], topn=5)
এখানে দেখি, বাবা + মেয়ে - ছেলে =?

[('মা', 0.6808090806007385),
 ('পিতা', 0.6501739621162415),
 ('দাদা', 0.6370166540145874),
 ('পিতামাতা', 0.6192508935928345),
 ('বান্ধবী', 0.6099355220794678)]
print(model.wv['বাংলাদেশ'])
[ 0.47465336  1.6979254  -2.058985    2.3955357   0.05341602 -0.05984123
  0.22838293  0.3715794   0.93708473 -0.56401557  0.864506    0.62503296
  0.14985324 -1.4774557   0.5915796  -1.3150611   1.8324492   2.3808618
  0.54691947  4.151364   -1.1955675   1.3761755  -1.2304349   0.9442904
 -0.15655555  1.1740373  -0.65801406 -0.29547226 -0.13476996 -2.771011
 -0.8829094   0.64367515  1.2357707   0.09527856  1.6726748   0.7327592
  2.2083585  -0.41217208  1.4147698  -0.7803361   0.05883798 -3.256775
 -0.5333822  -0.839592   -3.010173    0.4303193  -0.8576525   0.91541284
  1.7532002  -0.17395532 -2.3944476   1.1734742   0.10750934 -3.4137483
 -1.2700719  -0.56047267 -1.5561632   1.5821602  -1.3337445   0.93658894
  1.1160876  -0.53932893  0.94424546  0.37521785 -0.7722068  -1.0805587
 -0.30574694  0.91570383  2.700865   -0.9680715  -0.14924851  1.8231992
  2.2109523  -0.3651693  -0.397643    0.8523788   3.2056699   0.26128942
 -0.6535     -0.10631931  3.3168027  -0.5176928  -0.05205301 -0.8804305
  0.8046001  -0.40686098 -0.2891981  -0.81863105 -0.9747773  -0.03670701
  0.32589516  1.9878016  -1.1618168  -0.16822529  1.4897215  -3.0126944
 -0.8487738   1.6515619   1.3410716   0.00471912  0.91856664 -0.05932676
 -1.1302657  -0.9754544   0.81752974 -0.6842844   0.04337634 -0.42246413
 -1.8095124  -1.2585629   0.25722703  1.5258095   0.46770898 -0.25306585
 -0.07073525  0.4473772  -1.9499304   1.4085754  -0.7600875   2.0384746
 -1.8418869   1.1820074  -0.87884265 -0.8399573  -1.7892895   1.1480346
  0.02149497  1.9673309   0.52748406  1.9391041  -2.9540465  -1.5106716
 -0.5030738  -0.94844395 -1.6930846  -2.9189174  -1.9130685   1.6267107
  0.64483935  0.25364822  0.42543107  1.4215261  -2.6831162  -1.9624186
  2.2593734   0.3998477   2.9718199   0.41914302  0.43769148 -0.9424809
 -1.4903312   0.21915615  2.617412    1.0349852   1.3864113   2.383899
 -0.2564157   0.03220404  0.56614846  0.22525573  2.561288   -0.09410218
  0.12470096 -0.6466107  -1.3527399  -1.2821658   2.5643682  -0.30280894
 -2.3511822   2.1110947   1.3531933  -1.0076172   1.283717    1.07814
  2.5889244   0.03455029  0.296497   -1.6303657   1.060475    0.53312725
  0.2808083  -0.5654097   0.10495204 -2.4730425  -0.86111224  0.09144832
 -0.43474245  0.28571704  3.2044513  -0.5904202   0.87688035 -0.18928938
 -0.8915566  -0.75146323 -0.40565285 -3.8529725   0.227909   -2.1336107
 -0.3086042   1.4223515 ]
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 gensim.models.phrases import Phrases
bigram = Phrases(tokenized_lines, min_count=3, threshold=10)
print(bigram[tokenized_lines[0]])
['বাংলা_ভাষা', 'বাংলা_ভাষা', 'বাংলা_ভাষা', 'বাঙলা', 'বাঙ্গলা', 'তথা', 'বাঙ্গালা', 'নামগুলোতেও', 'পরিচিত', 'একটি', 'ইন্দো_আর্য', 'ভাষা', 'যা', 'দক্ষিণ_এশিয়ার', 'বাঙালি_জাতির', 'প্রধান', 'কথ্য', 'ও', 'লেখ্য_ভাষা']
# একটা ছবি আঁকবো যেখানে কাছাকাছি শব্দগুলো কোথায় আছে দেখাবে

from sklearn.decomposition import PCA

all_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))
['বাংলা', 'বাংলা৷', 'বাংলাঃ', 'বাংলালিংক', 'জোড়বাংলা', 'শেরেবাংলা', 'মাতা', 'মাতাপিতা', 'মাতামহ', 'মাতামহী', 'মাতাও', 'মাতাল', 'একুশে', 'একুশ', 'একুশতম', 'একুশের', '২১শে', '২৫শে', 'ভাষা', 'ভাষা৷', 'ভাষাও', 'কথ্যভাষা', 'ভাষাই', 'ভাষাভাষি', 'আনন্দ', 'আনন্দীবাঈ', 'আনন্দঘন', 'আনন্দমঠ', 'আনন্দলোক', 'আনন্দী', 'আকাশ', 'আকাশী', 'আকাশি', 'আকাশপথ', 'আকাশবাণী', 'আকাশপথে']
<class 'list'>
36
# প্রিন্সিপাল কম্পোনেন্ট অ্যানালাইসিস ব্যবহার করছি 

word_vectors = fasttext_model.wv[all_similar_words]
pca = PCA(n_components=2)
p_comps = pca.fit_transform(word_vectors)
word_names = all_similar_words

# আমরা শব্দগুলো একটু দেখি 
word_names
['বাংলা',
 'বাংলা৷',
 'বাংলাঃ',
 'বাংলালিংক',
 'জোড়বাংলা',
 'শেরেবাংলা',
 'মাতা',
 'মাতাপিতা',
 'মাতামহ',
 'মাতামহী',
 'মাতাও',
 'মাতাল',
 'একুশে',
 'একুশ',
 'একুশতম',
 'একুশের',
 '২১শে',
 '২৫শে',
 'ভাষা',
 'ভাষা৷',
 'ভাষাও',
 'কথ্যভাষা',
 'ভাষাই',
 'ভাষাভাষি',
 'আনন্দ',
 'আনন্দীবাঈ',
 'আনন্দঘন',
 'আনন্দমঠ',
 'আনন্দলোক',
 'আনন্দী',
 'আকাশ',
 'আকাশী',
 'আকাশি',
 'আকাশপথ',
 'আকাশবাণী',
 'আকাশপথে']
# ছবিটা কিছুটা টেন্সর-ফ্লো এর এমবেডিং প্রজেক্টরের মতো

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# সিয়াম রুপালি ফন্ট ব্যবহার করছি 
!wget https://www.omicronlab.com/download/fonts/Siyamrupali.ttf
prop = fm.FontProperties(fname='Siyamrupali.ttf')

plt.figure(figsize=(18, 10))
plt.scatter(p_comps[:, 0], p_comps[:, 1], c='red')

for word_name, x, y in zip(word_names, p_comps[:, 0], p_comps[:, 1]):
    plt.annotate(word_name, xy=(x+0.06, y+0.03), xytext=(0, 0), textcoords='offset points', fontproperties=prop)
--2019-11-04 06:17:45--  https://www.omicronlab.com/download/fonts/Siyamrupali.ttf
Resolving www.omicronlab.com (www.omicronlab.com)... 172.104.46.32
Connecting to www.omicronlab.com (www.omicronlab.com)|172.104.46.32|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 401040 (392K) [application/octet-stream]
Saving to: ‘Siyamrupali.ttf.1’

Siyamrupali.ttf.1   100%[===================>] 391.64K   430KB/s    in 0.9s    

2019-11-04 06:17:47 (430 KB/s) - ‘Siyamrupali.ttf.1’ saved [401040/401040]

সামনে কি করবো? বাংলায় সেন্টিমেন্ট অ্যানালাইসিস।

Last updated