Спектральное вложение для нелинейного понижения размерности.¶

Спектральное вложение (Spectral Embedding) - это подход к вычислению нелинейного вложения. Scikit-learn реализует собственные лапласианские карты, которые находят низкоразмерное представление данных с помощью спектрального разложения лапласиана графа. Сгенерированный граф можно рассматривать как дискретную аппроксимацию многообразия низкой размерности в пространстве высокой размерности. Минимизация функции стоимости на основе графика гарантирует, что точки, близкие друг к другу на многообразии, отображаются близко друг к другу в низкоразмерном пространстве с сохранением локальных расстояний.

Алгоритм Spectral Embedding (Laplacian Eigenmaps)¶

Входными данными алгоритма являются:

  • обучающая выборка $D = \{ x_1 ,x_2 ,...,x_p \} \subset \Re ^n$

  • функция близости $K (·, ·)$: $\Re ^n \times \Re ^n \to [0,\infty )$. Например, $\;K (x, x^*)=0$ для $\left| {x - x^* } \right| < \varepsilon$ и $0$ – иначе, где $\varepsilon > 0$.Однако, функция близости может зависеть и от объектов обучающей выборки.

Выходом алгоритма являются низкоразмерные описания точек обучающей выборки: $\;y_1 ,...,y_p \in \Re ^m ,\;\;m < n$

1.По выборке $D = \{ x_1 ,x_2 ,...,x_p \} \subset \Re ^n$ строим матрицу близости (affinity matrix) $M = (M{}_{ij})_{i,j = 1}^p $ размера $p \times p$ $M{}_{ij} = K(x_i ,x_j )$

2.Определим диагональную матрицу $Q$ : $Q_{ii} = \sum\nolimits_{j = 1}^p {M_{ij} }$ , и вычисляем матрицу:

$$\tilde M = (\tilde M_{ij} )_{i,j}^p = Q^{ - 0.5} \times M \times Q^{ - 0.5} {\rm \;\;\;\;(1)}$$

3.Находим $m + 1$ наименьшее собственное значение $\lambda _0 = 0 < \lambda _1 \le ... \le \lambda _m$ матрицы $\tilde M$ и соответствующие им собственные векторы $V_0 ,...,V_m \in \Re ^p$

4.Используя полученную матрицу собственных векторов, получаем вложение: $Y = (y_1 \left| {y{}_2} \right|...\left| {y_p } \right.)^T = (V_1 \left| {V{}_2} \right|...\left| {V_m } \right.)$ , где $y_1 ,...,y_p \in \Re ^m$

Этим алгоритмом решается задача минимизации:

$$\sum\limits_{i,j = 1}^p {K(x_i } ,x_j ) \cdot \left| {y{}_i - y_j } \right|^2 {\rm \;\;\;\;(2)}$$

При ограничениях $\sum\nolimits_{i = 1}^p {y_i } = 0\;\;$ и $\;\;\sum\nolimits_{i = 1}^p {y_i^2 } = 1$

Пример реализации алгоритма $LE$ на $python$ и $R$¶

Для рачетов использовались данный о Российских регионах. В $python$ реализации исходным было $3D$ пространство, регионы размечены на три класса.Для R реализаци исходное пространство $4D$, а регионы размечены на четыре класса.

В sklearn.manifold.SpectralEmbedding мы задаем следующие параметры n.components = 2 количество координат для коллектора (размерность выходного редуцируемого пространства) n.neighbors=5 число ближайших соседей для построения графа ближайших_соседей,random.state=0 -начальное значение генератор случайных чисел для воспроизводимости результатов остальные параметры принимаются по умолчанию

Код $python$ :

In [1]:
import warnings
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import scipy.stats as st
import matplotlib.pyplot as plt
from pandas import Series, DataFrame
import pandas as pd
#import umap
#import umap.plot
#from sklearn.manifold import Isomap
#from sklearn.manifold import LocallyLinearEmbedding
from sklearn.manifold import SpectralEmbedding

warnings.simplefilter('ignore')
result =pd.read_table('dan04.txt',sep='\s+')
print(result)

X =DataFrame(result, columns=['P10','P11','P14'])
X=np.array (X)

SUMX=X[:,0] +X[:,1] + X[:,2]
X[:,0] =X[:,0] /SUMX
X[:,1] =X[:,1] /SUMX
X[:,2] =X[:,2] /SUMX



YT=result['P18']
y=np.array(YT)

XX1=result.query("P18 in [0]")
XX2=result.query("P18 in [1]")
XX3=result.query("P18 in [2]")

XX1 =DataFrame(XX1, columns=['P10','P11','P14'])
XX1=np.array (XX1)
XX2 =DataFrame(XX2, columns=['P10','P11','P14'])
XX2=np.array (XX2)
XX3 =DataFrame(XX3, columns=['P10','P11','P14'])
XX3=np.array (XX3)

SUMX1=XX1[:,0] +XX1[:,1] + XX1[:,2]
XX1[:,0] =XX1[:,0] /SUMX1
XX1[:,1] =XX1[:,1] /SUMX1
XX1[:,2] =XX1[:,2] /SUMX1

