Резюме заметок Эндрю Нг по машинному обучению

машинное обучение
Резюме заметок Эндрю Нг по машинному обучению

машинное обучение

Эмммм, в этом семестре я закончил курс Эндрю Нг по машинному обучению на Coursera. Меня всегда не впечатлял этот курс, но я случайно зарегистрировался и подал заявку на финансовую помощь.После окончания курса я могу получить сертификат бесплатно (продается за несколько сотен долларов), а также я отправлю подлинный Matlab Online во время Конечно, эта серия случайных (профессиональных) естественных (мелких) вещей (удобных) (адаптивных) побудила меня начать чистить этот класс. А потом — так вкусно пахнет~! Этот класс действительно является хорошим введением в машинное обучение, и неудивительно, что так много людей рекомендуют его.

В примечаниях к курсу на Coursera есть краткое изложение каждой главы, и оно очень хорошее, рекомендуется просмотреть его после изучения. Но я все еще люблю писать свои собственные, поэтому во время просмотра видео я написал заметки, которые охватывают почти весь курс:

Низкая заметка.GitHub.IO/categories/…

Эти заметки были объединены в эту статью.

Здесь я в основном писал описание различных алгоритмов, а также извлек примерную кодовую реализацию алгоритма из задания по программированию, что удобно для быстрого ознакомления в будущем. Что же касается проектирования, оптимизации, отладки и различных ухищрений системы машинного обучения, о которых преподаватель очень старался рассказать в курсе, то я вообще не буду упоминать, для понимания сути нужно смотреть видео преподавателя ( только не признавайтесь мне в этом).ленивый). Давайте начнем.

контролируемое обучение

Обучение с учителем обучается на данных x и y.

image-20191105144318970

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

Чтобы делать прогнозы, диапазон представляет собой непрерывное число (например, интервал[0,100][0,100])

математическая модель:

  • функция предсказания:
hθ(x)=i=0mθixi=[θ0θ1θn][x0x1xn]=θTXh_\theta(x) = \sum_{i=0}^m \theta_ix_i = \left[\begin{array}{c}\theta_0 & \theta_1 & \ldots & \theta_n\end{array}\right] \left[\begin{array}{c}x_0 \\ x_1 \\ \vdots \\ x_n \end{array}\right] = \theta^TX
  • Запрашиваемые параметры:θ=[θ0θ1θn]\theta=\left[\begin{array}{c}\theta_0 & \theta_1 & \ldots & \theta_n\end{array}\right]

  • функция стоимости:

J(θ)=12mi=1m(h(x(i))y(i))2=(i=1mhθ(X)Y)22mJ(\theta)=\frac{1}{2m}\sum_{i=1}^m(h(x^{(i)})-y^{(i)})^2 =\frac{(\sum_{i=1}^mh_\theta(X)-Y)^2}{2m}

?Реализация кода:

  function J = computeCostMulti(X, y, theta)
  %COMPUTECOSTMULTI Compute cost for linear regression with multiple variables
  %   J = COMPUTECOSTMULTI(X, y, theta) computes the cost of using theta as the
  %   parameter for linear regression to fit the data points in X and y
  
  m = length(y); % number of training examples
  
  J = 0;
  
  J = 1 / (2*m) * (X*theta - y)' * (X*theta - y);
  
  % or less vectorizedly: 
  % predictions = X * theta;
  % sqrErrors = (predictions - y) .^ 2;
  % J = 1 / (2*m) * sum(sqrErrors);
  
  end
  • оптимизировать цель: найти наборθ\thetaсделатьJJминимум.

Решение:

градиентный спуск

(В настоящее время здесь обсуждается только пакетный градиентный спуск)

repeat until convergence {θj:=θjαθjJ(θ):=θjα1mi=1m[hθ(x(i))y(i)]xj(i)for j:=0,...,n}\begin{array}{ll} \textrm{repeat until convergence } \{ \\ \qquad \theta_j:=\theta_j-\alpha\frac{\partial}{\partial\theta_j}J(\theta)\\ \qquad\quad:= \theta_j - \alpha \frac{1}{m} \sum^m_{i=1}[h_\theta(x^{(i)})-y^{(i)}] \cdot x_j^{(i)}\qquad \textrm{for }j:=0, ..., n \\ \} \end{array}

Векторное представление:θ=θαmXT(hθ(X)Y)\theta=\theta-\frac{\alpha}{m}X^T(h_\theta(X)-Y)

?Реализация кода:

function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)
%GRADIENTDESCENTMULTI Performs gradient descent to learn theta
%   theta = GRADIENTDESCENTMULTI(x, y, theta, alpha, num_iters) updates theta by
%   taking num_iters gradient steps with learning rate alpha

