Цель состоит в том, чтобы предсказать рейтинг вина на основе его описания?
Датасет: 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']
Мешок слов: представляет тексты в векторном пространстве, связанные с весами (количество вхождений и т. д.), алгоритм:
- Count Vectorizer: взвешивание по подсчету слов
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))