Whatsapp Chat Analyzer

Jadi ceritanya mahasiswa asal Indonesia yang tinggal di Stockholm menggunakan whatsapp sebagai media komunikasi untuk saling berbagi informasi hingga keluh kesah. Karena jumlah pesertanya yang memang tidak terlalu banyak (20+++), saya rasa, dibanding grup Facebook atau mailing list, group chat whatsapp memang lebih cocok untuk komunikasi yang membutuhkan respons yang relatif cepat.

Berawal dari rasa ingin tahu akan esensi dari pembicaraan di grup whatsapp tersebut, saya pun penasaran dan ingin menganalisis kontennya. Bak gayung bersambut, ternyata whatsapp menyediakan fitur untuk mengarsip pembicaraan dan mengirimkannya lewat email. Caranya cukup tahan percakapan yang ingin diarsip. Kemudian pilih ‘Email conversation’ > ‘Without media’. Gambar di bawah menunjukkan langkah-langkah tersebut. Nama dan tulisan disamarkan untuk menjaga privasi.

archive conversationwithout media

Hasilnya adalah sebuah file text. Setiap pesan chat ditulis pada satu baris dengan format “Tanggal – User: Pesan” (tanpa tanda kutip). Kode python dibawah digunakan untuk membaca file tersebut.

def read(filename):
    """ Read text file containing whatsapp chat and return the list of list of time, author, and its text
    :param filename: the filename of the chat text file
    :return: chat 2d list
    """
    chat = []
    with open(filename, 'r') as f:
        for line in f:
            lines = line.split(' - ')  # Divide between date and the rest
            if len(lines) > 1:
                lines2 = lines[1].split(': ')  # Divide between user and text
                if len(lines2) > 1:
                    speaker = lines2[0]
                    text = lines2[1]
                else:
                    speaker = ''
                    text = lines2[0]
                timestamp = lines[0]
            else:
                timestamp = ''
                speaker = ''
                text = lines[0]
            chat += [[timestamp, speaker, text]]
    return chat

Sip, setelah kita punya datanya, kita bisa geledah dan obrak-abrik isinya untuk dianalisis lebih lanjut.

Statistika dasar

Pertama-pertama. kita ingin tahu ada berapa banyak baris dalam percakapan.

date

Hmmm, ternyata ada sekitar 137 pesan per harinya. Lumayan aktif juga.

Kemudian kita ingin tahu siapa sih yang paling sering bunyi dan siapa yang paling senyap. Kita hitung total berapa banyak pesan yang ditulis per orangnya.

user frequency
Nama dan nomor telepon disamarkan untuk menjaga privasi

Wah, ternyata ada perbedaan yang cukup jomplang antara yang paling sering mengirim pesan dengan yang paling tidak sering mengirim pesan. Bahkan yang nomor 1 jumlah pesannya sekitar 2 kali dari yang nomor 2. Distribusi ini sepertinya mengikuti Zipf’s Law.

Frekuensi kata

Fitur utama dalam analisis dokumen biasanya adalah frekuensi kata. Model ini biasanya dikenal dengan nama Bag-of-Words. Kalau misalkan fitur ini dirasa kurang cukup ekspresif, biasanya ditambah lagi menjadi n-grams model, dimana kata dihitung kemunculannya bersama kata lain.

Dalam analisis dokumen juga biasanya terdapat kata-kata yang frekuensinya tinggi namun tidak memberi makna lebih kepada tulisan, seperti kata hubung dan teman-temannya. Kumpulan kata-kata tersebut sering disebut dengan istilah stopwords. Stopwords ini biasanya dihilangkan sebelum analisis agar proses lebih ringkas dan akurat. Saya memakai daftar kata stopwords dari https://sites.google.com/site/kevinbouge/stopwords-lists yang ternyata mengambil dari thesis “A Study of Stemming Effects on Information Retrieval in Bahasa Indonesia“.

Sekarang kita coba hitung frekuensi kata dalam chat minus stopwords. Histogram hasilnya bisa dilihat di bawah.

word frequency

Hmm, menarik. Ternyata kata-kata yang paling banyak keluar adalah kata sambung yang salah ketik seperti ‘yg‘ dan ‘d‘.  Kata-kata lain yang banyak muncul adalah nama panggilan ke penghuni grup yang lain. Selain itu, ternyata grup ini cukup suka tertawa, terlihat dari 3 kemunculan ekspresi tawa yaitu ‘hahaha‘, ‘wkwk‘, dan ‘haha‘. Selain itu, ternyata grup ini rajin olah raga juga, dilihat dari kata ‘badminton‘ yang muncul lebih dari 200 kali.

