2015-03-26 2 views
0

Я делаю классификационную задачу на твитах (3 метки = pos, neg, нейтраль), для которых я использую Naive Bayes в NLTK. Я бы хотел добавить в ngrams (bigrams). Я попытался добавить их в код, но мне кажется, что не добирается, где им подходит. На данный момент кажется, что я «нарушаю» код, независимо от того, где я добавляю в bigrams. Может ли кто-нибудь помочь мне или перенаправить меня в учебник?NLTK: Наивный Байес - где/как добавить в ngrams?

Следующий код для униграмм. Если вам нужна какая-либо информация о том, как выглядят наборы данных, я был бы рад предоставить ее.

import nltk 
import csv 
import random 
import nltk.classify.util, nltk.metrics 
import codecs 
import re, math, collections, itertools 
from nltk.corpus import stopwords 
from nltk.classify import NaiveBayesClassifier 
from nltk.probability import FreqDist, ConditionalFreqDist 
from nltk.util import ngrams 
from nltk import bigrams 
from nltk.metrics import BigramAssocMeasures 
from nltk.collocations import BigramCollocationFinder 
from nltk.tokenize import word_tokenize 
from nltk.stem.snowball import SnowballStemmer 
from nltk.tokenize import WordPunctTokenizer 

tokenizer = WordPunctTokenizer() 
stemmer = SnowballStemmer("english", ignore_stopwords = True) 
stopset = set(stopwords.words('english')) 

stopset.add('username') 
stopset.add('url') 
stopset.add('percentage') 
stopset.add('number') 
stopset.add('at_user') 
stopset.add('AT_USER') 
stopset.add('URL') 
stopset.add('percentagenumber') 


inpTweets = [] 
##with open('sanders.csv', 'r', 'utf-8') as f: #input sanders  
## reader = csv.reader(f, delimiter = ';')  
## for row in reader: 
##  inpTweets.append((row)) 
reader = codecs.open('...sanders.csv', 'r', encoding='utf-8-sig') #input classified tweets 
for line in reader: 
    line = line.rstrip() 
    row = line.split(';') 
    inpTweets.append((row))  

def processTweet(tweet): 
    tweet = tweet.lower() 
    tweet = re.sub('((www\.[^\s]+)|(https?://[^\s]+))','URL',tweet) 
    tweet = re.sub('@[^\s]+','AT_USER',tweet) 
    tweet = re.sub('[\s]+', ' ', tweet) 
    tweet = re.sub(r'#([^\s]+)', r'\1', tweet) 
    tweet = tweet.strip('\'"') 
    return tweet 

def replaceTwoOrMore(s): 
    #look for 2 or more repetitions of character and replace with the character itself 
    pattern = re.compile(r"(.)\1{1,}", re.DOTALL) 
    return pattern.sub(r"\1\1", s) 


def preprocessing(doc): 
    tokens = tokenizer.tokenize(doc) 
    bla = [] 
    for x in tokens: 
     if len(x)>2: 
      if x not in stopset: 
       val = re.search(r"^[a-zA-Z][a-zA-Z0-9]*$", x) 
       if val is not None: 
        x = replaceTwoOrMore(x) 
        x = processTweet(x) 
        x = x.strip('\'"?,.') 
        x = stemmer.stem(x).lower() 
        bla.append(x) 
    return bla 

xyz = [] 

for lijn in inpTweets: 
    xyz.append((preprocessing (lijn[0]),lijn[1])) 
random.shuffle(xyz) 

featureList = [] 
k = 0 
while k in range (0, len(xyz)): 
    featureList.extend(xyz[k][0]) 
    k = k + 1 

fd = nltk.FreqDist(featureList) 
featureList = list(fd.keys())[2000:] 

def document_features(doc):  
    features = {} 
    document_words = set(doc) 
    for word in featureList: 
     features['contains(%s)' % word] = (word in document_words) 
    return features 


featuresets = nltk.classify.util.apply_features(document_features, xyz) 

training_set, test_set = featuresets[2000:], featuresets[:2000] 

classifier = nltk.NaiveBayesClassifier.train(training_set) 
+0

Как выглядит 'sanders.csv'? можете ли вы дать фрагмент данных? – alvas

+0

@alvas файл sanders, когда я загружаю его в Python (т. Е. Когда я загружаю его в inpTweets), список списков выглядит следующим образом: [['tweet1', 'sentiment1'], ['tweet2', 'sentiment2 «] ...]. Например: [['в честь steve jobs username ripsteve url', 'neutral'], [', когда имя пользователя собирается обновить факт, что я не могу видеть emoji на twitter для mac', 'neutral']]. Три метки, используемые в наборе Sanders, являются pos, neg и нейтральными. – thesisstudent

ответ

-1

Интересный подход использует sequential backoff tagger, который позволяет Вам цепь Taggers вместе: таким образом вы могли бы обучить энграммы Tagger и Наивный Байес и приковать их совмещено.

+0

Я не думаю, что классификатор когда-либо отступает - зачем? – alexis

+0

Из комментария ссылки, которую я опубликовал: «Если теггер не может определить тэг для указанного токена, тогда его тег тега обратного отсчета - это ». – unixo

+0

Вы все еще говорите об агитаторах; вопрос о классификаторах. – alexis

0

Ваш код использует 2000 наиболее распространенных слов в качестве функций классификации. Просто выберите биграммы, которые вы хотите использовать, и преобразуйте их в функции в document_features(). Функция, подобная "contains (the dog)", будет работать так же, как "contains (dog)".