ValueError: Ожидался 2D массив, вместо этого получен 1D массив.

Вопрос или проблема

Я хотел бы извлечь 20 самых информативных признаков из очень большого набора признаков $X$, который поступает из набора данных, содержащего клинические данные, с помощью функции RFE из библиотеки scikit-learn в Python.

$X$ представляет собой матрицу 68 x 1140, где

  • Каждая строка представляет собой записанную сессию.
  • Для каждого субъекта есть 4 записанные сессии.
  • Таким образом, в наборе данных 17 субъектов.

Моя идея заключается в том, чтобы использовать 70% набора данных (т.е. 70% x 1140 случайных признаков из каждой записи) и извлечь 50 признаков из всего набора данных.

$Y$ представляет рейтинг от 0 до 2.

Другими словами, мои данные выглядят так:

вставьте описание изображения здесь

А моя реализация в коде выглядит следующим образом:

## X = признаки
## Y = метки
p = 0.7
n_perc = round(X.shape[1]*X.shape[0]*p) #70% данных -> количество элементов (высота x ширина x 70%)
rand_idx = np.random.randint(X.shape[1]*X.shape[0], size=n_perc) #случайные индексы (70% данных)
X_rnd = X.flatten()[rand_idx] #выбор этих 70% в X
Y_rnd = np.repeat(Y,round(X.shape[1]*p)) #мы сопоставляем размеры для X_rnd - Y_rnd
selector = RFE(estimator=LogisticRegression(C=1),n_features_to_select=20) #запуск RFE
selector.fit(X_rnd.reshape,Y_rnd) #выбор лучших признаков

Идея заключается в том, что я выравниваю все значения из X и получаю только 70% случайных элементов из $X$, т.е. $X_{rnd}$ (и также адаптирую $Y$ соответственно, т.е. $Y_{rnd}$).

ValueError: Ожидался 2D массив, вместо этого получен 1D массив:
array=[-0.25367578  0.8069118  -0.63161352 ...  0.5500815  -0.37418711 
0.2580666 ]. Измените форму ваших данных, используя array.reshape(-1, 1), если ваши данные содержат одну особенность, или array.reshape(1, -1), если в них содержится один пример.

Но по какой-то причине я получаю эту ошибку, которую не понимаю. Говорится, что я должен изменить форму массива, если у меня есть либо одна особенность, либо один образец, но это не мой случай.

Кто-нибудь знает, что мне делать? Это тот подход, который я должен использовать для решения проблемы? Должен ли я изменить форму $X$ другим способом?

Спасибо.

selector.fit(X_rnd.reshape,Y_rnd) #выбор лучших признаков

X_rnd должен быть 2D матрицей.

Я думаю, что эта ошибка возникла, когда метод “fit” был выполнен с X_rnd, но ваш код показывает X_rnd.reshape. В этом случае ошибка должна быть –

    ValueError: Ожидался 2D массив, вместо этого получен скалярный массив:
    array=<встроенный метод reshape объекта numpy.ndarray на 0x000000000C28EAD0>.
    Измените форму ваших данных, используя array.reshape(-1, 1), если ваши данные содержат одну особенность, или array.reshape(1, -1), если в них содержится один пример.

Ответ или решение

Ошибка, с которой вы столкнулись — ValueError: Expected 2D array, got 1D array instead, возникает, потому что метод fit требует, чтобы входные данные имели двумерный формат. Давайте рассмотрим вашу реализацию и исправим её шаг за шагом.

Разбор проблемы:

Вы пытаетесь извлечь 70% случайных признаков из одномерного массива X_rnd, который вы получаете, используя X.flatten() и случайные индексы. Тем не менее, для метода fit требуется двумерный массив, где строки представляют собой образцы, а столбцы — признаки.

Также вы вызываете X_rnd.reshape без скобок, что не приводит к вызову метода и оставляет X_rnd в одномерной форме.

Исправление кода:

Вот как можно исправить ваш код:

  1. Случайный отбор: Вместо того чтобы использовать flatten, удерживайте данные в их исходной двумерной форме.
  2. Форматирование X_rnd и Y_rnd: Убедитесь, что X_rnd остается двумерным.
  3. Корректный вызов метода reshape: Определите правильный размер для X_rnd, чтобы он стал двумерным.

Вот исправленный код:

import numpy as np
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

# Предположим, что X и Y уже загружены

p = 0.7
n_samples = X.shape[0]  # количество сессий
n_features = X.shape[1]  # количество признаков
n_selected_features = 50  # число выбираемых признаков

# Генерируем случайные индексы для 70% сессий
rand_idx = np.random.choice(n_samples, size=int(n_samples * p), replace=False)

# Получаем подмассив X_rnd, который содержит только 70% сессий
X_rnd = X[rand_idx]  # X_rnd будет 2D массивом размером (число выбранных сессий, число признаков)

# Теперь нам нужно адаптировать Y_rnd, таким образом, чтобы он соответствовал выбранным сессиям
Y_rnd = Y[rand_idx]  # Предполагая, что Y имеет ту же базу индексов, что и X

# Теперь применяем RFE - нам нужно обращать внимание на то, что X_rnd имеет две размерности
selector = RFE(estimator=LogisticRegression(C=1), n_features_to_select=20)
selector.fit(X_rnd, Y_rnd)  # Заходим в RFE с уже правильно оформленными массивами

# Получение выбранных признаков
selected_features = selector.support_

Объяснение изменений:

  1. Выбор сессий: Вместо выбора случайных значений из X, мы выбираем случайные индексы записей (сессий) и формируем новый массив X_rnd, который остается 2D, сохраняя структуру данных.
  2. Корректное формирование Y_rnd: При генерации Y_rnd мы также выбираем только те метки, которые соответствуют отобранным сессиям.
  3. Использование fit: Теперь, когда X_rnd и Y_rnd имеют соответствующие размеры и формат, метод fit будет работать без ошибок.

Рекомендации:

  • Убедитесь, что ваши данные Y подходят для данной процедуры, так как если Y имеет значения, которые не могут быть обработаны моделью (например, не целые числа или NaN), это также может привести к ошибкам.
  • Проверьте, чтобы ваши функции и предобрабатывающие шаги были правильно выполнены, чтобы гарантировать качество ваших данных.

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

Оцените материал
Добавить комментарий

Капча загружается...