Запутанные вероятности из scikit-learn randomforest - PullRequest
0 голосов
/ 21 октября 2018

У меня есть временной ряд целочисленных значений, которые я пытаюсь предсказать.Я делаю это с помощью скользящего окна, где он учится связывать 99 значений, чтобы предсказать следующее.Значения находятся в диапазоне от 0 до 128. Представление для X представляет собой куб из n скользящих окон длиной 99, и каждое целое число закодировано в один вектор с горячим кодированием длиной 128 элементов.Форма этого массива (n, 99, 128).Форма Y (n, 128).Я рассматриваю это как проблему с несколькими классами, поскольку Y может принять только один результат.

Это прекрасно работает с Keras / Tensorflow, но когда я пытаюсь использовать RandomForest из scikit-learn, он жалуется на то, что входной вектор является 3Dвместо 2D.Поэтому я изменил входной куб X в 2D матрицу формы (n, 99 * 128).Результаты были не очень хорошими, и чтобы понять, что происходит, я запросил вероятности (см. Код ниже).

def rf(X_train, Y_train, X_val, Y_val, samples):
    clf = RandomForestClassifier(n_estimators=32, n_jobs=-1)
    clf.fit(X_train, Y_train)
    score = clf.score(X_val, Y_val)
    print('Score of randomforest =', score)

    # compute some samples
    for i in range(samples):
        index = random.randrange(0, len(X_val) - 1)
        xx = X_val[index].reshape(1, -1)
        probs = clf.predict_proba(xx)
        pred = clf.predict(xx)
        y_true = np.argmax(Y_val[index])
        y_hat = np.argmax(pred)
        print(index, '-', y_true, y_hat, xx.shape, len(probs))
        print(probs)
        print(pred)

Вывод, полученный из predict_proba:

[array([[0.841, 0.159]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), 
 array([[1.]]), array([[1., 0.]]), array([[1., 0.]]), array([[1., 0.]]),
 array([[1., 0.]]), array([[1., 0.]]), array([[0.995, 0.005]]), array([[0.999,
 0.001]]), array([[0.994, 0.006]]), array([[1., 0.]]), array([[0.994, 0.006]]),
 array([[0.977, 0.023]]), array([[0.999, 0.001]]), array([[0.939, 0.061]]),
 array([[0.997, 0.003]]), array([[0.969, 0.031]]), array([[0.997, 0.003]]),
 array([[0.984, 0.016]]), array([[0.949, 0.051]]), array([[1., 0.]]),
 array([[0.95, 0.05]]), array([[1., 0.]]), array([[0.918, 0.082]]), 
 array([[0.887, 0.113]]), array([[1.]]), array([[0.88, 0.12]]), array([[1.]]),
 array([[0.884, 0.116]]), array([[0.941, 0.059]]), array([[1.]]), array([[0.941,
 0.059]]), array([[1.]]), array([[0.965, 0.035]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]]),
 array([[1.]]), array([[1.]]), array([[1.]]), array([[1.]])]

Выходной вектор имеет длину 128, но почему он состоит из списка, содержащего двумерные массивы, иногда содержащий один элемент, а иногда два?Насколько я понимаю из руководства , массив должен быть возвращен с измерениями # samples * # classes, поэтому в моем примере формы (1128).

Может ли кто-нибудь помочь мне указатьчто я делаю не так?

Редактировать 1

Я проводил эксперименты в соответствии с рекомендациями @Vivek Kumar (спасибо Vivek) в его комментариях.Я ввожу последовательности целых чисел (X) и сопоставляю их со следующим целым числом в последовательности (y).Это код:

def rff(X_train, Y_train, X_val, Y_val, samples, cont=False):
    print('Input data:', X_train.shape, Y_train.shape, X_val.shape, Y_val.shape)
    clf = RandomForestClassifier(n_estimators=64, n_jobs=-1)
    clf.fit(X_train, Y_train)
    score = clf.score(X_val, Y_val)

    y_true = Y_val
    y_prob = clf.predict_proba(X_val)
    y_hat = clf.predict(X_val)
    print('y_true', y_true.shape, y_true)
    print('y_prob', y_prob.shape, y_prob)
    print('y_hat', y_hat.shape, y_hat)
    #sum_prob = np.sum(y_true == y_prob)
    sum_hat = np.sum(y_true == y_hat)
    print('Score of randomforest =', score)
    print('Score y_hat', sum_hat / len(X_val))
    #print('Score y_prob', sum_prob / len(X_val))

    # compute some individual samples
    for i in range(samples):
        index = random.randrange(0, len(X_val) - 1)
        y_true_i = Y_val[index]
        #y_prob_i = y_prob[index]
        y_hat_i = y_hat[index]
        print('{:4d} - {:3d}{:3d}'.format(index, y_true_i, y_hat_i))

И его вывод:

