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

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

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

Чи правда досить 1000 слів щоб вивчити мову?

leave a comment »

І що робити якщо цього мало? 🙂 Колись читав статтю одного заробітчанина про те що 1000 слів достатньо для впевненого користування мовою. Але зараз маючи статистику по вікіпедії, можна порахувати скільки слів достатньо щоб впевнено читати вікіпедію. (Для тих кому лінь читати ввесь текст: ні, 1000 слів явно замало, їх треба знати десятки тисяч, але скльки точно – ХЗ).

Наприклад українська вікіпедія містить приблизно 240 мільйонів слів, з них різних: 4.5 мільйонів. Якщо їх вчити в порядку частотності, графік частки розуміння до кількості вивчених слів буде виглядати так:

Частка розуміння тексту залежно від кількості знайомих слів

Крім того, дослідження показують що доросла людина знає від 20 до 40 тисяч слів рідної мови, що набагато менше ніж 4 з половиною мільйони (хоча думаю мої оцінки кількості “різних” слів завищені, бо морфологія і помилки, а оцінки знання слів занижені, бо знову ж таки відмінювання і т.п.). Давайте подивимось на графік ближче:

Частка розуміння тексту залежно від кількості знайомих слів

Виходить, що навіть якщо знати 20 тисяч слів, можна розуміти лише 3/4 тексту. І вивчення ще 20 000 помагає менше ніж 10 000 до того. Як так? Давайте візмемо якісь випадкові статті, і виділимо слова що не входять в найчастіші 20 тисяч:

Сексуальна жага, сублімована чуттєвістю, сумом і меланхолією, спричиненою постійним відчуттям невдоволення, є стрижневими компонентами танго. Колись це почуття народжувалося через важке становище мільйонів іммігрантів-робітників, переважно чоловіків, які почувалися самотніми на чужій землі, тому часто навідувалися до будинків розпусти, де кохання за гроші ще дужче підсилювало в них «ностальгію за єднанням і коханням, ностальгію за жінкою» і засвідчувало їхню самотуErnesto Sabato, pág. 14.. Танго, власне, і виникло як масова й популярна «еротична досада», що призвела до такої ж масової й популярної внутрішньої рефлексії про кохання, секс, відчай і врешті про сенс життя і смерть простої людини.

Бачимо, що хоча в вікіпедії достатньо часто вживають слово “секс” (1215 раз), слово “сексуальна” чомусь вживають рідше (385 раз). 🙂 Я б спихнув це на нейтральність, але “сексуальної” – 1224 рази. Суть в тому що якщо знати одне слово, то й похідні знатимеш.

Селяни з Ляцького взяли активну участь в повстанні Богдана Хмельницького. Так наприклад 6 серпня 1649 року Андрій Голинський скаржився на селян з Камінного, Велисниці, Гостова, Волосівської Слободи, Ляцького, які під проводом шляхтичів Русинів Олександра, Андрія, Кикули Березовських «маючи змову з козаками й бунтівниками» напали на село Перерісль і там попустошили шляхетські двори. Крім того, зважаючи на сильну присутність польської шляхти у самому селі, траплялись напади і на Ляцьке. Юрій Коморовський 30 травня 1650 року скаржився, що селяни сіл Волосова, Цуцилова, Тисменичан, та Ворони спустошили двірські маєтки в Цуцилові, опісля спалили двір та корчму в Ляцькім.

Зрозуміло, багато статтей містять багато власних назв. Може варто б замість “попустошили” писати “спустошили”, але одне передбачає значення “трошки”, а інше “зовсім”. Хоча що то – що то не входить до топ20000.

Шарам — село в Ірані, в дегестані Касма, в Центральному бахші, шагрестані Совмее-Сара остану Ґілян. За даними перепису 2006 року, його населення становило 392 особи, що проживали у складі 114 сімейПерепис населення Ірану 2006.

“сімейПерепис” не мало б потрапити до мого рейтингу слів, певне треба кращий код виділення слів зі статті. Те що “дегестані” і “шагрестані” входять до найчастіше вживаних 20000 – теж перекос вікіпедії, бо до словника середньостатистичної людини такі слова не мали б входити.

Приклад зі ще іншої області:

Кодований геном білок за функціями належить до репресорів, фосфопротеїнів.
Задіяний у таких біологічних процесах як взаємодія хазяїн-вірус, транскрипція, регуляція транскрипції, поліморфізм, альтернативний сплайсинг.
Локалізований у цитоплазмі, ядрі, хромосомах, центромерах, кінетохорі.

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

ядра,6772
ядрі,6369
ядро,3690
ядром,1452
ядрами,585
ядрах,298
ядру,74
мікроядра,26
ядрам,24
Сядристий,22
ядрові,22
ядраЧемпіонат,20
Сядристого,19
ядрова,19
коядро,17
мікроядро,15

Як німецька? Загалом більше мільярда слів з них різних 12 мільйонів. Ось графіки:

Залежність розуміння від знання слів в німецькій вікіпедії

Залежність розуміння від знання слів в німецькій вікіпедії

Бачимо що ситуація подібна. Ось приклад:

Berlin gehört zu den führenden Standorten der Informations- und Kreativwirtschaft in Europa. Der Wirtschaftsbereich umfasst den Buch- und Pressemarkt, Softwareentwicklung, Telekommunikationsleistungen, den Werbemarkt, Marktforschung, die Film- und Rundfunkwirtschaft, den Kunstmarkt, die Musikwirtschaft, die Architektenbranche, die Designwirtschaft und den Markt für Darstellende Künste.

Бачимо що більшість “рідкісних” слів – складаються з не таких вже й рідкісних. Напевне 100% треба змінити підрахунок, бо “Telekommunikationsleistungen” – це “Tele-kommunikations-leistungen”, телекомунікаційні потужності.

Таким чином щоб зробити нормальний частотний словник, треба напевне якийсь стеммер, і алгоритм для розбиття німецьких слів на частини. Для української просто стемер напевне. 🙂 Або робити його вручну…

Advertisements

Written by bunyk

Жовтень 10, 2019 at 16:55

Опубліковано в 1

Tagged with ,

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

with 3 comments

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

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

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