당뇨병의 SVM 분류 개선


10

당뇨병을 예측하기 위해 SVM을 사용하고 있습니다. 이 목적으로 BRFSS 데이터 세트를 사용하고 있습니다. 데이터 세트의 크기는 이며 비뚤어집니다. 목표 변수에서 s 의 비율 은 이고 s는 나머지 구성합니다 .11 % 89 %432607×136Y11%N89%

데이터 세트에서 독립 변수 15중 하나만 사용 136하고 있습니다. 데이터 세트를 줄이는 이유 중 하나는 NAs를 포함하는 행 이 생략 될 때 더 많은 학습 샘플을 갖기위한 것 입니다.

15변수는 랜덤 트리, 로지스틱 회귀와 같은 통계적 방법을 실행하고 결과 모델에서 어떤 변수가 중요한지 알아 낸 후에 선택되었습니다. 예를 들어 로지스틱 회귀 분석을 실행 한 후 p-value가장 중요한 변수를 정렬하는 데 사용 했습니다.

변수 선택 방법이 올바른가요? 어떤 제안이라도 대단히 환영합니다.

다음은 내 R구현입니다.

library(e1071) # Support Vector Machines

#--------------------------------------------------------------------
# read brfss file (huge 135 MB file)
#--------------------------------------------------------------------
y <- read.csv("http://www.hofroe.net/stat579/brfss%2009/brfss-2009-clean.csv")
indicator <- c("DIABETE2", "GENHLTH", "PERSDOC2", "SEX", "FLUSHOT3", "PNEUVAC3", 
    "X_RFHYPE5", "X_RFCHOL", "RACE2", "X_SMOKER3", "X_AGE_G", "X_BMI4CAT", 
    "X_INCOMG", "X_RFDRHV3", "X_RFDRHV3", "X_STATE");
target <- "DIABETE2";
diabetes <- y[, indicator];

#--------------------------------------------------------------------
# recode DIABETE2
#--------------------------------------------------------------------
x <- diabetes$DIABETE2;
x[x > 1]  <- 'N';
x[x != 'N']  <- 'Y';
diabetes$DIABETE2 <- x; 
rm(x);

#--------------------------------------------------------------------
# remove NA
#--------------------------------------------------------------------
x <- na.omit(diabetes);
diabetes <- x;
rm(x);

#--------------------------------------------------------------------
# reproducible research 
#--------------------------------------------------------------------
set.seed(1612);
nsamples <- 1000; 
sample.diabetes <- diabetes[sample(nrow(diabetes), nsamples), ]; 

#--------------------------------------------------------------------
# split the dataset into training and test
#--------------------------------------------------------------------
ratio <- 0.7;
train.samples <- ratio*nsamples;
train.rows <- c(sample(nrow(sample.diabetes), trunc(train.samples)));

train.set  <- sample.diabetes[train.rows, ];
test.set   <- sample.diabetes[-train.rows, ];

train.result <- train.set[ , which(names(train.set) == target)];
test.result  <- test.set[ , which(names(test.set) == target)];

#--------------------------------------------------------------------
# SVM 
#--------------------------------------------------------------------
formula <- as.formula(factor(DIABETE2) ~ . );
svm.tune <- tune.svm(formula, data = train.set, 
    gamma = 10^(-3:0), cost = 10^(-1:1));
svm.model <- svm(formula, data = train.set, 
    kernel = "linear", 
    gamma = svm.tune$best.parameters$gamma, 
    cost  = svm.tune$best.parameters$cost);

#--------------------------------------------------------------------
# Confusion matrix
#--------------------------------------------------------------------
train.pred <- predict(svm.model, train.set);
test.pred  <- predict(svm.model, test.set);
svm.table <- table(pred = test.pred, true = test.result);
print(svm.table);

나는 함께 도망 (교육 = 700 및 테스트 = 300 더 빨리 내 노트북에 있기 때문에) 샘플. 내가 얻는 테스트 데이터 ( 300 샘플)에 대한 혼란 매트릭스 는 상당히 나쁘다.7001000700300300

    true
pred   N   Y
   N 262  38
   Y   0   0

Y수업에 대한 예측을 향상시켜야합니다 . 사실, Y나는 성능이 좋지 않더라도 가능한 한 정확해야합니다 N. 분류의 정확성을 향상시키기위한 제안은 크게 감사하겠습니다.


SVM이 전혀 작동하지 않지만 왜 그런지 모르겠습니다! 또한 데이터를 정규화하는 것이 더 낫습니다 ...
user4581

예, 기본적으로 Y모든 입력을 예측 합니다. 이것은 의 시간 이 정확하다는 것을 의미합니다 .  90%
Anand

