La regresión multinomial es una extensión de la regresión logística binomial. El algoritmo nos permite predecir una variable dependiente categórica que tiene más de dos niveles. Como cualquier otro modelo de regresión, la salida multinomial se puede predecir usando una o más variables independientes. Las variables independientes pueden ser de tipo nominal, ordinal o continuo.

Se puede usar la regresión logística múltiple para predecir el tipo de flor que se ha dividido en tres categorías: setosa, versicolor y virginica. Alternativamente, puede utilizar la regresión logística multinomial para predecir el tipo de vino como tinto, rosado y blanco. En este tutorial, usaremos regresión logística multinomial para predecir el tipo de vino. Los datos están disponibles en el paquete {rattle.data} y, por lo tanto, le recomendamos que copie, pegue el código y vuelva a ejecutar el modelo en su sistema local.

Sin embargo, antes de llevar a cabo una regresión multinomial usando R, debemos verificar lo siguiente para asegurarnos de que el resultado final sea válido. lista de cosas que debemos verificar

  1. Su variable dependiente debe ser Nominal . Esto no significa que no se pueda utilizar la regresión multinomial para la variable ordinal. Sin embargo, para la regresión multinomial, necesitamos ejecutar una regresión logística ordinal.

  2. Debe convertir sus variables independientes categóricas en variables ficticias .

  3. No debe haber multicolinealidad .

  4. Debe haber una relación lineal entre la variable dependiente y las variables independientes continuas . Como no podemos medir esto directamente entre variables nominales y continuas, lo que hacemos es tomar la transformación logit de la variable dependiente.

  5. Asegúrese de que no tengamos valores atípicos y puntos de gran influencia en los datos .

PREDICCIÓN DEL TIPO DE VINO MEDIANTE REGRESIÓN LOGÍSTICA MULTINOMIAL

Para este ejemplo, como mencionamos, estamos usando un conjunto de datos de vino del paquete {rattle.data} en R.

Primero carguemos los datos.

# Loading the library
library(rattle.data)
# Loading the wine data
data(wine)

El conjunto de datos contiene información sobre 178 vinos únicos divididos en tres categorías que están representadas por números de 1 a 3. La variable dependiente aquí es Tipo. Para obtener una descripción general del conjunto de datos, verifiquemos la estructura de los datos del vino.

# Checking the structure of wine dataset
str(wine)
## 'data.frame':    178 obs. of  14 variables:
##  $ Type           : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
##  $ Alcohol        : num  14.2 13.2 13.2 14.4 13.2 ...
##  $ Malic          : num  1.71 1.78 2.36 1.95 2.59 1.76 1.87 2.15 1.64 1.35 ...
##  $ Ash            : num  2.43 2.14 2.67 2.5 2.87 2.45 2.45 2.61 2.17 2.27 ...
##  $ Alcalinity     : num  15.6 11.2 18.6 16.8 21 15.2 14.6 17.6 14 16 ...
##  $ Magnesium      : int  127 100 101 113 118 112 96 121 97 98 ...
##  $ Phenols        : num  2.8 2.65 2.8 3.85 2.8 3.27 2.5 2.6 2.8 2.98 ...
##  $ Flavanoids     : num  3.06 2.76 3.24 3.49 2.69 3.39 2.52 2.51 2.98 3.15 ...
##  $ Nonflavanoids  : num  0.28 0.26 0.3 0.24 0.39 0.34 0.3 0.31 0.29 0.22 ...
##  $ Proanthocyanins: num  2.29 1.28 2.81 2.18 1.82 1.97 1.98 1.25 1.98 1.85 ...
##  $ Color          : num  5.64 4.38 5.68 7.8 4.32 6.75 5.25 5.05 5.2 7.22 ...
##  $ Hue            : num  1.04 1.05 1.03 0.86 1.04 1.05 1.02 1.06 1.08 1.01 ...
##  $ Dilution       : num  3.92 3.4 3.17 3.45 2.93 2.85 3.58 3.58 2.85 3.55 ...
##  $ Proline        : int  1065 1050 1185 1480 735 1450 1290 1295 1045 1045 ...

Sin embargo, no estamos realizando un análisis de datos exploratorio. Recuerde que es un paso importante y no debe omitir ese paso mientras realiza cualquier ejercicio de modelado.

Ahora dividimos el conjunto de datos en train y probamos usando la función sample_frac () del paquete {dplyr}.

# Loading the dplyr package
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Using sample_frac to create 70 - 30 slipt into test and train
train <- sample_frac(wine, 0.8)
sample_id <- as.numeric(rownames(train)) # rownames() returns character so as.numeric
test <- wine[-sample_id,]

Para construir el modelo multinomial tenemos un par de funciones en R. Sin embargo, en este ejemplo usamos la función multinom () del paquete {nnet} . Recuerde que cuando construimos modelos logísticos, necesitamos establecer uno de los niveles de la variable dependiente como línea de base. Logramos esto usando la función relevel () . En otras funciones o algoritmos, este proceso generalmente está automatizado.

# Setting the basline 
train$Type <- relevel(train$Type, ref = '3')

Una vez que se ha especificado la línea de base, usamos la función multinom () para ajustar el modelo y luego usamos la función summary () para explorar los coeficientes beta del modelo.

# Loading the nnet package
require(nnet)
## Loading required package: nnet
# Training the multinomial model
multinom.fit <- multinom(Type ~ Alcohol + Color -1, data = train)
## # weights:  9 (4 variable)
## initial  value 156.002945 
## iter  10 value 90.530830
## final  value 90.395171 
## converged
# Checking the model
summary(multinom.fit)
## Call:
## multinom(formula = Type ~ Alcohol + Color - 1, data = train)
## 
## Coefficients:
##     Alcohol      Color
## 1 0.3072013 -0.6329648
## 2 0.9917584 -2.7766474
## 
## Std. Errors:
##      Alcohol     Color
## 1 0.07385004 0.1589315
## 2 0.14279619 0.4250378
## 
## Residual Deviance: 180.7903 
## AIC: 188.7903

Usamos -1 en la fórmula para eliminar la intersección. Creemos que no tiene sentido en el modelo y por eso lo quitamos.

La salida del resumen contiene la tabla de coeficientes y una tabla de error estándar. Cada fila de la tabla de coeficientes corresponde a la ecuación del modelo. La primera fila representa los coeficientes para el vino de Tipo 2 en comparación con nuestra línea de base, que es el vino de Tipo 3, y la segunda fila representa los coeficientes para el vino de Tipo 2 en comparación con nuestra línea de base, que es el vino de Tipo 3.

Los coeficientes de salida se representan en el registro de probabilidades.

Esta proporción de la probabilidad de elegir un vino de Tipo 2 sobre la línea de base que es un vino de Tipo 3 se conoce como riesgo relativo (a menudo descrito como probabilidades). Sin embargo, la salida del modelo es el registro de probabilidades. Para obtener la razón de probabilidades de IE de riesgo relativo, necesitamos exponenciar los coeficientes.

## extracting coefficients from the model and exponentiate
exp(coef(multinom.fit))
##    Alcohol      Color
## 1 1.359615 0.53101510
## 2 2.695971 0.06224685

El índice de riesgo relativo para un aumento de una unidad en la variable color es de .491 para el vino Tipo 1 frente al vino Tipo 3. Aquí un valor de 1 representa que no hay cambios. Sin embargo, un valor mayor que 1 representa un aumento y un valor menor que 1 representa una disminución.

También podemos usar probabilidades para comprender nuestro modelo.

head(probability.table <- fitted(multinom.fit))
##             3          1            2
## 1 0.023038992 0.14950068 0.8274603288
## 2 0.576810543 0.42213197 0.0010574829
## 3 0.715460936 0.28439017 0.0001488917
## 4 0.028189774 0.15790100 0.8139092273
## 5 0.003149638 0.03346687 0.9633834922
## 6 0.413550996 0.57528633 0.0111626707

La tabla anterior indica que la probabilidad de que la 89ª obs. Sea vino de Tipo 2 es del \(90,0\%\), siendo vino de Tipo 1 es de \(8,9\%\) y siendo vino de Tipo 3 es de \(0,0\%\). Por lo tanto, podemos concluir que la observación 89 es de tipo 2. En una nota similar, la observación 57 es de tipo 1, las observaciones de 170 es de tipo 3 y así sucesivamente.

Ahora comprobaremos la precisión del modelo mediante la tabla de clasificación de edificios. Entonces, primero construyamos la tabla de clasificación para el conjunto de datos de entrenamiento y calculemos la precisión del modelo.

# Predicting the values for train dataset
train$precticed <- predict(multinom.fit, newdata = train, "class")

# Building classification table
ctable <- table(train$Type, train$precticed)

# Calculating accuracy - sum of diagonal elements divided by total obs
round((sum(diag(ctable))/sum(ctable))*100,2)
## [1] 70.42

La precisión en el conjunto de datos de entrenamiento es del \(68,8\%\). Ahora repetimos lo anterior en el conjunto de datos invisible de testing.

# Predicting the values for train dataset
test$precticedt <- predict(multinom.fit, newdata = test, "class")

# Building classification table
ctable1 <- table(test$Type, test$precticedt)

# Calculating accuracy - sum of diagonal elements divided by total obs
round((sum(diag(ctable1))/sum(ctable1))*100,2)
## [1] 2.78

La precisión del conjunto de datos de prueba resulta ser un \(18,4\%\) menor en comparación con el conjunto de datos de entrenamiento. Entonces tenemos un problema de sobreajuste aquí. A pesar de la precisión que obtengamos, el proceso de construcción de la regresión logística multinomial sigue siendo el mismo.