Короче:
Это что-то делать с тем, как python3
хэши клавиши, когда функция similar()
использует словарь счетчика. См http://pastebin.com/ysAF6p6h
См How and why is the dictionary hashes different in python2 and python3?
В длинной:
Давайте начнем с:
from nltk.book import *
Импорт здесь происходит из https://github.com/nltk/nltk/blob/develop/nltk/book.py, который импортировать nltk.text.Text
объект и прочитать несколько корпусов в Text
objec т.
E.g. Это как переменная text1
была прочитана из nltk.book
:
>>> import nltk.corpus
>>> from nltk.text import Text
>>> moby = Text(nltk.corpus.gutenberg.words('melville-moby_dick.txt'))
Теперь, если мы спускаемся на код функции similar()
в https://github.com/nltk/nltk/blob/develop/nltk/text.py#L377, мы видим эту инициализацию, если это первый случай доступа self._word_context_index
:
def similar(self, word, num=20):
"""
Distributional similarity: find other words which appear in the
same contexts as the specified word; list most similar words first.
:param word: The word used to seed the similarity search
:type word: str
:param num: The number of words to generate (default=20)
:type num: int
:seealso: ContextIndex.similar_words()
"""
if '_word_context_index' not in self.__dict__:
#print('Building word-context index...')
self._word_context_index = ContextIndex(self.tokens,
filter=lambda x:x.isalpha(),
key=lambda s:s.lower())
word = word.lower()
wci = self._word_context_index._word_to_contexts
if word in wci.conditions():
contexts = set(wci[word])
fd = Counter(w for w in wci.conditions() for c in wci[w]
if c in contexts and not w == word)
words = [w for w, _ in fd.most_common(num)]
print(tokenwrap(words))
else:
print("No matches")
Так что мы указываем на объект nltk.text.ContextIndex
, то есть собираем все слова с похожим контекстным окном и храним их. В докстерии говорится:
Двунаправленный индекс между словами и их «контекстами» в тексте. Контекст слова обычно определяется как слова, которые встречаются в фиксированном окне вокруг слова; но другие определения могут также использоваться , предоставляя настраиваемую функцию контекста.
По умолчанию, если вы звоните функцию similar()
, он будет инициализировать _word_context_index
с настройками по умолчанию контекста т.е.левый и правый маркер окна, см https://github.com/nltk/nltk/blob/develop/nltk/text.py#L40
@staticmethod
def _default_context(tokens, i):
"""One left token and one right token, normalized to lowercase"""
left = (tokens[i-1].lower() if i != 0 else '*START*')
right = (tokens[i+1].lower() if i != len(tokens) - 1 else '*END*')
return (left, right)
Из функции similar()
, мы видим, что она перебирает слова в контексте, хранящихся в word_context_index, т.е. wci = self._word_context_index._word_to_contexts
.
По существу, _word_to_contexts
представляет собой словарь, где ключи слова в корпусе и значения левые и правые слова из https://github.com/nltk/nltk/blob/develop/nltk/text.py#L55:
self._word_to_contexts = CFD((self._key(w), self._context_func(tokens, i))
for i, w in enumerate(tokens))
И здесь мы видим, что это CFD, который является nltk.probability.ConditionalFreqDist
объект, который не включает сглаживание вероятности токена, см. Полный код на https://github.com/nltk/nltk/blob/develop/nltk/probability.py#L1646.
только возможно, и получение другого результата когда функция similar()
перебирает most_common слов на https://github.com/nltk/nltk/blob/develop/nltk/text.py#L402
Учитывая, что два ключа в Counter
объекта имеют те же счетчики, слово с ниже отсортированный хэш напечатает первый и хэш-ключа зависит от битового размера процессора, см http://www.laurentluce.com/posts/python-dictionary-implementation/
Весь процесс Попав подобные слова детерминировано, так как:
- желтый/вход фиксировано
Text(gutenberg.words('melville-moby_dick.txt'))
- контекста по умолчанию для каждого слова также фиксируются, т.е.
self._word_context_index
- вычисления условное распределение частот для
_word_context_index._word_to_contexts
дискретна
исключения случаев, когда функция выводит most_common
список, который когда есть галстук в значениях Counter
, он выведет список ключей с учетом их хэшей.
В python2
, нет никаких причин, чтобы получить другой выход из различных экземпляров той же машине со следующим кодом:
$ python
>>> from nltk.book import *
>>> text1.similar('monstrous')
>>> exit()
$ python
>>> from nltk.book import *
>>> text1.similar('monstrous')
>>> exit()
$ python
>>> from nltk.book import *
>>> text1.similar('monstrous')
>>> exit()
Но в Python3
, он дает другой результат, каждый раз, когда вы запускаете text1.similar('monstrous')
см http://pastebin.com/ysAF6p6h
Вот простой эксперимент, чтобы доказать, что изворотливые различия между хэширования python2
и python3
:
[email protected]:~$ python -c "from collections import Counter; x = Counter({'foo': 1, 'bar': 1, 'foobar': 1, 'barfoo': 1}); print(x.most_common())"
[('foobar', 1), ('foo', 1), ('bar', 1), ('barfoo', 1)]
[email protected]:~$ python -c "from collections import Counter; x = Counter({'foo': 1, 'bar': 1, 'foobar': 1, 'barfoo': 1}); print(x.most_common())"
[('foobar', 1), ('foo', 1), ('bar', 1), ('barfoo', 1)]
[email protected]:~$ python -c "from collections import Counter; x = Counter({'foo': 1, 'bar': 1, 'foobar': 1, 'barfoo': 1}); print(x.most_common())"
[('foobar', 1), ('foo', 1), ('bar', 1), ('barfoo', 1)]
[email protected]:~$ python3 -c "from collections import Counter; x = Counter({'foo': 1, 'bar': 1, 'foobar': 1, 'barfoo': 1}); print(x.most_common())"
[('barfoo', 1), ('foobar', 1), ('bar', 1), ('foo', 1)]
[email protected]:~$ python3 -c "from collections import Counter; x = Counter({'foo': 1, 'bar': 1, 'foobar': 1, 'barfoo': 1}); print(x.most_common())"
[('foo', 1), ('barfoo', 1), ('bar', 1), ('foobar', 1)]
[email protected]:~$ python3 -c "from collections import Counter; x = Counter({'foo': 1, 'bar': 1, 'foobar': 1, 'barfoo': 1}); print(x.most_common())"
[('bar', 1), ('barfoo', 1), ('foobar', 1), ('foo', 1)]
Можете ли вы предоставить текст ввода и фрагмент кода, который вы использовали? Затем мы можем попытаться пропустить код и посмотреть, как объяснить разницу. – alvas
Я просто выполнил инструкции, которые являются частью этой страницы книги NLTK. http://www.nltk.org/book/ch01.html –
Что такое битрейт машины, которую вы используете для фрагмента кода в вопросе? http://stackoverflow.com/questions/9964396/python-check-if-a-system-is-32-or-64-bit-to-determine-whether-to-run-the-funct, каков ваш результат для 'python -c" import struct; print struct.calcsize ('P') * 8 "' – alvas