Машинное обучение с несбалансированным набором данных - PullRequest
0 голосов
/ 06 июля 2018

У меня есть следующий несбалансированный набор данных , содержащий оценки вина от 1-10. Баланс класса следующий:

Рейтинг / # Образцы (%)

  • 1 - 0 (0,0%)
  • 2 - 0 (0,0%)
  • 3 - 10 (0,74%)
  • 4 - 53 (3,90%)
  • 5 - 577 (42,5%)
  • 6 - 535 (39,40%)
  • 7 - 167 (12,29%)
  • 8 - 17 (1,25%)
  • 9 - 0 (0,0%)
  • 10 - 0 (0,0%)

Поскольку я не могу получить больше данных, каков наилучший возможный способ прогнозирования скорости с использованием Scikit-Learning с этими несбалансированными данными? Можно ли использовать SMOTE в этом случае?

Спасибо всем!

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Прогнозирование значений данных

Изучение набора данных

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

import numpy as np
from matplotlib import pyplot as plt

data = np.array([(1, 0), (2, 0), (3, 0.74), (4, 3.90), (5, 42.5), (6, 39.40),
             (7, 12.29), (8, 1.25), (9, 0), (10, 0)])

x = data[:, 0]
y = data[:, 1] / 100 # We normalise the percentage points

plt.title("Wine ratings percentages")
plt.ylabel("Samples")
plt.xlabel("Ratings")
plt.plot(x, y, '.')
plt.plot(x, y)

Результаты в:

Wine ratings percentages

Интерпретация результатов

Распределение данных, как и следовало ожидать из набора данных рейтингов 1-10, составляет Binomial , дискретный гауссов. Это называется Распределение выборки .

Прогнозирование значений

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

Биномиальное распределение содержит два параметра: количество элементов n , в этом сценарии 10, и вероятность испытания, извлечение, обычно называемое p . Поскольку среднее для бинома составляет np , мы можем легко получить p = среднее / n .

mean = np.mean(x)
p = mean/10

Два значения: n = 10 и p = среднее / 10 = 0,010008 . Мы можем использовать их в качестве параметров, чтобы получить распределение, которое эти данные будут хранить, если они полностью заполнены.

from scipy.stats import binom

my_binom = binom(10, p)
x_b = np.arange(0, 10+1)
y_b = my_binom.pmf(x_b)

plt.plot(x_b, y_b, '.')
plt.plot(x_b, y_b)

Binomial distribution

Прогнозируемые значения

При таком подходе получаются следующие значения:

predictions = [(0, 0.0003405062891601558), (1, 0.004161743534179685),
           (2, 0.02288958943798826), (3, 0.07460310631640629),
           (4, 0.15956775517675784), (5, 0.2340327075925782),
           (6, 0.2383666466220704), (7, 0.1664782928789064),
           (8, 0.07630255090283203), (9, 0.020724149627929712),
           (10, 0.0025329516211914063)]

Prediction table

Дополнительные примечания

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

0 голосов
/ 06 июля 2018

Как упоминал Вивек в своем комментарии, вы ничего не можете сделать с классами, для которых у вас нет данных. Что касается остальных классов, то у некоторых из них слишком мало образцов. Вы можете попробовать веса классов (доступны в sklearn) или недостаточную выборку, но я сомневаюсь, что они будут работать хорошо.

Хорошая идея - потратить время на получение дополнительных данных для этих классов. Если это невозможно, возможно, имеется два классификатора: один для классов с меньшим числом, а другой для других классов. Вы можете использовать третий классификатор для разделения данного экземпляра на любой из этих двух классов (в основном иерархический классификатор)

...