Emoji

if a picture paints a thousand words then why can’t I paint you“. Kurang lebih itulah sepenggal lagu If dari Bread. Penggunaan emoji atau emoticon sangat kentara dalam chatting karena satu gambarnya bisa mengekspresikan hal yang sulit jika dicoba disampaikan dengan kata-kata. Penggunaan emoji ini sangat pesat hingga menimbulkan sentimen kalau nanti kita bisa kembali ke zaman Mesir kuno dengan tulisan hieroglyph-nya. Karena umumnya penggunaan emoji ini, saya pun mencoba menghitung frekuensi dari tiap-tiap emoji.

Yang agak menyulitkan mungkin adalah emoji ini direpresentasikan dalam unicode dan di-encode dalam UTF-8 sehingga harus dibuat fungsi konversinya dulu antar keduanya. Gambar untuk plot didapat dari https://github.com/github/gemoji/ yang saya dapat link-nya dari apps.timwhitlock.info/emoji/tables/unicode. Kesulitan lain adalah ternyata Python Image Library punya sedikit untuk png dengan transparency. Apa boleh buat, gambar emoji-nya pun harus saya konversi ke jpg dengan utilitas mogrify dari imagemagick. Histogram hasilnya bisa dilihat di gambar di bawah.

emoji frequency

Hmm, menarik. Bisa dilihat, emoji teratas adalah senyum sambil berkeringat yang saya baca sebagai ekspresi dari ‘hehe’. Sisanya adalah berbagai ekspresi untuk senyum dan tertawa. Tetapi emoji ke 3 yang agak aneh. Mata. Ada apa dengan mata? Emoji ke 8, ‘see no evil monkey’ juga aneh. Apakah ada hubungannya dengan emoji ke 3?

Topik

Target berikutnya adalah Topic modelling. Lazimnya, setahu saya ini memakai teknik Latent Dirichlet Allocation (LDA). Karena saya belum pernah implementasi teknik ini sebelumnya dan kekurangan waktu untuk mencoba, saya mencoba mencari apakah ada library lain siap pakai. Saya ketemu situs startup untuk klasifikasi teks http://www.monkeylearn.com/. Di situs tersebut terdapat servis untuk melakukan klasifikasi topik dokumen secara general. Untuk free account diberikan 1000 kali panggilan API. Yah, cukuplah untuk proyek kecil-kecilan ini.

monkeylearn1monkeylearn2

Karena model-nya dibangun dari korpus Bahasa Inggris, maka teks harus diterjemahkan dulu ke bahasa tersebut. Hal ini sebenarnya bisa mengurangi akurasi, akan tetapi akurasi bukan tujuan utama yang dicari. Pilihan pertama saya, Google Translate API, ternyata tidak gratis. Ini tentunya cukup memberatkan saya yang cuma mahasiswa. Saya pun memakai layanan alternatif dari Yandex, search engine buatan Rusia.

topic

Dan inilah hasilnya. Ternyata percakapan di grup whatsapp ini dikategorikan ke ‘Entertainment & Recreation’. Hmm, bisa jadi. Yang agak aneh adalah kategori kedua, ‘Anime’, yang merupakan subkategori dari Entertainment di atas karena seingat saya tidak ada diskusi tentang anime sama sekali di grup. Hmm, inilah sulitnya memakai model buatan orang. Sulit untuk dianalisis.

Sebenarnya masih ada lagi yang mau saya coba, seperti menggunakan t-SNE untuk melihat kemiripan antar user. Namun, apa daya TTM (thesis telah memanggil).

Kode lengkap dapat dilihat di https://github.com/mitbal/wca. Cukup ikuti petunjuk di README untuk menjalankan program.

Semoga bermanfaat. Salam.

