Как узнать энтропию английского языка - PullRequest
7 голосов
/ 07 марта 2012

Как узнать энтропию английского языка, используя изолированные вероятности символа языка?

1 Ответ

13 голосов
/ 08 марта 2012

Если мы определим «вероятности изолированных символов» так, как это делается в этом SO-ответе , мы должны будем сделать следующее:

  1. Получите репрезентативную выборку текста на английском языке (возможно, тщательно отобранный корпус новостных статей, постов в блогах, некоторых научных статей и некоторых личных писем), как можно большего размера

  2. Итерация по его символам и подсчет частоты появления каждого из них

  3. Используйте частоту, разделенную на общее количество символов, в качестве оценки для вероятности каждого символа

  4. Рассчитайте среднюю длину в битах каждого символа, умножив его вероятность на отрицательный логарифм той же вероятности (логарифм с основанием 2, если мы хотим, чтобы единица энтропии была немного )

  5. Возьмите сумму всех средних длин всех символов. Это результат.

Предостережения:

  • Эта изолированных символов энтропия равна , а не , что обычно называют оценка энтропии Шеннона для английского языка . Шеннон основывал энтропию на условных вероятностях n-грамм, а не на изолированных символах, и его знаменитая статья 1950 года в значительной степени посвящена тому, как определить оптимальное n.

  • Большинство людей, которые пытаются оценить энтропию английского языка, исключают знаки препинания и нормализуют весь текст в нижнем регистре.

  • Вышеприведенное предполагает, что символ определен как символ (или буква ) английского языка. Вы можете сделать аналогичную вещь для целых слов или других единиц текста.

Пример кода:

Вот код Python, который реализует процедуру, описанную выше. Он нормализует текст в нижнем регистре и исключает пунктуацию и любые другие не алфавитные, не пробельные символы. Предполагается, что вы собрали представительный корпус английского языка и предоставили его (в кодировке ASCII) на STDIN.

import re
import sys
from math import log

# Function to compute the base-2 logarithm of a floating point number.
def log2(number):
    return log(number) / log(2)

# Function to normalise the text.
cleaner = re.compile('[^a-z]+')
def clean(text):
    return cleaner.sub(' ',text)

# Dictionary for letter counts
letter_frequency = {}

# Read and normalise input text
text = clean(sys.stdin.read().lower().strip())

# Count letter frequencies
for letter in text:
    if letter in letter_frequency:
        letter_frequency[letter] += 1
    else:
        letter_frequency[letter] = 1

# Calculate entropy
length_sum = 0.0
for letter in letter_frequency:
    probability = float(letter_frequency[letter]) / len(text)
    length_sum += probability * log2(probability)

# Output
sys.stdout.write('Entropy: %f bits per character\n' % (-length_sum))
...