2013-11-23 28 views
5
中定義

我正在通過轉換情感分析腳本來使用它們來教導自己(可能是我的第一個錯誤)類和方法。未找到Python方法,但是在類

以爲我把所有的替代方法,但我不斷收到

global name 'get_bigram_word_feats' is not defined

我敢肯定,我會得到一個錯誤的get_word_feats也一樣,如果它得到了遠。

我對這件大事很感興趣。我嘗試刪除staticmethod並添加自我。我究竟做錯了什麼?

這裏是我的代碼:

def word_feats(words): 
    return dict([(word, True) for word in words]) 


class SentClassifier: 

    def __init__(self, name, location): 
     self.name = name 
     self.location = location 
     self.fullpath = location + "/" + name 

    def doesexist(self): 
     return os.path.isfile(self.fullpath) 

    def save_classifier(self): 
     rf = open(self.fullpath, 'wb') 
     pickle.dump(self.fullpath, rf) 
     rf.close() 

    def load_classifier(self): 
     sf = open(self.fullpath, 'rb') 
     sclassifier = pickle.load(sf) 
     sf.close() 
     return sclassifier 


class Training: 

    def __init__(self, neg, pos): 
     self.neg = neg 
     self.pos = pos 
     self.negids = open(self.neg, 'rb').read().splitlines(True) 
     self.posids = open(self.pos, 'rb').read().splitlines(True) 
     self.exclude = set(string.punctuation) 
     self.exclude = self.exclude, '...' 
     self.swords = stopwords.words('english') 

    def tokens(self, words): 
     words = [w for w in nltk.word_tokenize(words) if w not in self.exclude and len(w) > 1 
      and w not in self.swords and wordnet.synsets(w)] 
     return words 

    def idlist(self, words): 
     thisidlist = [self.tokens(tf) for tf in words] 
     return thisidlist 

    @staticmethod 
    def get_word_feats(words): 
     return dict([(word, True) for word in words]) 

    @staticmethod 
    def get_bigram_word_feats(twords, score_fn=BigramAssocMeasures.chi_sq, tn=200): 
     words = [w for w in twords] 
     bigram_finder = BigramCollocationFinder.from_words(words) 
     bigrams = bigram_finder.nbest(score_fn, tn) 
     return dict([(ngram, True) for ngram in itertools.chain(words, bigrams)]) 

    @staticmethod 
    def label_feats(thelist, label): 
     return [(get_word_feats(lf), label) for lf in thelist] 

    @staticmethod 
    def label_grams(thelist, label): 
     return [(get_bigram_word_feats(gf), label) for gf in thelist()] 

    @staticmethod 
    def combinegrams(grams, feats): 
     for g in grams(): 
      feats.append(g) 
     return feats 

    def negidlist(self): 
     return self.idlist(self.negids) 

    def posidlist(self): 
     return self.idlist(self.posids) 

    def posgrams(self): 
     return self.label_grams(self.posidlist, 'pos') 

    def neggrams(self): 
     return self.label_grams(self.negidlist, 'neg') 

    def negwords(self): 
     return self.label_feats(self.negidlist, 'neg') 

    def poswords(self): 
     return self.label_feats(self.posidlist, 'pos') 

    def negfeats(self): 
     return self.combinegrams(self.neggrams, self.negwords) 

    def posfeats(self): 
     return self.combinegrams(self.posgrams, self.poswords) 

starttime = time.time() 

myclassifier = SentClassifier("sentanalyzer.pickle", "classifiers") 

if myclassifier.doesexist() is False: 
    print "training new classifier" 
    trainset = Training('data/neg.txt', 'data/pos.txt') 
    negfeats = trainset.negfeats() 
    posfeats = trainset.posfeats() 
    negcutoff = len(negfeats) * 8/10 
    poscutoff = len(posfeats) * 8/10 

    trainfeats = negfeats[:negcutoff] + posfeats[:poscutoff] 
    testfeats = negfeats[negcutoff:] + posfeats[poscutoff:] 
    print 'train on %d instances, test on %d instances' % (len(trainfeats), len(testfeats)) 

    classifier = NaiveBayesClassifier.train(trainfeats) 
    print 'accuracy:', nltk.classify.util.accuracy(classifier, testfeats) 
    myclassifier.save_classifier() 

else: 
    print "using existing classifier" 
    classifier = myclassifier.load_classifier() 

classifier.show_most_informative_features(20) 
mystr = "16 steps to an irresistible sales pitch, via @vladblagi: slidesha.re/1bVV7OS" 
myfeat = word_feats(nltk.word_tokenize(mystr)) 
print classifier.classify(myfeat) 

probd = classifier.prob_classify(myfeat) 

print probd.prob('neg') 
print probd.prob('pos') 

donetime = time.time() - starttime 

print donetime 
+0

我要指出的 - 我知道我的代碼可能是可怕的。我的計劃是一旦開始工作,就開始整理/清理。我知道不是最好的技術,但... – user1066609

+2

「(可能是我的第一個錯誤)」,否則,相反。學習某些東西,包括編程的最好方法就是試驗。由於電腦是如此寬容(在這裏試驗時你很少會失去一個肢體),所以放手吧! –

回答

2

你需要的所有信息是在異常的消息:

全球名 'get_bigram_word_feats' 沒有定義

(我的重點)

Python不明白你想從類中訪問該方法,因爲你沒有指定類名作爲方法調用的一部分。因此,它正在尋找全局名稱空間中的函數,但未能找到它。

如果您記得調用實例方法,您需要在方法前綴self.以使Python解釋器在正確的位置查找,這也適用於靜態方法,儘管您沒有指定self.,而是指定類名稱。

因此,要解決這個問題,電話前綴與類名的方法:

return [(Training.get_bigram_word_feats(gf), label) for gf in thelist()] 
     ^---+---^ 
      | 
      +-- you need this part 
+0

像魅力一樣工作,謝謝! – user1066609

+0

FWIW,類方法比靜態方法更有意義 - 您可以訪問類,並且不必在'labelgrams'中對類名進行硬編碼。作爲一般規則,要麼將方法與類綁定,然後將其設爲類方法,要麼它確實沒有被覆蓋的含義,而只是使用普通函數(是的,它是「一般」規則,即如果你不知道更好的話,這是一種指導方針)。 –

1

全局名稱 'get_bigram_word_feats' 沒有定義

您的電話應該是這樣的(注意:類名在這裏被使用):

@staticmethod 
def label_grams(thelist, label): 
    return [(Training.get_bigram_word_feats(gf), label) for gf in thelist()] 

通常,對於靜態方法,請使用類名稱。


我試圖消除靜態方法和添加的自我。我究竟做錯了什麼?

在這種情況下,您將使用self.funcName(..)。像下面這樣:

def label_grams(self, thelist, label): 
    return [(self.get_bigram_word_feats(gf), label) for gf in thelist()] 
1

好消息:修復很簡單。這樣稱呼:Training.get_bigram_word_feats(...)

例如,

@staticmethod 
def label_grams(thelist, label): 
    return [(Training.get_bigram_word_feats(gf), label) for gf in thelist()]