Habraiting: membangun awan kata-kata berbahasa Rusia pada contoh header Habra

Hai, Habr.

Di bagian terakhir Habraiting, sebuah metode untuk membangun cloud kata untuk istilah bahasa Inggris diterbitkan. Tentu saja, tugas mengurai kata-kata Rusia jauh lebih rumit, tetapi seperti yang disarankan dalam komentar, ada perpustakaan siap pakai untuk ini.

Mari kita cari tahu cara membuat gambar seperti itu:



Kita juga akan melihat awan artikel Habr selama bertahun-tahun.

Siapa peduli apa yang terjadi, tolong, di bawah kucing.

Parsing


Dataset awal, seperti dalam kasus sebelumnya, adalah csv dengan tajuk artikel Habr dari 2006 hingga 2019. Jika ada yang tertarik untuk mencobanya sendiri, Anda dapat mengunduhnya di sini .

Untuk memulai, muat data ke dalam Bingkai Data Pandas dan pilih header untuk tahun yang diperlukan.

df = pd.read_csv(log_path, sep=',', encoding='utf-8', error_bad_lines=True, quotechar='"', comment='#') if year != 0: dates = pd.to_datetime(df['datetime'], format='%Y-%m-%dT%H:%MZ') df['datetime'] = dates df = df[(df['datetime'] >= pd.Timestamp(datetime.date(year, 1, 1))) & ( df['datetime'] < pd.Timestamp(datetime.date(year + 1, 1, 1)))] # Remove some unicode symbols def unicode2str(s): try: return s.replace(u'\u2014', u'-').replace(u'\u2013', u'-').replace(u'\u2026', u'...').replace(u'\xab', u"'").replace(u'\xbb', u"'") except: return s titles = df["title"].map(unicode2str, na_action=None) 

Fungsi unicode2str diperlukan untuk menghapus berbagai karakter unicode yang rumit dari output konsol, seperti kutipan non-standar - di bawah OSX, ini juga berfungsi, dan ketika mengeluarkan ke Windows Powershell, kesalahan “UnicodeEncodeError: 'charmap' codec tidak dapat menyandikan karakter” dikeluarkan. Terlalu malas untuk berurusan dengan pengaturan Powershell, jadi metode ini ternyata paling mudah.

Langkah selanjutnya adalah memisahkan kata-kata berbahasa Rusia dari yang lainnya. Ini cukup sederhana - kami menerjemahkan karakter ke pengkodean ascii, dan melihat apa yang tersisa. Jika ada lebih dari 2 karakter yang tersisa, maka kami menganggap kata "penuh" (satu-satunya pengecualian yang muncul dalam pikiran adalah bahasa Go, namun, mereka yang ingin dapat menambahkannya sendiri).

 def to_ascii(s): try: s = s.replace("'", '').replace("-", '').replace("|", '') return s.decode('utf-8').encode("ascii", errors="ignore").decode() except: return '' def is_asciiword(s): ascii_word = to_ascii(s) return len(ascii_word) > 2 

Tugas selanjutnya adalah menormalkan kata - untuk mendapatkan kata cloud, setiap kata harus ditampilkan dalam satu kasus dan kemunduran. Untuk bahasa Inggris, kami cukup menghapus "'s "di bagian akhir, dan juga menghapus karakter lain yang tidak dapat dibaca seperti tanda kurung. Saya tidak yakin metode ini benar secara ilmiah (dan saya bukan ahli bahasa), tetapi untuk tugas ini cukup.

 def normal_eng(s): for sym in ("'s", '{', '}', "'", '"', '}', ';', '.', ',', '[', ']', '(', ')', '-', '/', '\\'): s = s.replace(sym, ' ') return s.lower().strip() 

Sekarang hal yang paling penting, demi yang semuanya sebenarnya dimulai, adalah penguraian kata-kata Rusia. Seperti yang disarankan dalam komentar di bagian sebelumnya, untuk Python ini dapat dilakukan dengan menggunakan pymorphy2 library. Mari kita lihat cara kerjanya.

 import pymorphy2 morph = pymorphy2.MorphAnalyzer() res = morph.parse(u"") for r in res: print r.normal_form, r.tag.case 

Untuk contoh ini, kami memiliki hasil sebagai berikut:

  NOUN,inan,masc sing,datv datv  NOUN,inan,masc sing,loc2 loc2  NOUN,inan,neut sing,datv datv  NOUN,inan,masc sing,gen2 gen2 

Untuk kata "dunia", MorphAnalyzer mendefinisikan "bentuk normal" sebagai kata benda "dunia" (atau "dunia", namun, saya tidak tahu apa itu), tunggal, dan kemungkinan kasus sebagai dativ, genitiv, atau locative.

