ডাটাপ্রোকে প্রাকৃতিক ভাষা প্রক্রিয়াকরণের জন্য পাইস্পার্ক

1. ওভারভিউ

ন্যাচারাল ল্যাঙ্গুয়েজ প্রসেসিং (NLP) হল অন্তর্দৃষ্টি অর্জন এবং পাঠ্য ডেটার উপর বিশ্লেষণ পরিচালনা করার অধ্যয়ন। ইন্টারনেটে উত্পন্ন লেখার পরিমাণ বাড়তে থাকায়, এখন আগের চেয়ে অনেক বেশি, সংস্থাগুলি তাদের ব্যবসার সাথে প্রাসঙ্গিক তথ্য পেতে তাদের পাঠ্য ব্যবহার করতে চাইছে।

এনএলপি ভাষা অনুবাদ করা থেকে শুরু করে অনুভূতি বিশ্লেষণ করা থেকে শুরু থেকে বাক্য তৈরি করা এবং আরও অনেক কিছুর জন্য ব্যবহার করা যেতে পারে। এটি গবেষণার একটি সক্রিয় ক্ষেত্র যা পাঠ্যের সাথে আমাদের কাজ করার পদ্ধতিকে রূপান্তরিত করছে।

আমরা স্কেল এ বিপুল পরিমাণ পাঠ্য ডেটাতে কীভাবে NLP ব্যবহার করতে হয় তা অন্বেষণ করব। এটি অবশ্যই একটি কঠিন কাজ হতে পারে! সৌভাগ্যবশত, আমরা এটিকে সহজ করতে স্পার্ক MLlib এবং spark-nlp- এর মতো লাইব্রেরির সুবিধা নেব।

2. আমাদের ব্যবহারের ক্ষেত্রে

আমাদের (কাল্পনিক) সংস্থার প্রধান ডেটা সায়েন্টিস্ট, "FoodCorp" খাদ্য শিল্পের প্রবণতা সম্পর্কে আরও জানতে আগ্রহী৷ আমরা Reddit subreddit r/food থেকে পোস্টের আকারে টেক্সট ডেটার একটি কর্পাস অ্যাক্সেস করতে পারি যা আমরা অন্বেষণ করতে ব্যবহার করব লোকেরা কী বিষয়ে কথা বলছে।

এটি করার জন্য একটি পদ্ধতি হল "টপিক মডেলিং" নামে পরিচিত একটি NLP পদ্ধতির মাধ্যমে। টপিক মডেলিং একটি পরিসংখ্যানগত পদ্ধতি যা নথির একটি গোষ্ঠীর শব্দার্থিক অর্থের প্রবণতা সনাক্ত করতে পারে। অন্য কথায়, আমরা আমাদের রেডডিট "পোস্ট" এর কর্পাসে একটি টপিক মডেল তৈরি করতে পারি যা একটি প্রবণতা বর্ণনা করে এমন "বিষয়" বা শব্দের গোষ্ঠীর একটি তালিকা তৈরি করবে।

আমাদের মডেল তৈরি করতে, আমরা ল্যাটেন্ট ডিরিচলেট অ্যালোকেশন (এলডিএ) নামে একটি অ্যালগরিদম ব্যবহার করব, যা প্রায়শই ক্লাস্টার টেক্সট করতে ব্যবহৃত হয়। এলডিএর একটি চমৎকার ভূমিকা এখানে পাওয়া যাবে।

3. একটি প্রকল্প তৈরি করা

আপনার যদি ইতিমধ্যে একটি Google অ্যাকাউন্ট না থাকে (Gmail বা Google Apps), তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে। Google ক্লাউড প্ল্যাটফর্ম কনসোলে সাইন-ইন করুন ( console.cloud.google.com ) এবং একটি নতুন প্রকল্প তৈরি করুন:

7e541d932b20c074.png

2deefc9295d114ea.png

2016-02-10 12:45:26.png এর স্ক্রিনশট

এর পরে, Google ক্লাউড সংস্থানগুলি ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং সক্ষম করতে হবে৷

এই কোডল্যাবের মাধ্যমে চালানোর জন্য আপনার কয়েক ডলারের বেশি খরচ করা উচিত নয়, তবে আপনি যদি আরও সংস্থান ব্যবহার করার সিদ্ধান্ত নেন বা আপনি যদি সেগুলি চলমান রেখে দেন তবে এটি আরও বেশি হতে পারে। PySpark-BigQuery এবং Spark-NLP কোডল্যাব প্রতিটি শেষে "ক্লিন আপ" ব্যাখ্যা করে।

