В современном мире, когда люди вкладывают свои сердца и мысли в социальные сети, все свои желания и намерения можно узнать из того, чем этот человек делится или комментирует в социальных сетях. Эти комментарии могут быть сильным средством поиска потенциальных клиентов для любого продукта. Недавно я сделал проект, чтобы понять намерение комментария, чтобы понять, показывает ли это предложение намерение покупки или нет, который называется Классификация намерений.

Немного о классификации намерений

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

предварительная обработка данных

Для этого проекта я использовал данные с комментариями о продукте и намерении как PI (потенциальное намерение) и no. Файл данных был сохранен как файл с разделителями-запятыми.

Код для чтения и предварительной обработки данных следующий:

import pandas as pd
df = pd.read_csv("intent_data.csv")
# Removing all the duplicate data
df.drop_duplicates(inplace=True) 
#Renaming column names for easy understanding
df.columns = ["index","class","tweets"]

Итак, пока у нас есть все данные, хранящиеся во фрейме данных с именами столбцов, такими как «индекс», «класс» для намерения покупки и «твиты» для комментариев о продукте. Теперь данные нашего класса находятся в текстовом формате, который несовместим с обучением модели. Итак, мы преобразуем данные в двоичный код, где 1 будет означать намерение покупки, а 0 - намерение покупки.

df['class'] = prepareY(df['class']).copy()
y = df.iloc[:,1].values # Ready for the training
def prepareY(dfy):
  dfy = dfy.str.lower()
  dfy[dfy == 'pi'] = 1
  dfy[dfy == 'no'] = 0
  
  
  return dfy

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

text = df.iloc[:,2].values
wordnet_lemmatizer = WordNetLemmatizer()
stops = stopwords.words('english') 
nonan = re.compile(r'[^a-zA-Z ]')
x = []
for i in range(len(text)):
    sentence = nonan.sub('', text[i])
    words = word_tokenize(sentence.lower())
    filtered_words = [w for w in words if not w.isdigit() and not w in stops and not w in string.punctuation]
    tags = pos_tag(filtered_words)
    cleaned = ''
    pos = ['NN','NNS','NNP','NNPS','RP','MD','FW','VBZ','VBD','VBG','VBN','VBP','RBR','JJ','RB','RBS','PDT','JJ','JJR','JJS','TO','VB']
    for word, tag in tags:
       if tag in pos:
       cleaned = cleaned + wordnet_lemmatizer.lemmatize(word) + ' '
       
    x.append(cleaned)

После обработки наши текстовые данные с рисунка 1 будут выглядеть, как на изображении ниже, без стоп-слов и колебаний.

Модельное обучение

Теперь перейдем к тренировочной части. Для обучения я преобразовал данные в TF-IDF и обучился с классификатором XGBoost.

tfidf_vectorize = TfidfVectorizer()
vectors = tfidf_vectorize.fit_transform(x)
features = tfidf_vectorize.get_feature_names()
dense = vectors.todense().tolist()
x = pd.DataFrame(denselist, columns=features)
from sklearn.model_selection import train_test_split
# splitting data into 80% train and 20% test
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.20, random_state = 0) 
from xgboost import XGBClassifier    
classifier = XGBClassifier()
classifier.fit(x_train, y_train) 
y_pred = classifier.predict(x_test)
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
accuracy = metrics.accuracy_score(y_test, y_pred)

Теперь давайте попробуем построить график производительности модели с помощью перекрестных проверок.

plot_learning_curve(classifier, "XGBoost", x, y, ylim=(0.7, 1.01),cv=5)
def plot_learning_curve(estimator, title, X, y, axes=None, 
        ylim=None, cv=None,n_jobs=None,   
        train_sizes=numpy.linspace(.1, 1.0, 5)):
    if axes is None:
        _, axes = plt.subplots(1, 3, figsize=(20, 5))
    axes[0].set_title(title)
    if ylim is not None:
        axes[0].set_ylim(*ylim)
    axes[0].set_xlabel("Training examples")
    axes[0].set_ylabel("Score")
    train_sizes, train_scores, test_scores= \
        learning_curve(estimator,X,y,cv=cv,n_jobs=n_jobs,
        train_sizes=train_sizes)
    train_scores_mean = numpy.mean(train_scores, axis=1)
    train_scores_std = numpy.std(train_scores, axis=1)
    test_scores_mean = numpy.mean(test_scores, axis=1)
    test_scores_std = numpy.std(test_scores, axis=1)

# Plot learning curve
    axes[0].grid()
    axes[0].fill_between(train_sizes, train_scores_mean -
      train_scores_std,train_scores_mean + train_scores_std,  
      alpha=0.1,color="r")
    axes[0].fill_between(train_sizes, test_scores_mean - 
      test_scores_std,test_scores_mean + test_scores_std, 
      alpha=0.1,color="g")
    axes[0].plot(train_sizes, train_scores_mean, 'o-', color="r",
                 label="Training score")
    axes[0].plot(train_sizes, test_scores_mean, 'o-', color="g",
                 label="Cross-validation score")
    axes[0].legend(loc="best")

Визуализация

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

Резюме

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