2013-11-23 9 views
5

में परिभाषित किया गया है कि मैं स्वयं को (शायद मेरी पहली गलती) कक्षाओं और तरीकों को पढ़ाने के लिए एक भावना विश्लेषण स्क्रिप्ट को परिवर्तित कर रहा हूं।पायथन विधि नहीं मिली, लेकिन कक्षा

मैं सोचा मैं जगह में तरीकों के सभी था, लेकिन मैं हो रही

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'

परिभाषित नहीं है (मेरे जोर)

पायथन समझ में नहीं आता है कि आप उस विधि को कक्षा से एक्सेस करना चाहते हैं, क्योंकि आपने विधि नाम के हिस्से के रूप में कक्षा का नाम निर्दिष्ट नहीं किया है। इस प्रकार, यह वैश्विक नामस्थान में फ़ंक्शन की तलाश में है और इसे ढूंढने में विफल रहा है।

यदि आपको इंस्टेंस विधियों को कॉल करने से याद है, तो आपको पाइथन दुभाषिया को सही जगह पर देखने के लिए self. के साथ विधियों को उपसर्ग करना होगा, और यह स्थिर विधियों के लिए भी है, हालांकि आप self. निर्दिष्ट नहीं करते हैं, इसके बजाय आप कक्षा निर्दिष्ट करते हैं नाम।

तो यह तय करने के लिए, वर्ग के नाम के साथ विधि करने के लिए कॉल उपसर्ग:

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

एक आकर्षण की तरह काम किया, धन्यवाद! – user1066609

+0

एफडब्ल्यूआईडब्लू, एक क्लासमेड यहां एक स्टेटिक विधि से अधिक समझदार होगा - आपको कक्षा तक पहुंच प्राप्त होगी और 'लेबलग्राम' में कक्षा का नाम हार्डकोड नहीं करना पड़ेगा। एक सामान्य नियम के रूप में, या तो आप किसी वर्ग को विधि को जोड़ना चाहते हैं और फिर आप इसे क्लासमेड बनाते हैं, या इसका वास्तव में कोई अर्थ नहीं है और आप केवल सादा फ़ंक्शन का उपयोग करते हैं (और हाँ, यह एक "सामान्य" नियम है, यानी यदि आप बेहतर नहीं जानते हैं तो एक दिशानिर्देश का एक प्रकार)। –

1

वैश्विक नाम 'get_bigram_word_feats' परिभाषित नहीं है

आपका कॉल इस तरह दिखना चाहिए (यहां इस्तेमाल किया जा रहा वर्ग के नाम पर ध्यान दें):

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

सामान्य रूप से, स्थिर तरीकों के लिए, कक्षा का नाम उपयोग करें।


मैं staticmethod को दूर करने और स्वयं को जोड़ने की कोशिश की। मैं क्या गलत कर रहा हूं?

उस स्थिति में, आप 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()] 
संबंधित मुद्दे