#python #scikit-learn
#python #scikit-учиться
Вопрос:
Я пытаюсь разделить фрейм данных (~ 188 тыс. строк) на обучающий и тестовый образцы. Столбец (‘FLAG’) является моей целевой переменной, содержащей значение либо 0, либо 1.
Поскольку существует только около 1300 «ФЛАГОВ» со значением 1, я хочу выполнить стратифицированное разделение, чтобы убедиться, что в обоих образцах имеется репрезентативное число значений 1.
Я попытался разделить, используя функцию train_test_split от sklearn:
train, test = train_test_split(df, test_size=0.2, stratify=df["FLAG"])
Моя проблема в том, что результирующий поезд и тестовый образец имеют 177942, соответственно 52 строки. Я бы ожидал чего-то вроде 150400 и 37600 строк.
Мое понимание из чтения документации (sklearn.model_selection.train_test_split) заключается в том, что я должен предоставить свой фрейм данных, test_size и столбец, содержащий целевые классы (т.Е. «ФЛАГ» в моем случае).
Даже общий пример:
df = pd.DataFrame(data={'a': np.random.rand(100000), 'b': np.random.rand(100000), 'c': 0})
df.loc[np.random.randint(0, 100000, 1000), 'c'] = 1
tr, ts = train_test_split(df, test_size=.2, stratify=df['c'])
print(tr.shape, ts.shape)
ВОЗВРАТ: (93105, 3) (38, 3)
Мой список импорта:
import cx_Oracle
import pandas as pd
from sklearn.model_selection import train_test_split
import numpy as np
Моя версия python: 3.7.0
Версия Sklearn: 0.20.3
Версия Pandas: 0.23.4
Комментарии:
1. Очень интересно. Я провел несколько тестов со случайно построенным образцом df, и, похоже, он работает нормально. Вы должны опубликовать некоторые образцы данных, чтобы мы могли воспроизвести вашу проблему. Мой пример df:
df = pd.DataFrame(data={'a': np.random.rand(100000), 'b': np.random.rand(100000), 'c': 0})
. Установите около 1000 значений равными 1:df.loc[np.random.randint(0, 100000, 1000), 'c'] = 1
, разделите данные:tr, ts = train_test_split(df, test_size=.2, stratify=df['c'])
. проверка фигур:tr.shape
Out:(80000, 3)
, и число 1s:tr.c.sum()
Out:796
и для ts: 199. Итак, похоже, проблема с вашими данными2. @Scotty Я попробовал тот же тест. Как ни странно, мой train_test_split делает ту же странную вещь с вашим примером. Т.е. я получаю (93105, 3) и (38, 3) . Теперь я еще больше запутался.
3. @tk78: какие версии python и пакетов вы используете? Можете ли вы поместить весь импорт перед общим кодом и выполнить его повторно (например: возможно, ваш train_test_split переопределен каким-то другим пакетом, и это не тот, который вы думаете)
4. @vladmihaisima я добавил информацию, которую вы просили. Кстати: я просто тестирую эту самую вещь, используя виртуальную среду.
5. @tk78 Какова ваша версия sklean и pandas? Похоже на ошибку…
Ответ №1:
Мои исследования показали, что проблема вызвана переполнением целых чисел. Проблема возникает только на Python 3.7.x 32bit. 64-битная версия работает нормально.
В конце концов я переключился на 64-битный Python, чтобы решить проблему (ранее мне приходилось использовать 32-битную версию из-за несвязанной зависимости от пакета Oracle).