Матрица данных в 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Взять столбец: [row[j] for row in X]
BВзять строку X[j]
CСложить все строки
DТранспонировать каждый объект
3. Что делает центрирование признака?
AДелит его на максимум
BВычитает среднее столбца, делая его среднее равным нулю
CСортирует значения по возрастанию
DЗаменяет пропуски нулями