Использование моего собственного корпуса вместо корпуса movie_reviews для классификации в NLTK

Я использую следующий код и получаю его из Классификация с использованием корпуса обзоров фильмов в NLTK /Питон

import string
from itertools import chain
from nltk.corpus import movie_reviews as mr
from nltk.corpus import stopwords
from nltk.probability import FreqDist
from nltk.classify import NaiveBayesClassifier as nbc
import nltk

stop = stopwords.words('english')
documents = [([w for w in mr.words(i) if w.lower() not in stop and w.lower() not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]

word_features = FreqDist(chain(*[i for i,j in documents]))
word_features = word_features.keys()[:100]

numtrain = int(len(documents) * 90 / 100)
train_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in documents[:numtrain]]
test_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag  in documents[numtrain:]]

classifier = nbc.train(train_set)
print nltk.classify.accuracy(classifier, test_set)
classifier.show_most_informative_features(5)

выход:

0.655
Most Informative Features
                 bad = True              neg : pos    =      2.0 : 1.0
              script = True              neg : pos    =      1.5 : 1.0
               world = True              pos : neg    =      1.5 : 1.0
             nothing = True              neg : pos    =      1.5 : 1.0
                 bad = False             pos : neg    =      1.5 : 1.0

Я хочу создать свою папку вместо movie_reviews в nltk и положить в нее свои файлы.


person ZaM    schedule 26.03.2015    source источник
comment
Как выглядит ваша папка? Можете ли вы опубликовать фрагмент файлов в папке? Или ссылку на ваш набор данных?   -  person alvas    schedule 26.03.2015
comment
Она точно такая же, как папка movie_reviews, но имеет папки pos и neg. Но я сам выбираю содержимое .txt файлов   -  person ZaM    schedule 26.03.2015
comment
надеюсь ответ поможет   -  person alvas    schedule 26.03.2015
comment
@alvas Да, это было полезно. Спасибо. Не могли бы вы ответить на этот вопрос: ссылка   -  person ZaM    schedule 27.03.2015


Ответы (1)


Если у вас есть данные в точно такой же структуре, что и корпус movie_review в NLTK, есть два способа «взломать» свой путь:

<сильный>1. Поместите каталог вашего корпуса туда, где вы сохраняете nltk.data

Сначала проверьте, где хранится ваш nltk.data:

>>> import nltk
>>> nltk.data.find('corpora/movie_reviews')
FileSystemPathPointer(u'/home/alvas/nltk_data/corpora/movie_reviews')

Затем переместите свой каталог туда, где сохранено nltk_data/corpora:

# Let's make a test corpus like `nltk.corpus.movie_reviews`
~$ mkdir my_movie_reviews
~$ mkdir my_movie_reviews/pos
~$ mkdir my_movie_reviews/neg
~$ echo "This is a great restaurant." > my_movie_reviews/pos/1.txt
~$ echo "Had a great time at chez jerome." > my_movie_reviews/pos/2.txt
~$ echo "Food fit for the ****" > my_movie_reviews/neg/1.txt
~$ echo "Slow service." > my_movie_reviews/neg/2.txt
~$ echo "README please" > my_movie_reviews/README
# Move it to `nltk_data/corpora/`
~$ mv my_movie_reviews/ nltk_data/corpora/

В вашем коде Python:

>>> import string
>>> from nltk.corpus import LazyCorpusLoader, CategorizedPlaintextCorpusReader
>>> from nltk.corpus import stopwords
>>> my_movie_reviews = LazyCorpusLoader('my_movie_reviews', CategorizedPlaintextCorpusReader, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
>>> mr = my_movie_reviews
>>>
>>> stop = stopwords.words('english')
>>> documents = [([w for w in mr.words(i) if w.lower() not in stop and w.lower() not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]
>>> for i in documents:
...     print i
... 
([u'Food', u'fit', u'****'], u'neg')
([u'Slow', u'service'], u'neg')
([u'great', u'restaurant'], u'pos')
([u'great', u'time', u'chez', u'jerome'], u'pos')

(Подробнее см. https://github.com/nltk/nltk/blob/develop/nltk/corpus/util.py#L21 и https://github.com/nltk/nltk/blob/develop/nltk/corpus/init.py#L144)

<сильный>2. Создайте свой собственный CategorizedPlaintextCorpusReader

Если у вас нет доступа к каталогу nltk.data и вы хотите использовать свой собственный корпус, попробуйте следующее:

# Let's say that your corpus is saved on `/home/alvas/my_movie_reviews/`

>>> import string; from nltk.corpus import stopwords
>>> from nltk.corpus import CategorizedPlaintextCorpusReader
>>> mr = CategorizedPlaintextCorpusReader('/home/alvas/my_movie_reviews', r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
>>> stop = stopwords.words('english')
>>> documents = [([w for w in mr.words(i) if w.lower() not in stop and w.lower() not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]
>>> 
>>> for doc in documents:
...     print doc
... 
([u'Food', u'fit', u'****'], 'neg')
([u'Slow', u'service'], 'neg')
([u'great', u'restaurant'], 'pos')
([u'great', u'time', u'chez', u'jerome'], 'pos')

Подобные вопросы были заданы в разделе Создание пользовательского категоризированного корпуса в NLTK и Python и Использование моего собственного корпуса для категории классификация в Python NLTK


Вот полный код, который будет работать:

import string
from itertools import chain

from nltk.corpus import stopwords
from nltk.probability import FreqDist
from nltk.classify import NaiveBayesClassifier as nbc
from nltk.corpus import CategorizedPlaintextCorpusReader
import nltk

mydir = '/home/alvas/my_movie_reviews'

mr = CategorizedPlaintextCorpusReader(mydir, r'(?!\.).*\.txt', cat_pattern=r'(neg|pos)/.*', encoding='ascii')
stop = stopwords.words('english')
documents = [([w for w in mr.words(i) if w.lower() not in stop and w.lower() not in string.punctuation], i.split('/')[0]) for i in mr.fileids()]

word_features = FreqDist(chain(*[i for i,j in documents]))
word_features = word_features.keys()[:100]

numtrain = int(len(documents) * 90 / 100)
train_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag in documents[:numtrain]]
test_set = [({i:(i in tokens) for i in word_features}, tag) for tokens,tag  in documents[numtrain:]]

classifier = nbc.train(train_set)
print nltk.classify.accuracy(classifier, test_set)
classifier.show_most_informative_features(5)
person alvas    schedule 26.03.2015
comment
Просто добавьте другие строки после этого =). Используйте точно такой же код после строки documents = .... - person alvas; 26.03.2015
comment
Не могли бы вы объяснить, что вы имеете в виду? Я не понимаю. - person alvas; 26.03.2015
comment
Чтобы получить больше информации, используйте classifier.show_most_informative_features(5) - person alvas; 26.03.2015
comment
Большое спасибо. Оно работает. теперь я пытаюсь понять код;) - person ZaM; 26.03.2015
comment
@alvas Я получаю сообщение об ошибке в строке word_features = word_features.keys()[:100], говорящей о TypeError: объект 'dict_keys' не подлежит подписке. Что может быть возможной причиной? - person arqam; 13.03.2016
comment
И еще одно, сэр, не могли бы вы сказать, зачем нужна эта часть кодирования? - person arqam; 13.03.2016