вторник, 9 октября 2012 г.

Heaps' law

Наткнувшись в Introduction to Information Retrieval на Heaps' law (с ростом объема текста количество уникальных слов растет как степенная функция, для ангоийского языка показатель степени где-то между 0.4 и 0.6) мне жутко захотелось проверить его на реальныйх текстах и сравнить распределение для разных авторов.

Начал я с Достоевского и его романов "Бесы" и "Преступление и наказание". Действительно, получилась зависимость похожая на степенную:


По x - количество слов, по y - количество уникальных слов.

Давайте сравним с каким-нибудь другим автором. Например с Донцовой. Из её многочисленный произведений я взял "Стриптиз Жар-птицы", "Диета для трех поросят" и "Фейсконтроль на главкую роль". Не скрою, я ожидал, что график Достоевского будет выше. Все-таки сравниваем одного из величайших писателей и автора многочисленный одинаковых детективов. Словарный запас Достоейского должен быть больше, количество уникальных слов у него должно расти быстрее. Посмотрим, что получилось:


Вот так, может быть действительно "...Достоевский писатель не великий, а довольно посредственный, со вспышками непревзойденного юмора, которые, увы, чередуются с длинными пустошами литературных банальностей..." (Набоков). С кем бы еще сравнить? Кто находится вне конкуренции? Кто написал "Войну и мир", в конце концов? Итак, добавим романы Льва Толстого "Война и мир" и "Анна Каренина".



Может не зря Донцова так хорошо продается... Добавим Акунина ("Азазель", "Турецкий гамбит", "Левиафан").



Ну хоть кто-то потеснил Донцову с первого места. И разница между ними существенная (во всяком случае большая, чем между Толстым и Достоевским). Может быть разница из-за эпох, в которых творили писатели? Добавим еще какого-нибудь классика из 20-го века. Мне на ум пришел Шолохов ("Тихий Дон").



Шолохов обходит Акунина. Так что может быть дело во времени и развитии языка. Ну или ошибка в коде:) Кстати вот он:
List<Integer> getDistribution(final List<Reader> sources, 
                              final int step) throws IOException {
    long words = 0;
    final Set<String> uniqueWords = new HashSet<String>();
    final List<Integer> result = new ArrayList<Integer>();
    for (final Reader r : sources) {
        final StreamTokenizer tokenizer = new StreamTokenizer(r);
        tokenizer.quoteChar('.');
        int tokenType;
        while ((tokenType = tokenizer.nextToken()) != TT_EOF) {
            if (tokenType == TT_WORD) {
                uniqueWords.add(tokenizer.sval.toLowerCase());
                words++;
                if (words % step == 0) {
                    result.add(uniqueWords.size());
                }
            }
        }
    }
    return result;
}

Комментариев нет:

Отправить комментарий