Матрица данных в ML: объекты на признаки

В машинном обучении почти все данные — это одна большая матрица: строки-объекты, столбцы-признаки.

Матрица данных X — таблица, где каждая строка — один объект (пример), а каждый столбец — один признак. Размер N×D: N объектов, D признаков.

Форма данных, к которой всё сводится

Откуда бы ни пришли данные — из базы, CSV, картинок, — для модели они выглядят одинаково: прямоугольная таблица чисел. Строка — это вектор признаков одного объекта (из раздела про векторы). Вся таблица — матрица. Привыкните читать её «форму» (shape): сколько объектов на сколько признаков.

# Матрица данных: 4 цветка, по 3 признака
# признаки: длина_лепестка, ширина_лепестка, длина_чашелистика
X = [
    [1.4, 0.2, 5.1],
    [4.7, 1.4, 7.0],
    [1.3, 0.2, 4.9],
    [4.5, 1.5, 6.4],
]

N = len(X)        # объектов (строк)
D = len(X[0])     # признаков (столбцов)
print("Форма данных N x D:", N, "x", D)
print("Объект №1 (вектор признаков):", X[0])
print("Признак 0 у всех объектов:", [row[0] for row in X])

Вывод:

Форма данных N x D: 4 x 3
Объект №1 (вектор признаков): [1.4, 0.2, 5.1]
Признак 0 у всех объектов: [1.4, 4.7, 1.3, 4.5]

Строки — объекты, столбцы — признаки

Это важно не путать. Чтобы взять один объект, берём строку X[i]. Чтобы взять один признак целиком (его значения у всех объектов), берём столбец [row[j] for row in X]. Многие операции в ML — это операции над столбцами: посчитать среднее признака, его разброс, нормировать.

from statistics import mean

X = [
    [1.4, 0.2, 5.1],
    [4.7, 1.4, 7.0],
    [1.3, 0.2, 4.9],
    [4.5, 1.5, 6.4],
]

def column(X, j):
    return [row[j] for row in X]

for j in range(len(X[0])):
    col = column(X, j)
    print(f"Признак {j}: среднее = {round(mean(col), 3)}, диапазон = [{min(col)}, {max(col)}]")

Вывод:

Признак 0: среднее = 2.975, диапазон = [1.3, 4.7]
Признак 1: среднее = 0.825, диапазон = [0.2, 1.5]
Признак 2: среднее = 5.85, диапазон = [4.9, 7.0]

Центрирование: вычитаем среднее столбца

Частая подготовка данных — центрирование: из каждого признака вычитают его среднее, чтобы столбец имел нулевое среднее. Это первый шаг в PCA и стабилизирует обучение. Делается по столбцам.

from statistics import mean

X = [
    [1.4, 0.2],
    [4.7, 1.4],
    [1.3, 0.2],
    [4.5, 1.5],
]

means = [mean(row[j] for row in X) for j in range(len(X[0]))]
Xc = [[round(row[j] - means[j], 3) for j in range(len(row))] for row in X]

print("Средние по столбцам:", [round(m, 3) for m in means])
print("Центрированные данные:")
for row in Xc:
    print(row)
# Проверка: новые средние ~ 0
print("Новые средние:", [round(mean(r[j] for r in Xc), 3) for j in range(2)])

Вывод:

Средние по столбцам: [2.975, 0.825]
Центрированные данные:
[-1.575, -0.625]
[1.725, 0.575]
[-1.675, -0.625]
[1.525, 0.675]
Новые средние: [0.0, 0.0]

Итог

  • Данные в ML — матрица X размера N×D: строки-объекты, столбцы-признаки.
  • Строка X[i] — вектор признаков объекта; столбец — значения одного признака.
  • Многие преобразования (среднее, разброс, центрирование, нормировка) работают по столбцам.
  • Центрирование — вычесть среднее столбца — основа PCA и стабильного обучения.
Проверьте себя
1. Что обычно означает строка в матрице данных X?
AОдин признак у всех объектов
BОдин объект (его вектор признаков)
CСреднее по столбцу
DМетку класса
2. Как получить значения одного признака у всех объектов?
AВзять строку X[j]
BВзять столбец: [row[j] for row in X]
CСложить все строки
DТранспонировать каждый объект
3. Что делает центрирование признака?
AДелит его на максимум
BВычитает среднее столбца, делая его среднее равным нулю
CСортирует значения по возрастанию
DЗаменяет пропуски нулями
Поддержать проект