m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters

    predictions = X * theta;
    errors = (predictions - y);
    theta = theta - alpha / m * (X' * errors);
    
    % Save the cost J in every iteration    
    J_history(iter) = computeCostMulti(X, y, theta);

end

end

нормальное уравнение

θ=(XTX)1XTy\theta = (X^TX)^{-1}X^Ty

?Реализация кода:

function [theta] = normalEqn(X, y)
%NORMALEQN Computes the closed-form solution to linear regression 
%   NORMALEQN(X,y) computes the closed-form solution to linear 
%   regression using the normal equations.

theta = zeros(size(X, 2), 1);

theta = pinv(X' * X) * X' * y;

end

Здесь мы используем псевдоинверсию, чтобы обеспечить правильную работу. обычно вызываютXTXX^TXПричинами необратимости являются:

  1. Существуют редуцируемые признаки, то есть, если два или более признака связаны линейно, только один из них может быть решен путем удаления других. (например, есть размер дома в футах ^ 2 и размер дома в метрах ^ 2, где мы знаем, что 1 метр = 3,28 фута)
  2. Слишком много заданных функций, (mnm \le n) Некоторые неважные функции могут быть удалены (рассмотрите алгоритм PCA)

Градиентный спуск против нормального уравнения

Gradient Descent Normal Equation
Нужно выбрать альфу -
третья сторона -
временная сложность O(kn2)O(kn^2) попрошайничествоXTXX^TXПсевдоинверсияO(n3)O(n^3)
Когда n достаточно велико может работать очень медленный или даже неисчислимый

На самом деле, когдаn>10,000n>10,000, мы обычно предпочитаем использовать градиентный спуск, в противном случае нормальные уравнения обычно работают лучше.

Примечание. Масштабирование функций

Мы можем заставить градиентный спуск работать быстрее, сделав входные значения примерно в пределах определенного диапазона, например, мы можем изменить все значения на[1,1][-1,1]В то же время мы также можем сделать разрыв между входными значениями не слишком большим путем обработки (например, входное значение имеет большой разрыв, такой как 0,000001 и 1 одновременно, что повлияет на эффективность градиента спуск).

На практике мы обычно хотим убедиться, что значения переменных[3,13)(+13,+3][-3,-\frac{1}{3}) \cup (+\frac{1}{3}, +3]значение в этом диапазоне.

Для достижения этой цели мы делаем следующее:

  1. Feature scaling
Range:si=max(xi)min(xi)Or Range:si=standard deviation of xiScaling:xi:=xisi\begin{array}{rl} \textrm{Range:} & s_i = max(x_i)-min(x_i)\\ \textrm{Or Range:} & s_i = \textrm{standard deviation of } x_i\\ \textrm{Scaling:} & x_i:=\frac{x_i}{s_i} \end{array}
  1. Mean normalizaton
Mean(Average):μi=sum(xi)mnormalizing:xi:=xiμi\begin{array}{rl} \textrm{Mean(Average):} & \mu_i = \frac{sum(x_i)}{m}\\ \textrm{normalizing:} & x_i:=x_i-\mu_i \end{array}

Соедините две операции вместе, а именно:

xi:=xiμisix_i:=\frac{x_i-\mu_i}{s_i}

в,μi\mu_iявляется средним значением признака (i),sis_iэто диапазон значений.

?Реализация кода:

function [X_norm, mu, sigma] = featureNormalize(X)
%FEATURENORMALIZE Normalizes the features in X 
%   FEATURENORMALIZE(X) returns a normalized version of X where
%   the mean value of each feature is 0 and the standard deviation
%   is 1. This is often a good preprocessing step to do when
%   working with learning algorithms.

X_norm = X;
mu = zeros(1, size(X, 2));
sigma = zeros(1, size(X, 2));

mu = mean(X);
sigma = std(X);
X_norm = (X - mu) ./ sigma;

end

проблема классификации

Делайте прогнозы с диапазоном дискретных конкретных значений (например, 0 или 1; 0/1/2/3)

логистическая регрессия

Предположим, функция:

{hθ(x)=g(θTx)z=θTxg(z)=11+ez\left\{\begin{array}{l} h_\theta(x) = g(\theta^Tx)\\ z = \theta^T x\\ g(z) = \frac{1}{1+e^{-z}}\\ \end{array}\right.

в,g(z)g(z)Названная функцией Симоида или логистической функцией, ее график выглядит следующим образом:

image-20190917162504420

?Реализация кода:

function g = sigmoid(z)
%SIGMOID Compute sigmoid functoon
%   J = SIGMOID(z) computes the sigmoid of z.

g = 1.0 ./ (1.0 + exp(-z));
end

Приведенную выше формулу можно упростить до:

hθ(x)=11+eθTxh_\theta(x) = \frac{1}{1+e^{-\theta^Tx}}

hθh_\thetaВыходом является вероятность того, что прогнозируемое значение равно 1, и выполняются следующие два уравнения:

hθ(x)=P(y=1x;θ)=1P(y=0x;θ)h_\theta(x)=P(y=1 \mid x;\theta)=1-P(y=0 \mid x; \theta)
P(y=0x;θ)+P(y=1x;θ)=1P(y=0 \mid x;\theta) + P(y=1 \mid x;\theta) = 1

граница решения: Граница решения логистической регрессии состоит в том, чтобы разделить регион вy=0y=0иy=1y=1Гиперплоскость из двух частей.

Граница решения определяется функцией гипотезы. Это связано с тем, что для завершения классификации необходимо использоватьhθh_\thetaвывод, чтобы определить, является ли результат 0 или 1. Установите 0,5 в качестве отсечки, то есть:

hθ(x)0.5y=1hθ(x)<0.5y=0\begin{array}{rcl} h_\theta(x) \ge 0.5 &\Rightarrow& y=1\\ h_\theta(x) < 0.5 &\Rightarrow& y=0 \end{array}

Из свойств функции Simoid приведенная выше формула эквивалентна:

θTX0y=1θTX0y=0\begin{array}{rcl} \theta^TX \ge 0 &\Rightarrow& y=1\\ \theta^TX \le 0 &\Rightarrow& y=0\\ \end{array}

Тогда для заданного множестваθ\theta,Напримерθ=[510]\theta=\left[\begin{array}{c}5\\-1\\0\end{array} \right],имеютy=1y=1если и только если5+(1)x1+0x205+(-1)x_1+0x_2 \ge 0, то граница решенияx1=5x_1=5.

image-20190917173722734

Границы решений также могут быть такими сложными, как:

image-20190917174144868

модель логистической регрессии:

Training set:{(x(1),y(1)),(x(2),y(2)),,(x(m),y(m))}m examples:xе[x0x1xn]where (x0=1),yе{0,1}Hypothesis:hθ(x)=11+eθTxCost Function:J(θ)=1mi=1m[y(i)log(hθ(x))+(1y(i))log(1hθ(x(i)))]\begin{array}{rcl} \textrm{Training set} &:& \{(x^{(1)},y^{(1)}), (x^{(2)},y^{(2)}), \ldots, (x^{(m)},y^{(m)})\}\\ \\ \textrm{m examples} &:& x \in \left[\begin{array}{c} x_0\\x_1\\ \vdots \\ x_n \end{array}\right] \textrm{where }(x_0=1) ,\quad y \in \{0,1\}\\ \\ \textrm{Hypothesis} &:& h_\theta(x)=\frac{1}{1+e^{-\theta^Tx}}\\\\ \textrm{Cost Function} &:& J(\theta)=-\frac{1}{m}\sum_{i=1}^m\Bigg[y^{(i)}log\Big(h_\theta(x)\Big)+(1-y^{(i)})log\Big(1-h_\theta(x^{(i)})\Big)\Bigg] \end{array}

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

h=g(Xθ)J(θ)=1m(yTlog(h)(1y)Tlog(1h))\begin{array}{l} h=g(X\theta)\\ J(\theta)=\frac{1}{m}\cdot\big(-y^T log(h) -(1-y)^T log(1-h)\big) \end{array}

градиентный спуск:

Repeat{θj:=θjαmi=1m(hθ(x(i))y(i))xj(i)}\begin{array}{l} Repeat \quad \{\\ \qquad \theta_j:=\theta_j-\frac{\alpha}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})\cdot x_j^{(i)}\\ \} \end{array}

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

θ:=θαmXT(g(Xθ)y)\theta:=\theta-\frac{\alpha}{m}X^T(g(X\theta)-\overrightarrow{y})

?Реализация кода (с использованием расширенной оптимизации):

  1. поставкаJ(θ),θjJ(θ)J(\theta), \frac{\partial}{\partial\theta_j}J(\theta)
function [J, grad] = costFunction(theta, X, y)
%COSTFUNCTION Compute cost and gradient for logistic regression
%   J = COSTFUNCTION(theta, X, y) computes the cost of using theta as the
%   parameter for logistic regression and the gradient of the cost
%   w.r.t. to the parameters.

m = length(y); % number of training examples

J = 0;
grad = zeros(size(theta));

h = sigmoid(X*theta);

J = 1/m * (-y'*log(h) - (1-y)'*log(1-h));

grad = 1/m * X'*(h-y);

end
  1. Вызовите функцию расширенной оптимизации, чтобы решить проблему оптимизации:
options = optimset('GradObj', 'on', 'MaxIter', 100);
initialTheta = zeros(2, 1);

[optTheta, functionVal, exitFlag] = fminunc(@costFunction, initialTheta, options);
многомерная классификация

Мы выполняем многомерную классификацию, используя ряд единичных (логических) классификаций:

yе{0,1,,n}hθ(0)(x)=P(y=0x;θ)hθ(0)(x)=P(y=0x;θ)hθ(0)(x)=P(y=0x;θ)prediction=maxθ(hθ(i)(x))\begin{array}{l} y \in \{0,1,\cdots,n\}\\\\ h_\theta^{(0)}(x)=P(y=0|x;\theta)\\ h_\theta^{(0)}(x)=P(y=0|x;\theta)\\ \vdots\\ h_\theta^{(0)}(x)=P(y=0|x;\theta)\\\\ prediction = \mathop{max}\limits_{\theta}\big(h_\theta^{(i)}(x)\big) \end{array}

img

Примечание: переобучение

img

Данные очень хорошо подходят для тренировочного набора прогнозов, но незначительного влияния на прогнозы новой выборки не наблюдается.

Методы решения проблемы переобучения:

  1. Уменьшить количество функций (PCA)

  2. Регуляризация: добавление к функции стоимостиθ\thetaвес:

    minθ12m i=1m(hθ(x(i))y(i))2+λ j=1nθj2\mathop{min}\limits_{\theta} \dfrac{1}{2m}\ \sum_{i=1}^m (h_\theta(x^{(i)}) - y^{(i)})^2 + \lambda\ \sum_{j=1}^n \theta_j^2

    Уведомление,θ0\theta_0— постоянный член, который мы добавили, и его не следует регуляризировать.

    Код:

   function [J, grad] = lrCostFunction(theta, X, y, lambda)
   %LRCOSTFUNCTION Compute cost and gradient for logistic regression with 
   %regularization
   %   J = LRCOSTFUNCTION(theta, X, y, lambda) computes the cost of using
   %   theta as the parameter for regularized logistic regression and the
   %   gradient of the cost w.r.t. to the parameters. 
   
   m = length(y); % number of training examples
   
   J = 0;
   grad = zeros(size(theta));
   
   % Unregularized cost function & gradient for logistic regression
   h = sigmoid(X * theta);
   J = 1/m * (-y'*log(h) - (1-y)'*log(1-h));
   grad = 1/m * X'*(h-y);
   
   % Regularize
   temp = theta;
   temp(1) = 0;
   J = J + lambda/(2*m) * sum(temp.^2);
   grad = grad + lambda/m * temp;
   
   grad = grad(:);
   
   end

Нейронные сети

[x0x1x2x3][a1(2)a2(2)a3(2)][a1(3)a2(3)a3(3)]hθ(x)\left[\begin{array}{c}x_0 \\ x_1 \\ x_2 \\ x_3\end{array}\right] \rightarrow \left[\begin{array}{c}a_1^{(2)} \\ a_2^{(2)} \\ a_3^{(2)} \\ \end{array}\right] \rightarrow \left[\begin{array}{c}a_1^{(3)} \\ a_2^{(3)} \\ a_3^{(3)} \\ \end{array}\right] \rightarrow h_\theta(x)

Первый слой — это набор данных, называемый входным слоем, который можно рассматривать какa(0)a^{(0)}; В середине есть несколько скрытых слоев, а конечным результатом является функция предсказания, которая называется выходным слоем.

z(j)=Θ(j1)a(j1)z^{(j)} = \Theta^{(j-1)}a^{(j-1)}
a(j)=g(z(j))a^{(j)} = g(z^{(j)})

Предполагая, что есть c слоев, тогда:

hΘ(x)=a(c+1)=g(z(c+1))h_\Theta(x)=a^{(c+1)}=g(z^{(c+1)})

Например, с нейронной сетью одного слоя мы можем построить несколько нейронных сетей, которые выражают логистические функции:

AND:Θ(1)=[302020]NOR:Θ(1)=[102020]OR:Θ(1)=[102020]\begin{array}{l}AND:\\&\Theta^{(1)} &=\begin{bmatrix}-30 & 20 & 20\end{bmatrix} \\ NOR:\\&\Theta^{(1)} &= \begin{bmatrix}10 & -20 & -20\end{bmatrix} \\ OR:\\&\Theta^{(1)} &= \begin{bmatrix}-10 & 20 & 20\end{bmatrix} \\\end{array}
многомерная классификация
y(i)=[1000],[0100],[0010],[0001]y^{(i)}=\begin{bmatrix}1\\0\\0\\0\end{bmatrix},\begin{bmatrix}0\\1\\0\\0\end{bmatrix},\begin{bmatrix}0\\0\\1\\0\end{bmatrix},\begin{bmatrix}0\\0\\0\\1\end{bmatrix}
[x0x1x2x3][a1(2)a2(2)a3(2)...][a1(3)a2(3)a3(3)...][hΘ(x)1hΘ(x)2hΘ(x)3hΘ(x)4]\left[\begin{array}{c}x_0 \\ x_1 \\ x_2 \\ x_3\end{array}\right] \rightarrow \left[\begin{array}{c}a_1^{(2)} \\ a_2^{(2)} \\ a_3^{(2)} \\ ... \end{array}\right] \rightarrow \left[\begin{array}{c}a_1^{(3)} \\ a_2^{(3)} \\ a_3^{(3)} \\ ... \end{array}\right] \rightarrow \cdots \rightarrow \left[\begin{array}{c}h_\Theta(x)_1 \\ h_\Theta(x)_2 \\ h_\Theta(x)_3 \\ h_\Theta(x)_4 \end{array}\right]
Настройка нейронной сети
Notation Represent
LL Общее количество слоев в нейронной сети
sls_l первоеllКоличество узлов в слое (не считая элементов смещенияa0a_0)
KK Количество выходных узлов

функция стоимости:

J(Θ)=1mi=1mk=1K[yk(i)log((hΘ(x(i)))k)+(1yk(i))log(1(hΘ(x(i)))k)]+λ2ml=1L1i=1slj=1sl+1(Θj,i(l))2J(\Theta)=-\frac{1}{m}\sum_{i=1}^{m}\sum_{k=1}^{K}\Big[ y_k^{(i)}log\Big(\big(h_\Theta(x^{(i)})\big)_k\Big)+ (1-y_k^{(i)})log\Big(1-\big(h_\Theta(x^{(i)})\big)_k\Big) \Big]+ \frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}}\Big(\Theta_{j,i}^{(l)}\Big)^2

