Блоґ одного кібера

Історія хвороби контуженого інформаційним вибухом

Posts Tagged ‘вікіпедія

Скільки слів треба щоб написати вікіпедію? І які зустрічаються частіше?

with one comment

Виявляється відтоді як я рахував символи вікіпедії пройшло вже більше року. Рахував я їх за допомогою 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

Частота “року” наводить на думку що в українській вікіпедії якийсь перекос на історичні методи викладу. 🙂

Advertisements

Written by bunyk

Липень 30, 2019 at 23:24

Символи вікіпедії, детальніший аналіз

with one comment

Щодо моєї попередньої публікації, мені зауважили що є різні простори імен. Тому сьогодні буде аналіз лише тих символів які можна зустріти в статтях (а не в категоріях, шаблонах, на сторінках користувачів і проектів), розбивка по різних алфавітах (може кому треба буде для частотного аналізу).

Загалом статті складаються з 3 613 435 448 символів, з яких різних 23 717. Вони розподілені так (намальовано лише початок розподілу, бо решта – неозрброєним оком не видно):


Прочитати решту цього запису »

Written by bunyk

Березень 18, 2018 at 19:05

Опубліковано в Кодерство, Розмітка

Tagged with ,

Скільки символів потрібно щоб написати вікіпедію?

with 4 comments

Не так важливо скільки там людей говоритиме українською коли настане технологічна сингулярність. Важлива сумарна обчислювальна потужність інтелекту що володіє українською. 😉 І взагалі варто опановувати хоч якісь основи навчання машин – це професія в якій роботи ще не скоро замінять людей. Щоб навчити машину мови – їй треба багааатезно прикладів. І найбільший шмат української мови який можна легко згодувати машині – вікіпедія. Тому сьогодні ми спробуємо з’ясувати що потрібно щоб отримати цей масив тексту, і порахувати на ньому якусь простеньку статистику, для якої не треба бази даних а вистачить оперативної пам’яті.

Перше що нам потрібно – копія бази даних вікіпедії. Тому що вікіпедія містить більше чверті мільйона статтей, і навіть якщо ми робитимемо по запиту на секунду, що вікіпедія не схвалює для всяких там приватних павуків, то складання індексу займе в нас (750000 сек)/ 3600 / 24 = 8.68 діб > тижня. Тому заходимо на
https://dumps.wikimedia.org/ , вибираємо дамп який більше подобається, наприклад останній дамп що містить статті (без сторінок обговорень) української вікіпедії і ставимо на скачування.

А поки воно скачується підготуємось його розпаковувати. Ми скачуємо заархівований XML, який при розпаковуванні займає щось біля 5GB. Всередині є багато тисяч елементів , кожен з яких містить деталі про сторінку. Ось код на Go який містить функцію Read що розархівовує і водночас парсить XML, та повертає канал в який кидає сторінку за сторінкою, а в головній функції ітерується по всіх сторінках і підраховує кількість символів в їх тексті. В кінці виводить статистику:
Прочитати решту цього запису »

Written by bunyk

Березень 16, 2018 at 23:30

Опубліковано в Кодерство, Павутина

Tagged with ,

Як написати бота до Telegram?

with 5 comments

Легко. 🙂 Давайте напишемо бота який перекладатиме нам всяке з німецької:

Приклад діалогу

Для цього нам треба поговорити з botFather-ом:

А зараз трохи не по темі цієї статті. Ось код який перетворює вікідані на словник, шукаючи всі сутності які мають мітки однією мовою, а потім показучи їх мітки іншою мовою, використовуючи хитрий запит SPARQL:

import json
import requests

def translate(from_lang, to_lang, word):
    '''
        Переклдає мітки елементів вікіданих з мови на мову. Повертає список варіантів перекладу
    '''
    res = sparql('''
        SELECT  ?ukLabel WHERE {
          ?item ?label "%s"@%s.
          ?item rdfs:label ?ukLabel filter(lang(?ukLabel) = "%s")
        } LIMIT 10
    ''' % (word, from_lang, to_lang))
    return list(map(
        lambda e: e['ukLabel']['value'],
        res['results']['bindings']
    ))

def sparql(query):
    ''' Отримує JSON дані запиту SPARQL до вікіданих '''
    res = requests.get(
        'https://query.wikidata.org/sparql',
        params={
            'query': query,
            'format': 'json'
        }
    )
    return json.loads(res.text)

А тепер повертаємось до теми телеграмного бота. Аби його написати треба поставити бібліотеку:

pip install pyTelegramBotAPI

Ось її Github: https://github.com/eternnoir/pyTelegramBotAPI

А далі – елементарно як писати консольну програму:

import telebot

TOKEN = '' # тут вставити те що BotFather сказав

bot = telebot.TeleBot(TOKEN)

@bot.message_handler(content_types=["text"]) # Якщо прийдуть нові повідомлення
def respond_to_message(message):
    translations = translate('de', 'uk', message.text) # Отримати переклади тексту повідомленя
    resp = '\n'.join(translations) if translations else 'На жаль, перекладу слова %s не знайдено' % message.text
    bot.send_message( # відправити назад
        message.chat.id, # в той самий чат з якого прийшло (можна напевне й в інший)
        resp
    )

if __name__ == '__main__':
     bot.polling(none_stop=True) # Запустити бота аби той сидів на лінії і слухав повідомлення.