Google ক্লাউড প্ল্যাটফর্মের নতুন ব্যবহারকারীরা $300 বিনামূল্যের ট্রায়ালের জন্য যোগ্য৷

4. আমাদের পরিবেশ সেট আপ করা

প্রথমত, আমাদের Dataproc এবং Compute Engine APIs সক্ষম করতে হবে।

স্ক্রিনের উপরের বাম দিকে মেনু আইকনে ক্লিক করুন।

2bfc27ef9ba2ec7d.png

ড্রপ ডাউন থেকে API ম্যানেজার নির্বাচন করুন।

408af5f32c4b7c25.png

Enable APIs এবং Services- এ ক্লিক করুন।

a9c0e84296a7ba5b.png

অনুসন্ধান বাক্সে "কম্পিউট ইঞ্জিন" অনুসন্ধান করুন। প্রদর্শিত ফলাফল তালিকায় "Google Compute Engine API" এ ক্লিক করুন।

b6adf859758d76b3.png

Google Compute Engine পৃষ্ঠায় Enable এ ক্লিক করুন

da5584a1cbc77104.png

একবার এটি সক্রিয় হয়ে গেলে ফিরে যেতে বাম দিকে নির্দেশিত তীরটিতে ক্লিক করুন।

এখন "Google Dataproc API" অনুসন্ধান করুন এবং এটি সক্রিয় করুন।

f782195d8e3d732a.png

এরপরে, ক্লাউড কনসোলের উপরের ডানদিকের কোণায় বোতামটি ক্লিক করে ক্লাউড শেল খুলুন:

a10c47ee6ca41c54.png

আমরা কিছু এনভায়রনমেন্ট ভেরিয়েবল সেট করতে যাচ্ছি যা আমরা কোডল্যাবের সাথে এগিয়ে যাওয়ার সাথে সাথে উল্লেখ করতে পারি। প্রথমে, একটি Dataproc ক্লাস্টারের জন্য একটি নাম বেছে নিন যা আমরা তৈরি করতে যাচ্ছি, যেমন "my-cluster", এবং এটি আপনার পরিবেশে সেট করুন। আপনি যে কোনো নাম ব্যবহার করতে নির্দ্বিধায়.

CLUSTER_NAME=my-cluster

এরপরে, এখানে উপলব্ধ একটি থেকে একটি অঞ্চল বেছে নিন। একটি উদাহরণ us-east1-b.

REGION=us-east1

অবশেষে, আমাদের সেই সোর্স বাকেট সেট করতে হবে যা থেকে আমাদের কাজ ডেটা পড়তে যাচ্ছে। আমাদের bm_reddit বালতিতে নমুনা ডেটা উপলব্ধ আছে কিন্তু আপনি যদি এর আগে এটি সম্পূর্ণ করেন তবে BigQuery ডেটা প্রিপ্রসেস করার জন্য PySpark থেকে তৈরি করা ডেটা ব্যবহার করতে দ্বিধা বোধ করবেন না।

BUCKET_NAME=bm_reddit

আমাদের এনভায়রনমেন্ট ভেরিয়েবল কনফিগার করে, আমাদের Dataproc ক্লাস্টার তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

 gcloud beta dataproc clusters create ${CLUSTER_NAME} \
     --region ${REGION} \
     --metadata 'PIP_PACKAGES=google-cloud-storage spark-nlp==2.7.2' \
     --worker-machine-type n1-standard-8 \
     --num-workers 4 \
     --image-version 1.4-debian10 \
     --initialization-actions gs://dataproc-initialization-actions/python/pip-install.sh \
     --optional-components=JUPYTER,ANACONDA \
     --enable-component-gateway

আসুন এই প্রতিটি কমান্ডের মাধ্যমে পদক্ষেপ নেওয়া যাক:

gcloud beta dataproc clusters create ${CLUSTER_NAME} : আপনার আগে দেওয়া নাম দিয়ে একটি Dataproc ক্লাস্টার তৈরি করা শুরু করবে। কম্পোনেন্ট গেটওয়ের মতো ডেটাপ্রোকের বিটা বৈশিষ্ট্যগুলিকে সক্ষম করতে আমরা এখানে beta অন্তর্ভুক্ত করি, যা আমরা নীচে আলোচনা করি।

