Питон, как проверить, соответствует ли корпус закону Зипфа?
Как говорит титул, я хочу измерить, ведет ли Распределение слов Zipf в моем корпусе как истощенный. Я уже смотрел подобные вопросы здесь на stackru и на других страницах. Мне больше всего понравился ответ: Распределение Zipf: Как измерить Распределение Zipf по Anil_M.
import re
from operator import itemgetter
import matplotlib.pyplot as plt
from scipy import special
import numpy as np
#Get our corpus of medical words
frequency = {}
open_file = open('d2016.bin', 'r')
file_to_string = open_file.read()
words = re.findall(r'(\b[A-Za-z][a-z]{2,9}\b)', file_to_string)
#build dict of words based on frequency
for word in words:
count = frequency.get(word,0)
frequency[word] = count + 1
#limit words to 1000
n = 1000
frequency = {key:value for key,value in frequency.items()[0:n]}
#convert value of frequency to numpy array
s = frequency.values()
s = np.array(s)
#Calculate zipf and plot the data
a = 2. # distribution parameter
count, bins, ignored = plt.hist(s[s<50], 50, normed=True)
x = np.arange(1., 50.)
y = x**(-a) / special.zetac(a)
plt.plot(x, y/max(y), linewidth=2, color='r')
plt.show()
К сожалению, для меня этот код не работает. Когда я пытаюсь запустить этот код, я получаю следующий код ошибки:
frequency = {key:value for key,value in frequency.items()[0:n]}
TypeError: 'dict_items' object is not subscriptable
Если я опускаю часть кода [0:n] (мне не нужно ограничивать количество слов), я получаю другой код ошибки:
count, bins, ignored = plt.hist(s[s<50], 50, normed=True)
TypeError: '<' not supported between instances of 'dict_values' and 'int'
Кажется, что библиотеки как-то изменились с тех пор, как код был написан 2 года назад. Есть ли способ заставить этот код снова работать? Мне очень нравится, как вы видите распределение слов, а также точное распределение zipf. Другой, более простой способ:
from nltk import word_tokenize
import nltk
from nltk.book import *
import matplotlib
import numpy
f = open('test.txt', encoding='utf8')
raw = f.read()
tokens = word_tokenize(raw)
tokensNLTK = Text(tokens)
fdist1 = FreqDist(tokensNLTK)
print(fdist1.most_common(50))
fdist1.plot()
но с помощью этой функции вы не сможете оценить распределение очень хорошо.