Алгоритм обратного распространения:

Give training set (x(1),y(1)),...,(x(m),y(m))Set Δi,j(l):=0 for each l,i,j (get a matrix full of zeros)For training example t=1 to m:a(1):=x(t)Compute a(l) for l=2,3,,L by forward propagationUsing y(t) to compute δ(L)=a(L)y(t)Compute δ(l)=((Θ(l))Tδ(l+1)).*a(l).*(1a(l)) for δ(L1),δ(L2),...,δ(2)Δ(l):=Δ(l)+δ(l+1)(a(l))TEnd ForDi,j(l):=1mΔi,j(l) if j=0Di,j(l):=1m(Δi,j(l)+λΘi,j(l)) if j0Get Θi,j(l)J(Θ)=Di,j(l)\begin{array}{lll} \textrm{Give training set }{(x^{(1)},y^{(1)}),...,(x^{(m)},y^{(m)})}\\ \textrm{Set }\Delta_{i,j}^{(l)}:=0\textrm{ for each } l,i,j \textrm{ (get a matrix full of zeros)}\\ \mathop{\textrm{For}} \textrm{ training example $t=1$ to $m$}:\\ \qquad a^{(1)}:= x^{(t)}\\ \qquad \textrm{Compute $a^{(l)}$ for $l=2,3,\cdots,L$ by forward propagation}\\ \qquad \textrm{Using $y^{(t)}$ to compute } \delta^{(L)}=a^{(L)}-y^{(t)}\\ \qquad \textrm{Compute } \delta^{(l)}=\big((\Theta^{(l)})^T\delta^{(l+1)}\big).*a^{(l)}.*(1-a^{(l)}) \textrm{ for } \delta^{(L-1)},\delta^{(L-2)},...,\delta^{(2)}\\ \qquad \Delta^{(l)}:=\Delta^{(l)}+\delta^{(l+1)}(a^{(l)})^T\\ \textrm{End For}\\ D_{i,j}^{(l)}:=\frac{1}{m}\Delta_{i,j}^{(l)}\textrm{ if } j=0\\ D_{i,j}^{(l)}:=\frac{1}{m}\big(\Delta_{i,j}^{(l)}+\lambda\Theta_{i,j}^{(l)}\big) \textrm{ if } j\neq 0 \\ \textrm{Get } \frac{\partial}{\partial\Theta_{i,j}^{(l)}}J(\Theta)=D_{i,j}^{(l)} \end{array}

Примечание: в приведенной выше формуле.*.*Представляет поэлементное умножение в Matlab/Octave.

Использование обратного распространения:

Рассмотрим несколько задействованных методов:

  • Расширение параметра: Чтобы использовать функцию оптимизации, нам нужно преобразовать всеΘ\ThetaРасширение матрицы и объединение в длинный вектор:
thetaVector = [ Theta1(:); Theta2(:); Theta3(:) ];
deltaVector = [ D1(:); D2(:); D3(:) ];

После возврата к исходной матрице оптимизированы результаты:

Theta1 = reshape(thetaVector(1:110),10,11)
Theta2 = reshape(thetaVector(111:220),10,11)
Theta3 = reshape(thetaVector(221:231),1,11)
  • Проверка градиента: эксплойтΘjJ(Θ)J(Θ1,...,Θj+ϵ,...,Θn)J(Θ1,...,Θjϵ,...,Θn)2ϵ\frac{\partial}{\partial\Theta_j}J(\Theta) \approx \frac{J(\Theta_1,...,\Theta_j+\epsilon,...,\Theta_n)-J(\Theta_1,...,\Theta_j-\epsilon,...,\Theta_n)}{2\epsilon}Возьмем небольшой район, напримерϵ=104\epsilon=10^{-4}, вы можете проверить, является ли градиент, который мы получаем с обратнойпропрагацией, правильно (если он правильно, HODOPOPOXOX - Deltavector Holds). Код:
epsilon = 1e-4;
for i = 1 : n
	thetaPlus = theta;
	thetaPlus(i) += epsilon;
	thetaMinus = theta;
	thetaMinus(i) += epsilon;
	gradApprox(i) = (J(thetaPlus) - J(thetaMinus)) / (2*epsilon);
end
  • Немедленная инициализация: В началеΘij(l)\Theta_{ij}^{(l)}Случайная инициализация должна гарантировать, что значение случайного значения находится в пределах[ϵ,ϵ][-\epsilon,\epsilon]диапазон (этоϵ\epsilonНе связано с проверкой градиента). Код:
# If the dimensions of Theta1 is 10x11, Theta2 is 10x11 and Theta3 is 1x11.

Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;

Комбинируя вышеуказанные методы с алгоритмом обратного распространения, мы получаем способ обучения нейронной сети:

  1. случайная инициализация
  2. распространяться впередhΘ(x(i))h_\Theta(x^{(i)})любомуx(i)x^{(i)}
  3. Вычислить функцию стоимости
  4. Вычислите частные производные с помощью обратного распространения
  5. Используйте проверку градиента, чтобы убедиться в правильности обратного распространения. Если проблем нет, отключите функцию проверки градиента.
  6. Используйте градиентный спуск или функции оптимизации, чтобы получитьΘ\Theta

?Реализация кода:

  1. случайная инициализация
function W = randInitializeWeights(L_in, L_out)
%RANDINITIALIZEWEIGHTS Randomly initialize the weights of a layer with L_in
%incoming connections and L_out outgoing connections
%   W = RANDINITIALIZEWEIGHTS(L_in, L_out) randomly initializes the weights 
%   of a layer with L_in incoming connections and L_out outgoing 
%   connections. 
%
%   Note that W should be set to a matrix of size(L_out, 1 + L_in) as
%   the first column of W handles the "bias" terms
%

W = zeros(L_out, 1 + L_in);

% epsilon_init = 0.12
epsilon_init = sqrt(6 / (L_in + L_out));
W = rand(L_out, 1 + L_in) * (2 * epsilon_init) - epsilon_init;

end
  1. Вычислительная стоимость
function [J grad] = nnCostFunction(nn_params, ...
                                   input_layer_size, ...
                                   hidden_layer_size, ...
                                   num_labels, ...
                                   X, y, lambda)
%NNCOSTFUNCTION Implements the neural network cost function for a two layer
%neural network which performs classification
%   [J grad] = NNCOSTFUNCTON(nn_params, hidden_layer_size, num_labels, ...
%   X, y, lambda) computes the cost and gradient of the neural network. The
%   parameters for the neural network are "unrolled" into the vector
%   nn_params and need to be converted back into the weight matrices. 
% 
%   The returned parameter grad should be a "unrolled" vector of the
%   partial derivatives of the neural network.
%

% Reshape nn_params back into the parameters Theta_1 and Theta_2, the weight matrices
% for our 2 layer neural network
Theta_1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...
                 hidden_layer_size, (input_layer_size + 1));

Theta_2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...
                 num_labels, (hidden_layer_size + 1));

% Setup some useful variables
m = size(X, 1);
K = num_labels;

J = 0;
Theta_1_grad = zeros(size(Theta_1));
Theta_2_grad = zeros(size(Theta_2));

% y(5000x1) -> Y(5000x10)
Y = zeros(m, K);
for i = 1 : m
    Y(i, y(i)) = 1;
end

% Feedforward
a_1 = X;
a_1_bias = [ones(m, 1), a_1];

z_2 = a_1_bias * Theta_1';
a_2 = sigmoid(z_2);
a_2_bias = [ones(m, 1), a_2];

z_3 = a_2_bias * Theta_2';
a_3 = sigmoid(z_3);
h = a_3;

% Cost Function
% for i = 1 : K
%     yK = Y(:, i);
%     hK = h(:, i);
%     J += 1/m * (-yK'*log(hK) - (1-yK)'*log(1-hK));

% J can be get by element-wise compute more elegantly.
J = 1/m * sum(sum((-Y.*log(h) - (1-Y).*log(1-h))));

% Regularize
J = J + lambda/(2*m) * (sum(sum(Theta_1(:, 2:end).^2)) + sum(sum(Theta_2(:, 2:end).^2)));

