0

Я в процессе написания наивного классификатора заливов, потому что у меня есть большая группа текстовых документов, которые мне нужно классифицировать. Однако, когда я пытаюсь проверить свои предсказания я получаю следующую ошибкуКак преобразовать tfidf и «соответствовать» значениям для моего текстового классификатора?

sklearn.utils.validation.NotFittedError: TfidfVectorizer - Vocabulary wasn't fitted.

То, что я сделал, прежде чем спрашивать здесь

Я в курсе теории, как наивный байесовский работает классификация.

      P(B|A)*P(A) 
    P(A|B) =   ____________________ 

      P(B|A)*P(A) + P(B|C)*P(C) +...+P(B|n)*P(n) 

где п являются различные классы, которые вы хотите, чтобы классифицировать и P (B | A) есть вероятность B СОВЕРШАЕМЫЙ учитывая, что произошло, и P (A) является вероятность возникновения. Следует отметить, что я специально работаю с многомиллиальными наивными заливами.

Я также нашел этот вопрос:

SciPy and scikit-learn - ValueError: Dimension mismatch

, а также этот вопрос

cannot cast array data when a saved classifier is called

Однако, я все еще возникают проблемы, когда я пытаюсь делать прогнозы или проверить мой прогнозы.

Я написал следующие функции, которые я использую для создания обучения и тестирования набор

def split_data_set(original_data_set, percentage): 
    test_set = [] 
    train_set = [] 

    forbidden = set() 

    split_sets = {} 

    if is_float(percentage): 
     stop_len = int(percentage * len(original_data_set)) 

    while len(train_set) < stop_len: 
     random_selection = randrange(0, len(original_data_set)) 
     if random_selection not in forbidden: 
      forbidden.add(random_selection) 
      train_set.append(original_data_set[random_selection]) 

    for j in range(0, len(original_data_set)-1): 
     if j not in forbidden: 
      test_set.append(original_data_set[j]) 

    split_sets.update({'testing set': test_set}) 
    split_sets.update({'training set': train_set}) 
    split_sets.update({'forbidden': forbidden}) 

    return split_sets 

создать и обучить модель

def create_and_fit_baes_model(data_set): 

    train = [] 
    expect = [] 

    for data in data_set['training set']: 
     train.append(data[1]) 
     expect.append(data[0]) 

    vectorizer = TfidfVectorizer(min_df=1) 

    # I think this is one of the places where I'm doing something 
    # incorrectly 
    vectorized_training_data = vectorizer.fit_transform(train) 


    model = MultinomialNB() 


    model.fit(vectorized_training_data, expect) 

    return model 

и проверить свою модель

def test_nb_model(data_set, model): 

    test = [] 
    expect = [] 

    for data in data_set['testing set']: 
     test.append(data[1]) 
     expect.append(data[0]) 

    #This is the other section where I think that 
    # I'm doing something incorrectly 
    vectorizer = TfidfVectorizer(min_df=1) 
    vectorized_testing_data = vectorizer.transform(test) 
    fitted_vectorized_testing_data = vectorizer.fit(vectorized_testing_data) 

    predicted = model.predict(fitted_vectorized_testing_data) 

    print(metrics.confusion_matrix(expect,predicted)) 
    print(metrics.classification_report(expect, predicted)) 

Я считаю, что у меня возникла проблема на этапе трансформации/подгонки.

Я знаю, что tfidf векторизации работает следующим образом

Это будет правильная матрица из документов, которые имеют счетчики на разные сроки.

 _term1____term2____term3____termn____________ 
doc1| 5 | 0 |  13 | 1 
doc2| 0 | 8 |  2 | 0 
doc3| 1 | 5 |  5 | 10 
. | . | . |  . | . 
. | . | . |  . | . 
. | . | . |  . | . 
docn| 10 | 0 |  0 | 0 

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

Я знаю, как все это работает в теории, и я могу работать на математике на бумаге, но когда я пытаюсь читать the documentation для sklearn, я все еще немного смущен относительно того, как я должен все кодировать.

Я боролся с этим в течение последних двух дней. Если бы кто-то мог понять, что я делаю неправильно, и как я могу полностью обучать и управлять своей моделью, я был бы признателен.

+1

Вам также нужно сэкономить векторный указатель tfidf и использовать ** тот же самый ** на этапе обучения. – lejlot

+0

@lejlot Вы имеете в виду использование одного и того же вектора? Как мне нужно передать это от одного метода другому? –

+0

да, я имею в виду, что вам тоже нужно его спасти – lejlot

ответ

2

Я думаю, что самый чистый вариант - использовать Pipeline для упаковки вашего векторизатора с помощью вашего классификатора; то, если вы вызываете model.fit, это будет соответствовать лексике и терминам частот вашего векторизонта и сделать их доступными для последующих функций.Таким образом, вы все равно можете просто вернуть одну «модель» из своей учебной функции, и вы также можете ее рассортировать, если вам нужно сохранить свою модель.

from sklearn.pipeline import Pipeline 

def create_and_fit_model(data): 
    # ... get your train and expect data 
    vectorizer = TfidfVectorizer(min_df=1) 
    nb = MultinomialNB() 
    model = Pipeline([('vectorizer', vectorizer), ('nb', nb)]) 
    model.fit(train, expect) 
    return model 

Кстати, вам не нужно, чтобы написать свой собственный код для ж/тест раскола, вы можете использовать sklearn.cross_validation.train_test_split. Также вы должны посмотреть на использование панд для хранения ваших данных, а не простых списков; это облегчит извлечение столбцов.

 Смежные вопросы

  • Нет связанных вопросов^_^