Спасибо за разъяснение того, что, по вашему мнению, код должен делать в комментариях.
Мой ответ эффективно ответит, почему то, что вы думаете, происходит не то, что происходит.
Сначала давайтепоговорим о функциях mean
и std
.Когда их вводом является вектор (независимо от того, выровнены ли они по вертикали или горизонтали), тогда это вернет одно число, которое является средним или стандартным отклонением этого вектора соответственно, как и следовало ожидать.
Однако, когда вход представляет собой матрицу , вам нужно знать, что он делает по-другому.Если вы не укажете направление (измерение), в котором вы должны вычислять среднее значение / стандартное отклонение, тогда оно будет вычислять среднее значение по строкам, то есть возвращает одно число для каждого столбца.Следовательно, конечным результатом этой операции будет горизонтальный вектор.
Следовательно, и mu
и sigma
будут горизонтальными векторами в вашем коде.
Теперь давайте перейдем к оператору «умножения матриц» (т.е. *
).
При использовании оператора умножения матриц, если вы умножаете горизонтальный вектор на вертикальный вектор (то есть обычную матрицу).операция умножения), ваш вывод представляет собой одно число (то есть скаляр).Однако, если вы измените ориентацию, например, вы умножите вертикальный вектор на горизонтальный, вместо этого вы будете фактически вычислять «произведение Кронекера».Поскольку выходные данные операции *
полностью определяются строками первого ввода и столбцами второго ввода, независимо от того, получаете ли вы матричное умножение или произведение Кронекера, неявно и полностью зависит от ориентации вашеговходы.
Следовательно, в вашем случае строка mu_matrix = ones(m, 1) * mu;
фактически не добавляет вектор единиц, как вы говорите.Фактически он выполняет произведение Кронекера между вертикальным вектором единиц и горизонтальным вектором, которым является ваш mu
, эффективно создавая матрицу m-by-n
с повторением mu по вертикали для m строк.
Следовательно, вконец этой операции, как можно предположить по имени переменной, mu_matrix
на самом деле является матрицей (такой же, как у sigma_matrix
), имеющей тот же размер, что и X
.
Ваш последний шаг - X- mu_sigma
, который дает вам в каждом элементе разницу между x и mu в этом элементе.Затем вы «делитесь» с помощью сигма-матрицы.
Вот почему я спросил, уверены ли вы, что следует использовать ./
вместо /
.
/
- это матричное деление оператор.С /
Вы эффективно выполняете умножение матриц на обратную матрицу, поскольку D / S математически эквивалентно D * inv (S).Мне кажется, вы должны использовать ./
вместо этого, чтобы просто разделить каждый элемент на стандартное отклонение этого столбца (именно поэтому вам пришлось повторить горизонтальный вектор для m строк в sigma_matrix
, чтобы вы могли использовать егодля «поэлементного деления»), поскольку вы пытаетесь нормализовать каждую строку (т. е. наблюдение) определенного столбца с помощью стандартного отклонения, характерного для этого столбца (т. е. объекта).