score normalizar entre matlab machine-learning standardized

matlab - normalizar - ¿Cómo funciona este código para estandarizar datos?



z score matlab (1)

Tengo una función standardize para un curso de aprendizaje automático que no estaba bien documentada y todavía soy nuevo en MATLAB, así que solo estoy tratando de desglosar la función. Cualquier explicación de la sintaxis o la idea general de estandarización sería de gran ayuda. Utilizamos esta función para estandarizar un conjunto de datos de capacitación proporcionados en una matriz grande. Un desglose de la mayoría de las líneas del fragmento de código me ayudaría mucho. Muchas gracias.

function [X, mean_X, std_X] = standardize(varargin) switch nargin case 1 mean_X = mean(varargin{1}); std_X = std(varargin{1}); X = varargin{1} - repmat(mean_X, [size(varargin{1}, 1) 1]); for i = 1:size(X, 2) X(:, i) = X(:, i) / std(X(:, i)); end case 3 mean_X = varargin{2}; std_X = varargin{3}; X = varargin{1} - repmat(mean_X, [size(varargin{1}, 1) 1]); for i = 1:size(X, 2) X(:, i) = X(:, i) / std_X(:, i); end end


Este código acepta una matriz de datos de tamaño M x N , donde M es la dimensionalidad de una muestra de datos de esta matriz y N es el número total de muestras. Por lo tanto, una columna de esta matriz es una muestra de datos. Las muestras de datos están todas apiladas horizontalmente y son columnas.

Ahora, el verdadero propósito de este código es tomar todas las columnas de su matriz y estandarizar / normalizar los datos para que cada muestra de datos muestre media cero y varianza unitaria . Esto significa que después de esta transformación, si encuentra el valor medio de cualquier columna en esta matriz, sería 0 y la varianza sería 1. Este es un método muy estándar para normalizar valores en análisis estadístico, aprendizaje automático y visión por computadora. .

Esto en realidad proviene de la z-score en el análisis estadístico. Específicamente, la ecuación para la normalización es:

Dado un conjunto de puntos de datos, restamos el valor en cuestión por la media de estos puntos de datos, luego dividimos por la desviación estándar respectiva. Cómo llamarías a este código es el siguiente. Dada esta matriz, que llamaremos X , hay dos formas de llamar a este código:

  • Método # 1: [X, mean_X, std_X] = standardize(X);
  • Método # 2: [X, mean_X, std_X] = standardize(X, mu, sigma);

El primer método infiere automáticamente la media de cada columna de X y la desviación estándar de cada columna de X mean_X y std_X devolverán vectores 1 x N que le dan la desviación media y estándar de cada columna en la matriz X El segundo método le permite especificar manualmente una media ( mu ) y una desviación estándar ( sigma ) para cada columna de X Posiblemente sea para su uso en la depuración, pero en este caso especificaría tanto mu como sigma como vectores 1 x N Lo que se devuelve para mean_X y std_X es idéntico a mu y sigma .

El código está un poco mal escrito en mi humilde opinión, porque ciertamente puede lograr esto vectorizado, pero la esencia del código es que encuentra la media de cada columna de la matriz X si estamos utilizando el Método # 1, duplica este vector para que se convierte en una matriz M x N , luego restamos esta matriz con X Esto restará cada columna por su respectiva media. También calculamos la desviación estándar de cada columna antes de la resta media.

Una vez que hacemos eso, normalizamos nuestra X dividiendo cada columna por su respectiva desviación estándar. Por cierto, hacer std_X(:, i) es superfluo ya que std_X ya es un vector 1 x N std_X(:, i) significa tomar todas las filas en la i ésima columna. Si ya tenemos un vector 1 x N , esto simplemente se puede reemplazar con std_X(i) , un poco exagerado para mi gusto.

El Método # 2 realiza lo mismo que el Método # 1, pero proporcionamos nuestra propia media y desviación estándar para cada columna de X

Por el bien de la documentación, así es como habría comentado el código:

function [X, mean_X, std_X] = standardize(varargin) switch nargin %// Check how many input variables we have input into the function case 1 %// If only one variable - this is the input matrix mean_X = mean(varargin{1}); %// Find mean of each column std_X = std(varargin{1}); %// Find standard deviation of each column %// Take each column of X and subtract by its corresponding mean %// Take mean_X and duplicate M times vertically X = varargin{1} - repmat(mean_X, [size(varargin{1}, 1) 1]); %// Next, for each column, normalize by its respective standard deviation for i = 1:size(X, 2) X(:, i) = X(:, i) / std(X(:, i)); end case 3 %// If we provide three inputs mean_X = varargin{2}; %// Second input is a mean vector std_X = varargin{3}; %// Third input is a standard deviation vector %// Apply the code as seen in the first case X = varargin{1} - repmat(mean_X, [size(varargin{1}, 1) 1]); for i = 1:size(X, 2) X(:, i) = X(:, i) / std_X(:, i); end end

Si puedo sugerir otra forma de escribir este código, usaría la poderosa y poderosa función bsxfun . Esto evita tener que duplicar elementos y podemos hacerlo bajo el capó. Reescribiría esta función para que se vea así:

function [X, mean_X, std_X] = standardize(varargin) switch nargin case 1 mean_X = mean(varargin{1}); %// Find mean of each column std_X = std(varargin{1}); %// Find std. dev. of each column X = bsxfun(@minus, varargin{1}, mean_X); %// Subtract each column by its respective mean X = bsxfun(@rdivide, X, std_X); %// Take each column and divide by its respective std dev. case 3 mean_X = varargin{2}; std_X = varargin{3}; %// Same code as above X = bsxfun(@minus, varargin{1}, mean_X); X = bsxfun(@rdivide, X, std_X); end

Yo diría que el nuevo código anterior es mucho más rápido que usar for y repmat . De hecho, se sabe que bsxfun es más rápido que el enfoque anterior, especialmente para matrices más grandes.