2016-10-20 11 views
0

Теперь я изучаю классификатор naivebayes с помощью nltk.Как добавить частоту в классификатор nltk naivebayes?

В документе (http://www.nltk.org/book/ch06.html) 1.3 Классификация документов, есть пример оснастки.

featuresets = [(document_features(d), c) for (d,c) in documents] 
train_set, test_set = featuresets[100:], featuresets[:100] 
classifier = nltk.NaiveBayesClassifier.train(train_set) 

all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words()) 
word_features = list(all_words)[:2000] [1] 

def document_features(document): [2] 
    document_words = set(document) [3] 
    features = {} 
    for word in word_features: 
     features['contains({})'.format(word)] = (word in document_words) 
    return features 

Так пример формы featuresets является {('содержит (отходы)': false, 'содержит (много)': false, ...}, 'нег') ...}

Но я хочу изменить слово словарь формы из «содержит (отходы)»: Ложные к «содержит (отходы)»: 2. Я думаю, что эта форма («содержит (отходы)»: 2) хорошо объясняет документ, потому что он может рассчитать частоту мира. Так featureset будет {('содержит (отходы)': 2, 'содержит (много)': 5, ...}, 'нег') ...}

Но я беспокоился о том, содержит ли '(отходы)': 2 и 'содержит (отходы)': 1 - это совсем другое слово для naivebayesclassifier. Тогда он не может объяснить сходство 'содержит (отходы)': 2 и 'содержит (отходы)': 1.

{ 'содержит (много)': 1 и 'содержит (отходы)': 1} и { 'содержит (отходы)': 2 и 'содержит (отходы)': 1} может быть одинаковым для программы.

Может ли nltk.naivebayesclassifier понять частоту слова?

Это код, который я использовал

def split_and_count_word(data): 
    #belongs_to : Main 
    #Role : make featuresets from korean words using konlpy. 
    #Parameter : dictionary data(dict of contents ex.{'politic':{'parliament': [content,content]}..}) 
    #Return : list featuresets([{'word':True',...},'politic'] == featureset + category) 

    featuresets = [] 
    twitter = konlpy.tag.Twitter()#Korean word splitter 

    for big_cat in data: 

     for small_cat in data[big_cat]: 
      #save category name needed in featuresets 
      category = str(big_cat[0:3])+'/'+str(small_cat) 
      count = 0; print(small_cat) 

      for one_news in data[big_cat][small_cat]: 
       count+=1; if count%100==0: print(count,end=' ')     
       #one_news is list in list so open it! 
       doc = one_news 
       #split word as using konlpy 
       list_of_splited_word = twitter.morphs(doc[:-63])#delete useless sentences. 
       #get word length is higher than two and get list of splited words 
       list_of_up_two_word = [word for word in list_of_splited_word if len(word)>1] 
       dict_of_featuresets = make_featuresets(list_of_up_two_word) 
       #save 
       featuresets.append((dict_of_featuresets,category)) 

    return featuresets 


def make_featuresets(data): 
    #belongs_to : split_and_count_word 
    #Role : make featuresets 
    #Parameter : list list_of_up_two_word(ex.['비누','떨어','지다'] 
    #Return : dictionary {word : True for word in data} 

    #PROBLEM :(
    #cannot consider the freqency of word 
    return {word : True for word in data} 

def naive_train(featuresets): 
    #belongs_to : Main 
    #Role : Learning by naive bayes rule 
    #Parameter : list featuresets([{'word':True',...},'pol/pal']) 
    #Return : object classifier(nltk naivebayesclassifier object), 
    #   list test_set(the featuresets that are randomly selected) 

    random.shuffle(featuresets) 
    train_set, test_set = featuresets[1000:], featuresets[:1000] 
    classifier = naivebayes.NaiveBayesClassifier.train(train_set) 

    return classifier,test_set 

featuresets = split_and_count_word(data) 
classifier,test_set = naive_train(featuresets) 

ответ

0

наивный байесовский классификатор трактует NLTK оснащены значения, логически различны. Значения не ограничиваются True и False, но они никогда не рассматриваются как количества. Если у вас есть функции f=2 и f=3, они учитываются как разные значения. Единственный способ добавить количество к такой модели - сортировать их в «ведра», например, f=1, f="few" (2-5), f="several" (6-10), f="many" (11 или более), например. (Примечание. Если вы идете по этому маршруту, существуют алгоритмы выбора хороших диапазонов значений для ковшей.) И даже тогда модель не «знает», что «мало» находится между «одним» и «несколькими». Вам понадобится другой инструмент машинного обучения для обработки количества напрямую.

+0

Благодарим за идею. Тогда вы имеете в виду, что я не могу добавить слово, которое уже содержится в словаре функций? Например, словарь будет {** "привет": True, "hello": True **, "my": True ...}. Тогда вы можете порекомендовать другой полезный модуль машинного обучения? – dizwe

+0

Как вы уже указали в своем комментарии к @ aberger, нет, вы не можете иметь одну и ту же клавишу дважды в dict. Извините, я не могу прямо указать вам на количественное решение. Nltk ['MaxentClassifier'] (http://www.nltk.org/api/nltk.classify.html#nltk.classify.maxent.MaxentClassifier) ​​использует числовые веса, но они обычно создаются API из« номинального «функции, которые вы предоставляете; так что вам нужно будет выкарабкаться, чтобы правильно использовать его. Посмотрите также на scikit-learn. Лучший классификатор зависит от вашей задачи, поэтому экспериментируйте с несколькими! – alexis

+0

Спасибо, я попробую! – dizwe