% Backpropagation

delta_3 = a_3 .- Y;
delta_2 = (delta_3 * Theta_2) .* sigmoidGradient([ones(m, 1), z_2]);
% sigmoidGradient: return g = sigmoid(z) .* (1 - sigmoid(z));
delta_2 = delta_2(:, 2:end);

Delta_1 = delta_2' * a_1_bias;
Delta_2 = delta_3' * a_2_bias;

Theta_1_grad = Delta_1 ./ m + lambda/m * [zeros(size(Theta_1, 1), 1), Theta_1(:, 2:end)];
Theta_2_grad = Delta_2 ./ m + lambda/m * [zeros(size(Theta_2, 1), 1), Theta_2(:, 2:end)];

% Unroll gradients
grad = [Theta_1_grad(:) ; Theta_2_grad(:)];

end
  1. предсказывать
function p = predict(Theta1, Theta2, X)
%PREDICT Predict the label of an input given a trained neural network
%   p = PREDICT(Theta1, Theta2, X) outputs the predicted label of X given the
%   trained weights of a neural network (Theta1, Theta2)

% Useful values
m = size(X, 1);
num_labels = size(Theta2, 1);

p = zeros(size(X, 1), 1);

h1 = sigmoid([ones(m, 1) X] * Theta1');
h2 = sigmoid([ones(m, 1) h1] * Theta2');
[dummy, p] = max(h2, [], 2);

end
  1. водить машину
input_layer_size  = 400;  % 20x20 Input Images of Digits
hidden_layer_size = 25;   % 25 hidden units
num_labels = 10;          % 10 labels, from 1 to 10   
                          % (note that we have mapped "0" to label 10)

fprintf('\nInitializing Neural Network Parameters ...\n')

load('Xy.mat');

fprintf('\nTraining Neural Network... \n')

%  value to see how more training helps.
options = optimset('MaxIter', 1000);

lambda = 1;

% Create "short hand" for the cost function to be minimized
costFunction = @(p) nnCostFunction(p, ...
                                   input_layer_size, ...
                                   hidden_layer_size, ...
                                   num_labels, X, y, lambda);

% Now, costFunction is a function that takes in only one argument (the
% neural network parameters)
[nn_params, cost] = fmincg(costFunction, initial_nn_params, options);

% Obtain Theta1 and Theta2 back from nn_params
Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...
                 hidden_layer_size, (input_layer_size + 1));

Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...
                 num_labels, (hidden_layer_size + 1));

pred = predict(Theta1, Theta2, X);

fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y)) * 100);

Опорные векторные машины

оптимизировать цель:

minθCi=1m[y(i)cost1(θTx(i))+(1y(i)) cost0(θTx(i))]+12j=1nθj2\min_\theta C\sum_{i=1}^m \large[ y^{(i)} \mathop{\textrm{cost}_1}(\theta^Tx^{(i)}) + (1 - y^{(i)})\ \mathop{\textrm{cost}_0}(\theta^Tx^{(i)})\large] + \frac{1}{2}\sum_{j=1}^n \theta_j^2

когдаCCКогда значение относительно велико, эта цель оптимизации будет стремиться к тому, чтобы первый член суммирования стремился к нулю, так что цель оптимизации становится:

minθ12j=1nθj2s.t.θTx(i)1if y(i)=1θTx(i)1if y(i)=0\begin{array}{l} \min_\theta \frac{1}{2}\sum_{j=1}^{n}\theta_j^2\\\\ s.t. \quad \begin{array}{l} \theta^Tx^{(i)} \ge 1 & \textrm{if } y^{(i)}=1\\ \theta^Tx^{(i)} \le -1 & \textrm{if } y^{(i)}=0 \end{array} \end{array}

По знанию евклидова пространства:

u=length of vector u=u12+u22p=length of projection of v onto u (signed)uTv=pu\begin{array}{ccl} ||u|| &=& \textrm{length of vector } u= \sqrt{u_1^2+u_2^2}\\ p &=& \textrm{length of projection of } v \textrm{ onto } u \textrm{ (signed)} \\ \\ u^Tv &=& p \cdot ||u|| \end{array}

Вышеприведенная формула может быть выражена как:

minθ12j=1nθj2=12(j=1nθj2)2=12θ2s.t.p(i)θ1if y(i)=1p(i)θ1if y(i)=0where p(i) is the projection of x(i) onto the vector θ.\begin{array}{l} \min_\theta \frac{1}{2}\sum_{j=1}^{n}\theta_j^2 =\frac{1}{2}\Big(\sqrt{\sum_{j=1}^n\theta_j^2}\Big)^2 =\frac{1}{2}||\theta||^2 \\\\ s.t. \quad \begin{array}{l} p^{(i)}\cdot ||\theta|| \ge 1 & \textrm{if } y^{(i)}=1\\ p^{(i)}\cdot ||\theta|| \le -1 & \textrm{if } y^{(i)}=0 \end{array}\\\\ \textrm{where $p^{(i)}$ is the projection of $x^{(i)}$ onto the vector $\theta$.} \end{array}

SVM выберет самый большой разрыв:

屏幕快照 2019-10-31 12.58.43

ядерный метод

Столкнулся со следующими проблемами классификации:

image-20191102114127170

Мы можем использовать полиномы для регрессии, например, когдаθ0+θ1x1+θ2x2+θ3x1x2+θ4x12+θ5x22+0\theta_0+\theta_1x_1+\theta_2x_2+\theta_3x_1x_2+\theta_4x_1^2+\theta_5x_2^2+\cdots\ge 0прогноз времениy=1y=1;

Это более хлопотно, мы можем рассмотреть следующие методы:

Predict y=1ifθ0+θ1f1+θ2f2+θ3f3+0\begin{array}{lcl} \textrm{Predict } y=1 &\textrm{if}&\theta_0+\theta_1f_1+\theta_2f_2+\theta_3f_3+\cdots\ge 0 \end{array}

здесьf1=x1,f2=x2,f3=x1x2,f4=x12,...f_1=x_1,f_2=x_2,f_3=x_1x_2,f_4=x_1^2,...

мы используемfif_iПолином заменяется, и проблемы со старшими членами избегаются, так как определитьfif_i? Общая идея такова:

image-20191102124615797

Для удобства описания предположим, что у нас есть толькоx0,x1,x2x_0,x_1,x_2, и предназначен только для построенияf1,f2,f3f_1,f_2,f_3. Ну, несмотря ни на чтоx0x_0(зачетный срок), мы начинаем сx1x_1-x2x_2Выберите 3 точки на изображении , обозначенные какl(1),l(2),l(3)l^{(1)},l^{(2)},l^{(3)}, назови этоотмеченная точка. датьxx, получаем наборfif_i:

fi=similarity(x,l(i))=exp(xl(i)22о2)=exp(j=1n(xjlj(i))22о2)f_i = \mathop{\textrm{similarity}}(x,l^{(i)}) = \exp(-\frac{||x-l^{(i)}||^2}{2\sigma^2}) = \exp(-\frac{\sum_{j=1}^n(x_j-l_j^{(i)})^2}{2\sigma^2})

Конкретная функция подобия здесь называетсяФункция ядра, функция ядра варьируется. То, что мы пишем здесь, очень часто используетсяexp(j=1n(xjlj(i))22о2)\exp(-\frac{\sum_{j=1}^n(x_j-l_j^{(i)})^2}{2\sigma^2}), называемый Gaussian Kernel, код которого реализован следующим образом:

Из этого метода мы знаем, что заданоxx, для каждогоl(i)l^{(i)}мы получимfif_i, удовлетворять:

  1. когдаxxоколоl(i)l^{(i)}Время
filimxl(i)exp(xl(i)22о2)=exp(022о2)=1f_i \approx \lim_{x\to l^{(i)}}\exp(-\frac{||x-l^{(i)}||^2}{2\sigma^2}) = \exp(-\frac{0^2}{2\sigma^2}) = 1
  1. когдаxxдержаться подальшеl(i)l^{(i)}Время
filimxl(i)+exp(xl(i)22о2)=exp(22о2)=0f_i \approx \lim_{||x-l^{(i)}||\to +\infin}\exp(-\frac{||x-l^{(i)}||^2}{2\sigma^2}) = \exp(-\frac{\infin^2}{2\sigma^2}) = 0

о\sigmaвыбор повлияетfif_iзначение варьируетсяxxдержаться подальшеl(i)l^{(i)}и скорость снижения,о2\sigma^2чем большеfif_iУменьшать медленнее:

image-20191102132852867

Используя метод ядра, мы можем сделать этот прогноз:

image-20191102133600603

тогда и только тогда, когда даноxxоколоl(1)l^{(1)}илиl(2)l^{(2)}предсказывает 1, если это так, и 0 в противном случае.

Ядра, используемые в SVM
  1. данный тренировочный набор(x(1),y(1)),(x(2),y(2)),...,(x(m),y(m))(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})

  2. Выберите маркерные точки:l(i)=x(i)for i=1,2,,ml^{(i)}=x^{(i)} \quad \textrm{for }i=1,2,\cdots,m

  3. для образцаxx, вычисление ядра:fi=similarity(x,l(i))for i=1,2,,mf_i=\mathop{\textrm{similarity}}(x,l^{(i)}) \quad \textrm{for }i=1,2,\cdots,m

  4. сделатьf=[f0,f1,f2,,fm]Tf=[f_0,f_1,f_2,\cdots,f_m]^Tf01f_0 \equiv 1.

