改进糖尿病的SVM分类

机器算法验证 r 分类 支持向量机 特征选择 e1071
2022-03-10 11:36:47

我正在使用 SVM 预测糖尿病。为此,我正在使用BRFSS数据集。数据集的维度为并且是倾斜的。目标变量中 s的百分比s 构成剩余的432607×136Y11%N89%

我只使用数据集中15136自变量。NA减少数据集的原因之一是在省略包含 s 的行时有更多的训练样本。

这些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);

我运行了(训练 =和测试 =)样本,因为它在我的笔记本电脑中速度更快。我得到的测试数据(样本)的混淆矩阵非常糟糕。1000700300300

    true
pred   N   Y
   N 262  38
   Y   0   0

我需要改进我对Y班级的预测。事实上,我需要尽可能准确,Y即使我在N. 任何提高分类准确性的建议将不胜感激。

4个回答

我有4个建议:

  1. 您如何选择要包含在模型中的变量?也许您错过了更大数据集中的一些关键指标。
  2. 您使用的几乎所有指标(如性别、吸烟者等)都应被视为因素。将这些变量视为数字是错误的,并且可能会导致模型中的错误。
  3. 为什么要使用 SVM?您是否尝试过任何更简单的方法,例如线性判别分析甚至线性回归?也许对更大数据集的简单方法会产生更好的结果。
  4. 尝试插入符号包。它将帮助您交叉验证模型的准确性,它是并行化的,可以让您更快地工作,并且可以轻松探索不同类型的模型。

这是插入符号的一些示例代码:

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,我什至没有修复你的因素。我敢肯定,如果您将性、吸烟者等重新编码为因素,您将获得更好的结果。

如果您使用的是线性内核,那么特征选择可能不是一个好主意,并且正则化可以比特征选择更有效地防止过度拟合。请注意,SVM 近似实现的性能边界与特征空间的维度无关,这是 SVM 的卖点之一。

我最近遇到了这个问题,并发现了一些有用的东西。首先,尝试一个朴素贝叶斯模型(包 klaR),当分类问题中的少数类很小时,它有时会给你更好的结果。此外,如果您确实选择坚持使用 SVM,则可能需要尝试对少数类进行过采样。本质上,您将希望包含更多少数类的示例或为少数类综合创建案例

本文:http://www.it.iitb.ac.in/~kamlesh/Page/Reports/highlySkewed.pdf

在 Weka 中实现了这些技术的一些讨论和示例,但也可以在 R 中自己实现它们。

除了已经提到的内容之外,您正在修复您的最佳模型以使用线性内核。您应该使用已调整的最佳模型进行预测,包括在您的调整阶段使用/找到的相同内核(我假设是 RBF,因为您正在调整 gamma)。