--zone=${ZONE} : এটি ক্লাস্টারের অবস্থান নির্ধারণ করে।

--worker-machine-type n1-standard-8 : এটি আমাদের কর্মীদের জন্য ব্যবহার করার জন্য মেশিনের ধরন

--num-workers 4 : আমাদের ক্লাস্টারে চারজন কর্মী থাকবে।

--image-version 1.4-debian9 : এটি Dataproc এর ইমেজ-সংস্করণকে বোঝায় যা আমরা ব্যবহার করব।

--initialization-actions ... : ইনিশিয়ালাইজেশন অ্যাকশন হল কাস্টম স্ক্রিপ্ট যা ক্লাস্টার এবং কর্মী তৈরি করার সময় কার্যকর করা হয়। সেগুলি হয় ব্যবহারকারী দ্বারা তৈরি এবং একটি GCS বালতিতে সংরক্ষণ করা যেতে পারে বা পাবলিক বাকেট dataproc-initialization-actions থেকে উল্লেখ করা যেতে পারে। এখানে অন্তর্ভুক্ত প্রারম্ভিক ক্রিয়াটি Pip ব্যবহার করে পাইথন প্যাকেজ ইনস্টলেশনের অনুমতি দেবে, যেমন --metadata ফ্ল্যাগ প্রদান করা হয়েছে।

--metadata 'PIP_PACKAGES=google-cloud-storage spark-nlp' : এটি ডেটাপ্রোকে ইনস্টল করার জন্য প্যাকেজগুলির একটি স্থান-বিচ্ছিন্ন তালিকা। এই ক্ষেত্রে, আমরা google-cloud-storage Python ক্লায়েন্ট লাইব্রেরি এবং spark-nlp ইনস্টল করব।

--optional-components=ANACONDA : ঐচ্ছিক উপাদান হল Dataproc-এর সাথে ব্যবহৃত সাধারণ প্যাকেজ যা তৈরির সময় Dataproc ক্লাস্টারে স্বয়ংক্রিয়ভাবে ইনস্টল করা হয়। ইনিশিয়ালাইজেশন অ্যাকশনের উপর ঐচ্ছিক উপাদান ব্যবহার করার সুবিধার মধ্যে রয়েছে দ্রুত স্টার্টআপ সময় এবং নির্দিষ্ট ডেটাপ্রোক সংস্করণের জন্য পরীক্ষা করা। সামগ্রিকভাবে, তারা আরও নির্ভরযোগ্য।

--enable-component-gateway : এই পতাকাটি আমাদেরকে সাধারণ UI যেমন Zeppelin, Jupyter বা Spark History দেখার জন্য Dataproc এর কম্পোনেন্ট গেটওয়ের সুবিধা নিতে দেয়। দ্রষ্টব্য: এর মধ্যে কয়েকটির জন্য সংশ্লিষ্ট ঐচ্ছিক উপাদান প্রয়োজন।

Dataproc-এর আরও গভীরতর ভূমিকার জন্য, অনুগ্রহ করে এই কোডল্যাবটি দেখুন।

এর পরে, সঠিক ডিরেক্টরিতে নমুনা কোড এবং সিডি সহ রেপো ক্লোন করতে আপনার ক্লাউড শেলে নিম্নলিখিত কমান্ডগুলি চালান:

cd
git clone https://github.com/GoogleCloudPlatform/cloud-dataproc
cd cloud-dataproc/codelabs/spark-nlp

5. স্পার্ক এমএললিব

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

MLlib-এ ট্রান্সফরমার এবং এস্টিমেটরের একটি বড় সেট রয়েছে। একটি ট্রান্সফরমার হল একটি টুল যা আপনার ডেটা পরিবর্তন বা পরিবর্তন করতে পারে, সাধারণত একটি transform() ফাংশন সহ যখন একটি অনুমানকারী একটি পূর্ব-নির্মিত অ্যালগরিদম যা আপনি সাধারণত একটি fit() ফাংশনের সাথে আপনার ডেটা প্রশিক্ষণ দিতে পারেন৷

