sqrt(sum( eigen (A) $ vectors [ , 1 ] ^2 ) ) # Calcula la norma del primer autovector
[1] 1
import numpy as np# Definir la matriz A de 4x4A = np.array([[1, 2, -1, 1], [0, 1, 3, 1], [0, 0, 2, 0], [0, 0, 1, -1]])# Mostrar la matriz Aprint("Matriz A:")
Matriz A:
print(A)
[[ 1 2 -1 1]
[ 0 1 3 1]
[ 0 0 2 0]
[ 0 0 1 -1]]
# Calcular los autovalores de Aeigenvalues_A = np.linalg.eigvals(A)print("\nAutovalores de A:")
Autovalores de A:
print(eigenvalues_A)
[ 1. 1. -1. 2.]
## Comparar los siguientes cálculos:# Traza de A (suma de los elementos de la diagonal principal)trace_A = np.trace(A)print("\nTraza de A:")
Traza de A:
print(trace_A)
3
print(sum(np.diag(A)))
3
# Suma de los autovalores de A#sum_eigenvalues_A = np.sum(eigenvalues_A)#print("Suma de los autovalores de A:")#print(sum_eigenvalues_A)
## Comparar los siguientes cálculos:# Determinante de Adet_A = np.linalg.det(A)print("\nDeterminante de A:")
Determinante de A:
print(det_A)
-2.0
# Producto de los autovalores de Aprod_eigenvalues_A = np.prod(eigenvalues_A)print("Producto de los autovalores de A:")
Producto de los autovalores de A:
print(prod_eigenvalues_A)
-2.0
# Transpuesta de AA_transpose = A.Tprint("\nTranspuesta de A:")
Transpuesta de A:
print(A_transpose)
[[ 1 0 0 0]
[ 2 1 0 0]
[-1 3 2 1]
[ 1 1 0 -1]]
# Observar que las trazas de una matriz y su transpuesta son igualestrace_A_transpose = np.trace(A_transpose)print("\nTraza de la transpuesta de A:")
Traza de la transpuesta de A:
print(trace_A_transpose)
3
print(np.trace(A))
3
# Observar que los determinantes de una matriz y su transpuesta son igualesdet_A_transpose = np.linalg.det(A_transpose)print("Determinante de la transpuesta de A:")
Determinante de la transpuesta de A:
print(det_A_transpose)
-2.0
print("Determinante de A:")
Determinante de A:
print(np.linalg.det(A))
-2.0
# Observar que los autovalores de una matriz y su transpuesta son los mismoseigenvalues_A_transpose = np.linalg.eigvals(A_transpose)print("\nAutovalores de la transpuesta de A:")
Autovalores de la transpuesta de A:
print(eigenvalues_A_transpose)
[ 2. -1. 1. 1.]
print("\nAutovalores de A:")
Autovalores de A:
print(np.linalg.eigvals(A))
[ 1. 1. -1. 2.]
# Calcular la inversa de AA_inverse = np.linalg.inv(A)print("\nInversa de A:")
# Verificar que A y su inversa son efectivamente inversas (debe dar la matriz identidad)identity_check = np.dot(A, A_inverse)print("\nVerificación de que A y su inversa son inversas (matriz identidad):")
Verificación de que A y su inversa son inversas (matriz identidad):
# Observar que los determinantes de una matriz y su inversa son inversosdet_A_inverse = np.linalg.det(A_inverse)print("\nDeterminante de la inversa de A:")
Determinante de la inversa de A:
print(det_A_inverse)
-0.5
print("\nDeterminante de A:")
Determinante de A:
print(np.linalg.det(A))
-2.0
# Observar que los autovalores de una matriz y su inversa son inversoseigenvalues_A_inverse = np.linalg.eigvals(A_inverse)print("\nAutovalores de la inversa de A:")
Autovalores de la inversa de A:
print(eigenvalues_A_inverse)
[ 1. 1. -1. 0.5]
print("Recíprocos de los autovalores de A:")
Recíprocos de los autovalores de A:
print((eigenvalues_A)**(-1))
[ 1. 1. -1. 0.5]
print("\nAutovalores de A:")
Autovalores de A:
print(np.linalg.eigvals(A))
[ 1. 1. -1. 2.]
# Calcular los autovalores y autovectores de Aeigenvalues_A, eigenvectors_A = np.linalg.eig(A)# Mostrar los autovectores de Aprint("Autovectores de A (columnas):")
# Extraer el primer autovector (primera columna de eigenvectors_A)first_eigenvector = eigenvectors_A[:, 0]print("\nPrimer autovector:")
Primer autovector:
print(first_eigenvector)
[1. 0. 0. 0.]
## Verificar que el primer autovector es un autovector asociado al primer autovalor# Multiplicar A por el primer autovectorA_times_first_eigenvector = np.dot(A, first_eigenvector)print("\nA multiplicado por el primer autovector:")
A multiplicado por el primer autovector:
print(A_times_first_eigenvector)
[1. 0. 0. 0.]
# Multiplicar el primer autovector por su autovalor correspondientelambda_1 = eigenvalues_A[0] # Primer autovalorlambda_times_first_eigenvector = lambda_1 * first_eigenvectorprint("Autovalor multiplicado por el primer autovector:")
Autovalor multiplicado por el primer autovector:
print(lambda_times_first_eigenvector)
[1. 0. 0. 0.]
## Calcular la norma del primer autovectornorm_first_eigenvector = np.sqrt(np.sum(first_eigenvector**2))print("\nNorma del primer autovector:")
Norma del primer autovector:
print(norm_first_eigenvector)
1.0
Supongamos que deseamos explorar en nuestra población los factores de riesgo de sufrir una enfermedad coronaria. De estudios anteriores sabemos que se consideran como factores de riesgo para la enfermedad coronaria: la hipertensión arterial, la edad, la obesidad, el tiempo de antigüedad en el diagnóstico de hipertensión, el pulso, y el stress.
Para la investigación se seleccionan al azar 20 pacientes hipertensos de la población objetivo sobre los cuales se miden las siguientes variables:
*\(X_1\): presión arterial media en\(\mathrm{mm} / \mathrm{Hg}\),
*\(X_2\): edad en años
*\(X_3\): peso en kg
*\(X_4\): superficie corporal en\(\mathrm{m}^2\),
*\(X_5\): tiempo transcurrido desde el diagnóstico de hipertensión en años,
X6: pulsaciones por minuto,
X7: medida asociada al stress.
# Cargar paquetes necesarioslibrary(ggplot2) # Paquete para confeccionar dibujoslibrary(devtools) # Colección de herramientas de desarrollo para paquetes
Warning: package 'devtools' was built under R version 4.4.3
Cargando paquete requerido: usethis
Warning: package 'usethis' was built under R version 4.4.3
# Instalar el paquete "ggbiplot" desde GitHub (si no está instalado)#if (!requireNamespace("ggbiplot", quietly = TRUE)) {# install_github("vqv/ggbiplot") # Instala el paquete desde GitHub#}
library(ggbiplot) # Paquete para visualización de componentes principales
Cargando paquete requerido: plyr
Cargando paquete requerido: scales
Cargando paquete requerido: grid
library(readxl) # Permite leer archivos xlsx
PCA EN R
# Importar la base de datos con la cual se va a trabajarnad <-read_excel("nadadores.xlsx") # Asegúrate de especificar la ruta correcta al archivoprint(nad)
# Realizar el análisis de componentes principales sin estandarizaciónnad.pca.cov <-prcomp(nadadores, center =TRUE, scale. =FALSE)
# Realizar el análisis de componentes principales con estandarizaciónnad.pca.cor <-prcomp(nadadores, center =TRUE, scale. =TRUE)
# Resumen de las varianzas explicadas por las componentes principalessummary(nad.pca.cor) # Con estandarización
Importance of components:
PC1 PC2 PC3 PC4
Standard deviation 1.7098 0.9573 0.34831 0.19690
Proportion of Variance 0.7309 0.2291 0.03033 0.00969
Cumulative Proportion 0.7309 0.9600 0.99031 1.00000
summary(nad.pca.cov) # Sin estandarización
Importance of components:
PC1 PC2 PC3 PC4
Standard deviation 3.5840 1.9858 0.7030 0.42241
Proportion of Variance 0.7356 0.2258 0.0283 0.01022
Cumulative Proportion 0.7356 0.9615 0.9898 1.00000
# Gráfico de sedimentación (scree plot) para el análisis sin estandarizaciónggscreeplot(nad.pca.cov, type =c('pev', 'cev')) +xlab('Número de componentes principales') +ylab('Proporción de la varianza explicada') +geom_line(colour ='royalblue') +geom_point(colour ='royalblue')
# Detalles adicionales sobre las componentes principalesprint("Varianza explicada por cada componente (con estandarización):")
[1] "Varianza explicada por cada componente (con estandarización):"
# Gráfico de sedimentación (scree plot) para el PCA con estandarizaciónggscreeplot(nad.pca.cor, type =c('pev', 'cev')) +xlab('Número de componentes principales') +ylab('Proporción de la varianza explicada') +geom_line(colour ='royalblue') +geom_point(colour ='royalblue') +ggtitle("Gráfico de sedimentación (Scree Plot)")
# Visualización del biplot usando ggbiplotggbiplot(nad.pca.cor, labels =rownames(nadadores), ellipse =TRUE, circle =TRUE) +ggtitle("Biplot de Componentes Principales (Estandarizado)") +theme_minimal()
library(factoextra)
Warning: package 'factoextra' was built under R version 4.4.3
Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
# Usar factoextra para gráficos avanzados# Varianza acumulada explicada por cada componentefviz_eig(nad.pca.cor, addlabels =TRUE, ylim =c(0, 60))+ggtitle("Varianza Explicada por Cada Componente")
library(factoextra)# Biplot con factoextrafviz_pca_biplot(nad.pca.cor, col.ind ="cos2", # Color de individuos basado en calidad de representacióngradient.cols =c("#00AFBB", "#E7B800", "#FC4E07"),col.var ="contrib", # Color de variables basado en contribuciónrepel =TRUE) +# Evitar superposición de etiquetasggtitle("Biplot Avanzado con Factoextra")
# Contribución de las variables a las componentes principalesfviz_contrib(nad.pca.cor, choice ="var", axes =1) +ggtitle("Contribución de Variables a la PC1")
# Contribución de las variables a las componentes principalesfviz_contrib(nad.pca.cor, choice ="var", axes =2) +ggtitle("Contribución de Variables a la PC2")
# Calidad de representación de los individuos en el espacio de las componentesfviz_pca_ind(nad.pca.cor, col.ind ="cos2", # Color basado en calidad de representacióngradient.cols =c("#00AFBB", "#E7B800", "#FC4E07"),repel =TRUE) +ggtitle("Calidad de Representación de Individuos")
library(ggplot2)library(gridExtra)# Combinar múltiples gráficos en una sola figuragrid.arrange(fviz_eig(nad.pca.cor, addlabels =TRUE),fviz_pca_biplot(nad.pca.cor, col.ind ="cos2", col.var ="contrib", repel =TRUE),fviz_contrib(nad.pca.cor, choice ="var", axes =1),ncol =2)
# Extraer la calidad de representación (cos²) de los individuoscos2_pca_cor <- nad.pca.cor$ind$cos2 # Para PCA estandarizadocos2_pca_cov <- nad.pca.cov$ind$cos2 # Para PCA no estandarizado
PCA CON FACTOMINER
# Instalar y cargar el paquete FactoMineR#if (!requireNamespace("FactoMineR", quietly = TRUE)) {# install.packages("FactoMineR")}library(FactoMineR)
Warning: package 'FactoMineR' was built under R version 4.4.3
# Realizar el PCA con FactoMineRpca_factomine <-PCA(nadadores, scale.unit =TRUE, graph =FALSE)# Resumen del PCAsummary(pca_factomine)
Warning: package 'psych' was built under R version 4.4.3
Adjuntando el paquete: 'psych'
The following objects are masked from 'package:scales':
alpha, rescale
The following objects are masked from 'package:ggplot2':
%+%, alpha
describe(acp$li)
vars n mean sd median trimmed mad min max range skew kurtosis
Axis1 1 14 0 1.77 -0.07 -0.03 1.69 -2.67 3.05 5.72 0.08 -1.19
Axis2 2 14 0 0.99 0.23 0.01 1.31 -1.46 1.29 2.75 -0.15 -1.71
se
Axis1 0.47
Axis2 0.27
# Gráfica de individuos sobre el primer plano de componentes# Primera formas.label(acp$li,xax=1,yax=2,clabel=0.7,grid=FALSE,boxes=FALSE)
# Segunda forma fviz_pca_ind(acp)
# Gráfica de individuos sobre los componentes 2 y 3. Para realizar este gráfico se tiene que cambiar el número de factores en la función dudi.pca# s.label(acp$li,xax=2,yax=3,clabel=0.7,grid=FALSE,boxes=FALSE)# Gráfica de individuos sobre el primer plano con biplot# Primera formas.label(acp$li,clabel=0.7,grid=FALSE,boxes=FALSE)s.corcircle(acp$co,grid=FALSE,add=TRUE,clabel=0.7)
# Segunda formafviz_pca_biplot(acp, repel =FALSE,col.var ="steelblue",col.ind ="black" )
#Grabar los datos y los resultados de los scores en un archivo CSVsalida.acp <-cbind(nadadores,acp$li[,c(1,2)])head(salida.acp)
import pandas as pdruta_archivo ="nadadores.xlsx"# Cargar el archivonadadores = pd.read_excel(ruta_archivo)# Mostrar el DataFrame originalprint("DataFrame original:")
# Eliminar la primera columna (por posición)nadadores = nadadores.iloc[:, 1:]# Mostrar el DataFrame modificadoprint("\nDataFrame después de eliminar la primera columna:")
# Entrenamiento modelo PCA con escalado de los datos# ==============================================================================pca_pipe = make_pipeline(StandardScaler(), PCA())pca_pipe.fit(nadadores)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
# Se extrae el modelo entrenado del pipelinemodelo_pca = pca_pipe.named_steps['pca']
# Se convierte el array a dataframe para añadir nombres a los ejes.pd.DataFrame( data = modelo_pca.components_, columns = nadadores.columns, index = ['PC1', 'PC2', 'PC3', 'PC4'])
#La influencia de las variables en cada componente analizarse visualmente con un gráfico de tipo heatmap.# Heatmap componentes# ==============================================================================fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(4, 2))componentes = modelo_pca.components_plt.imshow(componentes.T, cmap='viridis', aspect='auto')plt.yticks(range(len(nadadores.columns)), nadadores.columns)
([<matplotlib.axis.YTick object at 0x0000023C3E1137A0>, <matplotlib.axis.YTick object at 0x0000023C3E137020>, <matplotlib.axis.YTick object at 0x0000023C3E0E3110>, <matplotlib.axis.YTick object at 0x0000023C3E152E40>], [Text(0, 0, 'tr1'), Text(0, 1, 'tr2'), Text(0, 2, 'tr3'), Text(0, 3, 'tr4')])
([<matplotlib.axis.XTick object at 0x0000023C3E134B30>, <matplotlib.axis.XTick object at 0x0000023C3E136FF0>, <matplotlib.axis.XTick object at 0x0000023C3E153B60>, <matplotlib.axis.XTick object at 0x0000023C3E198620>], [Text(0, 0, '1'), Text(1, 0, '2'), Text(2, 0, '3'), Text(3, 0, '4')])
plt.grid(False)plt.colorbar();plt.show()
# Porcentaje de varianza explicada por cada componente# ==============================================================================print('----------------------------------------------------')
ax.set_title('Porcentaje de varianza explicada por cada componente')ax.set_xlabel('Componente principal')ax.set_ylabel('Por. varianza explicada');plt.show()
# Porcentaje de varianza explicada acumulada# ==============================================================================prop_varianza_acum = modelo_pca.explained_variance_ratio_.cumsum()print('------------------------------------------')
------------------------------------------
print('Porcentaje de varianza explicada acumulada')
ax.set_xticks(np.arange(modelo_pca.n_components_) +1)ax.set_title('Porcentaje de varianza explicada acumulada')ax.set_xlabel('Componente principal')ax.set_ylabel('Por. varianza acumulada');plt.show()
#Una vez entrenado el modelo, con el método transform() se puede reducir la dimensionalidad de nuevas observaciones proyectándolas en el espacio definido por las componentes.# Proyección de las observaciones de entrenamiento# ==============================================================================proyecciones = pca_pipe.transform(X=nadadores)proyecciones = pd.DataFrame( proyecciones, columns = ['PC1', 'PC2', 'PC3', 'PC4'], index = nadadores.index)proyecciones.head()
#La transformación es el resultado de multiplicar los vectores que definen cada componente con el valor de las variables. Puede calcularse de forma manual:proyecciones = np.dot(modelo_pca.components_, scale(nadadores).T)proyecciones = pd.DataFrame(proyecciones, index = ['PC1', 'PC2', 'PC3', 'PC4'])proyecciones = proyecciones.transpose().set_index(nadadores.index)proyecciones.head()
#Reconstrucción#Puede revertirse la transformación y reconstruir el valor inicial con el método inverse_transform(). Es importante tener en cuenta que, la reconstrucción, solo será completa si se han incluido todas las componentes# Recostruccion de las proyecciones# ==============================================================================recostruccion = pca_pipe.inverse_transform(X=proyecciones)recostruccion = pd.DataFrame( recostruccion, columns = nadadores.columns, index = nadadores.index)print('------------------')
from sklearn.preprocessing import StandardScaler# Seleccionar solo variables numéricasvariables_numericas = nadadores.select_dtypes(include=['float64', 'int64'])# Estandarizar los datosscaler = StandardScaler()datos_estandarizados = scaler.fit_transform(variables_numericas)
from sklearn.decomposition import PCAimport matplotlib.pyplot as plt# Aplicar PCApca = PCA(n_components=2) # Reducir a 2 componentes principalescomponentes_principales = pca.fit_transform(datos_estandarizados)# Convertir a DataFrame para mejor visualizaciónpca_df = pd.DataFrame(componentes_principales, columns=["PC1", "PC2"])print(pca_df.head())
# Varianza explicadavarianza_explicada = pca.explained_variance_ratio_print("Varianza explicada por cada componente:", varianza_explicada)
Varianza explicada por cada componente: [0.73087186 0.22910599]
# Gráfico de dispersión de los datos en PC1 y PC2plt.figure(figsize=(8, 6))plt.scatter(pca_df["PC1"], pca_df["PC2"], c='blue', edgecolor='k', s=100)plt.xlabel("Componente Principal 1")plt.ylabel("Componente Principal 2")plt.title("PCA - Proyección en las dos primeras componentes")plt.grid(True)plt.show()
# Convertir a DataFrame para mejor visualizaciónscores_df = pd.DataFrame(componentes_principales, columns=["PC1", "PC2"])print("Scores (coordenadas de los individuos en las componentes principales):")
Scores (coordenadas de los individuos en las componentes principales):
# Biplotplt.figure(figsize=(10, 8))plt.scatter(scores_df["PC1"], scores_df["PC2"], color="blue", alpha=0.7, label="Individuos")for i, feature inenumerate(variables_numericas.columns): plt.arrow(0, 0, pca.components_[0, i], pca.components_[1, i], color='red', head_width=0.05) plt.text(pca.components_[0, i] *1.1, pca.components_[1, i] *1.1, feature, color='red')plt.axhline(0, color='gray', linestyle='--', linewidth=0.8)plt.axvline(0, color='gray', linestyle='--', linewidth=0.8)plt.xlabel("Componente Principal 1")plt.ylabel("Componente Principal 2")plt.title("Biplot: Scores y Loadings")plt.legend()plt.grid(True)plt.show()
from sklearn.decomposition import PCAimport pandas as pd# Supongamos que ya tenemos los datos estandarizados en 'datos_estandarizados'pca = PCA(n_components=2)pca.fit(datos_estandarizados)
PCA(n_components=2)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
PCA(n_components=2)
# Obtener los loadingsloadings = pd.DataFrame(pca.components_, columns=nadadores.columns, index=["PC1", "PC2"])print("Loadings (contribución de cada variable a las componentes principales):")
Loadings (contribución de cada variable a las componentes principales):