Ejemplo cálculo directo de PCA con R

El set de datos USArrests del paquete básico de R contiene el porcentaje de asaltos (\(Assault\)), asesinatos (\(Murder\)) y secuestros (\(Rape\)) por cada 100,000 habitantes para cada uno de los 50 estados de USA (1973). Además, también incluye el porcentaje de la población de cada estado que vive en zonas rurales (\(UrbanPoP\)).

data("USArrests")
head(USArrests)
##            Murder Assault UrbanPop Rape
## Alabama      13.2     236       58 21.2
## Alaska       10.0     263       48 44.5
## Arizona       8.1     294       80 31.0
## Arkansas      8.8     190       50 19.5
## California    9.0     276       91 40.6
## Colorado      7.9     204       78 38.7

El promedio de los datos muestra que hay tres veces más secuestros que asesinatos y 8 veces más asaltos que secuestros.

apply(X = USArrests, MARGIN = 2, FUN = mean)
##   Murder  Assault UrbanPop     Rape 
##    7.788  170.760   65.540   21.232

La varianza es muy distinta entre las variables, en el caso de Assault, la varianza es varios órdenes de magnitud superior al resto.

apply(X = USArrests, MARGIN = 2, FUN = var)
##     Murder    Assault   UrbanPop       Rape 
##   18.97047 6945.16571  209.51878   87.72916

Si no se estandarizan las variables para que tengan media cero y desviación estándar 1 antes de realizar el estudio \(\textbf{PCA}\), la variable Assault dominará la mayoría de las componentes principales.

La función prcomp() es una de las múltiples funciones en R que realizan \(\textbf{PCA}\). Por defecto, prcomp() centra las variables para que tengan media cero, pero si se quiere además que su desviación estándar sea de uno, hay que indicar scale = TRUE.

pca <- prcomp(USArrests, scale = TRUE)
names(pca)
## [1] "sdev"     "rotation" "center"   "scale"    "x"

Los elementos center y scale almacenados en el objeto pca contienen la media y desviación típica de las variables previa estandarización (en la escala original).

pca$center
##   Murder  Assault UrbanPop     Rape 
##    7.788  170.760   65.540   21.232
pca$scale
##    Murder   Assault  UrbanPop      Rape 
##  4.355510 83.337661 14.474763  9.366385

rotation contiene el valor de los loadings \(\phi\) para cada componente (\(eigenvector\)). El número máximo de componentes principales se corresponde con el \(mínimo(n-1,p)\), que en este caso es \(min(49,4)=4\).

pca$rotation
##                 PC1        PC2        PC3         PC4
## Murder   -0.5358995  0.4181809 -0.3412327  0.64922780
## Assault  -0.5831836  0.1879856 -0.2681484 -0.74340748
## UrbanPop -0.2781909 -0.8728062 -0.3780158  0.13387773
## Rape     -0.5434321 -0.1673186  0.8177779  0.08902432

Analizar con detalle el vector de \(loadings\) que forma cada componente puede ayudar a interpretar que tipo de información recoge cada una de ellas. Por ejemplo, la primera componente es el resultado de la siguiente combinación lineal de las variables originales:

\[PC1=−0.5358995 Murder−0.5831836 Assault−0.2781909 UrbanPop−0.5434321 Rape\]

Los pesos asignados en la primera componente a las variables \(Assault\), \(Murder\) y \(Rape\) son aproximadamente iguales entre ellos y bastante superiores al asignado a \(UrbanPoP\), esto significa que la primera componente recoge mayoritariamente la información correspondiente a los delitos. En la segunda componente, es la variable \(UrbanPoP\) la que tiene con diferencia mayor peso, por lo que se corresponde principalmente con el nivel de urbanización del estado. Si bien en este ejemplo la interpretación de las componentes es bastante clara, no en todos los casos ocurre lo mismo.

La función prcomp() calcula automáticamente el valor de las componentes principales para cada observación (\(principal\,\, component\,\, scores\)) multiplicando los datos por los vectores de \(loadings\). El resultado se almacena en la matriz \(x\).

