#python #machine-learning #scikit-learn #data-mining
#python #машинное обучение #scikit-learn #интеллектуальный анализ данных
Вопрос:
Я хочу разделить данные, которые у меня есть из словаря и отдельного массива, на обучающие и тестовые данные. Я пробовал разные способы, но у меня ничего не получается. Мне нужно изначально сохранить функции в виде словаря из-за того, как они предварительно обрабатываются в моем конвейере. У кого-нибудь в сообществе есть какие-либо предложения по этому поводу?
Словарь (значения функций):
{'input1': array([42., 50., 68., ..., 60., 46., 60.]),
'input2': array([[-2.00370455, -2.35689664, -1.96147382, ..., 2.11014128,
2.59383321, 1.24209607],
[-1.97130549, -2.19063663, -2.02996445, ..., 2.32125568,
2.27316046, 1.48600614],
[-2.01526666, -2.40440917, -1.94321752, ..., 2.15266657,
2.68460488, 1.23534095],
...,
[-2.1359458 , -2.52428007, -1.75701785, ..., 2.25480819,
2.68114281, 1.75468981],
[-1.95868206, -2.23297167, -1.96401751, ..., 2.07427239,
2.60306072, 1.28556955],
[-1.80507278, -2.62199521, -2.08697271, ..., 2.34080577,
2.48254585, 1.52028871]])}
Целевые значения
y = array([0.83, 0.4 , 0.53, ..., 0. , 0.94, 1. ])
Shape: (3000,)
Создание словаря
#Dictionary Values
input1 = embeddings.numpy()
input2 = df['feature'].values
y = df['target'].values
full_model_inputs = [input1 , embeddings]
original_model_inputs = dict(input1 = input1 , input2 = input2 )
Разделение данных
x_train, x_test, y_train, y_test = train_test_split([original_model_inputs['input1'],
original_model_inputs['input2']], y, test_size = 0.2, random_state = 6)
или
x_train, x_test, y_train, y_test = train_test_split(original_model_inputs, y, test_size = 0.2, random_state = 6)
Сообщение об ошибке
ValueError: Found input variables with inconsistent numbers of samples: [2, 3000]
Ввод1:
[55., 46., 46., ..., 60., 60., 45.]
Shape: (3000,)
Ввод2:
[[-2.00370455, -2.35689664, -1.96147382, ..., 2.11014128,
2.59383321, 1.24209607],
[-1.97130549, -2.19063663, -2.02996445, ..., 2.32125568,
2.27316046, 1.48600614],
[-2.01526666, -2.40440917, -1.94321752, ..., 2.15266657,
2.68460488, 1.23534095],
...,
[-2.1359458 , -2.52428007, -1.75701785, ..., 2.25480819,
2.68114281, 1.75468981],
[-1.95868206, -2.23297167, -1.96401751, ..., 2.07427239,
2.60306072, 1.28556955],
[-1.80507278, -2.62199521, -2.08697271, ..., 2.34080577,
2.48254585, 1.52028871]]
Shape: (3000, 3840)
Построение модели
input1= Input(shape = (1, ))
input2= Input(shape = (3840, ))
# The first branch operates on the first input
x = Dense(units = 128, activation="relu")(input1)
x = BatchNormalization()(x)
x = Dense(units = 128, activation="relu")(x)
x = BatchNormalization()(x)
x = Model(inputs=input1, outputs=x)
# The second branch operates on the second input (Embeddings)
y = Dense(units = 128, activation="relu")(input2)
y = BatchNormalization()(y)
y = Dense(units = 128, activation="relu")(y)
y = BatchNormalization()(y)
y = Model(inputs=input2, outputs=y)
# combine the output of the two branches
combined = Concatenate()([x.output, y.output])
out = Dense(128, activation='relu')(combined)
out = Dropout(0.5)(out)
out = Dense(1)(out)
# The model will accept the inputs of the two branches and then output a single value
model = Model(inputs = [x.input, y.input], outputs = out)
model.compile(loss='mse', optimizer = Adam(lr = 0.001), metrics = ['mse'])
model.fit([X1,X2], Y, epochs=3)
Комментарии:
1. Как выглядят эти входные данные? Все ли массивы словарей одинакового размера?
2. @yatu привет! да, все они имеют одинаковый размер. Я только что обновил вопрос, чтобы вы могли видеть фактические входные данные.
Ответ №1:
Поместите свой словарь в pandas
df, который сохранит размерность данных и разделит их по вашему желанию:
df = pd.DataFrame({"input1":original_model_inputs["input1"],
"input2":list(original_model_inputs["input2"])})
X_train, X_test, y_train, y_test = train_test_split(df,y)
Преобразование обратно в исходный формат:
X_train = X_train.to_dict("list")
X_test = X_test.to_dict("list")
Редактировать
Чтобы ваш конвейер оставался функциональным, вам может потребоваться добавить эти 2 строки:
X_train = {k:np.array(v) for k,v in X_train.items()}
X_test = {k:np.array(v) for k,v in X_test.items()}
Комментарии:
1. извините за задержку в ответе, просто пытался кое-что проверить. Можно ли преобразовать эти значения в массив numpy. «массив» или что-то в этом роде? вместо np.array(x_train[‘input1’]) для доступа только к одному входу из словаря.
2. Все значения доступны. Это точно такие же структуры данных, которые у вас есть в качестве входных данных. Можете ли вы пояснить, чего вы не можете достичь с помощью текущего решения? Примером может быть?
3. Я только что обновил свой пост о том, как я создаю модель, используя эти два отдельных ввода. Ошибка атрибута: объект ‘list’ не имеет атрибута ‘shape’. Когда я конвертирую в массив numpy, модель работает правильно. Извините за отсутствие разъяснений
4. model = build_model(np.array(x_train[‘input1’]), np.array(x_train[‘input2’])) например, когда я запускаю модель с указанным кодом в тексте.
5. большое вам спасибо. Это работает отлично. Я не думал об этом типе цикла foor. Довольно аккуратно!! Я ценю это 🙂
Ответ №2:
Вы передаете вложенный список, как X
при вызове train_test_split
, что вызывает ошибку. Вместо этого вы могли бы создать 2D-массив функций из словаря, а затем разделить на обучение и тестирование. Возьмем, к примеру:
d = {'input1': np.random.random((10,)),
'input2': np.random.random((10,3))}
y = np.random.choice([0,1],10)
Мы можем просто добавить ось, если один из массивов в словаре имеет одно измерение, а затем объединить результат в 2D-массив:
X = [a[:,None] if len(a.shape)==1 else a for a in d.values()]
X_train, X_test, y_train, y_test = train_test_split(np.concatenate(X, axis=1), y)
Комментарии:
1. Обновлено, теперь все должно быть хорошо, спасибо, что дали мне знать @sergey
2. спасибо за ответ, я работаю с множественным вводом ANN, поэтому мне нужно разделить значения. Но для меня это хорошее направление для работы! поэтому я оцениваю это
3. Я только что обновил свой пост о том, как я создаю модель, используя эти два отдельных ввода. Извините за недостаток информации и да, я только что проголосовал: D