Цель состоит в том, чтобы предсказать рейтинг вина на основе его описания?

Датасет: 130 тысяч отзывов с указанием сорта, местоположения, винодельни, цены и описания.

import pandas as pd
import numpy as np
import nltk
import re
from bs4 import BeautifulSoup
from contractions import CONTRACTION_MAP
import unicodedata
from nltk.corpus import stopwords
stopword_list = set(stopwords.words("english"))
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import confusion_matrix, classification_report
print("Number of rows before removing duplicates : ", len(dataset))
dataset = dataset[dataset.duplicated('description, keep=False)
print("Number of rows after removing duplicates : ",len(dataset))
dataset.dropna(subset=['description','points'])
print("Number of rows after removing NaN : ",len(dataset))

Количество строк до удаления дубликатов: 150930
Количество строк после удаления дубликатов: 92393
Количество строк после удаления NaN: 92393

Давайте посмотрим количество вин на баллы (рейтинги):

fig, ax = plt.subplots(figsize=(30,10))
plt.xticks(fontsize=20) # X Ticks
plt.yticks(fontsize=20) # Y Ticks
ax.set_title('Number of wines per points', fontweight="bold", size=25) # Title
ax.set_ylabel('Number of wines', fontsize = 25) # Y label
ax.set_xlabel('Points', fontsize = 25) # X label
dataset.groupby(['points']).count()['description'].plot(ax=ax, kind='bar')

Чтобы упростить модель с несколькими классификациями, давайте разделим задачу с 20 метками на задачу классификации с 4 метками:

1 -> Баллы от 80 до 85 (Средние вина)
2 -> Баллы от 85 до 90 (Средние вина)
3 -> Баллы от 90 до 95 (Хорошие вина)
4 -> Баллы от 95 до 100 (отличные вина)

#Transform method taking points as param
def transform_points_simplified(points):
    if points < 85:
        return 1
    elif points >= 85 and points < 90:
        return 2 
    elif points >= 90 and points < 95:
        return 3 
    elif points >= 95 and points < 100:
        return 4 
    else:
        return 5
dataset = dataset.assign(points_simplified = dp['points']
                        .apply(transform_points_simplified))

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

# Apply to the column
dataset['description'] = dp['description'].map(removeStopwords)

Для более глубокой очистки и лучшего результата выполните: Очистка и предварительная обработка текстовых данных.

Создание функций

X = dataset['description']
y = dataset['points_simplified']

Мешок слов: представляет тексты в векторном пространстве, связанные с весами (количество вхождений и т. д.), алгоритм:

vectorizer = CountVectorizer()
vectorizer.fit(X)
X = vectorizer.transform(X)
  • TF-IDF Vectorizer: вес увеличивается пропорционально количеству, но компенсируется частотой слова в общем корпусе.
vectorizer = TfidfVectorizer()
vectorizer.fit(X)
X = vectorizer.transform(X)

Разделение текста

  • Обучение модели
    90 % набора данных будет использоваться для обучения (около 80 000 вин).
  • Тестирование модели
    10 % набора данных будет использоваться для тестирования (около 9 000 вин).
X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                   test_size=0.1, 
                                                   random_state=101)

Классификация машинного обучения:

— Рандомлесклассификатор

rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
# Testing the model
predictions = rfc.predict(X_test)
print(classification_report(y_test, predictions))

Ссылка: https://www.kaggle.com/olivierg13/wine-ratings-analysis-w-supervised-ml