head(pca$x)
##                   PC1        PC2         PC3          PC4
## Alabama    -0.9756604  1.1220012 -0.43980366  0.154696581
## Alaska     -1.9305379  1.0624269  2.01950027 -0.434175454
## Arizona    -1.7454429 -0.7384595  0.05423025 -0.826264240
## Arkansas    0.1399989  1.1085423  0.11342217 -0.180973554
## California -2.4986128 -1.5274267  0.59254100 -0.338559240
## Colorado   -1.4993407 -0.9776297  1.08400162  0.001450164
dim(pca$x)
## [1] 50  4

Mediante la función biplot() se puede obtener una representación bidimensional de las dos primeras componentes. Es recomendable indicar el argumento scale = 0 para que las flechas estén en la misma escala que las componentes.

biplot(x = pca, scale = 0, cex = 0.6, col = c("blue4", "brown3"))

Una vez calculadas las componentes principales, se puede conocer la varianza explicada por cada una de ellas, la proporción respecto al total y la proporción de varianza acumulada.

library(ggplot2)
pca$sdev^2
## [1] 2.4802416 0.9897652 0.3565632 0.1734301
prop_varianza <- pca$sdev^2 / sum(pca$sdev^2)
prop_varianza
## [1] 0.62006039 0.24744129 0.08914080 0.04335752
ggplot(data = data.frame(prop_varianza, pc = 1:4),
       aes(x = pc, y = prop_varianza)) +
  geom_col(width = 0.3) +
  scale_y_continuous(limits = c(0,1)) +
  theme_bw() +
  labs(x = "Componente principal",
       y = "Prop. de varianza explicada")

prop_varianza_acum <- cumsum(prop_varianza)
prop_varianza_acum
## [1] 0.6200604 0.8675017 0.9566425 1.0000000
ggplot(data = data.frame(prop_varianza_acum, pc = 1:4),
       aes(x = pc, y = prop_varianza_acum, group = 1)) +
  geom_point() +
  geom_line() +
  theme_bw() +
  labs(x = "Componente principal",
       y = "Prop. varianza explicada acumulada")

En este caso, la primera componente explica el 62\(\%\) de la varianza observada en los datos y la segunda el 24.7\(\%\). Las dos últimas componentes no superan por separado el 1\(\%\) de varianza explicada. Si se empleasen únicamente las dos primeras componentes se conseguiría explicar el 86.75\(\%\) de la varianza observada.

PCR: PCA aplicado a regresión lineal

La cuantificación del contenido en grasa de la carne pude hacerse mediante técnicas de analítica química, sin embargo, este proceso es costoso en tiempo y recursos. Una posible alternativa para reducir costes y optimizar tiempo es emplear un espectrofotómetro (instrumento capaz de detectar la absorbancia que tiene un material a diferentes tipos de luz en función de sus características). Para comprobar su efectividad se mide el espectro de absorbancia de 100 longitudes de onda en 215 muestras de carne, cuyo contenido en grasa se obtiene también por análisis químico para poder comparar los resultados. El set de datos meatspec del paquete faraway contiene toda la información.

