Archive for the ‘Інструменти’ Category
Hunspell
Hunspell розшифровується як “угорський правопис”, і це найбільш просунута програма перевірки правопису якщо не враховувати Grammarly. А все тому що угорська мова – найбільш скажена в плані морфології. Тому якщо щось підходить для угорської – для інших європейських мов точно підійде.
sudo apt install hunspell hunspell-uk hunspell-de-de libhunspell-dev
sudo pip install hunspell
hunspell має доволі простий інтерфейс для використання в мовах програмування (хоча й складні словники (читати man hunspell.5
)):
>>> import hunspell
>>> spellchecker = hunspell.HunSpell('/usr/share/hunspell/uk_UA.dic', '/usr/share/hunspell/uk_UA.aff')
>>> spellchecker.spell('ласка')
True
>>> spellchecker.spell('ласкає')
False
>>> spellchecker.suggest('ласкає')
['ласка', 'ласкам', 'лускає', 'ласках', 'ляскає', 'ласка є', 'скалатає']
Скільки слів треба щоб написати вікіпедію? І які зустрічаються частіше?
Виявляється відтоді як я рахував символи вікіпедії пройшло вже більше року. Рахував я їх за допомогою Go, хоча можна було сильно спростити собі життя і рахувати їх за допомогою Python і pywikipediabot. Сьогодні розкажу як, і як можна побачити з назви – рахуватимемо слова.
Я чомусь боявся що щоб порахувати слова пам’яті не вистачить, тому треба якусь базу даних. Або пробувати все в пам’яті, але аби комп’ютеру не стало погано якось обмежити доступну пам’ять. Але мої 4Gb використовувались лише щось трохи більше ніж на 40% для підрахунку всіх слів включно зі сторінками обговорень, категорій, шаблонів, сторінок опису файлів, і т.п. німецької вікіпедії.
В модулі pywikibot.pagegenerators
є об’єкти XMLDumpOldPageGenerator
і XMLDumpPageGenerator
. Вони приймають назву архіву з XML дампом в конструкторі, а після створення по них можна ітеруватися отримуючи об’єкти сторінки. Не ведіться на слово “Old” в назві першого об’єкта, це означає не депрекацію, а те що текст сторінки буде братись з дампа, а в другому випадку з дампа буде братись лише заголовки, а за свіжим текстом зроблять запит, що сповільнить обробку разів в 500. Тобто замість кількох годин ви будете чекати рік. 🙂
Я спробував проаналізувати німецьку вікіпедію (код буде пізніше), на це пішло 694 хв (трохи менше ніж 12 годин) і вийшло що в ній на 6,425,028 сторінках використовується 2,381,457,397 слів (приблизно 371 на сторінку), з них різних слів 18,349,393. В кінцевому результаті CSV з частотним словничком виходить на 300MB.
Серед тих що зустрічаються лише раз є слова типу PikettdienstPikettdienst (помилка парсера який видаляв розмітку), слово – це юридичний термін швейцарської німецької і перекладається як “служба за викликом”. І є слова на зразок Werkshöfe – подвір’я фабрик.
Топ 50 слів виглядає так, і складає 28% всіх слів загалом:
der | 58761447 | sich | 9169933 |
und | 49084873 | wurde | 9114619 |
die | 44536463 | CET | 8614461 |
in | 35684744 | an | 8385637 |
von | 24448221 | er | 7835324 |
ist | 20614114 | dass | 7550955 |
den | 19454023 | du | 7435099 |
nicht | 17519638 | bei | 7420172 |
das | 17302844 | Diskussion | 7237855 |
zu | 16167971 | aus | 7065523 |
mit | 15906145 | Artikel | 6967243 |
im | 15167140 | oder | 6824420 |
des | 14661593 | werden | 6508092 |
für | 14016308 | war | 6449858 |
auf | 13957013 | nach | 6426826 |
auch | 12849476 | wird | 6117566 |
eine | 11903977 | aber | 6052645 |
ein | 11780352 | am | 6017703 |
Kategorie | 11369651 | sind | 5953632 |
als | 11167157 | Der | 5623930 |
dem | 11124726 | Das | 5545595 |
CEST | 11104741 | einen | 5465687 |
ich | 10886406 | noch | 5409154 |
Die | 10761776 | wie | 5293658 |
es | 10204681 | einer | 5228368 |
До списку потрапили такі вікіпедійно специфічні слова як Kategorie (сторінки без категорій вважаються не комільфо), CEST і CET (центральноєвропейський літній час і центральноєвропейський час, в підписах в обговореннях).
Ну а що без сторінок обговорень? Проблемав тому, що при створенні об’єкту сторінки XMLDumpOldPageGenerator
бере з дампа лише текст і заголовок, простір імен залишається не заповненим і за замовчуванням 0 (основний). Є ще поле isredirect
так при спробі доступу до нього знову здійснюється запит. Тому, краще перейти на рівень нижче і використати XmlDump
з pywikibot.xmlreader
, він використовується так само, просто дає об’єкти не Page, а попростіші, які не вміють робити запити до вікіпедії і не мають методу save
. Але нам його й не треба, правда?
Ось код який ігнорує перенаправлення і всі сторінки крім статтей:
"""Count word frequencies in wikipedia dump""" import csv from collections import Counter from itertools import islice import re import sys import mwparserfromhell from pywikibot.xmlreader import XmlDump def main(): """Iterate over pages and count words""" if len(sys.argv) < 2: print('Please give file name of dump') return filename = sys.argv[1] pages = 0 words = 0 words_counts = Counter() print('Processing dump') for page in XmlDump(filename).parse(): if (page.ns != '0') or page.isredirect: continue try: text = mwparserfromhell.parse(page.text).strip_code() except Exception as e: print(page.title, e) continue text = text.replace('\u0301', '') # remove accents # Ukrainian: # page_words = re.findall( # r'[абвгґдеєжзиіїйклмнопрстуфхцчшщьюя' # r'АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ’\'-]+', # text # ) # Any language: page_words = re.findall(r'\b[^\W\d]+\b', text) pages += 1 words += len(page_words) words_counts.update(page_words) if pages % 123 == 0: print('\rPages: %d. Words: %d. Unique: %d. Processing: %s' % ( pages, words, len(words_counts), (page.title + ' ' * 70)[:70], ), end='') print('Done. Writing csv') with open('common_words.csv', 'w', newline='') as csvfile: csvwriter = csv.writer(csvfile) for item in words_counts.most_common(): csvwriter.writerow(item) if __name__ == '__main__': main()
Він працює майже вдвічі швидше, 381 хвилину, бо обробляє лише 2,295,426 сторінок (обсяг німецької вікіпедії цього року). На цих сторінках є 1,074,446,116 слів (в середньому 468 на сторінку), з них різних – 12,002,417. (Виявляється є аж 6 мільйонів всяких слів які вживаються на всіляких службових сторінках німецької вікіпедії, і яких нема в статтях).
Якщо ж взяти українські статті, то на них треба ще менше часу – 131 хвилину (забув уточнити що в мене SSD), їх є 923238 (скоро мільйон!), слів 238263126 (в середньому 258 на сторінку, треба доповнювати 😉 ). З них різних – 4,571,418. Отак, в мене тепер є частотний словник української на 4.5 мільйони слів. І німецької на 12 мільйонів.
Хоча не спішіть з висновками що українська мова бідніша, бо мої методи потребують вдосконалення. По перше, так як Morgen (ранок) і morgen (завтра) – різні слова, то я не приводив букви в німецькій до одного регістру. (Правда й в українській забув це зробити).
По друге, в німецькому словнику 350590 разів зустрічається слово “www”, бо я вважав словом будь-яку послідовність літер латинки, а в українській відфільтрував кирилицю. Слово youtube зустрічається 8375 разів, а значить є ризик знайти якесь рідкісне слово на зразок “fCn8zs912OE”. 🙂
На WordPress глючить додавання картинок, тому нате вам відео:
А, і ось топ-10 української вікіпедії:
в,4551982
на,3730686
і,3475086
у,3353796
з,3053407
-,2695783
Категорія,2417267
та,2350573
до,1815429
року,1553492
Частота “року” наводить на думку що в українській вікіпедії якийсь перекос на історичні методи викладу. 🙂
Python – калькулятор – 2. Sympy
Намагаюсь тут вивчити матан для функцій багатьох змінних щоб зрозуміти як працюють штучні мережі. Для цього використовую Brilliant.org, такий собі гейміфікований сайт для вивчення математики. І враховуючи те що я там вже за 1200 задач зробив, гейміфікація таки працює.
Задачі там варіюються від “знайди x – ось він”, які можна розв’язувати однією рукою, поки іншою штовхаєш коляску парком. Наприклад:
Капітан Кортевеґ причалив біля пірсу, і його човен здійняв одиночну хвилю. Капітану стало цікаво, погнав за хвилею і на ходу виявив що висота води в залежності від часу і позиції в просторі
описується рівнянням:
Який найбільший порядок похідної в цьому рівнянні?
І ти такий думаєш: “Та ось він!”. Вписуєш відповідь на одну цифру, і переходиш до наступного завдання.
А потім капітан думає як розв’язувати те рівняння. І дають підказку, що розв’язок – це
Знайдіть значення c, яке задовольняє вищенаведене рівняння Кортевега – де Фріза.
І ти собі такий, ок, треба знайти кожну похідну, додати і прирівняти до нуля. Добре що дали розв’язок і треба знайти лише константу, бо дифрівняння я все ще не вмію розв’язувати, для того треба вміти інтегрувати. Але все одно без паперу не обійтись. Вдома списую пару листочків:
Прочитати решту цього запису »
Як створити блог з Hugo
Hugo – це такий генератор статичних сайтів. Статичні сайти – це сайти що складаються з набору фіксованих сторінок і не генеруються з шаблонів і запитів до бази даних при кожному завантаженні. Це з одного боку менш зручно бо немає можливості наприклад опублікувати щось автоматично встановивши час публікації, а з іншого боку – менш вимогливо до ресурсів, і краще з точки зору комп’ютерної безпеки. Крім того, wordpress.com зі своїми оновленнями інтерфейсу починає трохи дратувати. Хочеться markdown, свого javascript і стилів. А ще він не підсвічує синтаксис go. 🙂 Але ця стаття публікується на WordPress, яка іронія… Тому що я ще не вирішив що публікуватиму там.
До цього, мій статичний сайт на github генерувався самописним скриптом на python, який перетворював шаблони Mako в HTML, дозволяв вставляти javascript разом з залежностями, і так як я коли це придумував не знав ні про який node.js з npm (точніше знав, але не дуже цікавився), то залежності в мене описувались не в package.json, а в external_assets.py, і збирав їх не webpack чи gulp, чи browserify чи bower, а requirejs.py.
Але це я відхиляюсь від теми. Мова про те що велосипеди треба не винаходити, треба брати і їздити. Тому поїхали!
Прочитати решту цього запису »
Моніторинг випадкової змінної за допомогою Telegraf -> InfluxDB -> Grafana
В цій публікації я розкажу про те як побудувати графік зміни якоїсь змінної в реальному часі. Наприклад якоїсь ціни, чи кількості запитів до сервера. Ключові слова: Docker, Docker compose, time series database, InfluxDB, Grafana, Telegraf. Всі крім докера будуть пояснені детально, докер – лише використовуватись для економії часу на інсталяцію.
Прочитати решту цього запису »