Input data: (4272, 99) (4272,) (1257, 99) (1257,)
y_true (1257,) [ 0  0  0 ... 69 70 70]
y_prob (1257, 29) [[0.09375  0.       0.       ... 0.078125 0.078125 0.015625]
 [0.109375 0.       0.       ... 0.046875 0.0625   0.0625  ]
 [0.125    0.       0.       ... 0.015625 0.078125 0.015625]
 ...
 [0.078125 0.       0.       ... 0.       0.       0.      ]
 [0.046875 0.       0.       ... 0.       0.       0.      ]
 [0.078125 0.       0.       ... 0.       0.       0.      ]]
y_hat (1257,) [81 81 79 ... 67 67 65]
Score of randomforest = 0.20047732696897375
Score y_hat 0.20047732696897375
 228 -  76 77
  51 -  76  0
 563 -  81  0
 501 -   0 77
 457 -  79 79
 285 -  76 77
 209 -  81  0
1116 -  79  0
 178 -  72 77
1209 -  67 65

Массив вероятностей имеет постоянный размер, но его форма совершенно странная (128, 29).Откуда этот 29 приходит ...?Тем не менее, есть некоторые улучшения, о которых следует сообщить: точность значительно улучшиласьРаньше было около 0,0015, сейчас - около 0,20.

Есть какие-нибудь идеи о том, что представляет массив вероятностей?

Редактировать 2

Моя ошибка заключалась в том, что, вернувшись назад к 128 значениям, кодированным одним горячим способомк целым числам я не учел, что у меня было только 29 уникальных значений.predict_proba аккуратно предсказывает эти 29 значений, потому что это те, которые он выучил.

Единственный оставшийся вопрос - какие значения предсказывают вероятности?Предположим, что классы для предсказания равны 0, 101-128, predict_proba возвращает значения для индексов 0..28.Каково отображение вероятностей в классы: 0 -> 0, 1 -> 101, 2 -> 102, ..., 29-128?Я не мог найти никаких подсказок по этому поводу в руководстве.

1 Ответ

0 голосов
/ 23 октября 2018

Сначала поговорим о ваших целях y.

  • 2-й y рассматривается как матрица меток-индикаторов, которая используется для мульти-меток или мульти-меток.вывод мультиклассовой задачи в scikit-learn.Судя по вашим данным, это не соответствует действительности, поэтому я не думаю, что вам захочется быстро кодировать y.

  • Второе о целях в вашей проблемеявляется то, что вам сначала нужно решить, хотите ли вы классификацию или регрессионную задачу.Вы говорите, что у вас есть "time series of integer values".Таким образом, вопрос состоит в том, можно ли численно сравнить эти целые числа друг с другом ?

Пример 1 : Учтите, что у вас возникла проблема, когда выЯ хочу разделить некоторые данные на три страны: «Япония», «Россия», «США».

  • Теперь эти строки можно закодировать как 1 («Япония»), 2 («Россия») и 3 («США»), чтобы их можно было использовать в моделях машинного обучения.,Но мы не можем сравнивать эти кодировки как числа, так как в 2 больше 1 или меньше 3. Здесь 1,2,3 - просто числовое представление категориальных данных, которые на самом деле не имеют никакого числового смысла.В этом случае классификационная задача подходит для помещения данных в эти три класса.

  • Но в любом другом сценарии, например, прогнозировании цен на акции или прогнозировании темпов и т. Д., Числа могут иследует сравнивать друг с другом и, следовательно, следует использовать регрессию (для прогнозирования реальных целевых показателей).

Пример 2 : для лучшего понимания вы также можете подуматьправильности (функция потерь) вашей модели.Предположим для модели, которая прогнозирует цели от 1 до 10, и что правильная цель для конкретной выборки равна 9.

  • В задаче классификации важен только правильный прогноз.Не имеет значения, если модель прогнозирует цель как 8 или 1.

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

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

Примечание : В настоящее время я иду дальше с классификацией в качестве исходного вопроса.

Теперь перейдем к функциям X

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

  • Рассмотрим еще один пример трех категорий: "высокая", "средняя", "низкая".Они имеют внутреннее упорядочение. Здесь, если вы закодируете как 0 (низкий), 1 (средний) и 2 (высокий), тогда их можно сравнить численно.Таким образом, вы можете решить оставить их как 0,1,2 или одноразово закодировать их.

  • Как я уже сказал в своем комментарии, случайные леса довольно устойчивы к таким вещам и не должны сильно влиять на производительность, если категории кодируются стратегически.Например, производительность может снизиться, если вы закодируете 0 (высокий), 1 (низкий), 2 (средний) и т. Д.

Теперь снова перейдем к вашему делу и моему вопросу из пункта 1: Можно ли численно сравнить эти целые числа друг с другом ?Если да, нет необходимости горячо кодировать функции.Если нет, сделай это.

...