library(faraway)
data(meatspec)
head(meatspec)
##        V1      V2      V3      V4      V5      V6      V7      V8      V9
## 1 2.61776 2.61814 2.61859 2.61912 2.61981 2.62071 2.62186 2.62334 2.62511
## 2 2.83454 2.83871 2.84283 2.84705 2.85138 2.85587 2.86060 2.86566 2.87093
## 3 2.58284 2.58458 2.58629 2.58808 2.58996 2.59192 2.59401 2.59627 2.59873
## 4 2.82286 2.82460 2.82630 2.82814 2.83001 2.83192 2.83392 2.83606 2.83842
## 5 2.78813 2.78989 2.79167 2.79350 2.79538 2.79746 2.79984 2.80254 2.80553
## 6 3.00993 3.01540 3.02086 3.02634 3.03190 3.03756 3.04341 3.04955 3.05599
##       V10     V11     V12     V13     V14     V15     V16     V17     V18
## 1 2.62722 2.62964 2.63245 2.63565 2.63933 2.64353 2.64825 2.65350 2.65937
## 2 2.87661 2.88264 2.88898 2.89577 2.90308 2.91097 2.91953 2.92873 2.93863
## 3 2.60131 2.60414 2.60714 2.61029 2.61361 2.61714 2.62089 2.62486 2.62909
## 4 2.84097 2.84374 2.84664 2.84975 2.85307 2.85661 2.86038 2.86437 2.86860
## 5 2.80890 2.81272 2.81704 2.82184 2.82710 2.83294 2.83945 2.84664 2.85458
## 6 3.06274 3.06982 3.07724 3.08511 3.09343 3.10231 3.11185 3.12205 3.13294
##       V19     V20     V21     V22     V23     V24     V25     V26     V27
## 1 2.66585 2.67281 2.68008 2.68733 2.69427 2.70073 2.70684 2.71281 2.71914
## 2 2.94929 2.96072 2.97272 2.98493 2.99690 3.00833 3.01920 3.02990 3.04101
## 3 2.63361 2.63835 2.64330 2.64838 2.65354 2.65870 2.66375 2.66880 2.67383
## 4 2.87308 2.87789 2.88301 2.88832 2.89374 2.89917 2.90457 2.90991 2.91521
## 5 2.86331 2.87280 2.88291 2.89335 2.90374 2.91371 2.92305 2.93187 2.94060
## 6 3.14457 3.15703 3.17038 3.18429 3.19840 3.21225 3.22552 3.23827 3.25084
##       V28     V29     V30     V31     V32     V33     V34     V35     V36
## 1 2.72628 2.73462 2.74416 2.75466 2.76568 2.77679 2.78790 2.79949 2.81225
## 2 3.05345 3.06777 3.08416 3.10221 3.12106 3.13983 3.15810 3.17623 3.19519
## 3 2.67892 2.68411 2.68937 2.69470 2.70012 2.70563 2.71141 2.71775 2.72490
## 4 2.92043 2.92565 2.93082 2.93604 2.94128 2.94658 2.95202 2.95777 2.96419
## 5 2.94986 2.96035 2.97241 2.98606 3.00097 3.01652 3.03220 3.04793 3.06413
## 6 3.26393 3.27851 3.29514 3.31401 3.33458 3.35591 3.37709 3.39772 3.41828
##       V37     V38     V39     V40     V41     V42     V43     V44     V45
## 1 2.82706 2.84356 2.86106 2.87857 2.89497 2.90924 2.92085 2.93015 2.93846
## 2 3.21584 3.23747 3.25889 3.27835 3.29384 3.30362 3.30681 3.30393 3.29700
## 3 2.73344 2.74327 2.75433 2.76642 2.77931 2.79272 2.80649 2.82064 2.83541
## 4 2.97159 2.98045 2.99090 3.00284 3.01611 3.03048 3.04579 3.06194 3.07889
## 5 3.08153 3.10078 3.12185 3.14371 3.16510 3.18470 3.20140 3.21477 3.22544
## 6 3.43974 3.46266 3.48663 3.51002 3.53087 3.54711 3.55699 3.55986 3.55656
##       V46     V47     V48     V49     V50     V51     V52     V53     V54
## 1 2.94771 2.96019 2.97831 3.00306 3.03506 3.07428 3.11963 3.16868 3.21771
## 2 3.28925 3.28409 3.28505 3.29326 3.30923 3.33267 3.36251 3.39661 3.43188
## 3 2.85121 2.86872 2.88905 2.91289 2.94088 2.97325 3.00946 3.04780 3.08554
## 4 3.09686 3.11629 3.13775 3.16217 3.19068 3.22376 3.26172 3.30379 3.34793
## 5 3.23505 3.24586 3.26027 3.28063 3.30889 3.34543 3.39019 3.44198 3.49800
## 6 3.54937 3.54169 3.53692 3.53823 3.54760 3.56512 3.59043 3.62229 3.65830
##       V55     V56     V57     V58     V59     V60     V61     V62     V63
## 1 3.26254 3.29988 3.32847 3.34899 3.36342 3.37379 3.38152 3.38741 3.39164
## 2 3.46492 3.49295 3.51458 3.53004 3.54067 3.54797 3.55306 3.55675 3.55921
## 3 3.11947 3.14696 3.16677 3.17938 3.18631 3.18924 3.18950 3.18801 3.18498
## 4 3.39093 3.42920 3.45998 3.48227 3.49687 3.50558 3.51026 3.51221 3.51215
## 5 3.55407 3.60534 3.64789 3.68011 3.70272 3.71815 3.72863 3.73574 3.74059
## 6 3.69515 3.72932 3.75803 3.78003 3.79560 3.80614 3.81313 3.81774 3.82079
##       V64     V65     V66     V67     V68     V69     V70     V71     V72
## 1 3.39418 3.39490 3.39366 3.39045 3.38541 3.37869 3.37041 3.36073 3.34979
## 2 3.56045 3.56034 3.55876 3.55571 3.55132 3.54585 3.53950 3.53235 3.52442
## 3 3.18039 3.17411 3.16611 3.15641 3.14512 3.13241 3.11843 3.10329 3.08714
## 4 3.51036 3.50682 3.50140 3.49398 3.48457 3.47333 3.46041 3.44595 3.43005
## 5 3.74357 3.74453 3.74336 3.73991 3.73418 3.72638 3.71676 3.70553 3.69289
## 6 3.82258 3.82301 3.82206 3.81959 3.81557 3.81021 3.80375 3.79642 3.78835
##       V73     V74     V75     V76     V77     V78     V79     V80     V81
## 1 3.33769 3.32443 3.31013 3.29487 3.27891 3.26232 3.24542 3.22828 3.21080
## 2 3.51583 3.50668 3.49700 3.48683 3.47626 3.46552 3.45501 3.44481 3.43477
## 3 3.07014 3.05237 3.03393 3.01504 2.99569 2.97612 2.95642 2.93660 2.91667
## 4 3.41285 3.39450 3.37511 3.35482 3.33376 3.31204 3.28986 3.26730 3.24442
## 5 3.67900 3.66396 3.64785 3.63085 3.61305 3.59463 3.57582 3.55695 3.53796
## 6 3.77958 3.77024 3.76040 3.75005 3.73929 3.72831 3.71738 3.70681 3.69664
##       V82     V83     V84     V85     V86     V87     V88     V89     V90
## 1 3.19287 3.17433 3.15503 3.13475 3.11339 3.09116 3.06850 3.04596 3.02393
## 2 3.42465 3.41419 3.40303 3.39082 3.37731 3.36265 3.34745 3.33245 3.31818
## 3 2.89655 2.87622 2.85563 2.83474 2.81361 2.79235 2.77113 2.75015 2.72956
## 4 3.22117 3.19757 3.17357 3.14915 3.12429 3.09908 3.07366 3.04825 3.02308
## 5 3.51880 3.49936 3.47938 3.45869 3.43711 3.41458 3.39129 3.36772 3.34450
## 6 3.68659 3.67649 3.66611 3.65503 3.64283 3.62938 3.61483 3.59990 3.58535
##       V91     V92     V93     V94     V95     V96     V97     V98     V99
## 1 3.00247 2.98145 2.96072 2.94013 2.91978 2.89966 2.87964 2.85960 2.83940
## 2 3.30473 3.29186 3.27921 3.26655 3.25369 3.24045 3.22659 3.21181 3.19600
## 3 2.70934 2.68951 2.67009 2.65112 2.63262 2.61461 2.59718 2.58034 2.56404
## 4 2.99820 2.97367 2.94951 2.92576 2.90251 2.87988 2.85794 2.83672 2.81617
## 5 3.32201 3.30025 3.27907 3.25831 3.23784 3.21765 3.19766 3.17770 3.15770
## 6 3.57163 3.55877 3.54651 3.53442 3.52221 3.50972 3.49682 3.48325 3.46870
##      V100  fat
## 1 2.81920 22.5
## 2 3.17942 40.1
## 3 2.54816  8.4
## 4 2.79622  5.9
## 5 3.13753 25.5
## 6 3.45307 42.7
dim(meatspec)
## [1] 215 101