Menggunakan parsing MorphAnalyzer cukup sederhana - pastikan kata tersebut adalah kata benda, dan dapatkan bentuk normalnya.

 morph = pymorphy2.MorphAnalyzer() def normal_rus(w): res = morph.parse(w) for r in res: if 'NOUN' in r.tag: return r.normal_form return None 

Tetap mengumpulkan semuanya dan melihat apa yang terjadi. Kode terlihat seperti ini (fragmen yang tidak relevan dihapus):

 from collections import Counter c_dict = Counter() for s in titles.values: for w in s.split(): if is_asciiword(w): # English word or digit n = normal_eng(w) c_dict[n] += 1 else: # Russian word n = normal_rus(w) if n is not None: c_dict[n] += 1 

Pada output kami memiliki kamus kata-kata dan jumlah kemunculannya. Kami memperoleh 100 yang pertama dan membentuk dari mereka awan popularitas kata-kata:

 common = c_dict.most_common(100) wc = WordCloud(width=2600, height=2200, background_color="white", relative_scaling=1.0, collocations=False, min_font_size=10).generate_from_frequencies(dict(common)) plt.axis("off") plt.figure(figsize=(9, 6)) plt.imshow(wc, interpolation="bilinear") plt.title("%d" % year) plt.xticks([]) plt.yticks([]) plt.tight_layout() file_name = 'habr-words-%d.png' % year plt.show() 

Namun hasilnya ternyata sangat aneh:



Dalam bentuk teks, terlihat seperti ini:

   3958  3619  1828  840 2018 496  389  375  375 

Kata-kata "pertunjukan", "kedua" dan "abad" memimpin dengan margin yang sangat besar. Dan meskipun, pada prinsipnya, itu mungkin (Anda dapat membayangkan tajuk seperti "Mencari kata sandi dengan kecepatan 1000 kali per detik akan memakan waktu seabad"), tetapi mencurigakan bahwa ada begitu banyak kata-kata ini. Dan tidak sia-sia - seperti yang ditunjukkan oleh debugging, MorphAnalyzer mendefinisikan kata "c" sebagai "kedua", dan kata "c" sebagai "abad". Yaitu dalam judul "Menggunakan Teknologi ..." MorphAnalyzer menyoroti 3 kata - "kedua", "bantuan", "teknologi", yang jelas-jelas salah. Kata-kata tidak jelas berikutnya adalah "kapan" ("Saat menggunakan ...") dan "sudah", yang masing-masing didefinisikan sebagai kata benda "langsung" dan "sudah". Solusinya sederhana - ketika parsing, pertimbangkan hanya kata-kata yang lebih panjang dari 2 karakter, dan masukkan daftar kata pengecualian berbahasa Rusia yang akan dikeluarkan dari analisis. Sekali lagi, mungkin ini tidak sepenuhnya ilmiah (misalnya, sebuah artikel tentang "mengamati perubahan warna sudah" akan keluar dari analisis), tetapi untuk tugas ini sudah :) sudah cukup.

Hasil akhirnya kurang lebih mirip dengan kebenaran (dengan pengecualian Go dan artikel yang mungkin tentang ular). Tetap menyimpan semua ini dalam gif (kode generasi gif ada di bagian sebelumnya ), dan kami mendapatkan hasil animasi dalam bentuk popularitas kata kunci dalam judul Habr dari 2006 hingga 2019.



Kesimpulan


Seperti yang Anda lihat, analisis teks Rusia dengan bantuan perpustakaan siap pakai ternyata cukup sederhana. Tentu saja, dengan beberapa keberatan, bahasa lisan adalah sistem yang fleksibel dengan banyak pengecualian dan kehadiran rasa konteks tergantung pada konteksnya, dan mungkin mustahil untuk mendapatkan kepastian 100% di sini sama sekali. Tetapi untuk tugas yang ada, kode di atas sudah cukup.

Pekerjaan dengan teks Cyrillic dalam Python itu sendiri, omong-omong, masih jauh dari sempurna - masalah kecil dengan output karakter ke konsol, rusaknya output array dengan cetak, kebutuhan untuk menambahkan "" dalam baris untuk Python 2.7, dll. Bahkan aneh bahwa pada abad ke-21, ketika tampaknya semua atavisme seperti KOI8-R atau CP-1252 telah mati, masalah pengkodean string masih relevan.

Akhirnya, menarik untuk dicatat bahwa menambahkan kata-kata Rusia ke cloud teks praktis tidak meningkatkan konten informasi gambar dibandingkan dengan versi bahasa Inggris - hampir semua istilah IT berbahasa Inggris, sehingga daftar kata-kata Rusia telah berubah jauh kurang signifikan selama 10 tahun. Mungkin, untuk melihat perubahan dalam bahasa Rusia, Anda harus menunggu 50-100 tahun - setelah waktu yang ditentukan akan ada kesempatan untuk memperbarui artikel lagi;)

Source: https://habr.com/ru/post/id442626/


All Articles