2013-05-10 37 views
0

我試圖用一個nltk樸素分類器來分類電影的流派。但是我得到了一些奇怪的結果。目前它只根據輸入的流派數量進行猜測。NLTK樸素貝葉斯分類器奇怪的結果

如果我輸入兩個動作電影,並且每個猜測都會有一個喜劇動作。當然,我希望它基於輸入的文本:

def RemoveStopWords(wordText): 
    keep_list = [] 
    for word in wordText: 
     if word not in wordStop: 
      keep_list.append(word.lower()) 

    return set(keep_list) 

def getFeatures(element): 

    splitter=re.compile('\\W*') 
    f = {} 
    plot = [s for s in RemoveStopWords(splitter.split(element['imdb']['plot'])) 
    if len(s)>5 and len(s) < 15] 

    for w in plot: 
      f[w]= w 

    return f 

def FindFeaturesForList(MovieList): 
    featureSet = [] 
    for w in MovieList: 
     print w['imdb']['title'] 
     try: 
      for genre in w['imdb']['genres']: 
       featureSet.append((getFeatures(w), genre)) 
     except: 
      print "Error when retriving genre, skipping element" 

    return featureSet 

featureList = FindFeaturesForList(trainset) 
cl = nltk.NaiveBayesClassifier.train(featureList) 

所以每當我做一個cl.classify(電影),它返回的最常見的輸入風格,我究竟做錯了什麼?

+1

使用兩個喜劇和一個動作片似乎太小的訓練集。你有沒有試過用至少*幾百部電影訓練分類器? – unutbu 2013-05-10 19:59:28

+0

是的,我已經嘗試過數百次,但是在查看數據時,猜測是基於流派的數量而不是輸入的文本。 – TheTango 2013-05-10 21:00:53

+0

你可以發佈'cl.show_most_informative_features(5)'嗎? – unutbu 2013-05-10 21:05:50

回答

0

在nltk書中的電影評論classification example中注意到,收集了所有電影中所有單詞的頻率,然後只有最常見的單詞被選爲特徵鍵。

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

我認爲需要注意的是,這是一個選擇是很重要的。功能鍵的選擇不是強制性的。其他一些聰明的功能選擇可能會導致更好的分類器。選擇好的特徵是科學背後的藝術。

不管怎樣,也許嘗試使用您的分級相同的想法:

def getFeatures(text, word_features): 
    text = text.lower() 
    f = {word: word in text for word in word_features} 
    return f 


def FindFeaturesForList(MovieList): 
    featureSet = [] 
    splitter = re.compile('\\W*') 
    all_words = nltk.FreqDist(
     s.lower() 
     for w in MovieList 
     for s in RemoveStopWords(splitter.split(w['imdb']['plot'])) 
     if len(s) > 5 and len(s) < 15) 
    word_features = all_words.keys()[:2000] 
    for w in MovieList: 
     print w['imdb']['title'] 
     try: 
      for genre in w['imdb']['genres']: 
       featureSet.append(
        (getFeatures(w['imdb']['plot'], word_features), genre)) 
     except: 
      print "Error when retriving genre, skipping element" 

    return featureSet 
+0

嗨,感謝您的反饋。 我絕對看到了這個想法。它可以改善分類器。但目前它並沒有改變結果。 - 目前每個輸入都被認爲是相同的類型。這是分類器訓練次數最多的類型。 – TheTango 2013-05-11 14:47:13

+0

@TheTango你應該儘量保持訓練集的平衡。我不知道在訓練模型時應該有什麼樣的「官方」立場。但是根據我的經驗,當每個輸出類的樣本數相同時,我總能找到更好的準確性。當我有一個不平衡的集合,我看到表現下降。 – Steve 2013-05-12 21:13:01

+0

@steve是否需要平衡訓練集?我一直認爲你需要每個類的一定數量的項目,但不應該混淆算法,應該嗎? – patrick 2016-07-13 16:45:45