El set de datos contiene 101 columnas. Las 100 primeras, nombradas como \(v_1, ..., v_{100}\) recogen el valor de absorbancia para cada una de las 100 longitudes de onda analizadas, y la columna fat el contenido en grasa medido por técnicas químicas.

Para poder evaluar la capacidad predictiva del modelo, se dividen las observaciones disponibles en dos grupos: uno de entrenamiento para ajustar el modelo (80\(\%\) de los datos) y uno de test (20\(\%\) de los datos).

training <- meatspec[1:172, ]
test     <- meatspec[173:215, ]

En primer lugar se ajusta un modelo incluyendo todas las longitudes de onda como predictores.

modelo <- lm(fat ~ ., data = training)
summary(modelo)
## 
## Call:
## lm(formula = fat ~ ., data = training)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.09837 -0.35779  0.04555  0.38080  2.33860 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      6.324      2.012   3.143 0.002439 ** 
## V1           12134.077   3659.798   3.316 0.001443 ** 
## V2          -12585.857   5971.891  -2.108 0.038605 *  
## V3           -5107.556   9390.265  -0.544 0.588200    
## V4           23880.493  17143.644   1.393 0.167977    
## V5          -40509.555  22129.359  -1.831 0.071360 .  
## V6           28469.416  19569.400   1.455 0.150134    
## V7          -20901.082  12501.639  -1.672 0.098952 .  
## V8            8369.465   7515.467   1.114 0.269193    
## V9           -1539.328   5397.505  -0.285 0.776327    
## V10           4706.267   7406.895   0.635 0.527217    
## V11           7012.943  11720.620   0.598 0.551516    
## V12          14891.444  20169.170   0.738 0.462749    
## V13         -30963.902  26186.839  -1.182 0.240983    
## V14          34338.612  22323.830   1.538 0.128444    
## V15         -22235.237  13842.268  -1.606 0.112640    
## V16          -7466.797   8558.172  -0.872 0.385890    
## V17           6716.653   6561.805   1.024 0.309500    
## V18          -2033.071   6741.330  -0.302 0.763851    
## V19           8541.212   9419.998   0.907 0.367627    
## V20          -1667.207  17300.433  -0.096 0.923500    
## V21         -31972.494  24622.615  -1.299 0.198317    
## V22          59526.389  27730.712   2.147 0.035244 *  
## V23         -49241.388  23117.226  -2.130 0.036632 *  
## V24          16184.597  16679.609   0.970 0.335180    
## V25          12077.951  10751.912   1.123 0.265081    
## V26         -12632.330   6774.573  -1.865 0.066361 .  
## V27          -6298.837   7032.334  -0.896 0.373442    
## V28          29625.988   9011.227   3.288 0.001573 ** 
## V29         -39374.835  13561.228  -2.903 0.004914 ** 
## V30          31251.427  18742.000   1.667 0.099829 .  
## V31         -27238.189  21335.756  -1.277 0.205887    
## V32          23009.543  19776.156   1.163 0.248522    
## V33          -4584.373  14572.471  -0.315 0.753995    
## V34          -5437.943  10344.728  -0.526 0.600754    
## V35          -6128.931   8762.663  -0.699 0.486564    
## V36           5599.605   6652.640   0.842 0.402776    
## V37          -5569.160   6670.198  -0.835 0.406557    
## V38             97.451   9291.480   0.010 0.991661    
## V39          36021.407  12574.711   2.865 0.005488 ** 
## V40         -54273.400  17144.384  -3.166 0.002280 ** 
## V41          52084.876  21758.024   2.394 0.019318 *  
## V42         -48458.089  23950.549  -2.023 0.046813 *  
## V43          29334.488  20232.617   1.450 0.151500    
## V44         -18282.834  13508.157  -1.353 0.180200    
## V45          22110.934   9725.348   2.274 0.026020 *  
## V46         -11735.692   6631.245  -1.770 0.081061 .  
## V47           -514.521   3800.612  -0.135 0.892696    
## V48           2551.480   6131.893   0.416 0.678592    
## V49           3707.639   8970.401   0.413 0.680618    
## V50         -25762.703  10934.783  -2.356 0.021236 *  
## V51          46844.468  15367.852   3.048 0.003233 ** 
## V52         -47783.626  18069.344  -2.644 0.010065 *  
## V53          26233.604  18822.491   1.394 0.167744    
## V54             87.825  17403.836   0.005 0.995988    
## V55          -8475.119  13232.005  -0.641 0.523908    
## V56           3488.507   7228.428   0.483 0.630858    
## V57          -1520.733   4988.093  -0.305 0.761355    
## V58           2275.175   5495.630   0.414 0.680124    
## V59          -5415.427   5721.475  -0.947 0.347099    
## V60           7152.015   4754.317   1.504 0.136935    
## V61          -4494.234   4512.937  -0.996 0.322702    
## V62           3662.045   4811.634   0.761 0.449129    
## V63          13993.987   7098.106   1.972 0.052563 .  
## V64         -23252.133   8973.839  -2.591 0.011604 *  
## V65           4373.731  10048.591   0.435 0.664695    
## V66           4580.913  10146.146   0.451 0.653011    
## V67           -837.676  10747.974  -0.078 0.938097    
## V68          -7074.425  10852.430  -0.652 0.516587    
## V69           9506.571   9739.256   0.976 0.332325    
## V70          -2765.100   9519.031  -0.290 0.772295    
## V71          -1125.135   8586.061  -0.131 0.896113    
## V72          -7295.096   7489.488  -0.974 0.333341    
## V73          17059.811   6522.093   2.616 0.010870 *  
## V74          -9889.553   6543.945  -1.511 0.135162    
## V75           -325.615   6125.973  -0.053 0.957759    
## V76            782.219   5421.002   0.144 0.885677    
## V77           8058.935   5793.416   1.391 0.168554    
## V78         -15869.978   6448.208  -2.461 0.016282 *  
## V79          21768.619   6435.678   3.382 0.001172 ** 
## V80         -28338.145   8180.874  -3.464 0.000906 ***
## V81           8523.317  10053.153   0.848 0.399384    
## V82          22319.451  12098.046   1.845 0.069226 .  
## V83         -17244.722  13991.685  -1.232 0.221829    
## V84         -18325.836  14959.964  -1.225 0.224627    
## V85          33345.457  13868.197   2.404 0.018808 *  
## V86          -7955.157  14571.278  -0.546 0.586813    
## V87          -7837.966  16141.553  -0.486 0.628762    
## V88          -1815.552  17261.928  -0.105 0.916532    
## V89            631.595  15684.751   0.040 0.967992    
## V90          -2701.955  16187.612  -0.167 0.867911    
## V91           4375.678  19400.005   0.226 0.822199    
## V92          12925.188  16456.244   0.785 0.434816    
## V93          -7441.235  12417.883  -0.599 0.550923    
## V94          -2464.532  11815.234  -0.209 0.835366    
## V95          -2090.635   9666.576  -0.216 0.829394    
## V96          10912.352   9950.716   1.097 0.276505    
## V97         -20331.405  11022.234  -1.845 0.069270 .  
## V98           3948.443   8227.133   0.480 0.632753    
## V99           6358.930   8652.372   0.735 0.464800    
## V100          -263.365   4104.463  -0.064 0.949019    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.074 on 71 degrees of freedom
## Multiple R-squared:  0.997,  Adjusted R-squared:  0.9928 
## F-statistic: 237.5 on 100 and 71 DF,  p-value: < 2.2e-16

