Если мы определим «вероятности изолированных символов» так, как это делается в этом SO-ответе , мы должны будем сделать следующее:
Получите репрезентативную выборку текста на английском языке (возможно, тщательно отобранный корпус новостных статей, постов в блогах, некоторых научных статей и некоторых личных писем), как можно большего размера
Итерация по его символам и подсчет частоты появления каждого из них
Используйте частоту, разделенную на общее количество символов, в качестве оценки для вероятности каждого символа
Рассчитайте среднюю длину в битах каждого символа, умножив его вероятность на отрицательный логарифм той же вероятности (логарифм с основанием 2, если мы хотим, чтобы единица энтропии была немного )
Возьмите сумму всех средних длин всех символов. Это результат.
Предостережения:
Эта изолированных символов энтропия равна , а не , что обычно называют оценка энтропии Шеннона для английского языка . Шеннон основывал энтропию на условных вероятностях 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))