предсказывать:

  • данныйxx,рассчитатьfеRm+1f\in\R^{m+1}
  • предсказыватьy=1y=1еслиθTf=θ0f0+θ1f1+0\theta^Tf=\theta_0f_0+\theta_1f_1+\cdots\ge 0

тренироваться:

minθCi=1m[y(i)cost1(θTf(i))+(1y(i)) cost0(θTf(i))]+12j=1nθj2\min_\theta C\sum_{i=1}^m \large[ y^{(i)} \mathop{\textrm{cost}_1}(\theta^Tf^{(i)}) + (1 - y^{(i)})\ \mathop{\textrm{cost}_0}(\theta^Tf^{(i)})\large] + \frac{1}{2}\sum_{j=1}^n \theta_j^2

выполнить:

Мы можем использовать такие библиотеки, как liblinear, libsvm, чтобы получить параметры SVM.θ\theta, чтобы использовать эти библиотеки, нам обычно нужно сделать следующее:

  • выберите параметрыCC
  • выбрать функцию ядра
    • No kernel(т.е. линейное ядро, то есть логистическая регрессия: Predicty=1y=1 if θTx0\theta^Tx\ge0), зап большой м маленький(чтобы избежать переобучения)
    • Gaussian kernel(fi=exp(xl(i)22о2) where l(i)=x(i) for i=1,,mf_i=\exp(-\frac{||x-l^{(i)}||^2}{2\sigma^2})\textrm{ where } l^{(i)}=x^{(i)} \textrm{ for } i=1,\cdots,m) относится км большой н маленькийслучай (могут быть установлены более сложные нелинейные оценки)
  • Предоставьте функцию ядра (например, ядро ​​Гаусса):
function f = kernel(x1, x2)f=exp(x1x222о2)return\begin{array}{l} \textrm{function f = kernel(x1, x2)}\\ \qquad \textrm{f} = \exp(-\frac{||\textrm{x1}-\textrm{x2}||^2}{2\sigma^2})\\ \textrm{return} \end{array}

Примечание. Используйте Gaussian Kernel, чтобы обеспечить характерный масштаб!

?Реализация кода бескорпусной функции:

function sim = linearKernel(x1, x2)
%LINEARKERNEL returns a linear kernel between x1 and x2
%   sim = linearKernel(x1, x2) returns a linear kernel between x1 and x2
%   and returns the value in sim

% Ensure that x1 and x2 are column vectors
x1 = x1(:); x2 = x2(:);

% Compute the kernel
sim = x1' * x2;  % dot product

end

?Реализация кода ядра Гаусса:

function sim = gaussianKernel(x1, x2, sigma)
%RBFKERNEL returns a radial basis function kernel between x1 and x2
%   sim = gaussianKernel(x1, x2) returns a gaussian kernel between x1 and x2
%   and returns the value in sim

% Ensure that x1 and x2 are column vectors
x1 = x1(:); x2 = x2(:);

sim = 0;

sim = exp(-sum((x1 - x2).^2) / (2 * sigma ^ 2));

end

?Пример SVM:

% Load X, y, Xtest and ytest
load('data.mat');

% SVM Parameters
C = 1;         % C = 1 ~ 100 is fine
sigma = 0.1;    % sigma = 0.03 ~ 0.1 gives somewhat good boundary, less is better

% We set the tolerance and max_passes lower here so that the code will run
% faster. However, in practice, you will want to run the training to
% convergence.
model= svmTrain(X, y, C, @(x1, x2) gaussianKernel(x1, x2, sigma)); 
p = svmPredict(model, Xtest);

fprintf('Test Accuracy: %f\n', mean(double(p == ytest)) * 100);
многомерная классификация

image-20191102171432072

Логистическая регрессия против нейронных сетей против SVM

nn= количество функций (xеRn+1x\in\R^{n+1})

mm= количество обучающих выборок

  • n больше, чем m (например,n=10,000,m=101000n=10,000, m=10 \sim 1000)
    • Логистическая регрессия или безъядерный SVM
  • n мало, m умеренно (например,n=11000,m=50,000n=1\sim1000,m=50,000)
    • SVM с ядром Гаусса
  • n маленькое, m большое
    • Создайте/добавьте функции, затем используйте логистическую регрессию или безъядерную SVM

Нейронные сети обычно могут решить любой из вышеперечисленных случаев, но могут быть относительно медленными.

неконтролируемое обучение

Неконтролируемому обучению даются только данные x, а не y.

屏幕快照 2019-11-05 14.49.05

Кластеризация K-средних

Разделите кучу вещей на K стопок автоматически.

входить:

  • KK: количество кластеров
  • {x(1),x(2),,x(m)}\{x^{(1)},x^{(2)},\cdots,x^{(m)}\}:Обучающий набор

вывод:

  • KKклассы

Алгоритм K-средних:

Randomly initialize K cluster centroids μ1,μ2,...μkеRnRepeat {for i=1 to m:// Cluster assignment stepc(i):=k  s.t. minkx(i)μk2for k=1 to K:// Move centroid stepμk:=average (mean) of points assigned to cluster k}\begin{array}{l} \textrm{Randomly initialize $K$ cluster centroids $\mu_1, \mu_2,...\mu_k \in \R^n$}\\ \textrm{Repeat }\{\\ \qquad \textrm{for $i=1$ to $m$:}\qquad\textrm{// Cluster assignment step}\\ \qquad\qquad c^{(i)} := k \ \textrm{ s.t. } \min_k||x^{(i)}-\mu_k||^2 \\ \qquad \textrm{for $k=1$ to $K$:}\qquad\textrm{// Move centroid step}\\ \qquad\qquad \mu_k:= \textrm{average (mean) of points assigned to cluster $k$}\\ \}\\ \end{array}

Функция стоимости:

J(c(1),,c(m),μ1,,μK)=1mi=1mx(i)μc(i)2J(c^{(1)},\cdots,c^{(m)},\mu_1,\cdots,\mu_K)=\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}-\mu_{c^{(i)}}||^2

оптимизировать цель:

min1c(1),,c(m),μ1,,μKJ(c(1),,c(m),μ1,,μK)\min_{ \begin{array}{c} {1}c^{(1)},\cdots,c^{(m)},\\ \mu_1,\cdots,\mu_K \end{array}} J(c^{(1)},\cdots,c^{(m)},\mu_1,\cdots,\mu_K)

Алгоритмы для получения лучшего решения (не обязательно оптимального решения):

For i=1 to 100 <or 50 1000> {Randomly initialize K-means.Run K-means. Get c(1),,c(m),μ1,,μkCompute cost function (distortion):J(c(1),,c(m),μ1,,μK)}pick clustering that gave lowest J.\begin{array}{l} \textrm{For $i=1$ to $100$ <or 50~1000> \{}\\ \qquad\textrm{Randomly initialize K-means.}\\ \qquad\textrm{Run K-means. Get $c^{(1)},\cdots,c^{(m)},\mu_1,\cdots,\mu_k$}\\ \qquad\textrm{Compute cost function (distortion):}\\ \qquad\qquad J(c^{(1)},\cdots,c^{(m)},\mu_1,\cdots,\mu_K)\\ \textrm{\}}\\ \textrm{pick clustering that gave lowest $J$.} \end{array}

KKвыбор:

  1. Более практические требования легко доступны;
  2. Выберите точку перегиба:image-20191106171612460

?Код

  1. Найдите ближайший учебный центр:
function idx = findClosestCentroids(X, centroids)
%FINDCLOSESTCENTROIDS computes the centroid memberships for every example
%   idx = FINDCLOSESTCENTROIDS (X, centroids) returns the closest centroids
%   in idx for a dataset X where each row is a single example. idx = m x 1 
%   vector of centroid assignments (i.e. each entry in range [1..K])
%

% Set K
K = size(centroids, 1);

idx = zeros(size(X,1), 1);

for i = 1 : size(X, 1)
    min_j = 0;
    min_l = Inf;
    for j = 1 : size(centroids, 1)
        l = sum((X(i, :) - centroids(j, :)) .^ 2);
        if l <= min_l
            min_j = j;
            min_l = l;
        end
    end
    idx(i) = min_j;
end

end
  1. Вычислительный центр:
function centroids = computeCentroids(X, idx, K)
%COMPUTECENTROIDS returns the new centroids by computing the means of the 
%data points assigned to each centroid.
%   centroids = COMPUTECENTROIDS(X, idx, K) returns the new centroids by 
%   computing the means of the data points assigned to each centroid. It is
%   given a dataset X where each row is a single data point, a vector
%   idx of centroid assignments (i.e. each entry in range [1..K]) for each
%   example, and K, the number of centroids. You should return a matrix
%   centroids, where each row of centroids is the mean of the data points
%   assigned to it.
%

% Useful variables
[m n] = size(X);

centroids = zeros(K, n);

for i = 1 : K
    ck = find(idx == i);
    centroids(i, :) = sum(X(ck,:)) / size(ck, 1);
end

end
  1. Запуск K-средних
function [centroids, idx] = runkMeans(X, initial_centroids, ...
                                      max_iters, plot_progress)
%RUNKMEANS runs the K-Means algorithm on data matrix X, where each row of X
%is a single example
%   [centroids, idx] = RUNKMEANS(X, initial_centroids, max_iters, ...
%   plot_progress) runs the K-Means algorithm on data matrix X, where each 
%   row of X is a single example. It uses initial_centroids used as the
%   initial centroids. max_iters specifies the total number of interactions 
%   of K-Means to execute. plot_progress is a true/false flag that 
%   indicates if the function should also plot its progress as the 
%   learning happens. This is set to false by default. runkMeans returns 
%   centroids, a Kxn matrix of the computed centroids and idx, a m x 1 
%   vector of centroid assignments (i.e. each entry in range [1..K])
% 若使用 plot_progress 需要额外的画图函数实现,这里没有给出.
%

