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)))]
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):
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;)