El valor \(R^2_{ajustado}\) obtenido es muy alto (0.9928) lo que indica que el modelo es capaz de predecir con gran exactitud el contenido en grasa de las observaciones con las que se ha entrenado. El hecho de que el modelo en conjunto sea significativo (p-value: < 2.2\(e^{-16}\)), pero que muy pocos de los predictores lo sean a nivel individual, es un indicativo de una posible redundancia entre los predictores (colinealidad).

¿Cómo de bueno es el modelo prediciendo nuevas observaciones que no han participado en ajuste? Al tratarse de un modelo de regresión, la estimación del error de predicción se obtiene mediante el \(Mean\,\, Square\,\, Error\,\, (MSE)\).

\[MSE = \frac{1}{2} \displaystyle\sum^n_{i=1} (\hat{y_i} - y_i)^2\]

# MSE empleando las observaciones de entrenamiento
training_mse <- mean((modelo$fitted.values - training$fat)^2)
training_mse
## [1] 0.4765372
# MSE empleando nuevas observaciones
predicciones <- predict(modelo, newdata = test)
test_mse <- mean((predicciones - test$fat)^2)
test_mse
## [1] 14.54659

Se observa que el modelo tiene un MSE muy bajo (0.48) cuando predice las mismas observaciones con las que se ha entrenado, pero 30 veces más alto (14.54) al predecir nuevas observaciones. Esto significa que el modelo no es útil, ya que el objetivo es aplicarlo para predecir el contenido en grasa de futuras muestras de carne. A este problema se le conoce como \(overfitting\). Una de las causas por las que un modelo puede sufrir \(overfitting\) es la incorporación de predictores innecesarios, que no aportan información o que la información que aportan es redundante.