ট্রান্সফরমারের উদাহরণগুলির মধ্যে রয়েছে:

  • টোকেনাইজেশন (শব্দের স্ট্রিং থেকে সংখ্যার ভেক্টর তৈরি করা)
  • এক-হট এনকোডিং (একটি স্ট্রিং-এ উপস্থিত শব্দের প্রতিনিধিত্বকারী সংখ্যার একটি স্পার্স ভেক্টর তৈরি করা)
  • স্টপওয়ার্ড রিমুভার (একটি স্ট্রিংয়ে শব্দার্থিক মান যোগ করে না এমন শব্দগুলি অপসারণ করা)

অনুমানকারীদের উদাহরণগুলির মধ্যে রয়েছে:

  • শ্রেণিবিন্যাস (এটি কি আপেল না কমলা?)
  • রিগ্রেশন (এই আপেলের দাম কত হওয়া উচিত?)
  • ক্লাস্টারিং (সব আপেল একে অপরের সাথে কতটা মিল?)
  • সিদ্ধান্ত গাছ (যদি রঙ == কমলা, তাহলে এটি একটি কমলা। অন্যথায় এটি একটি আপেল)
  • মাত্রিকতা হ্রাস (আমরা কি আমাদের ডেটাসেট থেকে বৈশিষ্ট্যগুলি সরিয়ে ফেলতে পারি এবং এখনও একটি আপেল এবং একটি কমলার মধ্যে পার্থক্য করতে পারি?)

MLlib-এ মেশিন লার্নিংয়ের অন্যান্য সাধারণ পদ্ধতি যেমন হাইপারপ্যারামিটার টিউনিং এবং নির্বাচনের পাশাপাশি ক্রস-ভ্যালিডেশনের জন্য সরঞ্জাম রয়েছে।

অতিরিক্তভাবে, MLlib-এ Pipelines API রয়েছে, যা আপনাকে বিভিন্ন ট্রান্সফরমার ব্যবহার করে ডেটা ট্রান্সফরমেশন পাইপলাইন তৈরি করতে দেয় যা পুনরায় কার্যকর করা যেতে পারে।

6. স্পার্ক-এনএলপি

স্পার্ক-এনএলপি জন স্নো ল্যাবস দ্বারা স্পার্ক ব্যবহার করে দক্ষ প্রাকৃতিক ভাষা প্রক্রিয়াকরণ কার্য সম্পাদনের জন্য তৈরি একটি লাইব্রেরি। এটিতে অন্তর্নির্মিত সরঞ্জাম রয়েছে যা সাধারণ কাজের জন্য টীকা বলা হয় যেমন:

  • টোকেনাইজেশন (শব্দের স্ট্রিং থেকে সংখ্যার ভেক্টর তৈরি করা)
  • শব্দ এমবেডিং তৈরি করা (ভেক্টরের মাধ্যমে শব্দের মধ্যে সম্পর্ক সংজ্ঞায়িত করা)
  • পার্ট-অফ-স্পীচ ট্যাগ (কোন শব্দ বিশেষ্য? কোনটি ক্রিয়া?)

এই কোডল্যাবের সুযোগের বাইরে থাকাকালীন, spark-nlp এছাড়াও TensorFlow- এর সাথে চমৎকার একত্রিত করে।

সম্ভবত সবচেয়ে উল্লেখযোগ্যভাবে, স্পার্ক-এনএলপি স্পার্ক MLlib-এর ক্ষমতা প্রসারিত করে এমন উপাদান প্রদান করে যা সহজেই MLlib পাইপলাইনে স্লট করে।

7. প্রাকৃতিক ভাষা প্রক্রিয়াকরণের জন্য সর্বোত্তম অনুশীলন

আমরা আমাদের ডেটা থেকে দরকারী তথ্য বের করার আগে, আমাদের কিছু গৃহস্থালির যত্ন নিতে হবে। আমরা যে প্রিপ্রসেসিং পদক্ষেপগুলি গ্রহণ করব তা নিম্নরূপ:

টোকেনাইজেশন

প্রথম জিনিসটি আমরা ঐতিহ্যগতভাবে করতে চাই তা হল ডেটা "টোকেনাইজ"। এতে ডেটা নেওয়া এবং "টোকেন" বা শব্দের উপর ভিত্তি করে বিভক্ত করা জড়িত। সাধারণত, আমরা এই ধাপে যতিচিহ্ন মুছে ফেলি এবং সমস্ত শব্দ ছোট হাতের অক্ষরে সেট করি। উদাহরণস্বরূপ, ধরা যাক আমাদের নিম্নলিখিত স্ট্রিং আছে: What time is it? টোকেনাইজেশনের পরে, এই বাক্যটিতে চারটি টোকেন থাকবে: " what" , "time", "is", "it". আমরা চাই না যে মডেলটি দুটি ভিন্ন ক্যাপিটালাইজেশন সহ দুটি ভিন্ন শব্দ হিসাবে what ব্যবহার করুক। উপরন্তু, বিরাম চিহ্ন সাধারণত শব্দগুলি থেকে অনুমান শিখতে আমাদের সাহায্য করে না, তাই আমরা এটিও বাদ দিই।

স্বাভাবিককরণ

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

কান্ড

স্টেমিং শব্দগুলিকে তাদের মূল অর্থ দিয়ে প্রতিস্থাপন করবে। উদাহরণস্বরূপ, "কার", "কারস" এবং "কারের" শব্দগুলিকে "কার" শব্দ দিয়ে প্রতিস্থাপিত করা হবে, কারণ এই সমস্ত শব্দগুলি তাদের মূলে একই জিনিস বোঝায়।

স্টপওয়ার্ড অপসারণ

স্টপওয়ার্ডগুলি হল "এবং" এবং "দ্য" এর মতো শব্দ যা সাধারণত একটি বাক্যের শব্দার্থগত অর্থে মূল্য যোগ করে না। আমরা সাধারণত আমাদের পাঠ্য ডেটাসেটের গোলমাল কমানোর উপায় হিসাবে এগুলি সরাতে চাই।

8. কাজের মাধ্যমে চলমান

আসুন আমরা যে কাজটি চালাতে যাচ্ছি তা দেখে নেওয়া যাক। কোডটি Cloud-dataproc/codelabs/spark-nlp/topic_model.py এ পাওয়া যাবে। কি ঘটছে তা বোঝার জন্য এটি এবং সংশ্লিষ্ট মন্তব্যগুলি পড়তে অন্তত কয়েক মিনিট ব্যয় করুন। এছাড়াও আমরা নীচের কয়েকটি বিভাগ হাইলাইট করব:

# Python imports
import sys

# spark-nlp components. Each one is incorporated into our pipeline.
from sparknlp.annotator import Lemmatizer, Stemmer, Tokenizer, Normalizer
from sparknlp.base import DocumentAssembler, Finisher

# A Spark Session is how we interact with Spark SQL to create Dataframes
from pyspark.sql import SparkSession

# These allow us to create a schema for our data
from pyspark.sql.types import StructField, StructType, StringType, LongType

# Spark Pipelines allow us to sequentially add components such as transformers
from pyspark.ml import Pipeline

# These are components we will incorporate into our pipeline.
from pyspark.ml.feature import StopWordsRemover, CountVectorizer, IDF

# LDA is our model of choice for topic modeling
from pyspark.ml.clustering import LDA

# Some transformers require the usage of other Spark ML functions. We import them here
from pyspark.sql.functions import col, lit, concat

# This will help catch some PySpark errors
from pyspark.sql.utils import AnalysisException

# Assign bucket where the data lives
try:
    bucket = sys.argv[1]
except IndexError:
    print("Please provide a bucket name")
    sys.exit(1)

# Create a SparkSession under the name "reddit". Viewable via the Spark UI
spark = SparkSession.builder.appName("reddit topic model").getOrCreate()

# Create a three column schema consisting of two strings and a long integer
fields = [StructField("title", StringType(), True),
          StructField("body", StringType(), True),
          StructField("created_at", LongType(), True)]
schema = StructType(fields)

# We'll attempt to process every year / month combination below.
years = ['2016', '2017', '2018', '2019']
months = ['01', '02', '03', '04', '05', '06',
          '07', '08', '09', '10', '11', '12']

# This is the subreddit we're working with.
subreddit = "food"

# Create a base dataframe.
reddit_data = spark.createDataFrame([], schema)

# Keep a running list of all files that will be processed
files_read = []

for year in years:
    for month in months:

        # In the form of <project-id>.<dataset>.<table>
        gs_uri = f"gs://{bucket}/reddit_posts/{year}/{month}/{subreddit}.csv.gz"

        # If the table doesn't exist we will simply continue and not
        # log it into our "tables_read" list
        try:
            reddit_data = (
                spark.read.format('csv')
                .options(codec="org.apache.hadoop.io.compress.GzipCodec")
                .load(gs_uri, schema=schema)
                .union(reddit_data)
            )

            files_read.append(gs_uri)

        except AnalysisException:
            continue

if len(files_read) == 0:
    print('No files read')
    sys.exit(1)

# Replacing null values with their respective typed-equivalent is usually
# easier to work with. In this case, we'll replace nulls with empty strings.
# Since some of our data doesn't have a body, we can combine all of the text
# for the titles and bodies so that every row has useful data.

df_train = (
    reddit_data
    # Replace null values with an empty string
    .fillna("")
    .select(
         # Combine columns
        concat(
            # First column to concatenate. col() is used to specify that we're referencing a column
            col("title"),
            # Literal character that will be between the concatenated columns.
            lit(" "),
            # Second column to concatenate.
            col("body")
        # Change the name of the new column
        ).alias("text")
    )
)

# Now, we begin assembling our pipeline. Each component here is used to some transformation to the data.
# The Document Assembler takes the raw text data and convert it into a format that can
# be tokenized. It becomes one of spark-nlp native object types, the "Document".
document_assembler = DocumentAssembler().setInputCol("text").setOutputCol("document")

# The Tokenizer takes data that is of the "Document" type and tokenizes it.
# While slightly more involved than this, this is effectively taking a string and splitting
# it along ths spaces, so each word is its own string. The data then becomes the
# spark-nlp native type "Token".
tokenizer = Tokenizer().setInputCols(["document"]).setOutputCol("token")

# The Normalizer will group words together based on similar semantic meaning.
normalizer = Normalizer().setInputCols(["token"]).setOutputCol("normalizer")

# The Stemmer takes objects of class "Token" and converts the words into their
# root meaning. For instance, the words "cars", "cars'" and "car's" would all be replaced
# with the word "car".
stemmer = Stemmer().setInputCols(["normalizer"]).setOutputCol("stem")

# The Finisher signals to spark-nlp allows us to access the data outside of spark-nlp
# components. For instance, we can now feed the data into components from Spark MLlib.
finisher = Finisher().setInputCols(["stem"]).setOutputCols(["to_spark"]).setValueSplitSymbol(" ")

# Stopwords are common words that generally don't add much detail to the meaning
# of a body of text. In English, these are mostly "articles" such as the words "the"
# and "of".
stopword_remover = StopWordsRemover(inputCol="to_spark", outputCol="filtered")

# Here we implement TF-IDF as an input to our LDA model. CountVectorizer (TF) keeps track
# of the vocabulary that's being created so we can map our topics back to their
# corresponding words.
# TF (term frequency) creates a matrix that counts how many times each word in the
# vocabulary appears in each body of text. This then gives each word a weight based
# on its frequency.
tf = CountVectorizer(inputCol="filtered", outputCol="raw_features")

# Here we implement the IDF portion. IDF (Inverse document frequency) reduces
# the weights of commonly-appearing words.
idf = IDF(inputCol="raw_features", outputCol="features")

# LDA creates a statistical representation of how frequently words appear
# together in order to create "topics" or groups of commonly appearing words.
lda = LDA(k=10, maxIter=10)

# We add all of the transformers into a Pipeline object. Each transformer
# will execute in the ordered provided to the "stages" parameter
pipeline = Pipeline(
    stages = [
        document_assembler,
        tokenizer,
        normalizer,
        stemmer,
        finisher,
        stopword_remover,
        tf,
        idf,
        lda
    ]
)

# We fit the data to the model.
model = pipeline.fit(df_train)

# Now that we have completed a pipeline, we want to output the topics as human-readable.
# To do this, we need to grab the vocabulary generated from our pipeline, grab the topic
# model and do the appropriate mapping.  The output from each individual component lives
# in the model object. We can access them by referring to them by their position in
# the pipeline via model.stages[<ind>]

# Let's create a reference our vocabulary.
vocab = model.stages[-3].vocabulary

# Next, let's grab the topics generated by our LDA model via describeTopics(). Using collect(),
# we load the output into a Python array.
raw_topics = model.stages[-1].describeTopics().collect()

# Lastly, let's get the indices of the vocabulary terms from our topics
topic_inds = [ind.termIndices for ind in raw_topics]

# The indices we just grab directly map to the term at position <ind> from our vocabulary.
# Using the below code, we can generate the mappings from our topic indices to our vocabulary.
topics = []
for topic in topic_inds:
    _topic = []
    for ind in topic:
        _topic.append(vocab[ind])
    topics.append(_topic)