SUMX2=XX2[:,0] +XX2[:,1] + XX2[:,2]
XX2[:,0] =XX2[:,0] /SUMX2
XX2[:,1] =XX2[:,1] /SUMX2
XX2[:,2] =XX2[:,2] /SUMX2

SUMX3=XX3[:,0] +XX3[:,1] + XX3[:,2]
XX3[:,0] =XX3[:,0] /SUMX3
XX3[:,1] =XX3[:,1] /SUMX3
XX3[:,2] =XX3[:,2] /SUMX3

# Преобразование данных, уменьшающее размерность до 2
#результат имеет два измерения
mod_LE  = SpectralEmbedding(n_components=2, n_neighbors = 5,
 random_state=0 )
X_LE = mod_LE.fit_transform(X)
X_LE.shape



XL =DataFrame(X_LE, columns=['1','2'])
XL = XL.join(YT)

XL1=XL.query("P18 in [0]")
XL2=XL.query("P18 in [1]")
XL3=XL.query("P18 in [2]")

XL1 =DataFrame(XL1, columns=['1','2'])
XL1=np.array (XL1)
XL2 =DataFrame(XL2, columns=['1','2'])
XL2=np.array (XL2)
XL3 =DataFrame(XL3, columns=['1','2'])
XL3=np.array (XL3)