Se recurre en primer lugar a la selección de predictores mediante \(stepwise\) selection empleando el AIC como criterio de evaluación:

modelo_step_selection <- step(object = modelo, trace = FALSE)

# Número de predictores del modelo resultante
length(modelo_step_selection$coefficients)
## [1] 73
# Training-MSE
training_mse <- mean((modelo_step_selection$fitted.values - training$fat)^2)
training_mse
## [1] 0.5034001

El proceso de \(stepwise\) selection devuelve como mejor modelo el formado por 73 de los 100 predictores disponibles. Al haber eliminado predictores del modelo, el \(training\,\, MSE\) siempre aumenta, en este caso de 0.48 a 0.05, pero el \(test-MSE\) se ha reducido a 12.88986.

Véase ahora el resultado si se ajusta el modelo empleando las componentes principales:

# Cálculo de componentes principales. Se excluye la columna con la variable 
# respuesta *fat*
pca <- prcomp(training[, -101], scale. = TRUE)

# Se muestra la proporción de varianza explicada y acumulada de las 9 primeras
# componentes
summary(pca)$importance[, 1:9]
##                            PC1      PC2       PC3       PC4        PC5
## Standard deviation     9.92492 1.043606 0.5357885 0.3312792 0.07898436
## Proportion of Variance 0.98504 0.010890 0.0028700 0.0011000 0.00006000
## Cumulative Proportion  0.98504 0.995930 0.9988000 0.9999000 0.99996000
##                               PC6        PC7        PC8         PC9
## Standard deviation     0.04974461 0.02700194 0.02059129 0.008603878
## Proportion of Variance 0.00002000 0.00001000 0.00000000 0.000000000
## Cumulative Proportion  0.99999000 0.99999000 1.00000000 1.000000000

