Невозможно использовать Pandas и NLTK для обучения Naive Bayes (машинное обучение) в Python

Вот что я пытаюсь сделать. У меня есть CSV. файл со столбцом 1 с именами людей (например, «Майкл Джордан», «Андерсон Сильва», «Мухаммад Али») и столбцом 2 с этнической принадлежностью людей (например: англичане, французы, китайцы).

В моем коде я создаю фрейм данных pandas, используя все данные. Затем создайте дополнительные фреймы данных: один только с китайскими именами, а другой только с некитайскими именами. И тогда я создаю отдельные списки.

Функция three_split извлекает особенности каждого имени, разбивая их на подстроки из трех символов. Например, "Кэти Перри" в "кат", "ати", "ты", "у п"... и т.д.

Затем я тренируюсь с Наивным Байесом и, наконец, проверяю результаты.

При запуске моих кодов ошибок нет, но когда я пытаюсь использовать некитайские имена непосредственно из базы данных и ожидаю, что программа вернет False (не китайский), она возвращает True (китайский) для любого имени, которое я тестирую. Есть идеи?

import pandas as pd
from pandas import DataFrame, Series
import numpy as np
import nltk
from nltk.classify import NaiveBayesClassifier as nbc
from nltk.classify import PositiveNaiveBayesClassifier

# Get csv file into data frame
data = pd.read_csv("C:\Users\KubiK\Dropbox\Python exercises_KW\_Scraping\BeautifulSoup\FamilySearch.org\FamSearch_Analysis\OddNames_sampleData3.csv", 
    encoding="utf-8")
df = DataFrame(data)
df.columns = ["name", "ethnicity"]

# Recategorize different ethnicities into 1) Chinese or 2) non-Chinese; and then create separate lists
df_chinese = df[(df["ethnicity"] == "chinese") | (df["ethnicity"] == "Chinese")]
chinese_names = list(df_chinese["name"])

df_nonchinese = df[(df["ethnicity"] != "chinese") & (df["ethnicity"] != "Chinese") & (df["ethnicity"].notnull() == True)]
nonchinese_names = list(df_nonchinese["name"])

# Function to split word string into three-character substrings
def three_split(word):
    word = str(word).lower().replace(" ", "_")
    split = 3
    return dict(("contains(%s)" % word[start:start+split], True) 
        for start in range(0, len(word)-2))

# Training naive bayes machine learning algorithm
positive_featuresets = list(map(three_split, chinese_names))
unlabeled_featuresets = list(map(three_split, nonchinese_names))
classifier = PositiveNaiveBayesClassifier.train(positive_featuresets, unlabeled_featuresets)

# Testing results
name = "Hubert Gillies" # A non-Chinese name from the dataset
print classifier.classify(three_split(name))
>>> True # Wrong output

person KubiK888    schedule 04.04.2015    source источник


Ответы (1)


Может быть много проблем, когда дело доходит до того, почему вы не получаете желаемых результатов, чаще всего это либо:

  • Характеристики недостаточно сильны
  • Недостаточно данных для тренировки
  • Неправильный классификатор
  • Ошибки кода в классификаторах NLTK

По первым трем причинам невозможно проверить/устранить проблему, если вы не опубликуете ссылку на свой набор данных, и мы посмотрим, как это исправить. Что касается последней причины, то ее не должно быть для базового классификатора NaiveBayes и PositiveNaiveBayes.

Итак, вопрос, который нужно задать:

  • Сколько экземпляров обучающих данных (то есть строк) у вас есть?
  • Почему вы не нормализовали свои метки (например, китайский | китайский -> китайский) после того, как прочитали набор данных перед извлечением функций?
  • Какие еще особенности учитывать?
  • Рассматривали ли вы возможность использования NaiveBayes вместо PositiveNaiveBayes?
person alvas    schedule 04.04.2015
comment
Спасибо за ответ. Я очень смущен тем, почему это не дает мне ожидаемого результата. Я относительно новичок в Python, поэтому я построил его в несколько этапов. Сначала я проверил, просто разделив все имя на имя и фамилию и используя классификатор, он дает ожидаемые результаты. Затем я перехожу к функции three_split, используя только краткий список, который я просто набрал, например: chinese_names = [Чун ли, Джеки Чан, ...]. Это также дало ожидаемые результаты, различающие китайские имена и некитайские имена. - person KubiK888; 04.04.2015
comment
Затем я сделал это окончательное кодирование, используя небольшую выборку полных данных. Эта небольшая выборка включает в себя ›1000 имен и соответствующую этническую принадлежность. Есть около 50 китайских имен, а остальные некитайские. Таким образом, вероятностно, он должен склоняться к False. Особенно, когда я использую некитайские имена, а он все равно выводит True. Я даже печатаю наборы свойств Positive_featuresets и unlabeled_featuresets, и похоже, что они успешно создали наборы признаков подстроки. - person KubiK888; 04.04.2015
comment
Чтобы ответить на ваши другие вопросы, я не нормализовал метки, потому что я выполняю начальное тестирование, и я думаю, что мой текущий способ кодирования перед составлением списка в порядке. Я рассмотрю другие функции, но эта (функция трехбуквенной подстроки) должна быть достаточно мощной, чтобы различать китайские и некитайские имена. Я рассмотрю NaiveBayes. - person KubiK888; 04.04.2015
comment
В качестве обновления я попытался использовать полный набор данных (миллион+), и он кажется более точным (70-80%?). Хотя я все еще не понимаю, почему при использовании меньшей выборки результаты, как правило, были верными для китайского языка, даже несмотря на то, что небольшая выборка имеет соотношение 10: 1, а имена, которые я тестировал, не китайские. - person KubiK888; 04.04.2015
comment
Кроме того, я попытался найти больше ссылок, чтобы узнать, как использовать PositiveNaiveBayesClassifier. Но мало что могу найти. Любая идея, как я могу научиться использовать этот классификатор для объединения обучающих и тестовых наборов как 50:50 из исходного полного набора данных, и как я могу выполнить проверку точности (например, чувствительность и специфичность)? Спасибо. - person KubiK888; 04.04.2015
comment
Вы прошли через это: coursera.org/course/ml? Это полезно для понимания того, как работает базовое машинное обучение. Мне потребовались месяцы, чтобы изучить материалы, так как я повторял некоторые лекции довольно много раз, но это того стоило. - person alvas; 04.04.2015
comment
Спасибо, я думаю, что я уже обращался к этому однажды (не глубоко), но мне трудно на самом деле выполнять машинное обучение с использованием Python, так как есть много модулей и способов сообщить python параметры и т. д. - person KubiK888; 04.04.2015