#построение исходного графика 3 D
fig = plt.figure(1, figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

xs1 = XX1[:,0] 
ys1 = XX1[:,1] 
zs1 = XX1[:,2] 

xs2 = XX2[:,0] 
ys2 = XX2[:,1] 
zs2 = XX2[:,2] 

xs3 = XX3[:,0] 
ys3 = XX3[:,1] 
zs3 = XX3[:,2] 

ax.scatter(xs1, ys1, zs1,c='g', cmap=plt.cm.nipy_spectral, edgecolor='k',s=80,label='A')
ax.scatter(xs2, ys2, zs2,c='r', cmap=plt.cm.nipy_spectral, edgecolor='k',s=80,label='P')
ax.scatter(xs3, ys3, zs3,c='b', cmap=plt.cm.nipy_spectral, edgecolor='k',s=80,label='D')
ax.set_title("Исходное пространство предикторов",fontsize=16, fontweight='bold')
ax.set_xlabel('P10',fontsize=14, fontweight='bold')
ax.set_ylabel('P11',fontsize=14, fontweight='bold')
ax.set_zlabel('P14',fontsize=14, fontweight='bold')
ax.legend(loc="best")

y = np.choose(y, [1, 2, 0]).astype(np.float)
fig = plt.figure(2,figsize=(10, 8))
plt.clf()
plt.cla()
plt.scatter(XL1[:, 0], XL1[:, 1], c='g', cmap=plt.cm.nipy_spectral, edgecolor='k',s=100,label='A')
plt.scatter(XL2[:, 0], XL2[:, 1], c='r', cmap=plt.cm.nipy_spectral, edgecolor='k',s=100,label='P')
plt.scatter(XL3[:, 0], XL3[:, 1], c='b', cmap=plt.cm.nipy_spectral, edgecolor='k',s=100,label='D')
plt.title("Снижение размерности методом LE",fontsize=16, fontweight='bold')
plt.xlabel("LE1",fontsize=14, fontweight='bold')
plt.ylabel("LE2",fontsize=14, fontweight='bold')
plt.legend(loc='best')

plt.show()
          P10      P11     P14        P16  P18
0    148863.0   710829  257038   336148.5    0
1       262.0   218544   85146   253157.2    0
2      5005.0   448428   29651   225731.2    1
3      7726.0   448223  219151   552288.4    0
4       972.0   152792   16085   164827.4    0
..        ...      ...     ...        ...  ...
76  1016799.0    60300   11147   148497.4    2
77    10330.0     6632    5772    24075.7    2
78    67502.0     1055    1334     9573.8    2
79  1808823.0  6413663    7308  4798454.0    2
80    24035.0  2615910       0  1412406.0    1

[81 rows x 5 columns]

В в функции llle (LE) R пакета 'Rdimtools' мы задаем следующие параметры ndim =2 целочисленное целевое измерение., K= 6 размер ближайшего окружения для каждой точки данных,P=3 размер искусственного соседства,bandwidth = (0.1,0.5,0.9) параметр масштаба для гауссова ядра. Он должен быть в (0, 1), остальные параметры по умолчанию.

Код $R$ :

In [2]:
options(warn=-1)
library(gmodels)
library(lattice)
library(vegan)
library(grDevices)
library(reshape2)
library(ggplot2)
library(ggthemes)
library(psych)

load("xRegion.RData")

#ФОРМИРОВАНИЕ data.frame ОСНОВНЫЕ СОЦИАЛЬНО-ЭКОНОМИЧЕСКИЕ ПОКАЗАТЕЛИ РЕГИОНОВ РФ 
xreg <-data.frame(P1=x$Pok_001,P2=x$Pok_002,P3=x$Pok_003,P4=x$Pok_004,
P5=x$Pok_005,P6=x$Pok_006,P7=x$Pok_007,P8=x$Pok_008,P9=x$Pok_009,P10=x$Pok_010,
P11=x$Pok_011,P12=x$Pok_012,P13=x$Pok_013,P14=x$Pok_014,P15=x$Pok_015,P16=x$Pok_016,
P17=x$Pok_017,P18=x$Pok_018)
#xreg
#Формирование фактора тип экономики региона
xreg_f <- as.factor(x$Pok_018)

#выбор исследуемого подмножества показателей регионов
w=c(10,11,14,16)
reg.ekon <-xreg[,w]
valreg <-rowSums(reg.ekon)
xreg_nor <-reg.ekon/valreg
Y <- xreg_nor
X=Y
(X <- as.matrix(X))

#Метод le =====================================================

library(Rdimtools)
label=xreg_f

# see the effect bandwidth
out1 = do.llle(X, bandwidth=0.1,K=6,P=3)
out2 = do.llle(X, bandwidth=0.5,K=6,P=3)
out3 = do.llle(X, bandwidth=0.9,K=6,P=3)
# visualize the results

opar <- par(no.readonly=TRUE)
par(mfrow=c(1,3))
plot(out1$Y, col=label, main="bandwidth=0.1")
plot(out2$Y, col=label, main="bandwidth=0.5")
plot(out3$Y, col=label, main="bandwidth=0.9")
par(opar)

#График регионов по классам в двухмерном пространстве LE  

yx.le <-data.frame( le1=out2$Y[,1],le2=out2$Y[,2],Econ=xreg_f)

x11()
g4 <-ggplot(data= yx.le, aes(x=le1,y=le2,colour = Econ),
colors = "Accent")
g4 <-g4 +geom_point(size=6)
g4 <-g4 +labs(title ="Регионы в пространсте двух компонент LE",
x="le1", y="le2",colour = "Классы")
#g4 <-g4 + theme_stata() + scale_colour_stata()
g4 <-g4 + theme_fivethirtyeight() + scale_colour_manual( values = c('darkgoldenrod4', 
'blue','red','green'))
g4
A matrix: 81 × 4 of type dbl
P10P11P14P16
0.10246073570.489255640.1769163770.2313672
0.00047028480.392282160.1528353870.4544122
0.00706107880.632644450.0418317780.3184627
0.00629466600.365184320.1785506530.4499704
0.00290429800.456536520.0480613510.4924978
0.00366124060.772333960.0407691880.1832356
0.00157895280.534796420.0627210440.4009036
0.14126268710.301450910.2271110910.3301753
0.00618608750.664027200.1046547060.2251320
0.00251025700.512203510.0213566850.4639295
0.00072407360.361390770.2254833970.4124018
0.00299636420.546627590.1024508060.3479252
0.00442192850.516921220.0596182620.4190386
0.00040736960.331987930.2593070720.4082976
0.00169614520.539069920.0680678810.3911661
0.00577993030.660654590.0617963140.2717692
0.00236754880.589796320.0515115730.3563246
0.25170750320.367050180.0135761180.3676662
0.52722183550.255860730.0133736910.2035437
0.42449796550.272680700.0121345870.2906867
0.00087764250.761856340.0321747240.2050913
0.02303555290.720789800.0434247920.2127499
0.00985634730.681089950.0570091830.2520445
0.21240163590.409169600.0040226080.3744062
0.00342764700.585400200.0756002750.3355719
0.00769223220.406969740.1450058410.4403322
0.01961437210.303661470.1265944990.5501297
0.00000000000.019048750.5439954450.4369558
0.03522998030.229286580.1074671280.6280163
0.01856239090.362458100.1352341140.4837454
............
0.1670426810.498415400.0403679410.29417397
0.0453231460.430000460.1393094110.38536698
0.0162846350.524035950.0772571470.38242226
0.0122672810.401675390.1504321910.43562514
0.0234694050.603763300.0260519040.34671539
0.6892816440.202862970.0082208540.09963453
0.0366339550.674769500.0540155210.23458102
0.0611765560.081045280.2662818860.59149628
0.4861468980.008781090.1041016840.40097033
0.2811066290.347925780.0524804250.31848716
0.0061866050.397590680.1623629750.43385973
0.2910036680.469427500.0303074280.20926141
0.3948787320.335988880.0415553410.22757704
0.5054732230.299548570.0215964190.17338179
0.0751834810.442510360.0665017340.41580443
0.0027496240.691739700.0676952740.23781540
0.3658525720.316074200.0516404430.26643279
0.0975016720.228637830.0565129090.61734759
0.7338742770.033916190.0235210030.20868853
0.3387092490.074328560.0715663900.51539580
0.0977588340.604920830.0374761880.25984414
0.0320091340.334732930.0567088280.57654911
0.1297545700.385708730.0242854860.46025121
0.1923883050.109004800.1523176670.54628923
0.7596875560.027435510.0165573790.19631956
0.8221584200.048757080.0090131870.12007131
0.2206807560.141680040.1233077760.51433143
0.8494578730.013276320.0167873070.12047850
0.1388385450.492288990.0005609350.36831153
0.0059311250.645528980.0000000000.34853990
In [ ]: