تکرار واژگان در ضرب‌المثل‌های فارسی

چند روز پیش داشتم درباره پردازش واژگان فکر می‌کردم که این سوال به ذهنم رسید که چه کلمه‌ای در ضرب‌المثل‌های فارسی بیشتر تکرار شده یا به بیان دیگر فارسی‌زبانان از چه واژه‌ای بیشتر استفاده کرده‌اند؟

با پیش‌فرض چند حدس (حدس می‌زدم واژه «خر» پرتکرارترین باشد)، در اولین قدم در اینترنت جست‌وجو کردم ولی به نتیجه‌ای نرسیدم و خب در قدم دوم مثل هر برنامه‌نویس دیگر خودم دست به کار شدم، در ادامه فرآیند حل مساله را دنبال می‌کنیم، البته یادآوری کنم شاید روش‌ها و کدها خیلی بهینه و تخصصی نباشند، به بزرگواری خودتان ببخشید


جمع‌آوری ضرب‌المثل‌ها

در اولین قدم برای تحلیل ضرب‌المثل‌ها، باید ضرب‌المثل‌ها را می‌داشتم و خب شروع کردم باز به جست‌وجو و چند سایت دیدم که دیتابیس ضرب‌المثل‌ها برای فروش گذاشته بودند ولی ترجیح دادم خودم جمع آوری کنم و باز دنبال سایتی گشتم که همه ضرب‌المثل‌ها را یکجا قرار داده باشد که در بین چند نمونه سایت http://www.zibasho.com/zarb که ضرب‌المثل‌ها را به تفکیک شروعشان با حروف الفبا قرار داده است بهتر از بقیه بود

خب ظاهرا ضرب‌المثل‌ها با شروع فقط ۲۹ حرف شروع می‌شدند، لینک‌ها را به کمک اینسپکت مرورگر جدا و در یک فایل به اسم links قرار دادم

http://www.zibasho.com/zarb/kh.htm
http://www.zibasho.com/zarb/ch.htm
http://www.zibasho.com/zarb/jim.htm
http://www.zibasho.com/zarb/t.htm
http://www.zibasho.com/zarb/p.htm
http://www.zibasho.com/zarb/b.htm
http://www.zibasho.com/zarb/a.htm
http://www.zibasho.com/zarb/zad.htm
http://www.zibasho.com/zarb/sad.htm
http://www.zibasho.com/zarb/shin.htm
http://www.zibasho.com/zarb/sin.htm
http://www.zibasho.com/zarb/z.htm
http://www.zibasho.com/zarb/r.htm
http://www.zibasho.com/zarb/zal.htm
http://www.zibasho.com/zarb/d.htm
http://www.zibasho.com/zarb/gaf.htm
http://www.zibasho.com/zarb/kaf.htm
http://www.zibasho.com/zarb/ghaf.htm
http://www.zibasho.com/zarb/f.htm
http://www.zibasho.com/zarb/ghayn.htm
http://www.zibasho.com/zarb/ayn.htm
http://www.zibasho.com/zarb/za.htm
http://www.zibasho.com/zarb/ta.htm
http://www.zibasho.com/zarb/ya.htm
http://www.zibasho.com/zarb/ha.htm
http://www.zibasho.com/zarb/vav.htm
http://www.zibasho.com/zarb/noon.htm
http://www.zibasho.com/zarb/mim.htm
http://www.zibasho.com/zarb/lam.htm

وارد هرکدام از این صفحات که بشوید ضرب‌المثل‌هایی که با آن حرف شروع می‌شوند را نوشته شده، پس با جمع‌آوری محتویات همه این صفحات، دیتابیسی از همه ضرب‌المثل‌های فارسی خواهیم داشت

برای جمع‌آوری ضرب‌المثل‌ها تابع پایتونی کوچکی نوشتم که این صفحات را اسکرپ می‌کند

