Я пытаюсь написать функцию на R, которая будет правильно классифицировать Виды кенгуру (Giganteus, Melonops или Fuliginosus) на основе 5 переменных:
- длина носа (nas.l)
- ширина носа (nas.w)
- длина резца (в c .l)
- длина челюсти (man.l)
- ширина челюсти (man .w)
Для линейного дискриминантного анализа я написал следующую функцию:
classify.lda = function(x, prior, mu, covar){
x = matrix(as.numeric(x), ncol=1)
log(prior) - (0.5*t(mu)%*%solve(covar)%*%mu) + (t(x)%*%solve(covar)%*%mu)
}
dfs.1 <- rep(0,G)
for(g in 1:G){
dfs.1[g] = classify.lda(x, lda.kang$prior[g], lda.kang$mean[g,], cov.pool)
}
levels(kangaroo$Species)[dfs.1 == max(dfs.1)]
Входные данные для функции были сгенерированы следующим образом:
lda.kang <- lda(Species ~ nas.l + nas.w + inc.l + man.l + man.w, data = kangaroo)
lda.kang
N = nrow(kangaroo)
G = length(levels(kangaroo$Species))
##Covarince matrix for Fuliginous
cov.ful = kangaroo %>%
dplyr::filter(Species == "fuliginosus") %>%
dplyr::select(nas.l, nas.w, inc.l, man.l, man.w) %>%
do(as.data.frame(cov(.)))
##Number in Fuliginous group
n.ful = kangaroo %>%
dplyr::filter(Species == "fuliginosus") %>%
summarise(n=n())
##Covarince matrix for Giganteus
cov.gig = kangaroo %>%
dplyr::filter(Species == "giganteus") %>%
dplyr::select(nas.l, nas.w, inc.l, man.l, man.w) %>%
do(as.data.frame(cov(.)))
##Number in Giganteus group
n.gig = kangaroo %>%
dplyr::filter(Species == "giganteus") %>%
summarise(n=n())
##Covarince matrix for Melanops
cov.mel = kangaroo %>%
dplyr::filter(Species == "melanops") %>%
dplyr::select(nas.l, nas.w, inc.l, man.l, man.w) %>%
do(as.data.frame(cov(.)))
##Number in Melanops group
n.mel = kangaroo %>%
dplyr::filter(Species == "melanops") %>%
summarise(n=n())
cov.pool = (cov.ful*(n.ful$n-1) + cov.gig*(n.gig$n-1) + cov.mel*(n.mel$n-1)/N-G)
При тестировании функции я вытащил наблюдение из набора данных и пропустил его через функцию, и он правильно идентифицировал кенгуру как Гигантеус. Теперь я хочу сделать то же самое, используя функцию анализа дискриминанта quadrati c, и я создал следующую функцию:
qda.kang <- qda(Species ~ nas.w + nas.l + inc.l + man.w + man.l, data = kangaroo)
classify.qda = function(x, prior, mu, covar){
x = matrix(as.numeric(x), ncol=1)
log(prior) - 0.5*log(det(as.matrix(covar))) -0.5*t(x-mu)%*%solve(covar)%*%(x-mu)
}
dfs.2 <- rep(0,G)
for(g in 1:G){
dfs.2[g] = classify.qda(x2, qda.kang$prior[g], qda.kang$means[g,], as.matrix(cov.pool))
}
levels(kangaroo$Species)[dfs.2 == max(dfs.2)]
На этот раз функция идентифицирует кенгуру как меланопса. Это происходит и для других наблюдений по данным. Все наблюдения идентифицированы как меланопсы независимо от их фактического вида.
Может ли кто-нибудь определить ошибку в коде, которая приводит к неправильной классификации? Или, если у них есть альтернативный метод использования QDA для правильной идентификации видов, я буду открыт для предложений.
Набор данных кенгуру