Tarea 3
Alejandro Rendón de Jesús - A01664589
In [196… import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import itertools as it
Importación de datos
In [224… data = pd.read_csv('Banknotes.csv')
n, X, cols = len(data), data.values, list(data.columns)
data
Out[224… x1 x2 x3 x4 x5 x6
0 214.8 131.0 131.1 9.0 9.7 141.0
1 214.6 129.7 129.7 8.1 9.5 141.7
2 214.8 129.7 129.7 8.7 9.6 142.2
3 214.8 129.7 129.6 7.5 10.4 142.0
4 215.0 129.6 129.7 10.4 7.7 141.8
... ... ... ... ... ... ...
195 215.0 130.4 130.3 9.9 12.1 139.6
196 215.1 130.3 129.9 10.3 11.5 139.7
197 214.8 130.3 130.4 10.6 11.1 140.0
198 214.7 130.7 130.8 11.2 11.2 139.4
199 214.3 129.9 129.9 10.2 11.5 139.6
200 rows × 6 columns
1.- En cada pregunta añade una interpretación de los
resultados, usando la base de datos de los billetes del banco
Suizo.
a) Calcula la media y la varianza
1 T
X̄ = n 1n X
In [198… unos_vec = np.ones(n)
X_bar = (unos_vec @ X) / n
X_bar
Out[198… array([214.896 , 130.1215, 129.9565, 9.4175, 10.6505, 140.4835])
n (X X (I − n 1n 1n ) X
1 1 1 1
S= T
− n X 1n 1n X)
T T
= nX
T T
1
H = In − 1n 1Tn
n
In [199… H = np.identity(n) - (np.outer(unos_vec, unos_vec))/n
S = (X.T @ H @ X)/n
pd.DataFrame(S)
Out[199… 0 1 2 3 4 5
0 0.141084 0.031286 0.022976 -0.102730 -0.018448 0.083884
1 0.031286 0.129688 0.107885 0.214724 0.104514 -0.208295
2 0.022976 0.107885 0.162458 0.282711 0.129347 -0.239268
3 -0.102730 0.214724 0.282711 2.076444 0.163716 -1.031811
4 -0.018448 0.104514 0.129347 0.163716 0.641500 -0.546867
5 0.083884 -0.208295 -0.239268 -1.031811 -0.546867 1.321078
b) Calcula los valores y vectores propios para diagonalizar la matriz de
varianza covarianza ΓΛΓT .
In [200… eigvals_S, Gamma_S = np.linalg.eig(S)
Eigenvalores (λi ):
In [201… eigvals_S
Out[201… array([2.98530335, 0.93094242, 0.24219664, 0.19368545, 0.08478579,
0.0353371 ])
Matriz Γ :
In [202… pd.DataFrame(Gamma_S)
Out[202… 0 1 2 3 4 5
0 -0.043774 -0.010710 -0.326316 -0.561692 0.752573 0.098098
1 0.112162 -0.071447 -0.258961 -0.455459 -0.346801 -0.766512
2 0.139191 -0.066282 -0.344733 -0.415330 -0.534652 0.631697
3 0.768305 0.563072 -0.218022 0.186108 0.099968 -0.022217
4 0.201766 -0.659290 -0.556686 0.450699 0.101902 -0.034859
5 -0.578902 0.488543 -0.591763 0.258448 -0.084459 -0.045679
c) Calcula los valores muestrales de los componentes principales, usa la
formula
Y = (X − 1n x̄T )Γs
Realiza scatter plots de Yi vs Yj (i ≠ j), distinguiendo los billetes genuinos
de los falsos.
In [203… Y = (X - np.outer(np.ones(n), X_bar)) @ Gamma_S
data_y = pd.DataFrame(Y, columns = [i.replace('x', 'y') for i in cols])
data_y
Out[203… y1 y2 y3 y4 y5 y6
0 -0.549648 0.506373 -0.275865 -1.193728 -1.170503 0.058363
1 -2.018629 0.661264 0.501997 0.015445 -0.291137 0.145824
2 -1.835675 1.175307 -0.045629 0.189065 -0.112681 0.125788
3 -2.494367 -0.118892 -0.076525 0.316138 -0.080764 0.070528
4 -0.701323 3.194767 0.838774 -0.521050 0.082628 0.268793
... ... ... ... ... ... ...
195 1.249123 -1.159365 -0.613762 0.186819 0.068592 -0.007173
196 1.306226 -0.457122 -0.294979 0.172196 0.362790 -0.165930
197 1.365068 0.092151 -0.389711 0.086127 -0.166416 0.114063
198 2.298487 0.016919 -0.429981 -0.204354 -0.473408 0.060919
199 1.277440 -0.525137 0.150638 0.759278 -0.102099 0.068986
200 rows × 6 columns
In [204… combs_y = list(it.combinations([i.replace('x', 'y') for i in cols], 2))
data_y = pd.DataFrame(Y, columns = [i.replace('x', 'y') for i in cols])
fig = plt.figure(figsize = (15,15))
plt.suptitle('Scatter de variables\n(y)', fontsize = 25, y = 1)
for i, (yi, yj) in enumerate(combs_y, start = 1):
ax = fig.add_subplot(5, 3, i)
ax.grid(True)
ax.scatter(data_y[yi][:100], data_y[yj][:100], color = 'b', label = 'Reales')
ax.scatter(data_y[yi][100:], data_y[yj][100:], color = 'g', label = 'Falsos')
ax.set_xlabel(yi); ax.set_ylabel(yj)
ax.set_title(f'{yi} vs {yj}')
ax.legend()
plt.tight_layout()
d) Calcula los aportes porcentuales de cada componente principal y sus
acumulados. En un problema de reducción de dimensionalidad cuantos (y
cuales) componentes principales escogerias?
In [205… Psi_sum = eigvals_S / sum(eigvals_S)
sum_cum = np.cumsum(Psi_sum)
arg_red_var = np.argmax(sum_cum > 0.90) + 1
In [206… plt.figure(figsize=(15,5))
plt.subplot(1, 2, 1)
plt.plot(range(1, len(Psi_sum)+1), Psi_sum, marker = 'o', color = 'rebeccapurple')
plt.xlabel('$\lambda \' s$'); plt.ylabel('Aporte porcentual')
plt.title('Aportes porcentuales')
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(range(1, len(sum_cum)+1), sum_cum, marker = 'o', color = 'rebeccapurple')
plt.xlabel('$\lambda \' s$'); plt.ylabel('Acumulado')
plt.title('Acumulados')
plt.grid(True)
plt.suptitle('Aportes porcentuales y acumulados', fontsize = 20)
plt.tight_layout()
Para obtener información significativa de los datos, los aportes porcentuales de la varianza
deben ser bastantes grandes. En este inciso y para los posteriores consideraremos un umbral
del 90%.
En las gráficas de arriba y en el cálculo proveído por arg_red_var, vemos que dicho umbral se
supera considerando las primeras tres componentes principales y1 , y2 , y3 . A continuación se
muestra el desarrollo de las componentes.
In [207… pd.DataFrame(Y[:, :arg_red_var], columns = ['y1', 'y2', 'y3'])
Out[207… y1 y2 y3
0 -0.549648 0.506373 -0.275865
1 -2.018629 0.661264 0.501997
2 -1.835675 1.175307 -0.045629
3 -2.494367 -0.118892 -0.076525
4 -0.701323 3.194767 0.838774
... ... ... ...
195 1.249123 -1.159365 -0.613762
196 1.306226 -0.457122 -0.294979
197 1.365068 0.092151 -0.389711
198 2.298487 0.016919 -0.429981
199 1.277440 -0.525137 0.150638
200 rows × 3 columns
e) Demuestra que para el esquema PCA Cov(X, Y ) = ΓΛ, y por ende la
correlación entre Xi y Yj está dada por
1/2
ρXi Yj = γij ( )
λi
σii
(ρXi Yj )2 representa la porción de la varianza de Xi explicada por Yj .
Demostración :
Y = ΓT (X − μ)
E[X] = μ, E[Y ] = 0
Cov(X, Y ) = E [(X − E[X])(Y − E[Y ])T ] = E [(X − μ)Y T ] =
= E [(X − μ)(ΓT (X − μ))T ] = E [(X − μ)(X − μ)T Γ] =
= E [(X − μ)(X − μ)T ] Γ = V ar(X)Γ = (ΓΛΓT )Γ
= ΓΛ
Por lo que podemos representar cada una de los covarianzas de la siguiente:
γij λj
ρ X i Yj =
√σiiX √σjj
Y
donde σiiX y σjj
Y
son las varianzas i y j de las matrices de covarianza de X y Y
respectivamente. Pero σjj
Y = λ , por lo que:
j
1/2
γij √λj
= γij ( )
γij λj λj
ρ X i Yj = =
√σiiX √λj √σiiX σiiX
⎛ γ11 λ1 γ12 λ2 ⋯ γ1p λp ⎞
⎜ γ21 λ1 γ2p λp ⎟
⎜ ⎟
γ22 λ2 ⋯
Cov(X, Y ) = ⎜ ⎟
⎜ ⎟
⎜ ⋮ ⋮ ⋱ ⋮ ⎟
⎝γ λ γp2 λ2 ⋯ γpp λp ⎠
p1 1
En forma matricial se representa de la siguiente forma, donde
−1/2
DX = diag(1/√σ11 , 1/√σ22 , … , 1/√σpp ) y
−1/2
DY = diag(1/√λ1 , 1/√λ2 , … , 1/√λp ):
−1/2 −1/2
DX Cov(X, Y )DY
Covarianza:
In [208… CovXY = Gamma_S @ np.diag(eigvals_S)
pd.DataFrame(CovXY)
Out[208… 0 1 2 3 4 5
0 -0.130679 -0.009970 -0.079033 -0.108792 0.063807 0.003467
1 0.334836 -0.066513 -0.062720 -0.088216 -0.029404 -0.027086
2 0.415526 -0.061705 -0.083493 -0.080443 -0.045331 0.022322
3 2.293623 0.524188 -0.052804 0.036046 0.008476 -0.000785
4 0.602333 -0.613761 -0.134827 0.087294 0.008640 -0.001232
5 -1.728198 0.454805 -0.143323 0.050058 -0.007161 -0.001614
Correlación:
In [209… D_x, D_y = np.diag(1/np.sqrt(np.diag(S))), np.diag(1/np.sqrt(eigvals_S))
R = D_x @ CovXY @ D_y
pd.DataFrame(R)
Out[209… 0 1 2 3 4 5
0 -0.201361 -0.027510 -0.427547 -0.658124 0.583406 0.049095
1 0.538132 -0.191424 -0.353891 -0.556606 -0.280409 -0.400115
2 0.596670 -0.158667 -0.420917 -0.453494 -0.386244 0.294614
3 0.921229 0.377021 -0.074460 0.056840 0.020200 -0.002898
4 0.435255 -0.794218 -0.342055 0.247649 0.037047 -0.008181
5 -0.870232 0.410109 -0.253377 0.098960 -0.021397 -0.007471
f) Usando los datos, calcula las correlaciones correspondientes y grafica
rXi Y1 vs rXi Y2 vs rXi Y3 , dentro del círculo unitario.
In [210… combs_r = [[0,1], [0,2], [1,2]]
t = np.arange(0, 2*np.pi, 0.01)
colors = ['orange', 'green', 'red']
plt.figure(figsize=(14,5))
for idx, (i, j) in enumerate(combs_r, start = 1):
plt.subplot(1,3, idx)
plt.scatter(R[:, i], R[:, j], color = colors[idx-1])
plt.plot(np.cos(t), np.sin(t), color = 'black', linestyle = '--')
plt.title(f'$X_i Y_{i+1} \ vs \ X_i Y_{j+1}$')
plt.grid(True)
plt.xlabel(f'$X_i Y_{i+1}$'); plt.ylabel(f'$X_i Y_{j+1}$')
plt.suptitle('Correlaciones en el circulo unitario', fontsize = 18)
plt.tight_layout()
En estos gráficos, podemos observar que algunos puntos están más cercanos al contorno
del círculo que otros; entre más lo estén, implica que la correlación de esa componente con
la columna de los datos Xi es más estrecha, mientras que por el otro lado, los que se hallen
más lejanos a la circunferencia, tendiendo más hacia el centro del círculo, mantienen una
correlación baja y no tan significativa.
2.- Ahora cambia las caracteristicas X1, X2, X3 y X6 a
centímetros y realiza los items (1)(a − d). Revisa bien las
diferencias con el punto anterior y concluye por qué se dan.
In [244… X[:, [0,1,2,5]] = X[:, [0,1,2,5]] / 10
pd.DataFrame(X, columns = data.columns)
Out[244… x1 x2 x3 x4 x5 x6
0 21.48 13.10 13.11 9.0 9.7 14.10
1 21.46 12.97 12.97 8.1 9.5 14.17
2 21.48 12.97 12.97 8.7 9.6 14.22
3 21.48 12.97 12.96 7.5 10.4 14.20
4 21.50 12.96 12.97 10.4 7.7 14.18
... ... ... ... ... ... ...
195 21.50 13.04 13.03 9.9 12.1 13.96
196 21.51 13.03 12.99 10.3 11.5 13.97
197 21.48 13.03 13.04 10.6 11.1 14.00
198 21.47 13.07 13.08 11.2 11.2 13.94
199 21.43 12.99 12.99 10.2 11.5 13.96
200 rows × 6 columns
a)
In [245… unos_vec = np.ones(n)
X_bar = (unos_vec @ X) / n
X_bar
Out[245… array([21.4896 , 13.01215, 12.99565, 9.4175 , 10.6505 , 14.04835])
In [246… H = np.identity(n) - (np.outer(unos_vec, unos_vec))/n
S = (X.T @ H @ X)/n
pd.DataFrame(S)
Out[246… 0 1 2 3 4 5
0 0.001411 0.000313 0.000230 -0.010273 -0.001845 0.000839
1 0.000313 0.001297 0.001079 0.021472 0.010451 -0.002083
2 0.000230 0.001079 0.001625 0.028271 0.012935 -0.002393
3 -0.010273 0.021472 0.028271 2.076444 0.163716 -0.103181
4 -0.001845 0.010451 0.012935 0.163716 0.641500 -0.054687
5 0.000839 -0.002083 -0.002393 -0.103181 -0.054687 0.013211
b)
In [247… eigvals_S, Gamma_S = np.linalg.eig(S)
In [248… eigvals_S
Out[248… array([2.10125862e+00, 6.26260639e-01, 4.66366188e-03, 2.08876626e-03,
8.60987547e-04, 3.53901192e-04])
In [249… pd.DataFrame(Gamma_S)
Out[249… 0 1 2 3 4 5
0 0.004970 0.001078 -0.054184 -0.632468 0.766186 -0.099902
1 -0.010766 -0.012793 0.100370 -0.535200 -0.334335 0.769043
2 -0.014120 -0.015491 0.062924 -0.556946 -0.537307 -0.629852
3 -0.992014 0.117213 -0.045325 0.006266 0.008503 0.002035
4 -0.113415 -0.990521 -0.076230 0.011764 0.006846 0.003047
5 0.052020 0.068736 -0.987505 -0.056379 -0.111178 0.043184
c)
In [250… Y = (X - np.outer(np.ones(n), X_bar)) @ Gamma_S
data_y = pd.DataFrame(Y, columns = [i.replace('x', 'y') for i in cols])
data_y
Out[250… y1 y2 y3 y4 y5 y6
0 0.522045 0.893198 0.056908 -0.121342 -0.113967 -0.005019
1 1.444458 0.994433 0.023047 0.026918 -0.027408 -0.014235
2 0.840609 0.969167 -0.062230 0.016385 -0.011857 -0.012549
3 1.939395 0.034874 -0.049703 0.024975 -0.008987 -0.007118
4 -0.632200 3.047819 0.042968 -0.000356 0.012705 -0.026295
... ... ... ... ... ... ...
195 -0.648370 -1.386155 -0.040725 -0.015558 0.004049 0.000326
196 -0.975884 -0.743511 -0.027054 0.000631 0.034728 0.016249
197 -1.227417 -0.310884 -0.035013 -0.012759 -0.018646 -0.011560
198 -1.838133 -0.344874 -0.003507 -0.041802 -0.048716 -0.006059
199 -0.877170 -0.755494 -0.012327 0.072574 -0.012932 -0.007156
200 rows × 6 columns
In [251… combs_y = list(it.combinations([i.replace('x', 'y') for i in cols], 2))
data_y = pd.DataFrame(Y, columns = [i.replace('x', 'y') for i in cols])
fig = plt.figure(figsize = (15,15))
plt.suptitle('Scatter de variables\n(y)', fontsize = 25, y = 1)
for i, (yi, yj) in enumerate(combs_y, start = 1):
ax = fig.add_subplot(5, 3, i)
ax.grid(True)
ax.scatter(data_y[yi][:100], data_y[yj][:100], color = 'b', label = 'Reales')
ax.scatter(data_y[yi][100:], data_y[yj][100:], color = 'g', label = 'Falsos')
ax.set_xlabel(yi); ax.set_ylabel(yj)
ax.set_title(f'{yi} vs {yj}')
ax.legend()
plt.tight_layout()
d)
In [252… Psi_sum = eigvals_S / sum(eigvals_S)
sum_cum = np.cumsum(Psi_sum)
arg_red_var = np.argmax(sum_cum > 0.90) + 1
In [253… plt.figure(figsize=(15,5))
plt.subplot(1, 2, 1)
plt.plot(range(1, len(Psi_sum)+1), Psi_sum, marker = 'o', color = 'rebeccapurple')
plt.xlabel('$\lambda \' s$'); plt.ylabel('Aporte porcentual')
plt.title('Aportes porcentuales')
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(range(1, len(sum_cum)+1), sum_cum, marker = 'o', color = 'rebeccapurple')
plt.xlabel('$\lambda \' s$'); plt.ylabel('Acumulado')
plt.title('Acumulados')
plt.grid(True)
plt.suptitle('Aportes porcentuales y acumulados', fontsize = 20)
plt.tight_layout()
In [255… pd.DataFrame(Y[:, :arg_red_var], columns = ['y1', 'y2'])
Out[255… y1 y2
0 0.522045 0.893198
1 1.444458 0.994433
2 0.840609 0.969167
3 1.939395 0.034874
4 -0.632200 3.047819
... ... ...
195 -0.648370 -1.386155
196 -0.975884 -0.743511
197 -1.227417 -0.310884
198 -1.838133 -0.344874
199 -0.877170 -0.755494
200 rows × 2 columns
Vemos que en este caso, el umbral del aporte porcentual de 90% se sobrepasa con apenas
y1 y y2 , además de que lo hace de manera muy eficiente, ya que el acumulado alcanza el
99% de varianza, mayor a la obtenida en la primera pregunta con tres componentes
principales y sirviéndose de una componente menos.
3.- PSA Normalizado.
a) Explica porque los datos estandarizados están dados por:
Xc = HXD−1/2
Donde D = diag(σ11 , σ22 , … , σpp )
1
Xc = HXD−1/2 = (In − 1n 1Tn )XD−1/2
n
1 1
1n 1Tn X)D−1/2 = (X − 1n ( 1Tn X))D−1/2 = (X − 1n X̄ )D−1/2
T
= (X −
n n
⎛ x11 − x̄1 x12 − x̄2 ⋯ x1p − x̄p ⎞
⎜ x21 − x̄1 x2p − x̄p ⎟
⎜ ⎟
x22 − x̄2 ⋯
=⎜ ⎟ diag(1/√σ11 , 1/√σ22 , … , 1/√σpp ) =
⎜ ⎟
⎜ ⋮ ⋮ ⋱ ⋮ ⎟
⎝ x − x̄ xn2 − x̄2 ⋯ xnp − x̄p ⎠
n1 1
⎛ ⎞
x11 −x̄1 x12 −x̄2 x1p −x̄p
⋯
⎜ ⎟
√σ11 √σ22 √σpp
⎜ ⎟
⎜ ⎟
x21 −x̄1 x22 −x̄2 x2p −x̄p
⎜ ⎟
⋯
=⎜ ⎟
√σ11 √σ22 √σpp
⎜ ⎟
⎜ ⎟
⎜ ⎟
⎜ ⎟
⋮ ⋮ ⋱ ⋮
⎝ ⎠
xn1 −x̄1 xn2 −x̄2 xnp −x̄p
⋯
√σ11 √σ22 √σpp
x−μ
Con esto, podemos ver que los datos siguen la siguiente transformación: z = , por lo
√σ
tanto están estandarizados.
In [225… X_c = H @ X @ D_x
pd.DataFrame(X_c)
Out[225… 0 1 2 3 4 5
0 -0.255583 2.439452 2.837043 -0.289732 -1.186735 0.449372
1 -0.788048 -1.170437 -0.636381 -0.914304 -1.436443 1.058395
2 -0.255583 -1.170437 -0.636381 -0.497923 -1.311589 1.493412
3 -0.255583 -1.170437 -0.884483 -1.330685 -0.312759 1.319405
4 0.276882 -1.448121 -0.636381 0.681824 -3.683811 1.145399
... ... ... ... ... ... ...
195 0.276882 0.773349 0.852229 0.334840 1.809756 -0.768674
196 0.543114 0.495666 -0.140177 0.612427 1.060633 -0.681671
197 -0.255583 0.495666 1.100331 0.820618 0.561218 -0.420661
198 -0.521816 1.606401 2.092738 1.236999 0.686072 -0.942681
199 -1.586746 -0.615070 -0.140177 0.543031 1.060633 -0.768674
200 rows × 6 columns
b) Nota que x̄c = 0 y Sc = R la matriz de correlaciones.
Para que los datos estén estandarizados, tenemos que verificar dos cosas:
Media de cada columna de X igual a 0.
Varianza de cada columna de X igual a 1.
X̄c = 0p
In [229… unos_vec = np.ones(n)
X_c_bar = (unos_vec @ X_c) / n
np.round(X_c_bar, decimals = 2)
Out[229… array([-0., -0., -0., -0., -0., 0.])
V ar(Xi ) = 1
In [227… H_c = np.identity(n) - (np.outer(unos_vec, unos_vec))/n
S_c = (X_c.T @ H_c @ X_c)/n
pd.DataFrame(S_c)
Out[227… 0 1 2 3 4 5
0 1.000000 0.231293 0.151763 -0.189801 -0.061321 0.194301
1 0.231293 1.000000 0.743263 0.413781 0.362350 -0.503229
2 0.151763 0.743263 1.000000 0.486758 0.400670 -0.516476
3 -0.189801 0.413781 0.486758 1.000000 0.141851 -0.622983
4 -0.061321 0.362350 0.400670 0.141851 1.000000 -0.594045
5 0.194301 -0.503229 -0.516476 -0.622983 -0.594045 1.000000
c) Realiza el mismo procedimiento que en el punto (1) pero con los
componentes principales normalizados (NPC) y concluye (Elabora!)
b)
In [231… eigvals_S_c, Gamma_S_c = np.linalg.eig(S_c)
In [232… eigvals_S_c
Out[232… array([2.9455582 , 1.27808378, 0.86903255, 0.44976868, 0.2686769 ,
0.18887988])
In [234… pd.DataFrame(Gamma_S_c)
Out[234… 0 1 2 3 4 5
0 0.006987 0.815495 0.017681 -0.574617 0.058796 -0.031057
1 -0.467758 0.341967 -0.103383 0.394923 -0.639496 0.297748
2 -0.486679 0.252459 -0.123475 0.430278 0.614097 -0.349153
3 -0.406758 -0.266229 -0.583538 -0.403674 0.215476 0.462354
4 -0.367891 -0.091487 0.787571 -0.110227 0.219849 0.418968
5 0.493458 0.273941 -0.113875 0.391931 0.340160 0.631798
c)
In [235… Y = (X_c - np.outer(np.ones(n), X_c_bar)) @ Gamma_S_c
data_y = pd.DataFrame(Y, columns = [i.replace('x', 'y') for i in cols])
data_y
Out[235… y1 y2 y3 y4 y5 y6
0 -1.747401 1.650828 -1.423761 2.754865 -0.003302 -0.603533
1 2.274318 -0.538793 -0.532648 0.659005 0.158569 -0.457688
2 2.277402 -0.107677 -0.717415 0.341694 0.455020 0.045443
3 2.283555 -0.087654 0.605634 0.392809 0.283623 0.055578
4 2.632128 0.039196 -3.196385 -0.425081 0.278199 -0.722072
... ... ... ... ... ... ...
195 -1.955869 0.240125 1.137169 -0.122909 0.253629 0.351502
196 -1.135519 0.130202 0.531243 -0.807947 -0.237860 0.476509
197 -1.516984 -0.146190 -0.180585 0.258068 0.500821 0.120112
198 -2.994277 0.001798 -0.507859 0.890275 0.323890 0.027611
199 -0.645550 -1.991881 0.658820 -0.028833 0.302675 0.124883
200 rows × 6 columns
In [236… combs_y = list(it.combinations([i.replace('x', 'y') for i in cols], 2))
data_y = pd.DataFrame(Y, columns = [i.replace('x', 'y') for i in cols])
fig = plt.figure(figsize = (15,15))
plt.suptitle('Scatter de variables\n(y)', fontsize = 25, y = 1)
for i, (yi, yj) in enumerate(combs_y, start = 1):
ax = fig.add_subplot(5, 3, i)
ax.grid(True)
ax.scatter(data_y[yi][:100], data_y[yj][:100], color = 'b', label = 'Reales')
ax.scatter(data_y[yi][100:], data_y[yj][100:], color = 'g', label = 'Falsos')
ax.set_xlabel(yi); ax.set_ylabel(yj)
ax.set_title(f'{yi} vs {yj}')
ax.legend()
plt.tight_layout()
d)
In [238… Psi_sum = eigvals_S_c / sum(eigvals_S_c)
sum_cum = np.cumsum(Psi_sum)
arg_red_var = np.argmax(sum_cum > 0.90) + 1
In [239… plt.figure(figsize=(15,5))
plt.subplot(1, 2, 1)
plt.plot(range(1, len(Psi_sum)+1), Psi_sum, marker = 'o', color = 'rebeccapurple')
plt.xlabel('$\lambda \' s$'); plt.ylabel('Aporte porcentual')
plt.title('Aportes porcentuales')
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(range(1, len(sum_cum)+1), sum_cum, marker = 'o', color = 'rebeccapurple')
plt.xlabel('$\lambda \' s$'); plt.ylabel('Acumulado')
plt.title('Acumulados')
plt.grid(True)
plt.suptitle('Aportes porcentuales y acumulados', fontsize = 20)
plt.tight_layout()
In [240… pd.DataFrame(Y[:, :arg_red_var], columns = ['y1', 'y2', 'y3', 'y4'])
Out[240… y1 y2 y3 y4
0 -1.747401 1.650828 -1.423761 2.754865
1 2.274318 -0.538793 -0.532648 0.659005
2 2.277402 -0.107677 -0.717415 0.341694
3 2.283555 -0.087654 0.605634 0.392809
4 2.632128 0.039196 -3.196385 -0.425081
... ... ... ... ...
195 -1.955869 0.240125 1.137169 -0.122909
196 -1.135519 0.130202 0.531243 -0.807947
197 -1.516984 -0.146190 -0.180585 0.258068
198 -2.994277 0.001798 -0.507859 0.890275
199 -0.645550 -1.991881 0.658820 -0.028833
200 rows × 4 columns
e)
In [241… CovXY = Gamma_S_c @ np.diag(eigvals_S_c)
pd.DataFrame(CovXY)
Out[241… 0 1 2 3 4 5
0 0.020581 1.042271 0.015365 -0.258445 0.015797 -0.005866
1 -1.377809 0.437063 -0.089843 0.177624 -0.171818 0.056239
2 -1.433540 0.322663 -0.107304 0.193526 0.164994 -0.065948
3 -1.198130 -0.340263 -0.507114 -0.181560 0.057893 0.087329
4 -1.083645 -0.116928 0.684425 -0.049577 0.059068 0.079135
5 1.453510 0.350119 -0.098961 0.176278 0.091393 0.119334
In [242… D_x, D_y = np.diag(1/np.sqrt(np.diag(S_c))), np.diag(1/np.sqrt(eigvals_S_c))
R = D_x @ CovXY @ D_y
pd.DataFrame(R)
Out[242… 0 1 2 3 4 5
0 0.011992 0.921936 0.016482 -0.385366 0.030476 -0.013497
1 -0.802796 0.386602 -0.096375 0.264854 -0.331477 0.129402
2 -0.835269 0.285410 -0.115105 0.288565 0.318311 -0.151743
3 -0.698104 -0.300978 -0.543986 -0.270723 0.111690 0.200940
4 -0.631398 -0.103428 0.734189 -0.073923 0.113957 0.182085
5 0.846904 0.309696 -0.106157 0.262847 0.176319 0.274582
f)
In [243… combs_r = [[0,1], [0,2], [1,2]]
t = np.arange(0, 2*np.pi, 0.01)
colors = ['orange', 'green', 'red']
plt.figure(figsize=(14,5))
for idx, (i, j) in enumerate(combs_r, start = 1):
plt.subplot(1,3, idx)
plt.scatter(R[:, i], R[:, j], color = colors[idx-1])
plt.plot(np.cos(t), np.sin(t), color = 'black', linestyle = '--')
plt.title(f'$X_i Y_{i+1} \ vs \ X_i Y_{j+1}$')
plt.grid(True)
plt.xlabel(f'$X_i Y_{i+1}$'); plt.ylabel(f'$X_i Y_{j+1}$')
plt.suptitle('Correlaciones en el circulo unitario', fontsize = 18)
plt.tight_layout()
Estandarizar los datos previo a aplicar un PCA es importante, ya que de no hacerlo, aquellas
variables que cuenten con una mayor magnitud representarán, por lógica, una mayor
porción de la varianza de los datos, aunque no sean tan relevantes a la hora de comprender
su estructura. Cuando estandarizamos, nos aseguramos que la media sea 0 y la varianza 1
para cada una de las variables, otorgándoles un peso equivalente en el análisis; de esta
forma nos aseguramos de obtener un estudio menos sesgado y completo, a pesar de que al
hacerlo el ummbral del 90% en los aportes porcentuales se supera con cuatro componentes,
que son más de las requeridas en los dos casos anteriores.