# Let's see our topics!
for i, topic in enumerate(topics, start=1):
    print(f"topic {i}: {topic}")

চাকরী চালানো

এর এখন এগিয়ে যান এবং আমাদের কাজ চালানো যাক. এগিয়ে যান এবং নিম্নলিখিত কমান্ড চালান:

gcloud dataproc jobs submit pyspark --cluster ${CLUSTER_NAME}\
    --region ${REGION}\
    --properties=spark.jars.packages=com.johnsnowlabs.nlp:spark-nlp_2.11:2.7.2\
    --driver-log-levels root=FATAL \
    topic_model.py \
    -- ${BUCKET_NAME}

এই কমান্ডটি আমাদের ডেটাপ্রোক জবস এপিআই লিভারেজ করতে দেয়। pyspark কমান্ডটি অন্তর্ভুক্ত করে আমরা ক্লাস্টারে ইঙ্গিত করছি যে এটি একটি PySpark কাজ। আমরা এখানে উপলব্ধ ক্লাস্টারের নাম, ঐচ্ছিক পরামিতি এবং কাজ সম্বলিত ফাইলের নাম সরবরাহ করি। আমাদের ক্ষেত্রে, আমরা পরামিতি প্রদান করছি --properties যা আমাদের স্পার্ক, ইয়ার্ন বা ডেটাপ্রোকের জন্য বিভিন্ন বৈশিষ্ট্য পরিবর্তন করতে দেয়। আমরা স্পার্ক সম্পত্তি packages পরিবর্তন করছি যা আমাদের স্পার্ককে জানাতে দেয় যে আমরা আমাদের কাজের সাথে প্যাকেজ হিসাবে spark-nlp অন্তর্ভুক্ত করতে চাই। এছাড়াও আমরা --driver-log-levels root=FATAL পরামিতি প্রদান করছি যা PySpark থেকে ত্রুটি ছাড়া বেশিরভাগ লগ আউটপুট দমন করবে। সাধারণভাবে, স্পার্ক লগগুলি সশব্দ হতে থাকে।

সবশেষে, -- ${BUCKET} পাইথন স্ক্রিপ্টের জন্য একটি কমান্ড লাইন আর্গুমেন্ট যা বাকেটের নাম প্রদান করে। -- এবং ${BUCKET} এর মধ্যে স্থানটি নোট করুন।

কাজ চালানোর কয়েক মিনিট পরে, আমাদের মডেলগুলি ধারণকারী আউটপুট দেখতে হবে:

167f4c839385dcf0.png

অসাধারণ!! আপনি আপনার মডেল থেকে আউটপুট দেখে প্রবণতা অনুমান করতে পারেন? আমাদের সম্পর্কে কেমন?

উপরের আউটপুট থেকে, কেউ প্রাতঃরাশের খাবার সম্পর্কিত টপিক 8 থেকে এবং টপিক 9 থেকে ডেজার্টের একটি প্রবণতা অনুমান করতে পারে।

9. পরিচ্ছন্নতা

এই কুইকস্টার্টটি সম্পূর্ণ করার পরে আপনার GCP অ্যাকাউন্টে অপ্রয়োজনীয় চার্জ এড়াতে:

  1. আপনার তৈরি করা পরিবেশের জন্য ক্লাউড স্টোরেজ বালতি মুছুন
  2. Dataproc পরিবেশ মুছুন

আপনি যদি এই কোডল্যাবের জন্য একটি প্রকল্প তৈরি করেন তবে আপনি ঐচ্ছিকভাবে প্রকল্পটি মুছে ফেলতে পারেন:

  1. GCP কনসোলে, প্রকল্প পৃষ্ঠায় যান।
  2. প্রকল্প তালিকায়, আপনি যে প্রকল্পটি মুছতে চান সেটি নির্বাচন করুন এবং মুছুন ক্লিক করুন।
  3. বাক্সে, প্রজেক্ট আইডি টাইপ করুন এবং তারপরে প্রজেক্ট মুছে ফেলতে শাট ডাউন ক্লিক করুন।

লাইসেন্স

এই কাজটি ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন 3.0 জেনেরিক লাইসেন্স এবং Apache 2.0 লাইসেন্সের অধীনে লাইসেন্সপ্রাপ্ত।