Поки що все, бо й висипатись іноді треба. Пізніше нагадайте мені не забути написати більше про SPARQL, як поставити собі локальну mediawiki і розширення до неї, як логінити сторонні застосунки через OAuth, і як переписати інтерфейс вікіпедії на Vue.js. 🙂

Written by bunyk

Травень 22, 2017 at 01:51

Опубліковано в Кодерство, Павутина

Tagged with ,

Подарунки Україні до Дня Незалежності

with 4 comments

Найперше, я купив найдорожчу книжку яку купляв в своєму житті: Шлях до кріпацтва. Витратив на неї 2000 грн (хоча були люди які витратили більше), тепер можу подарувати.

Але є ще кращий подарунок. Добре було б зробити “смерть ворогам”, та, на щастя є ті хто краще за мене це можуть. Ще краще було б зробити “асиміляцію ворогам”. Це і гуманніше, і страшніше для ворога. Тому, як крихітний крок що цього – моя операція в рамках поточної кібервійни, під умовною назвою “засуньте язик за поребрик”. Назва придумана під впливом кібервійськ, до яких я, на жаль, жодного стосунку не маю, не доріс.

Все почалось з того що я якось читаючи вікіпедію, переходив за посиланнями, відкривав статті і перейшов на статтю російською. Спершу нічого не зрозумів (Бо за останніми даними українці російською не володіють), а потім мене це розізлило, бо як виявилось такі випадки непоодинокі. І це в той час, коли українською є кращі і точніші статті на цю ж тему. Іноді посилання на рувікі були червоні (відкриваєш, а там запрошення створити статтю), хоч виглядали синіми. І ці посилання зустрічались трохи більше ніж в 2000 статтей.

Сприймати інформацію російською мовою окрім того що важко (бо, як я вже зауважував, нею мало хто володіє 😉 ), але й небезпечно. Тому що російськомовне світосприйняття, кхм, кхм, дещо викривлене. Ось приклад:

Труднощі перекладу

Труднощі перекладу

Про всякі дивні поняття на зразок “Дреєвнєруское государство” і т.п. взагалі промовчу, то було ще здається до збройної війни і обговорювалось.

А чим більше посилань кудись існує, тим більший там PageRank, тобто логарифм ймовірності того що випадково блукаючи сторінками ви на якусь потрапите.

Короште, аби довго не розказувати вам деталі, доповідаю результати. Я трохи попрацював, завів бота, який теж добряче попрацював, і з цих 2000 посилань, залишилось менше 50 тих які вже таки треба (в основному посилання на всякі документи СРСР).

Тепер треба буде те саме з англійською і іншими мовами зробити. Може хтось хоче допомогти? Поділюсь своїм одноразовим недосконалим скриптом. А то я вже замучився з тою рутиною, хочеться чимось творчішим зайнятись. Наприклад написати про нову мову програмування. І роботою зайнятись.

Written by bunyk

Серпень 24, 2016 at 10:05

Опубліковано в Нещоденник

Tagged with

Звідки взялось танго?

with 4 comments

У вікіпедії я з командою пишемо статтю яка розповість про танго все в найдрібніших деталях. Поки що можна прочитати як воно виникло. Я знаю (бо бачу статистику переходів) що вам неохота багато читати, тому я викладу тут найцікавіші фрагменти з тої історії. Після чого поділюсь своїми пошуками того як танго з’явилось у Львові, і взагалі складнощами написання статтей на основі пошуку. Бо потрібна допомога, тому що я точно знаю що є люди які знають більше.

Але спершу про те що писало у вікіпедії іспанською. Якщо ви щось чули про те що танго з’явилось в борделях Буенос-Айреса, то вас майже правильно поінформували. Хоча звісно насправді все було ще гірше і ще цікавіше. Отож, справа була портових містах біля гирла річки Ла-Плата:
Прочитати решту цього запису »

Written by bunyk

Травень 7, 2016 at 01:58

Як дописувати до Вікіпедії?

with 6 comments

Мене іноді питають про найелементарніші речі, тому почну з найелементарнішого. Якщо вам щось не подобається у Вікіпедії, і ви знаєте як воно повинно було бути правильно – ось як це виправляється:

Шляхи до редагування Вікіпедії

Шляхи до редагування Вікіпедії

Хоча звісно не все так просто. Іноді ваші зміни можуть не прийняти, тоді варто піти на сторінку обговорення і обговорити всі питаня які виникають.

Також вам крім кнопки “[ред.]” дуже потрібні ще дві речі: сильна цікавість до чогось, і бажання розібратись, та бажання поділитись тим про що довідались з іншими. А далі – деяке знання розмітки, але це не настільки вже й обов’язково. Оформлення вас навчать, головне аби стаття відповідала правилам, тобто мала незалежні від вас джерела і не порушувала авторські права (копіпаст або переклад дозволяється лише з матеріалів під вільними ліцензіями). Тому писати Вікіпедію трохи складніше ніж скачувати реферати з інтернету. 😉 А написати вибрану статтю складніше ніж написати дипломну роботу. Тут трохи про те як пишуться вибрані. Коли сам напишу вибрану – може розповім як і це робилось.

А поки що, розглянемо наприклад як дописувалась стаття про компанію Fujikura, яка відповідає мінімальним вимогам до якості. Той самий підхід працює як і для розширення існуючих статтей, так і для створення нових. Про Fujikura я дізнався завдяки прес-релізу “Міністерства магії”:
Прочитати решту цього запису »

Written by bunyk

Травень 2, 2016 at 13:58

Опубліковано в Інструменти, Конспекти

Tagged with ,