2011-04-12 18 views
8

Después de completar un análisis discriminante lineal en R utilizando lda(), hay una manera conveniente para extraer la classification functions para cada grupo?funciones de clasificación en el análisis discriminante lineal en R

Desde el enlace,

Estos no deben ser confundidos con las funciones discriminantes. Las funciones de clasificación se pueden usar para determinar a qué grupo pertenece cada caso. Hay tantas funciones de clasificación como grupos. Cada función nos permite calcular clasificación puntuaciones para cada caso para cada grupo, mediante la aplicación de la fórmula:

Si = ci + wi1*x1 + wi2*x2 + ... + wim*xm 

En esta fórmula, el subíndice i denota el grupo respectivo; los subíndices 1, 2, ..., m denotan las m variables; ci es una constante para el i-ésimo grupo, wij es el peso para la variable j-ésima en el cálculo de la puntuación de clasificación para el i-ésimo grupo; xj es el valor observado para el caso respectivo para la variable j'th. Si es el puntaje de clasificación resultante.

Podemos utilizar las funciones de clasificación para calcular las puntuaciones de clasificación directa para algunas nuevas observaciones.

Puedo construirlos desde cero utilizando fórmulas de libros de texto, pero eso requiere reconstruir una serie de pasos intermedios desde el análisis lda. ¿Hay alguna manera de obtenerlos después del hecho del objeto lda?

Agregado:

A menos Todavía estoy malentendido algo en la respuesta de Brandon (! Lo siento por la confusión), parece que la respuesta es no. Es de suponer que la mayoría de los usuarios pueden obtener la información que necesitan de predict(), que proporciona clasificaciones basadas en lda().

Por razones educativas más que una necesidad investigación seria, yo quería ver las funciones de clasificación reales, y para la posteridad aquí es una función que los añade a la lda() resultado:

ty.lda <- function(x, groups){ 
    x.lda <- lda(groups ~ ., as.data.frame(x)) 

    gr <- length(unique(groups)) ## groups might be factors or numeric 
    v <- ncol(x) ## variables 
    m <- x.lda$means ## group means 

    w <- array(NA, dim = c(v, v, gr)) 

    for(i in 1:gr){ 
    tmp <- scale(subset(x, groups == unique(groups)[i]), scale = FALSE) 
    w[,,i] <- t(tmp) %*% tmp 
    } 

    W <- w[,,1] 
    for(i in 2:gr) 
    W <- W + w[,,i] 

    V <- W/(nrow(x) - gr) 
    iV <- solve(V) 

    class.funs <- matrix(NA, nrow = v + 1, ncol = gr) 
    colnames(class.funs) <- paste("group", 1:gr, sep=".") 
    rownames(class.funs) <- c("constant", paste("var", 1:v, sep = ".")) 

    for(i in 1:gr) { 
    class.funs[1, i] <- -0.5 * t(m[i,]) %*% iV %*% (m[i,]) 
    class.funs[2:(v+1) ,i] <- iV %*% (m[i,]) 
    } 

    x.lda$class.funs <- class.funs 

    return(x.lda) 
} 

Este código sigue las fórmulas en Legendre y numérica Ecología de Legendre (1998), página 625, y coincide con los resultados del ejemplo trabajado partir de la página 626.

+0

Sería posible extraer las funciones de clasificación del código para 'MASS ::: predict.lda'. En realidad, hay tres versiones diferentes. El método predeterminado es usar "plug-in". Hay un término adicional de 'log (priors)' que no veo representado anteriormente. También hay un paso de exponenciación, pero las medidas de distancia deben mantener sus propiedades deseadas bajo una transformación mediante una función convexa. Creo que tal paso podría ser necesario para mantener rowSums == 1 para la matriz $ posterior que es parte del resultado. –

Respuesta

1

Supongamos que x es el objeto LDA:

x$terms 

Usted puede tener un pico en el objeto examinado su estructura:

str(x) 

Actualización:

Iris <- data.frame(rbind(iris3[,,1], iris3[,,2], iris3[,,3]),Sp = rep(c("s","c","v"), rep(50,3))) 
train <- sample(1:150, 75) 
table(Iris$Sp[train]) 
z <- lda(Sp ~ ., Iris, prior = c(1,1,1)/3, subset = train) 
predict(z, Iris[-train, ])$class 
str(z) 
List of 10 
$ prior : Named num [1:3] 0.333 0.333 0.333 
    ..- attr(*, "names")= chr [1:3] "c" "s" "v" 