16 thoughts on “Whatsapp Chat Analyzer

  1. hahahahah itu 5000an chat seoraaanggg..
    bal bal itu kayanya yang dipilih ’email conversation’ bal. kalo ‘archive conversation’ ntar malah ilang dari layar conversation-nya.

  2. Wah mas pengen juga bikin analisis gini, cuma stuck di download python, download programnya sama ngedapetin text chat wa. Selanjutnya gimana ya? Awam banget, haha

      • udah buka2 youtube learn as beginners bahasa python masih bingung, x_x
        dulu iseng2 cuma pake excel cuma bisa frekuensi doank hehe
        eksekusiin analisis utk salah satu grup chat wa-ku bisa mas?

      • Waduh, maaf saya merasa tidak enak kalau membaca pesan untuk orang karena saya rasa itu hal yang bersifat privasi. Mungkin bisa minta tolong temannya yang mengerti programming…

  3. Halo,

    Tertarik buat cobain scriptnya. Kena error saat deteksi datetime di line teksnya.

    D:\_P R O J E C T S_\wca>python wca.py tc07.txt
    Traceback (most recent call last):
    File “wca.py”, line 237, in
    start_date = convert_date(chat[0][0])
    File “wca.py”, line 167, in convert_date
    start_month = months[start_date[0].split(‘ ‘)[0]]
    KeyError: ’10:17PM’

    Di teks tsb, format datenya adalah:
    11:05AM, Feb 14 – [nama_user]

    Sedangkan di file yang lain, saya juga kena error yang sama dengan format datetime yang berbeda:10 Feb 09:02 – [nama_user]

    format datetime seperti apakah yang dipakai?

    Thanks!

    • Nah, ini yang saya takutkan. Karena format dari tanggal tidak diketahui dengan pasti, saya gunakan format sesuai dengan yang ada di text file yang saya dapatkan dimana untuk tanggal awal formatnya adalah
      Aug 8, 2014, 00:22 –
      sedangkan tanggal akhir formatnya
      Feb 6, 01:08 –
      yang mana tidak ada tahun sehingga saya asumsikan dia mengambil tahun saat ini.

      Kalau misalkan format tanggalnya seperti yang diberikan haris, ada yang pakai AM dan ada yang tidak pakai koma, maka fungsi convert_date harus dimodifikasi. Kalau saran saya instruksi-nya di-comment saja sehingga tidak dieksekusi walau harus kehilangan satu informasi tentang frekuensi pesan per hari karena tampaknya format untuk tiap file bisa berbeda-beda.

  4. Halo mas,

    Untuk 1 dan 2 sudah bisa dengan sedikit modifikasi di kode, namun pas yg emoji error:

    Traceback (most recent call last):
    File “wca.py”, line 280, in
    codepoint = f.split(‘\\’)[1][:-4]
    IndexError: list index out of range

    saya coba di linux dimodif sedikit bisa lg :D

    yang lama pas topic modelling per chat :D

    Untuk mengumpulkan data text ini mas iqbal backup setiap hari atau gmn? lumayan banyak kan ya 182 hari dan untuk pemrosesan yg Topic berapa lama tu?

    Thanks mas

    • Halo purbo,

      Backup-nya sih pas kemarin aja waktu mau coba analisis.
      Kalau topic modelling-nya sendiri, kalau pakai pretrained model bawaannya monkeylearn, jadi cepet cuma buat prediksi. Yang bikin lama itu translate ke bahasa inggris-nya, karena harus dikirim lewat internet tiap barisnya.

  5. Mas, saya coba kodenya untuk hitung rata – rata pesan perhari, saya pakai iPython dan cuman ubah variabel chat jadi read(‘whatsapp.txt) kaya dibawah ini.

    # Read the chat text file into chat list
    chat = read(‘whatsapp.txt’)

    # Date counting
    start_date = convert_date(chat[0][0])
    end_date = convert_date(chat[-1][0])
    num_days = (end_date – start_date).days
    print ‘From:’, start_date, ‘to’, end_date, ‘total:’, num_days, ‘days’

    Tapi tiba – tiba muncul pesan error gini:

    KeyError Traceback (most recent call last)
    in ()
    4
    5 # Date counting
    —-> 6 start_date = convert_date(chat[0][0])
    7 end_date = convert_date(chat[-1][0])
    8 num_days = (end_date – start_date).days

    in convert_date(txt)
    165 def convert_date(txt):
    166 start_date = txt.split(‘, ‘)
    –> 167 start_month = months[start_date[0].split(‘ ‘)[0]]
    168 start_day = int(start_date[0].split(‘ ‘)[1])
    169 if len(start_date) > 2:

    KeyError: ” ”

    Apa ya maksudnya itu?

    • Halo arifin. Maaf baru sempat balas.
      Wah, saya sudah lama tidak pegang kodenya. Kalau dari pesan errornya kayaknya ada format yg salah di salah satu baris input nya. Ini agak susah diperiksa kalau tidak ada contoh inputnya.

      Apakah arifin sudah solve error-nya?

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s