% Set default value for plot progress
if ~exist('plot_progress', 'var') || isempty(plot_progress)
    plot_progress = false;
end

% Plot the data if we are plotting progress
if plot_progress
    figure;
    hold on;
end

% Initialize values
[m n] = size(X);
K = size(initial_centroids, 1);
centroids = initial_centroids;
previous_centroids = centroids;
idx = zeros(m, 1);

% Run K-Means
for i=1:max_iters
    
    % Output progress
    fprintf('K-Means iteration %d/%d...\n', i, max_iters);
    if exist('OCTAVE_VERSION')
        fflush(stdout);
    end
    
    % For each example in X, assign it to the closest centroid
    idx = findClosestCentroids(X, centroids);
    
    % Optionally, plot progress here
    if plot_progress
        plotProgresskMeans(X, centroids, previous_centroids, idx, K, i);
        previous_centroids = centroids;
        fprintf('Press enter to continue.\n');
        input("...");
    end
    
    % Given the memberships, compute new centroids
    centroids = computeCentroids(X, idx, K);
end

% Hold off if we are plotting progress
if plot_progress
    hold off;
end

end
  1. Скрипт драйвера:
% Load an example dataset
load('data.mat');

% Settings for running K-Means
K = 3;
max_iters = 10;

% For consistency, here we set centroids to specific values
% but in practice you want to generate them automatically, such as by
% settings them to be random examples (as can be seen in
% kMeansInitCentroids).
initial_centroids = [3 3; 6 2; 8 5];

% Run K-Means algorithm. The 'true' at the end tells our function to plot
% the progress of K-Means
[centroids, idx] = runkMeans(X, initial_centroids, max_iters, true);
fprintf('\nK-Means Done.\n\n');

Уменьшение размерности PCA

Анализ основных компонентов: уменьшите n-мерные данные (проекцию) до k-мерных и опустите неважную часть (k

Алгоритм PCA:

  1. предварительная обработка данных

    Обучающий набор:x(1),x(2),,x(m)x^{(1)},x^{(2)},\cdots,x^{(m)}

    Предварительная обработка (масштабирование признаков и нормализация среднего):

    • μj=1mi=1mxj(i),sj=standard deviation of feature j\mu_j=\frac{1}{m}\sum_{i=1}^m x_j^{(i)},\qquad s_j=\textrm{standard deviation of feature }j

    • Replace each xj(i)x_j^{(i)} with xjμjsj\frac{x_j-\mu_j}{s_j}

2) уменьшение размерности

  1. Вычислить ковариационную матрицуΣ\Sigma(Эта матрица записывается как большая сигма, обратите внимание, чтобы отличить ее от знака суммирования):
Σ=1mi=1n(x(i))(x(i))T\Sigma = \frac{1}{m}\sum_{i=1}^n(x^{(i)})(x^{(i)})^T
  1. попрошайничествоΣ\SigmaСобственные значения (фактически сингулярное разложение):[U, S, V] = svd(Sigma);
  2. Из предыдущего шага svd получаем:
U=[u(1)u(2)u(n)]еRn×nUreduce=[u(1)u(2)u(k)]U = \left[\begin{array}{cccc} | & | & & |\\ u^{(1)} & u^{(2)} & \cdots & u^{(n)}\\ | & | & & | \end{array}\right] \in \R^{n\times n} \Rightarrow U_{reduce}=\left[\begin{array}{cccc} | & | & & |\\ u^{(1)} & u^{(2)} & \cdots & u^{(k)}\\ | & | & & | \end{array}\right]
  1. Полное уменьшение размерности:xеRnzеRkx\in\R^n\to z\in\R^k:
z=UreduceTx=[(u(1))T(u(k))T]xz = U_{reduce}^Tx =\left[\begin{array}{ccc} -- & (u^{(1)})^T & --\\ & \vdots & \\ -- & (u^{(k)})^T & --\\ \end{array}\right]x

?Реализация кода:

% do feature scaling & mean normalization

Sigma = 1/m * X' * X;
[U, S, V] = svd(Sigma);

Ureduce = U(:, 1:K);
Z = X * Ureduce;

восстановление данных: восстановить исходные размеры данных (zеRkxapproxеRnz\in\R^k \to x_{approx}\in\R^n):

xapprox=Ureducezx_{approx}=U_{reduce}z

В целомxxapproxx \neq x_{approx}, мы можем только ожидатьxapproxx_{approx}как можно ближеxx.

image-20191110215011122

kkВыбор (количество основных компонентов)

Как правило, выбирайтеkkДля минимального значения, при котором справедливо следующее уравнение:

1mi=1mx(i)xapprox(i)21mi=1mx(i)20.01\frac{\frac{1}{m}\sum_{i=1}^m||x^{(i)}-x_{approx}^{(i)}||^2}{\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}||^2}\le0.01

алгоритм:

Try PCA with k=1,,n:Compute Ureduce,z(1),,z(m),xapprox(1),,xapproxmCheck if 1mi=1mx(i)xapprox(i)21mi=1mx(i)20.01\begin{array}{l} \textrm{Try PCA with } k=1,\cdots,n:\\ \quad \textrm{Compute } U_{reduce},z^{(1)},\cdots,z^{(m)},x_{approx}^{(1)},\cdots,x_{approx}^{m}\\ \quad \textrm{Check if } \frac{\frac{1}{m}\sum_{i=1}^m||x^{(i)}-x_{approx}^{(i)}||^2}{\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}||^2}\le0.01 \end{array}

аномальное обнаружение

Найдите выбросы из множества данных.

Описание проблемы: задан набор данных{x(1),x(2),,x(m)}\{x^{(1)},x^{(2)},\cdots,x^{(m)}\}, путем обучения, судитьxtestx_{test}Разве это ненормально.

Для решения этой проблемы мы можемp(x)p(x)(Вероятность) Построить модель, выбрать критическое значениеϵ\epsilon,сделать:

p(xtest)<ϵanomalyp(xtest)ϵOK\begin{array}{l} p(x_{test})<\epsilon \Rightarrow \textrm{anomaly}\\ p(x_{test})\ge\epsilon \Rightarrow \textrm{OK} \end{array}

Эта проблема может быть преобразована вОценка значения плотности. Обычно мы решаем эту задачу с помощью распределения Гаусса.

Гауссово распределение

xxСледуйте распределению Гаусса:xN(μ,о2)x \sim \mathcal{N}(\mu,\sigma^2)

но,xxВероятность:

p(x)=12число Пиоexp((xμ)22о2)p(x) = \frac{1}{\sqrt{2\pi}\sigma}\exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)

где параметрыμ\muио\sigmaОпределяется по следующей формуле (это формат, обычно используемый в машинном обучении, не обязательно такой же, как в математике):

μ=1mi=1mx(i)\mu=\frac{1}{m}\sum_{i=1}^{m}x^{(i)}
о2=1mi=1m(x(i)μ)2\sigma^2=\frac{1}{m}\sum_{i=1}^{m}\left(x^{(i)}-\mu\right)^2

?Реализация кода:

function [mu sigma2] = estimateGaussian(X)
%ESTIMATEGAUSSIAN This function estimates the parameters of a 
%Gaussian distribution using the data in X
%   [mu sigma2] = estimateGaussian(X), 
%   The input X is the dataset with each n-dimensional data point in one row
%   The output is an n-dimensional vector mu, the mean of the data set
%   and the variances sigma^2, an n x 1 vector
% 

% Useful variables
[m, n] = size(X);

mu = zeros(n, 1);
sigma2 = zeros(n, 1);

mu = mean(X);
sigma2 = var(X) * (m - 1) / m;

end

Отсюда мы можем получить алгоритм проверки исключений:

Алгоритм проверки аномалий
  1. Выберите функции данных, которые, как считается, могут демонстрировать выборочные аномалииxix_i
  2. Расчетные параметрыμ1,,μn,о12,,оn2\mu_1,\cdots,\mu_n,\sigma_1^2,\cdots,\sigma_n^2
μ=1mi=1mx(i)\mu=\frac{1}{m}\sum_{i=1}^{m}x^{(i)}
о2=1mi=1m(x(i)μ)2\sigma^2=\frac{1}{m}\sum_{i=1}^{m}\left(x^{(i)}-\mu\right)^2
  1. Для вновь предоставленных образцовxx,рассчитатьp(x)p(x):
p(x)=j=1np(xj;μj,оj2)=j=1n12число Пиоjexp((xjμj)22оj2)p(x)=\prod_{j=1}^{n}p(x_j;\mu_j,\sigma_j^2)=\prod_{j=1}^{n}\frac{1}{\sqrt{2\pi}\sigma_j}\exp\left(-\frac{(x_j-\mu_j)^2}{2\sigma_j^2}\right)
  1. еслиp(x)<ϵp(x)<\epsilon, прогноз ненормальный.

Многомерное распределение Гаусса

p(x;μ,Σ)=exp(12(xμ)TΣ1(xμ))(2число Пи)nΣp(x;\mu,\Sigma)=\frac {\exp\left(-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)\right)} {\sqrt{(2\pi)^{n}|\Sigma|}}

