خیلی هامون ابر کلمات رو تو شبکه های اجتماعی دیدیم و یا خودمون به اشتراک گذاشتیم. به طور کلی ساختار ابر کلمات به این صورته که، هرچه قدر تعداد تکرار هر کلمه بیشتر باشه فضایی که اون کلمه توی عکس اشغال می کنه بیشتره.
داستان این پست از اونجایی شروع شد که می خواستم ببینم ابر کلمات شاعران معروف ما چه شکلیه و با خودم گفتم که خوبه دست به کار شم، صورت مسئله به این قشنگی حیفه حل نشه خلاصه داستان به سادگی صورت مسئله نبود و یه سری چالش هایی هم داشت از همه مهم تر اینکه چه طوری این منبع داده از شعر ها رو پیدا کنم اصلا چه طوری این ابر کلمات رو بسازم و ... تو ادامه این پست قرار درباره این چالش ها صحبت کنم و کارایی رو که انجام دادم توضیح بدم اگه دوست دارین بدونید که چالش های دیگه چی بوده و چه طور حل شده ادامه رو بخونید ولی اگه نه می خواین فقط خروجی ها رو ببیند توی این لینک از گیت هاب که کل پروژه توش هست می تونین خروجی برنامه رو برای بعضی از شاعرامون ببیند و مثل من کیف کنید.
یکی از بهترین منابع برای شعر فارسی بدون شک وبسایت گنجور هست برای این کار ما از منابع وبسایت گنجور استفاده کردیم به این صورت که یه سرچ ساده تو وبسایت زدم و دیدم که نمیشه به سادگی دیتا بیس مربوط به شعرا رو پیدا کرد پس دست به کار شدم و دیدم بهترین راه استفاده از نرم افزار ساغر هست پس نصبش کردم و با یه کم ور رفتن باهاش فهمیدم که از یک دیتاست sqlite استفاده می کنه چند تا کار می شد انجام بدم یکی به تفکیک شاعرا از دیتا ها خروجی بگیرم که نه راه حل معقولی نبود پس رفتم سراغ یه ابزار خوب، از کتابخونه sqlite تو python استفاده کردم و با چند خط کد خیلی راحت به دیتاست دسترسی پیدا کردم.
import sqlite3 conn = sqlite3.connect('ganjoor.s3db')
اگه بخواین می تونین تو اون لینک گیت هابی که اول پست دادم و دوباره اینجا هم می زارم دیتا ست گنجور رو پیدا کنید و باهاش مثل من بازی کنید .
تا اینجا مرحله ی اول با موفقیت تموم شد و موفق شده بودم دیتا ها رو پیدا کنم.
برای اینکه بتونیم ساختاری رو که نیاز داریم از دیتا بیس بیرون بکشم نیاز به این داشتیم که بفهمم دیتابیس به چه صورتی طراحی شده با استفاده از دستور زیر اسم جداولی که در دیتا بیس موجوده رو دریافت کردیم .
cursor = conn.execute("SELECT name FROM sqlite_master WHERE type='table';") print(cursor. fetchall()) >> [('cat',), ('poem',), ('poet',), ('verse',), ('fav',), ('gver',), ('gil',), ('poemsnd',), ('sndsync',)]
تو خروجی کد بالا ( که بعد از << مشخص شده) میشه دید که ما 9 تا جدول داریم .
تو مرحله بعد نوبت به بررسی فیلد های مربوط به جداول میشه برای اینکه بتونیم فیلد های موجود رو ببینم می تونیم از دستور زیر استفاده کنیم.
cursor.execute("pragma table_info('cat')") print(cursor.fetchall()) >> [(0, 'id', 'INTEGER', 1, None, 1), (1, 'poet_id', 'INTEGER', 0, None, 0), (2, 'text', 'NVARCHAR(100)', 0, None, 0), (3, 'parent_id', 'INTEGER', 0, None, 0), (4, 'url', 'NVARCHAR(255)', 0, None, 0)]
به عنوان مثال جدول cat که خلاصه شده category هست 5 تا فیلد داره که به ترتیب شامل :
بعد از اینکه همه ی فیلده ای جداول دیتا بیس رو بررسی کردم فهمیدم که چهار جدول cat, poem, poet, verse جداولی هستن که بهشون برای این کار نیاز داریم برای درست کردن ابر کلمات ما نیاز به متن تمام شعر های یک شاعر داریم که با شمارش کلمات اون بتونیم ابر کلمات رو بسازیم.
نتیجه ی بررسی ها رو میشه به صورت شکل زیر خلاصه کرد که ارتباطات بین جداول هم تو شکل زیر مشخص شده.
اول از همه از جدول cat(category) شروع کنیم چیزایی چیزی که بیشتر از همه توی این جدول به چشم می یاد ارتباط بین cat و poet(شاعر) هست به این صورت که هر شاعر ممکنه تو دسته های مختلفی شعر داشته باشه مثلا برای حافظ ما غزلیات رو به عنوان یک دسته و منظومه ها رو به عنوان یه دسته دیگه داریم با این توضیح ارتباط داخلی cat هم مشخص شد .
جدول بعدی poem (شعر یا منظومه) هر شاعر قائدتا شعر هایی داره که اسم اون شعر ها رو ما توی این جدول نگه داری می کنیم و اما جدول آخر verse(آیه یا شعر) که متن مربوط به هر شعر رو در اینجا میشه پیدا کرد. و صد البته ارتباط هایی که بینشون هست.
به عنوان مثال من می خوام تمام شعر های حافظ رو پیدا کنم برای این کار اول باید آیدی مربوط به حافظ رو توی جدول poet پیدا کنم بعد تمامی cat هایی که آیدی حافظ رو توی فیلد poet_id دارن تا اینجا ما منظومه ها یا مجموعه هایی که حافظ نوشته رو پیدا کردیم حالا میریم سراغ poem و توی اون با استفاده از cat_id شعر هایی که برای حافظ هست رو در نظر می گیرم و در انتها از جدول verse کل ابیات مربوط به حافظ رو بیرون می کشیم..
بذارین یه لیوان آب بخورم یه کم داستان پیچیده شد .. توی این فرصت به دیدتون بهترین روش برای گرفتن خروجی برای این دیتا ها چیه؟
بله حلقه ی for ... . اگه جواب شما هم استفاده از این حلقه بوده باید بگم که راه حل ساده تری هم هست و اون هم استفاده از JOIN در دیتابیس اینجا بود که یکی از دوستام وارد عمل شد و بهم کمک کرد همینجا جا داره ازش تشکر کنم (مرسی کوچولو:) .
"SELECT verse.text from poet left join cat on poet.id = cat.poet_id left join poem on cat.id = poem.cat_id left join verse on verse.poem_id = poem.id where poet.id={}"
خیلی قشنگ کاری رو که من با چند تا حلقه ی for انجام دادم رو توی یه sql query خلاصه کرد. شما هم ببینید و مثل من لذت ببرید.
برای این کشیدن ابر کلمات اول از همه باید تعداد کلماتی که تو شعر ها به کار رفته رو به دست بیاریم، تو مرحله ی قبل ما متن تموم شعر ها رو به دست آوردیم حالا باید بریم سراغ کلمه شماری برای این کار از کد زیر استفاده کردم.
بعد از اینکه چند بار این کار رو انجام دادم و خروجی رو دیدم متوجه شدم یه سری کلمات مثل ز ، در، اما و ... تکرار خیلی زیادی دارن و باید از روند شمارش حذف بشن یه کم سرچ کردم و دیدم که این جور کلمات تو انگلیسی معروف به stop words هستن و معادل نه چندان دلچسب واژه ایستادهضشده رو در فارسی براش درنظر گرفتن طبق تعریف ویکی پدیا :
کلماتی هستند که قبل یا بعد از پردازش دادههای زبان طبیعی پالایش (تصفیه) میشوند. معمولا واژههای پالایشی به رایجترین کلمات در یک زبان اشاره دارد، اما هیچ فهرست جامعی از این واژهها، که در تمام ابزارهای پردازش زبان طبیعی استفاده شوند، موجود نیست.
اول تصمیم گرفتم خودم یه لیست ازشون بسازم بعد گفتم چه کاریه سرچ می کنم و تونستم چند تا لیست خوب پیدا کنم ولی متاسفانه منابعی که ازشون استفاده کردم رو یادداشت نکردم :( . از اینجا هم می تونین این کلماتی رو که در نظر نگرفتم رو ببنید.
رسیدیم به قسمت ساده ماجرا یعنی کشیدن ابر کلمات این از کتابخونه wordcloud_fa استفاده کردم که با یه سرچ ساده می تونین کلی آموزش ازش تو نت پیدا کنید باس همین زیاد جزئیات این کتاب خونه رو نمی گم و فقط به آوردن اسمش اینجا بسنده می کنیم.
همیشه خروجی کار خیلی لذت بخشه یه چند از این خروجی ها باز هم ببینم بد نیست.
بقیه ی این خروجی ها و هر چیزی که لازمه برای ایجاد این ابر کلمات داشته باشین رو می تونین توی این ریپوی گیت هاب ببیند.