def get():
    links = list()
    with open('links') as f:
        for line in f:
            links.append(line.replace('\n', ''))

        for l in links:
            print(l)
            html = urllib.request.urlopen(l)
            soup = BeautifulSoup(html, 'lxml')
            data = soup.findAll('p')
            for i in data:
                t = str(i)
                t = t.split('>')
                t = t[2].split('<')
                t = t[0].replace('ضرب المثل هاي ايراني', '')
                with open('db', 'a') as db:
                    db.write(t + '\n')
                print(t)

تابع هر لینک را از همان فایل links می‌خواند و در هر صفحه محتویات بین تگ‌های <p> که همان ضرب‌المثل‌ها هستند را با حذف اضافات در هر خط فایلی جدید بنام db می‌نویسد

حالا دیتابیسی فایلی با ۲هزار خط از ضرب‌المثل‌های فارسی داریم (البته کمی شلخته و نامنظم)

شمارش و پردازش ضرب‌المثل‌ها

برای شمارش تکرار کلمات، ابتدا یک فایل به اسم stopwords.txt از فعل‌ها، حرف‌های ربط و علامت‌ها و واژگان بی‌ربط ساختم که آن‌ها را از بررسی حذف کنیم

https://gist.github.com/mostafaasadi/fd24ae7f89556acdc66a847e588ff3d0

https://gist.github.com/mostafaasadi/fd24ae7f89556acdc66a847e588ff3d0

و حالا این تابع پایتونی که با خواندن محتویات فایل db و حذف اضافات با استناد به فایل stepwords.txt تکرار واژگان در ضرب‌المثل‌های فارسی را شمارش کرده و نمایش می‌دهد

def count():
    swl = []
    with open('stopwords.txt', 'r') as f:
        for line in f:
            for s in line.split():
                swl.append(str(s))
    with open('db', 'r') as f:
        words = f.read().split()
        wordCount = dict(Counter(words))
        wordCount = sorted(wordCount.items(), key=lambda x: x[1])

        for i in wordCount:
            if i[0] not in swl:
                print(i[0] + ' :: ' + str(i[1]))

خب نتیجه واقعا جالب بود 😎 ولی متاسفانه حدسم یک پله عقب افتاد 😅

سر ۶۶ بار

خر ۵۶ بار

دست ۵۲ بار

آب ۴۵ بار

خدا ۴۲ بار

كار ۳۳ بار

سگ ۳۱ بار

زن ۳۰ بار

خانه، صد ۲۸ بار

مال ۲۴ بار

مار، نون ۲۳ بار

شتر ۲۲ بار

مرد ۲۱ بار

شب، گربه ۲۰ بار

برای درک بهتر و جذاب‌تر آمار و ارقام یک تابع دیگر پایتونی هم نوشتم که ابر واژگان ضرب‌المثل‌ها را بر اساس تعداد تکرار طراحی می‌کرد

def wc():
    wl = []
    text = ''
    swl = []
    with open('stopwords.txt', 'r') as f:
        for line in f:
            for s in line.split():
                swl.append(str(s))
    stopwords = set(swl)
    with open('db', 'r') as f:
        for line in f:
            for s in line.split():
                if s not in stopwords:
                    wl.append(str(convert(s.replace('،', ''))))
    text = '\n'.join(wl)
    wordcloud = PersianWordCloud(
        only_persian=True,
        max_words=150,
        margin=5,
        width=800,
        height=800,
        min_font_size=1,
        colormap='Accent',
        max_font_size=500,
        background_color="white"
    ).generate(text)
    image = wordcloud.to_image()
    image.show()
    image.save('result.png')

نهایتا خروجی به این شکل است 😍

ابرواژگان ضرب‌المثل‌های فارسی
ابرواژگان ضرب‌المثل‌های فارسی

کد کامل همه این فرآیند هم روی گیتهاب در خدمت شما 🆓

https://gist.github.com/mostafaasadi/5e29fa74441ddb78e095961ccec4376a