параметр:

  • μеRn\mu\in\R^n
  • ΣеRn×n\Sigma\in\R^{n\times n} (covariance matrix, Sigma = 1/m * X' * X;)

Расчет параметров:

μ=1mi=1mx(i)Σ=1mi=1m(x(i)μ)(x(i)μ)T\mu=\frac{1}{m}\sum_{i=1}^mx^{(i)} \qquad \Sigma=\frac{1}{m}\sum_{i=1}^m\left(x^{(i)}-\mu\right)\left(x^{(i)}-\mu\right)^T

?Реализация кода:

function p = multivariateGaussian(X, mu, Sigma2)
%MULTIVARIATEGAUSSIAN Computes the probability density function of the
%multivariate gaussian distribution.
%    p = MULTIVARIATEGAUSSIAN(X, mu, Sigma2) Computes the probability 
%    density function of the examples X under the multivariate gaussian 
%    distribution with parameters mu and Sigma2. If Sigma2 is a matrix, it is
%    treated as the covariance matrix. If Sigma2 is a vector, it is treated
%    as the \sigma^2 values of the variances in each dimension (a diagonal
%    covariance matrix)
%

k = length(mu);

if (size(Sigma2, 2) == 1) || (size(Sigma2, 1) == 1)
    Sigma2 = diag(Sigma2);
end

X = bsxfun(@minus, X, mu(:)');
p = (2 * pi) ^ (- k / 2) * det(Sigma2) ^ (-0.5) * ...
    exp(-0.5 * sum(bsxfun(@times, X * pinv(Sigma2), X), 2));

end
Проверка аномалий с помощью многомерного распределения Гаусса
  1. Подгонка многомерного распределения Гауссаp(x)p(x)модель, через параметры:
μ=1mi=1mx(i)Σ=1mi=1m(x(i)μ)(x(i)μ)T\mu=\frac{1}{m}\sum_{i=1}^mx^{(i)} \qquad \Sigma=\frac{1}{m}\sum_{i=1}^m\left(x^{(i)}-\mu\right)\left(x^{(i)}-\mu\right)^T
  1. для новыхxx, рассчитать:
p(x)=exp(12(xμ)TΣ1(xμ))(2число Пи)nΣp(x)=\frac {\exp\left(-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)\right)} {\sqrt{(2\pi)^{n}|\Sigma|}}
  1. еслиp(x)<ϵp(x)<\epsilon, прогноз ненормальный.

Выбор порога

через вычислениеF1F_1значение, чтобы получить наилучшее соответствиеϵ\epsilon.

F1F_1Значение определяется точностью (precprec) И напомнить(recrec) дает:

F1=2precrecprec+recF_1=\frac{2\cdot prec \cdot rec}{prec+rec}

в:

prec=tptp+fpprec = \frac{tp}{tp+fp}
rec=tptp+fnrec = \frac{tp}{tp+fn}
  • tptpДа, истинные срабатывания: прогноз положительный, фактический также положительный
  • fpfpда ложные срабатывания: предсказано положительное, фактически отрицательное
  • fnfnда ложноотрицательные: прогнозируемый отрицательный, фактически положительный

image-20191026152903469

?Реализация кода:

function [bestEpsilon bestF1] = selectThreshold(yval, pval)
%SELECTTHRESHOLD Find the best threshold (epsilon) to use for selecting
%outliers
%   [bestEpsilon bestF1] = SELECTTHRESHOLD(yval, pval) finds the best
%   threshold to use for selecting outliers based on the results from a
%   validation set (pval) and the ground truth (yval).
%

bestEpsilon = 0;
bestF1 = 0;
F1 = 0;

stepsize = (max(pval) - min(pval)) / 1000;
for epsilon = min(pval):stepsize:max(pval)

    cvPredictions = pval < epsilon;
    
    tp = sum((cvPredictions == 1) & (yval == 1));
    fp = sum((cvPredictions == 1) & (yval == 0));
    fn = sum((cvPredictions == 0) & (yval == 1));

    prec = tp / (tp + fp);
    rec = tp / (tp + fn);

    F1 = (2 * prec * rec) / (prec + rec);

    if F1 > bestF1
       bestF1 = F1;
       bestEpsilon = epsilon;
    end
end

end

Рекомендуемая система

Через рейтинги рекомендуйте новый контент пользователям.

Описание обозначения: (Предположим, что мы хотим порекомендовать фильм)

  • nun_u= количество пользователей
  • nmn_m= количество фильмов
  • r(i,j)=1r(i,j)=1Если пользовательjjна пленкеiiПереоценен, иначе 0
  • y(i,j)y^{(i,j)}= пользовательjjдать фильмiiРейтинг (только еслиr(i,j)=1r(i,j)=1определено, когда)

Рекомендация на основе контента

прогностическая модель:

屏幕快照 2019-11-26 16.04.26

  • r(i,j)=1r(i,j)=1Если пользовательjjна пленкеiiпереоцененный
  • y(i,j)y^{(i,j)}= пользовательjjдать фильмiiоценка (если определено)
  • θ(j)\theta^{(j)}Пользовательjjпараметры (вектор)
  • x(i)x^{(i)}Киноiiхарактеристика (вектор)

для пользователейjj,Киноii, прогнозируемый счет:(θ(j))T(x(i))(\theta^{(j)})^T(x^{(i)}).

оптимизировать цель:

  1. оптимизацияθ(j)\theta^{(j)}(для одного пользователяjjпараметры)
minθ(j)i:r(i,j)=1((θ(j))Tx(i)y(i,j))2+λ2k=1n(θk(j))2\min_{\theta^{(j)}}\sum_{i:r(i,j)=1}\left((\theta^{(j)})^Tx^{(i)}-y^{(i,j)}\right)^2+\frac{\lambda}{2}\sum_{k=1}^n \left(\theta_k^{(j)}\right)^2
  1. оптимизацияθ(1),θ(2),,θ(nu)\theta^{(1)},\theta^{(2)},\cdots,\theta^{(n_u)}(для всех пользователей)
minθ(1),,θ(nu)j=1nui:r(i,j)=1((θ(j))Tx(i)y(i,j))2+λ2j=1nuk=1n(θk(j))2\min_{\theta^{(1)},\cdots,\theta^{(n_u)}} \sum_{j=1}^{n_u}\sum_{i:r(i,j)=1}\left((\theta^{(j)})^Tx^{(i)}-y^{(i,j)}\right)^2 + \frac{\lambda}{2}\sum_{j=1}^{n_u}\sum_{k=1}^n \left(\theta_k^{(j)}\right)^2

Мы можем решить проблему с градиентным спуском:

Repeat{θ0(j):=θ0(j)αi:r(i,j)=1((θ(j))T(x(i))y(i,j))x0(i)θk(j):=θk(j)α[(i:r(i,j)=1((θ(j))T(x(i))y(i))xk(i))+λθk(j)](for k0)}\begin{array}{l} Repeat\quad\{\\ \qquad \theta_0^{(j)}:=\theta_0^{(j)}-\alpha\sum_{i:r(i,j)=1} \big((\theta^{(j)})^T(x^{(i)})-y^{(i,j)}\big)x_0^{(i)}\\ \qquad \theta_k^{(j)}:=\theta_k^{(j)}-\alpha\Big[\Big(\sum_{i:r(i,j)=1}\big((\theta^{(j)})^T(x^{(i)})-y^{(i)}\big)x_k^{(i)}\Big)+\lambda\theta_k^{(j)}\Big]\qquad (\textrm{for } k \neq 0)\\ \} \end{array}

Совместная фильтрация

В рекомендации по содержанию нам иногда трудно понять фильм (мы хотим что-то порекомендовать) Каковы характеристики (x(i)x^{(i)}), мы хотим, чтобы машинное обучение само находил функции, для чего используется совместная фильтрация.

Новая цель оптимизации: (Цель оптимизации в рекомендации на основе контента все еще необходимо учитывать)

  • данныйθ(1),θ(2),,θ(nu)\theta^{(1)},\theta^{(2)},\cdots,\theta^{(n_u)},учитьсяx(i)x^{(i)}:
minx(i)12i:r(i,j)=1((θ(j))Tx(i)y(i,j))2+λ2k=1n(xk(i))2\min_{x^{(i)}}\frac{1}{2}\sum_{i:r(i,j)=1}\left((\theta^{(j)})^Tx^{(i)}-y^{(i,j)}\right)^2+\frac{\lambda}{2}\sum_{k=1}^n \left(x_k^{(i)}\right)^2
  • данныйθ(1),θ(2),,θ(nu)\theta^{(1)},\theta^{(2)},\cdots,\theta^{(n_u)},учитьсяx(1),,x(nm)x^{(1)},\cdots,x^{(n_m)}:
minx(1),,x(nm)12i=1nmi:r(i,j)=1((θ(j))Tx(i)y(i,j))2+λ2i=1nmk=1n(xk(i))2\min_{x^{(1)},\cdots,x^{(n_m)}}\frac{1}{2} \sum_{i=1}^{n_m}\sum_{i:r(i,j)=1}\left((\theta^{(j)})^Tx^{(i)}-y^{(i,j)}\right)^2 + \frac{\lambda}{2}\sum_{i=1}^{n_m}\sum_{k=1}^n \left(x_k^{(i)}\right)^2

Совместная фильтрация:

Теперь наша проблема в том, что нет обученногоθ\theta, и нет набора полностью оптимизированныхxx, но учитсяθ\thetaиметь первыйxx,учитьсяxxиметь первыйθ\theta. Это превратилось в проблему курицы и яйца.

Мы можем думать о решении этой дилеммы следующим образом:

Первое случайное угадывание группыθ\theta, то используйте этот наборθ\thetaчтобы получить наборxx; получается с этим наборомxxможно оптимизироватьθ\theta, оптимизированныйθ\thetaснова оптимизироватьxx... и продолжайте повторять этот процесс, мы можем ожидать получить наборxxиθ\thetaявляются полностью оптимизированными решениями (на самом деле они со временем сойдутся).

屏幕快照 2019-11-28 15.20.59

Given x(1),,x(nm) , estimate θ(1),,θ(nu):minθ(1),,θ(nu)j=1nui:r(i,j)=1((θ(j))Tx(i)y(i,j))2+λ2j=1nuk=1n(θk(j))2Given θ(1),,θ(nu) , estimate x(1),,x(nm):minx(1),,x(nm)12i=1nmi:r(i,j)=1((θ(j))Tx(i)y(i,j))2+λ2i=1nmk=1n(xk(i))2\begin{array}{l} \textrm{Given } x^{(1)},\cdots,x^{(n_m)} \textrm{ , estimate } \theta^{(1)},\cdots,\theta^{(n_u)}:\\ \quad \min_{\theta^{(1)},\cdots,\theta^{(n_u)}} \sum_{j=1}^{n_u}\sum_{i:r(i,j)=1}\left((\theta^{(j)})^Tx^{(i)}-y^{(i,j)}\right)^2 + \frac{\lambda}{2}\sum_{j=1}^{n_u}\sum_{k=1}^n \left(\theta_k^{(j)}\right)^2\\ \textrm {Given } \theta^{(1)},\cdots,\theta^{(n_u)} \textrm{ , estimate } x^{(1)},\cdots,x^{(n_m)}:\\ \quad \min_{x^{(1)},\cdots,x^{(n_m)}}\frac{1}{2} \sum_{i=1}^{n_m}\sum_{i:r(i,j)=1}\left((\theta^{(j)})^Tx^{(i)}-y^{(i,j)}\right)^2 + \frac{\lambda}{2}\sum_{i=1}^{n_m}\sum_{k=1}^n \left(x_k^{(i)}\right)^2 \end{array}

Мы случайным образом инициализируем набор параметров, а затем повторяем вычисления туда и обратно.θ\thetaиxx, в конечном итоге получим решение, но это более хлопотно, мы можем сделать это более эффективно:

в то же времяоптимизацияx(1),,x(nm)x^{(1)},\cdots,x^{(n_m)}иθ(1),,θ(nu)\theta^{(1)},\cdots,\theta^{(n_u)}:

J(x(1),,x(nm),θ(1),,θ(nu))=12(i,j):r(i,j)=1((θ(j))Tx(i)y(i,j))2+λ2i=1nmk=1n(xk(i))2+λ2i=1nmk=1n(xk(i))2J(x^{(1)},\cdots,x^{(n_m)},\theta^{(1)},\cdots,\theta^{(n_u)})= \frac{1}{2} \sum_{(i,j):r(i,j)=1}\left((\theta^{(j)})^Tx^{(i)}-y^{(i,j)}\right)^2+ \frac{\lambda}{2}\sum_{i=1}^{n_m}\sum_{k=1}^n \left(x_k^{(i)}\right)^2+ \frac{\lambda}{2}\sum_{i=1}^{n_m}\sum_{k=1}^n \left(x_k^{(i)}\right)^2
minx(1),,x(nm)θ(1),,θ(nu)J(x(1),,x(nm),θ(1),,θ(nu))\min_{\begin{array}{c}x^{(1)},\cdots,x^{(n_m)}\\\theta^{(1)},\cdots,\theta^{(n_u)}\end{array}} J(x^{(1)},\cdots,x^{(n_m)},\theta^{(1)},\cdots,\theta^{(n_u)})

Алгоритм совместной фильтрации:

  1. будетx(1),,x(nm),θ(1),,θ(nu)x^{(1)},\cdots,x^{(n_m)},\theta^{(1)},\cdots,\theta^{(n_u)}Случайно инициализируется некоторым небольшим случайным значением
  2. оптимизацияJ(x(1),,x(nm),θ(1),,θ(nu))J(x^{(1)},\cdots,x^{(n_m)},\theta^{(1)},\cdots,\theta^{(n_u)})
  3. Для данного пользователя параметры для этого пользователяθ\theta, то используйте свойство фильма, полученное путем обученияxx, мы можем предсказать, что пользователь, скорее всего, поставит оценку этому фильму:θTx\theta^Tx.

матричная факторизация низкого ранга:

Мы видим, что наш окончательный прогноз выглядит так:

Predict=[(x(1))T(θ(1))(x(1))T(θ(nu))(x(nm))T(θ(1))(x(nm))T(θ(nu))]Predict = \left[\begin{array}{ccccc} (x^{(1)})^T(\theta^{(1)}) & \ldots & (x^{(1)})^T(\theta^{(n_u)})\\ \vdots & \ddots & \vdots \\ (x^{(n_m)})^T(\theta^{(1)}) & \ldots & (x^{(n_m)})^T(\theta^{(n_u)})\end{array}\right]

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

X=[(x(1))T(x(nm))T],Θ=[(θ(1))T(θ(nu))T]X = \left[\begin{array}{ccc} - & (x^{(1)})^T & - \\ & \vdots & \\ - & (x^{(n_m)})^T & - \\ \end{array}\right], \qquad \Theta = \left[\begin{array}{ccc} - & (\theta^{(1)})^T & - \\ & \vdots & \\ - & (\theta^{(n_u)})^T & - \\ \end{array}\right]

Тогда есть:

Predict=XΘTPredict=X\Theta^T

Мы разделили его на две части. получить этот методXXиΘ\Theta, для получения параметров, требуемых рекомендательной системой, которые называютсяматричная факторизация низкого ранга. Этот метод может не только получать параметры напрямую через векторизацию во время программирования, но и экономить место в памяти за счет декомпозиции матрицы.

Найти похожие фильмы:

Нам часто нужны рекомендации и фильмыiiпохожие фильмыjj, который можно найти так:

smallestx(i)x(j)\mathop{\textrm{smallest}} ||x^{(i)}-x^{(j)}||

средняя нормализация:

В проблеме рекомендации фильмов, поскольку оценка всегда составляет от 1 до 5 (или другие диапазоны), нет масштабирования признаков, но можно выполнить среднюю нормализацию:

μi=averagey(i,:)\mu_i=\mathop{\textrm{average}} y^{(i,:)}
Yi=YiμiY_i = Y_i-\mu_i

пользователямjj, Киноii, предсказывать:

(Θ(j))T(x(i))+μi\left(\Theta^{(j)}\right)^T\left(x^{(i)}\right)+\mu_i

?Код:

  1. Функция стоимости:
function [J, grad] = cofiCostFunc(params, Y, R, num_users, num_movies, ...
                                  num_features, lambda)
%COFICOSTFUNC Collaborative filtering cost function
%   [J, grad] = COFICOSTFUNC(params, Y, R, num_users, num_movies, ...
%   num_features, lambda) returns the cost and gradient for the
%   collaborative filtering problem.
%

% Unfold the U and W matrices from params
X = reshape(params(1:num_movies*num_features), num_movies, num_features);
Theta = reshape(params(num_movies*num_features+1:end), ...
                num_users, num_features);

            
J = 0;
X_grad = zeros(size(X));
Theta_grad = zeros(size(Theta));

h = X * Theta';
er = (h - Y) .* R;

J = 1/2 * sum(sum(er.^2));
X_grad = er * Theta;
Theta_grad = er' * X; 

% Regularized

J += lambda/2 *(sum(sum(Theta.^2)) + sum(sum(X.^2)));
X_grad += lambda * X;
Theta_grad += lambda * Theta;
grad = [X_grad(:); Theta_grad(:)];

end
  1. средняя нормализация
function [Ynorm, Ymean] = normalizeRatings(Y, R)
%NORMALIZERATINGS Preprocess data by subtracting mean rating for every 
%movie (every row)
%   [Ynorm, Ymean] = NORMALIZERATINGS(Y, R) normalized Y so that each movie
%   has a rating of 0 on average, and returns the mean rating in Ymean.
%

[m, n] = size(Y);
Ymean = zeros(m, 1);
Ynorm = zeros(size(Y));
for i = 1:m
    idx = find(R(i, :) == 1);
    Ymean(i) = mean(Y(i, idx));
    Ynorm(i, idx) = Y(i, idx) - Ymean(i);
end

end
  1. сценарий драйвера
%  Normalize Ratings
[Ynorm, Ymean] = normalizeRatings(Y, R);

%  Useful Values
num_users = size(Y, 2);
num_movies = size(Y, 1);
num_features = 10;

% Set Initial Parameters (Theta, X)
X = randn(num_movies, num_features);
Theta = randn(num_users, num_features);

initial_parameters = [X(:); Theta(:)];

% Set options for fmincg
options = optimset('GradObj', 'on', 'MaxIter', 100);

% Set Regularization
lambda = 10;
theta = fmincg (@(t)(cofiCostFunc(t, Ynorm, R, num_users, num_movies, ...
                                num_features, lambda)), ...
                initial_parameters, options);

% Unfold the returned theta back into U and W
X = reshape(theta(1:num_movies*num_features), num_movies, num_features);
Theta = reshape(theta(num_movies*num_features+1:end), ...
                num_users, num_features);

fprintf('Recommender system learning completed.\n');

p = X * Theta';
my_predictions = p(:,1) + Ymean;

EOF