El estudio de la proporción de varianza explicada muestra que la primera componente recoge la mayor parte de la información (98.5\(\%\)), decayendo drásticamente la varianza en las sucesivas componentes.

Una vez obtenido el valor de las componentes para cada observación (\(principal\,\, component\,\, scores\)), puede ajustarse el modelo lineal empleando dichos valores junto con la variable respuesta que le corresponde a cada observación. Con la función pcr() del paquete pls se evita tener que codificar cada uno de los pasos intermedios.

Acorde a la proporción de varianza acumulada, emplear las 4 primeras componentes podría ser una buena elección, ya que en conjunto explican el 99.99100 \(\%\) de varianza.

library(pls)
## 
## Attaching package: 'pls'
## The following object is masked from 'package:stats':
## 
##     loadings
modelo_pcr <- pcr(formula = fat ~ ., data = training, scale. = TRUE, ncomp = 4)

# Test-MSE
predicciones <- predict(modelo_pcr, newdata = test, ncomp = 4)
test_mse <- mean((predicciones - test$fat)^2)
test_mse
## [1] 20.55699

El \(test-MSE\) obtenido (20.56) para el modelo que emplea como predictores las 4 primeras componentes es mucho mayor que el obtenido con el modelo generado por \(stepwise\) selection (12.89) e incluso que el obtenido incluyendo todos los predictores (14.54659). Esto significa que, o bien el hecho de emplear componentes principales como predictores no es útil para este caso, o que el número de componentes incluido no es el adecuado.

La función pcr() incluye la posibilidad de recurrir a \(cross\,\, validation\) para identificar el número óptimo de componentes con el que se minimiza el MSE.

set.seed(123)
modelo_pcr <- pcr(formula = fat ~ ., data = training, scale. = TRUE,
                  validation = "CV")
modelo_pcr_CV <- MSEP(modelo_pcr, estimate = "CV")
which.min(modelo_pcr_CV$val)
## [1] 20
par(mfrow = c(1,2))
plot(modelo_pcr_CV$val, main = "MSE vs nº componentes", type = "l",
     ylab = "MSE",
     col = "blue", xlab = "Componentes")
plot(modelo_pcr_CV$val, main = "zoom", type = "l", ylab = "MSE",
     xlab = "Componentes", col = "blue", ylim = c(0,20))

# Test-MSE
predicciones <- predict(modelo_pcr, newdata = test, ncomp = 18)
test_mse <- mean((predicciones - test$fat)^2)
test_mse
## [1] 4.524698

El número óptimo de componentes principales identificado por \(cross\,\, validation\) es de 18. Empleando este número en la \(PCR\) se consigue reducir el \(test-MSE\) a 4.52, un valor muy por debajo del conseguido con los otros modelos.