데이터를 정규화하는 것이 가장 좋습니다. 그것으로 시작하십시오. 비선형 커널이 더 나은 결과를 보여줄 수도 있습니다. (귀하의 프론티어
프리 비전에

당신은 또한 시도 할 수 있습니다 kernlab대신 e1071- 자동 정상화을 수행하고 첫 번째 모델을 부트 스트랩 쉽게 만드는 몇 가지 추론이있다.

답변:


9

네 가지 제안이 있습니다.

  1. 모델에 포함 할 변수를 어떻게 선택합니까? 더 큰 데이터 세트에서 일부 주요 지표가 누락되었을 수 있습니다.
  2. 사용중인 거의 모든 지표 (예 : 성별, 흡연자 등)를 요인으로 취급해야합니다. 이러한 변수를 숫자로 취급하는 것은 잘못되었으며 모델의 오류에 영향을 줄 수 있습니다.
  3. 왜 SVM을 사용하고 있습니까? 선형 판별 분석 또는 선형 회귀 분석과 같은 간단한 방법을 시도 했습니까? 더 큰 데이터 세트에 대한 간단한 접근 방식으로 더 나은 결과를 얻을 수 있습니다.
  4. 캐럿 패키지를 사용해보십시오 . 모델 정확도를 교차 검증하고 병렬화되어보다 빠르게 작업 할 수 있으며 다양한 유형의 모델을 쉽게 탐색 할 수 있습니다.

다음은 caret 용 코드 예입니다.

library(caret)

#Parallize
library(doSMP)
w <- startWorkers()
registerDoSMP(w)

#Build model
X <- train.set[,-1]
Y <- factor(train.set[,1],levels=c('N','Y'))
model <- train(X,Y,method='lda')

#Evaluate model on test set
print(model)
predY <- predict(model,test.set[,-1])
confusionMatrix(predY,test.set[,1])
stopWorkers(w)

이 LDA 모델은 귀하의 SVM을 능가하며 귀하의 요인을 고치지도 않았습니다. 성별, 흡연자 등을 요인으로 코딩하면 더 나은 결과를 얻을 수 있습니다.


다음과 같은 오류가 발생 task 1 failed - "could not find function "predictionFunction""합니다. 나는 이것이 포럼이 아니라는 것을 알고 있지만 의견이 있으면 알려주십시오.
Anand

1
@Anand : admin으로 새 R 세션을 엽니 다 (또는 mac / linux에서 sudo R을 실행). 실행 update.packages.완료되면 R을 닫고 일반 (관리자가 아닌) 세션을 다시여십시오. "SVM"및 "Confusion matrix"섹션을 제외하고 코드를 실행하십시오. 그런 다음 내 코드를 실행하십시오. 여전히 오류가 발생하면 정확한 오류와 함께 오류를 반환 한 줄을 게시하십시오.
Zach

1
@Anand : 또한 최신 버전의 R (2.14)을 실행하고 최신 버전의 캐럿을 사용하고 있는지 확인하십시오. install.packages('caret')다시 실행 하여 캐럿을 업데이트 할 수 있습니다 .
Zach

@Anand : 좋아요! 사용자는 서로 다른 방법에 놓을 수 train등의 함수 nb(나이브 베이 즈) glm(로지스틱 회귀) svmLinearsvmRadial. svm은 적응하는 데 시간이 오래 걸립니다.
Zach

3

선형 커널을 사용하는 경우 기능 선택이 잘못된 아이디어 일 수 있으며 정규화를 통해 기능 선택보다 과적 합을보다 효과적으로 방지 할 수 있습니다. SVM이 대략적으로 구현하는 성능 한계는 SVM의 판매 지점 중 하나 인 기능 공간의 차원과 무관합니다.


2

나는 최근 에이 문제가 있었고 도움이되는 몇 가지를 발견했습니다. 먼저 분류 문제의 소수 클래스가 작을 때 더 나은 결과를 제공하는 Naive Bayes 모델 (패키지 klaR)을 사용해보십시오. 또한 SVM을 사용하기로 선택한 경우 소수 클래스를 오버 샘플링하려고 할 수 있습니다. 기본적으로 소수 클래스의 더 많은 예제를 포함 시키거나 소수 클래스에 대한 합성 사례를 작성하려고합니다.

이 백서 : http : //www.it.iitb.ac.in/~kamlesh/Page/Reports/highlySkewed.pdf

Weka에서 구현 된 이러한 기술에 대한 토론과 예가 있지만 R에서 직접 기술하는 것도 가능합니다.


유용한 의견에 감사드립니다. 당신의 제안을 시험해 보도록하겠습니다.
Anand

1

이미 언급 한 것 외에도 선형 커널을 사용하도록 최상의 모델을 수정하고 있습니다. 튜닝 단계에서 사용 / 발견 된 동일한 커널을 포함하여 튜닝 된 최상의 모델을 사용하여 예측해야합니다 (튜닝 감마이므로 RBF라고 가정).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.