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

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

Для примера, учитывая два вектора данных x и y, можно подгонять линию, которая минимизирует перпендикулярные расстояния от каждой из точек (x (i), y (i)) до линии. В более общем случае с p наблюдаемыми переменными можно подгонять r-мерную гиперплоскость в p-мерном пространстве (r < p). Выбор r эквивалентен выбору количества компонентов для сохранения в PCA. Это может быть основано на ошибке предсказания, или это может быть просто прагматический выбор, чтобы уменьшить данные до управляемого количества размерностей.

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

Подбор плоскости для 3-D данных

Во-первых, мы генерируем некоторые трехмерные нормальные данные для примера. Две переменные довольно сильно коррелируют.

rng(5,'twister');
X = mvnrnd([0 0 0], [1 .2 .7; .2 1 0; .7 0 1],50);
plot3(X(:,1),X(:,2),X(:,3),'bo');
grid on;
maxlim = max(abs(X(:)))*1.1;
axis([-maxlim maxlim -maxlim maxlim -maxlim maxlim]);
axis square
view(-9,12);

Figure contains an axes. The axes contains an object of type line.

Затем мы подбираем плоскость к данным с помощью PCA. Коэффициенты для первых двух главных компонентов задают векторы, которые образуют базис для плоскости. Третий ПК ортогональен первым двум, и его коэффициенты определяют нормальный вектор плоскости.

[coeff,score,roots] = pca(X);
basis = coeff(:,1:2)
basis = 3×2

    0.6774   -0.0790
    0.2193    0.9707
    0.7022   -0.2269

normal = coeff(:,3)
normal = 3×1

    0.7314
   -0.0982
   -0.6749

Это все, что нужно для подгонки. Но давайте посмотрим поближе на результаты, и постройте график подгонки вместе с данными.

Поскольку первые два компонента объясняют как можно большую часть отклонения в данных две размерностей, плоскость является лучшим 2-D линейным приближением к данным. Эквивалентно, третий компонент объясняет наименьшее количество изменений в данных, и это термин ошибки в регрессии. Скрытые корни (или собственные значения) из PCA определяют количество объяснённого отклонения для каждого компонента.

pctExplained = roots' ./ sum(roots)
pctExplained = 1×3

    0.6226    0.2976    0.0798

Первые две координаты счетов основного компонента дают проекцию каждой точки на плоскость в системе координат плоскости. Чтобы получить координаты подобранных точек в терминах исходной системы координат, мы умножаем каждый вектор коэффициента PC на соответствующий счет и добавляем назад в среднем значении данных. Невязки являются просто исходными данными минус подобранные точки.

[n,p] = size(X);
meanX = mean(X,1);
Xfit = repmat(meanX,n,1) + score(:,1:2)*coeff(:,1:2)';
residuals = X - Xfit;

Уравнение установленной плоскости, удовлетворяемое каждой из установленных точек в Xfit, есть ([x1 x2 x3] - meanX)*normal = 0. Плоскость проходит через точку meanX, и его перпендикулярное расстояние до источник meanX*normal. Перпендикулярное расстояние от каждой точки в X к плоскости, т.е. норме невязок, является скалярным продуктом каждой центрированной точки с нормалью к плоскости. Установленная плоскость минимизирует сумму квадратичных невязок.

error = abs((X - repmat(meanX,n,1))*normal);
sse = sum(error.^2)
sse = 15.5142

Чтобы визуализировать подгонку, мы можем построить график плоскости, исходных данных и их проекции на плоскость.

[xgrid,ygrid] = meshgrid(linspace(min(X(:,1)),max(X(:,1)),5), ...
                         linspace(min(X(:,2)),max(X(:,2)),5));
zgrid = (1/normal(3)) .* (meanX*normal - (xgrid.*normal(1) + ygrid.*normal(2)));
h = mesh(xgrid,ygrid,zgrid,'EdgeColor',[0 0 0],'FaceAlpha',0);

hold on
above = (X-repmat(meanX,n,1))*normal < 0;
below = ~above;
nabove = sum(above);
X1 = [X(above,1) Xfit(above,1) nan*ones(nabove,1)];
X2 = [X(above,2) Xfit(above,2) nan*ones(nabove,1)];
X3 = [X(above,3) Xfit(above,3) nan*ones(nabove,1)];
plot3(X1',X2',X3','-', X(above,1),X(above,2),X(above,3),'o', 'Color',[0 .7 0]);
nbelow = sum(below);
X1 = [X(below,1) Xfit(below,1) nan*ones(nbelow,1)];
X2 = [X(below,2) Xfit(below,2) nan*ones(nbelow,1)];
X3 = [X(below,3) Xfit(below,3) nan*ones(nbelow,1)];
plot3(X1',X2',X3','-', X(below,1),X(below,2),X(below,3),'o', 'Color',[1 0 0]);

hold off
maxlim = max(abs(X(:)))*1.1;
axis([-maxlim maxlim -maxlim maxlim -maxlim maxlim]);
axis square
view(-9,12);

Figure contains an axes. The axes contains 53 objects of type surface, line.

Зеленые точки находятся над плоскостью, красные - ниже.

Подбор линии для 3-D данных

Подгонка прямой линии к данным еще проще, и из-за свойства вложенности PCA мы можем использовать уже вычисленные компоненты. Вектор направления, который определяет линию, задается коэффициентами для первого главного компонента. Второй и третий ПК ортогональны первому, и их коэффициенты определяют направления, которые перпендикулярны линии. Самое простое уравнение для описания линии meanX + t*dirVect, где t параметризирует положение вдоль линии.

dirVect = coeff(:,1)
dirVect = 3×1

    0.6774
    0.2193
    0.7022

Первая координата счетов основного компонента дает проекцию каждой точки на линию. Как и в случае с 2-D подгонкой, векторы коэффициентов PC, умноженные на счета, дают подобранные точки в исходной системе координат.

Xfit1 = repmat(meanX,n,1) + score(:,1)*coeff(:,1)';

Постройте график линии, исходных данных и их проекции на линию.

t = [min(score(:,1))-.2, max(score(:,1))+.2];
endpts = [meanX + t(1)*dirVect'; meanX + t(2)*dirVect'];
plot3(endpts(:,1),endpts(:,2),endpts(:,3),'k-');

X1 = [X(:,1) Xfit1(:,1) nan*ones(n,1)];
X2 = [X(:,2) Xfit1(:,2) nan*ones(n,1)];
X3 = [X(:,3) Xfit1(:,3) nan*ones(n,1)];
hold on
plot3(X1',X2',X3','b-', X(:,1),X(:,2),X(:,3),'bo');
hold off
maxlim = max(abs(X(:)))*1.1;
axis([-maxlim maxlim -maxlim maxlim -maxlim maxlim]);
axis square
view(-9,12);
grid on

Figure contains an axes. The axes contains 52 objects of type line.

Хотя кажется, что многие проекции на этом графике не перпендикулярны линии, это только потому, что мы строим 3-D данные в двух размерностях. В живом MATLAB® Окно рисунка можно в интерактивном режиме повернуть график к разным перспективам, чтобы убедиться, что проекции действительно перпендикулярны, и получить лучшее представление о том, как линия соответствует данным.

Для просмотра документации необходимо авторизоваться на сайте