我的特征向量中包含整数类型的特征,但NLTK的NaiveBayesClassifier
将其视为名义值处理。
背景
我正在尝试使用n-gram构建一个语言分类器。例如,bigrams ‘th’ 在英语中比法语中更常见。
对于训练集中的每个句子,我提取特征的方式如下:bigram(th): 5
,其中5(示例)代表bigrams ‘th’ 在句子中出现的次数。
当我尝试使用此类特征构建分类器并检查最具信息量的特征时,我发现分类器没有意识到这些特征是线性的。例如,它可能会将bigram(ea): 4
视为法语,bigram(ea): 5
视为英语,而bigram(ea): 6
又视为法语。这相当随意,并不代表bigrams在英语或法语中更常见的逻辑。这就是为什么我需要整数被正确处理的原因。
更多思考
当然,我可以用如has(th): True
这样的特征来替代这些特征。然而,我认为这是一个坏主意,因为一个带有1个’th’实例的法语句子和一个带有5个’th’实例的英语句子都会有特征has(th): True
,这无法区分它们。
我还找到了这个相关链接,但它没有为我提供答案。
特征提取器
我的特征提取器如下所示:
def get_ngrams(word, n): ngrams_list = [] ngrams_list.append(list(ngrams(word, n, pad_left=True, pad_right=True, left_pad_symbol='_', right_pad_symbol='_'))) ngrams_flat_tuples = [ngram for ngram_list in ngrams_list for ngram in ngram_list] format_string = '' for i in range(0, n): format_string += ('%s') ngrams_list_flat = [format_string % ngram_tuple for ngram_tuple in ngrams_flat_tuples] return ngrams_list_flat# Feature extractordef get_ngram_features(sentence_tokens): features = {} # Unigrams for word in sentence_tokens: ngrams = get_ngrams(word, 1) for ngram in ngrams: features[f'char({ngram})'] = features.get(f'char({ngram})', 0) + 1 # Bigrams for word in sentence_tokens: ngrams = get_ngrams(word, 2) for ngram in ngrams: features[f'bigram({ngram})'] = features.get(f'bigram({ngram})', 0) + 1 # Trigrams for word in sentence_tokens: ngrams = get_ngrams(word, 3) for ngram in ngrams: features[f'trigram({ngram})'] = features.get(f'trigram({ngram})', 0) + 1 # Quadrigrams for word in sentence_tokens: ngrams = get_ngrams(word, 4) for ngram in ngrams: features[f'quadrigram({ngram})'] = features.get(f'quadrigram({ngram})', 0) + 1 return features
特征提取示例
get_ngram_features(['test', 'sentence'])
返回:
{'char(c)': 1, 'char(e)': 4, 'char(n)': 2, 'char(s)': 2, 'char(t)': 3, 'bigram(_s)': 1, 'bigram(_t)': 1, 'bigram(ce)': 1, 'bigram(e_)': 1, 'bigram(en)': 2, 'bigram(es)': 1, 'bigram(nc)': 1, 'bigram(nt)': 1, 'bigram(se)': 1, 'bigram(st)': 1, 'bigram(t_)': 1, 'bigram(te)': 2, 'quadrigram(_sen)': 1, 'quadrigram(_tes)': 1, 'quadrigram(ence)': 1, 'quadrigram(ente)': 1, 'quadrigram(est_)': 1, 'quadrigram(nce_)': 1, 'quadrigram(nten)': 1, 'quadrigram(sent)': 1, 'quadrigram(tenc)': 1, 'quadrigram(test)': 1, 'trigram(_se)': 1, 'trigram(_te)': 1, 'trigram(ce_)': 1, 'trigram(enc)': 1, 'trigram(ent)': 1, 'trigram(est)': 1, 'trigram(nce)': 1, 'trigram(nte)': 1, 'trigram(sen)': 1, 'trigram(st_)': 1, 'trigram(ten)': 1, 'trigram(tes)': 1}
回答: