1

Я бы хотел спрогнозировать, например, китайские или некитайские этнические группы, используя фамилии. В частности, я хочу извлечь трехбуквенные подстроки из фамилий. Так, например, фамилия «гао» даст одну функцию «гао», а «чан» даст две функции: «ча» и «хан».Создание словаря функций для алгоритма машинного обучения Python (наивные байки)

Разделение успешно выполняется в функции three_split ниже. Но, насколько я понимаю, для включения этого в качестве набора функций мне нужно вернуть выход в качестве словаря. Любые намеки на то, как это сделать? Для словаря «Чан» словарь должен возвращать «cha» и «han» как TRUE.

from nltk.classify import PositiveNaiveBayesClassifier 
import re 

chinese_names = ['gao', 'chan', 'chen', 'Tsai', 'liu', 'Lee'] 

nonchinese_names = ['silva', 'anderson', 'kidd', 'bryant', 'Jones', 'harris', 'davis'] 

def three_split(word): 
    word = word.lower() 
    word = word.replace(" ", "_") 
    split = 3 
    return [word[start:start+split] for start in range(0, len(word)-2)] 

positive_featuresets = list(map(three_split, chinese_names)) 
unlabeled_featuresets = list(map(three_split, nonchinese_names)) 
classifier = PositiveNaiveBayesClassifier.train(positive_featuresets, 
    unlabeled_featuresets) 

print three_split("Jim Silva") 
print classifier.classify(three_split("Jim Silva")) 

ответ

2

Вот белого ящика ответ:

Использование Orginal код, он выдает:

Traceback (most recent call last): 
    File "test.py", line 17, in <module> 
    unlabeled_featuresets) 
    File "/usr/local/lib/python2.7/dist-packages/nltk/classify/positivenaivebayes.py", line 108, in train 
    for fname, fval in featureset.items(): 
AttributeError: 'list' object has no attribute 'items' 

Глядя на линии 17:

classifier = PositiveNaiveBayesClassifier.train(positive_featuresets, 
    unlabeled_featuresets) 

Кажется, что PositiveNaiveBayesClassifier требуется объект, который имеет атрибут '.items()', и интуитивно он должен быть a dict, если код NLTK является pythonic.

Глядя на https://github.com/nltk/nltk/blob/develop/nltk/classify/positivenaivebayes.py#L88, не существует какого-либо четкого объяснения того, что параметр positive_featuresets должен содержать:

: Param positive_featuresets: Список featuresets, которые известны как положительных примеров (т.е. их метка True).

Проверка строки документации, мы видим этот пример:

Example: 
    >>> from nltk.classify import PositiveNaiveBayesClassifier 
Some sentences about sports: 
    >>> sports_sentences = [ 'The team dominated the game', 
    ...      'They lost the ball', 
    ...      'The game was intense', 
    ...      'The goalkeeper catched the ball', 
    ...      'The other team controlled the ball' ] 
Mixed topics, including sports: 
    >>> various_sentences = [ 'The President did not comment', 
    ...      'I lost the keys', 
    ...      'The team won the game', 
    ...      'Sara has two kids', 
    ...      'The ball went off the court', 
    ...      'They had the ball for the whole game', 
    ...      'The show is over' ] 
The features of a sentence are simply the words it contains: 
    >>> def features(sentence): 
    ...  words = sentence.lower().split() 
    ...  return dict(('contains(%s)' % w, True) for w in words) 
We use the sports sentences as positive examples, the mixed ones ad unlabeled examples: 
    >>> positive_featuresets = list(map(features, sports_sentences)) 
    >>> unlabeled_featuresets = list(map(features, various_sentences)) 
    >>> classifier = PositiveNaiveBayesClassifier.train(positive_featuresets, 
    ...             unlabeled_featuresets) 

Теперь мы находим функцию feature(), преобразующее предложения в особенность и возвращает

dict(('contains(%s)' % w, True) for w in words) 

В основном это вещь, которая имеет возможность позвонить по телефону .items(). Глядя на понимание дикта, кажется, что 'contains(%s)' % w немного избыточно, если только он не предназначен для чтения человеком. Таким образом, вы могли бы просто использовать dict((w, True) for w in words).

Кроме того, замена пространства символом подчеркивания также может быть избыточной, если в дальнейшем это не будет использовано.

Наконец, нарезка и ограниченная итерация могли заменяться функцией ngram, которая может извлекать символьные ngrams, например.

>>> word = 'alexgao' 
>>> split=3 
>>> [word[start:start+split] for start in range(0, len(word)-2)] 
['ale', 'lex', 'exg', 'xga', 'gao'] 
# With ngrams 
>>> from nltk.util import ngrams 
>>> ["".join(ng) for ng in ngrams(word,3)] 
['ale', 'lex', 'exg', 'xga', 'gao'] 

Ваша функция функция извлечения может быть упрощена, как например:

from nltk.util import ngrams 
def three_split(word): 
    return dict(("".join(ng, True) for ng in ngrams(word.lower(),3)) 

[выход]:

{'im ': True, 'm s': True, 'jim': True, 'ilv': True, ' si': True, 'lva': True, 'sil': True} 
False 

В самом деле, NLTK классификаторы настолько универсален, что вы можете использовать кортежи символов, так что вам не нужно исправлять ngram при извлечении функций, то есть:

from nltk.classify import PositiveNaiveBayesClassifier 
import re 
from nltk.util import ngrams 

chinese_names = ['gao', 'chan', 'chen', 'Tsai', 'liu', 'Lee'] 

nonchinese_names = ['silva', 'anderson', 'kidd', 'bryant', 'Jones', 'harris', 'davis'] 


def three_split(word): 
    return dict(((ng, True) for ng in ngrams(word.lower(),3)) 

positive_featuresets = list(map(three_split, chinese_names)) 
unlabeled_featuresets = list(map(three_split, nonchinese_names)) 

classifier = PositiveNaiveBayesClassifier.train(positive_featuresets, 
    unlabeled_featuresets) 

print three_split("Jim Silva") 
print classifier.classify(three_split("Jim Silva")) 

[выход]:

{('m', ' ', 's'): True, ('j', 'i', 'm'): True, ('s', 'i', 'l'): True, ('i', 'l', 'v'): True, (' ', 's', 'i'): True, ('l', 'v', 'a'): True, ('i', 'm', ' '): True} 
0

С некоторыми проб и ошибок, я думаю, что у меня это есть. Благодарю.

from nltk.classify import PositiveNaiveBayesClassifier 
import re 

chinese_names = ['gao', 'chan', 'chen', 'Tsai', 'liu', 'Lee'] 

nonchinese_names = ['silva', 'anderson', 'kidd', 'bryant', 'Jones', 'harris', 'davis'] 

def three_split(word): 
    word = word.lower() 
    word = word.replace(" ", "_") 
    split = 3 
    return dict(("contains(%s)" % word[start:start+split], True) 
     for start in range(0, len(word)-2)) 

positive_featuresets = list(map(three_split, chinese_names)) 
unlabeled_featuresets = list(map(three_split, nonchinese_names)) 
classifier = PositiveNaiveBayesClassifier.train(positive_featuresets, 
    unlabeled_featuresets) 

name = "dennis kidd" 
print three_split(name) 
print classifier.classify(three_split(name)) 
Смежные вопросы