$ counts : Named int [1:3] 30 25 20 
    ..- attr(*, "names")= chr [1:3] "c" "s" "v" 
$ means : num [1:3, 1:4] 6.03 5.02 6.72 2.81 3.43 ... 
    ..- attr(*, "dimnames")=List of 2 
    .. ..$ : chr [1:3] "c" "s" "v" 
    .. ..$ : chr [1:4] "Sepal.L." "Sepal.W." "Petal.L." "Petal.W." 
$ scaling: num [1:4, 1:2] 0.545 1.655 -1.609 -3.682 -0.443 ... 
    ..- attr(*, "dimnames")=List of 2 
    .. ..$ : chr [1:4] "Sepal.L." "Sepal.W." "Petal.L." "Petal.W." 
    .. ..$ : chr [1:2] "LD1" "LD2" 
$ lev : chr [1:3] "c" "s" "v" 
$ svd : num [1:2] 33.66 2.93 
$ N  : int 75 
$ call : language lda(formula = Sp ~ ., data = Iris, prior = c(1, 1, 1)/3, subset = train) 
$ terms :Classes 'terms', 'formula' length 3 Sp ~ Sepal.L. + Sepal.W. + Petal.L. + Petal.W. 
    .. ..- attr(*, "variables")= language list(Sp, Sepal.L., Sepal.W., Petal.L., Petal.W.) 
    .. ..- attr(*, "factors")= int [1:5, 1:4] 0 1 0 0 0 0 0 1 0 0 ... 
    .. .. ..- attr(*, "dimnames")=List of 2 
    .. .. .. ..$ : chr [1:5] "Sp" "Sepal.L." "Sepal.W." "Petal.L." ... 
    .. .. .. ..$ : chr [1:4] "Sepal.L." "Sepal.W." "Petal.L." "Petal.W." 
    .. ..- attr(*, "term.labels")= chr [1:4] "Sepal.L." "Sepal.W." "Petal.L." "Petal.W." 
    .. ..- attr(*, "order")= int [1:4] 1 1 1 1 
    .. ..- attr(*, "intercept")= int 1 
    .. ..- attr(*, "response")= int 1 
    .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv 
    .. ..- attr(*, "predvars")= language list(Sp, Sepal.L., Sepal.W., Petal.L., Petal.W.) 
    .. ..- attr(*, "dataClasses")= Named chr [1:5] "factor" "numeric" "numeric" "numeric" ... 
    .. .. ..- attr(*, "names")= chr [1:5] "Sp" "Sepal.L." "Sepal.W." "Petal.L." ... 
$ xlevels: Named list() 
- attr(*, "class")= chr "lda" 
+0

Creo que falta algo aquí: ¡no hay elemento de términos en mi objeto lda! – Tyler

+0

¿Está utilizando lda() del paquete MASS? –

+0

Sí, y no hay términos - str() muestra: "anterior", "cuenta", "significa", "escala", "lev", "svd", "N", "llamada" – Tyler

0

Creo que su pregunta era errónea ... OK, tal vez no defectuoso, pero algo engañoso por lo menos. La (s) función (es) discriminante (s) se refiere (n) a las distancias entre grupos, por lo que no hay ninguna función asociada con un solo grupo, sino más bien una función que describe las distancias entre dos centroides de cualquier grupo. Acabo answered a more recent question y se coloca un ejemplo de cálculo de una función de puntuación usando el conjunto de datos del iris y utilizarlo para etiquetar los casos en una parcela 2d de predictores.En el caso de un análisis de 2 grupos, la función será mayor que cero para un grupo y menor que cero para el otro grupo.

+0

No pregunté sobre las funciones discriminantes, pregunté sobre las funciones de clasificación. No són la misma cosa. Vea el enlace para una descripción. – Tyler

+0

Derecha. Una función de clasificación proyecta los datos en las funciones discriminantes y las discretiza en función de una regla de umbral. Si quiere ver cómo lo hace MASS :: prediction.lda, cargue MASS y escriba 'getAnywhere (predic.lda)'. –

+0

Hay una función de clasificación para cada grupo en un lda, como se indica en el enlace que proporcioné, así como el libro que cité. He incluido una cita de la página vinculada para aclarar, para que al menos podamos estar seguros de que estamos discutiendo sobre lo mismo. 'prediction.lda' proporciona los resultados de la aplicación de las funciones de clasificación, pero no devuelve las funciones por sí mismas. Eso es lo que pedí. Todavía no entiendo qué fue erróneo o engañoso acerca de esta pregunta. – Tyler