One-class classification with SVM in R

18,329

Solution 1

I think this is what you want:

library(e1071)
data(iris)
df <- iris

df <- subset(df ,  Species=='setosa')  #choose only one of the classes

x <- subset(df, select = -Species) #make x variables
y <- df$Species #make y variable(dependent)
model <- svm(x, y,type='one-classification') #train an one-classification model 


print(model)
summary(model) #print summary

# test on the whole set
pred <- predict(model, subset(iris, select=-Species)) #create predictions

Output:

-Summary:

> summary(model)

Call:
svm.default(x = x, y = y, type = "one-classification")


Parameters:
   SVM-Type:  one-classification 
 SVM-Kernel:  radial 
      gamma:  0.25 
         nu:  0.5 

Number of Support Vectors:  27




Number of Classes: 1

-Predictions (only some of the predictions are shown here (where Species=='setosa') for visual reason):

> pred
    1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16    17    18    19    20    21    22 
 TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE 
   23    24    25    26    27    28    29    30    31    32    33    34    35    36    37    38    39    40    41    42    43    44 
FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE 
   45    46    47    48    49    50 
FALSE  TRUE  TRUE  TRUE  TRUE  TRUE 

Solution 2

A little bit elaborated code with accuracy: train=78.125 test= 91.53:

library(e1071)
library(caret)
library(NLP)
library(tm)

data(iris)

iris$SpeciesClass[iris$Species=="versicolor"] <- "TRUE"
iris$SpeciesClass[iris$Species!="versicolor"] <- "FALSE"
trainPositive<-subset(iris,SpeciesClass=="TRUE")
testnegative<-subset(iris,SpeciesClass=="FALSE")
inTrain<-createDataPartition(1:nrow(trainPositive),p=0.6,list=FALSE)

trainpredictors<-trainPositive[inTrain,1:4]
trainLabels<-trainPositive[inTrain,6]

testPositive<-trainPositive[-inTrain,]
testPosNeg<-rbind(testPositive,testnegative)

testpredictors<-testPosNeg[,1:4]
testLabels<-testPosNeg[,6]

svm.model<-svm(trainpredictors,y=NULL,
               type='one-classification',
               nu=0.10,
               scale=TRUE,
               kernel="radial")

svm.predtrain<-predict(svm.model,trainpredictors)
svm.predtest<-predict(svm.model,testpredictors)

# confusionMatrixTable<-table(Predicted=svm.pred,Reference=testLabels)
# confusionMatrix(confusionMatrixTable,positive='TRUE')

confTrain<-table(Predicted=svm.predtrain,Reference=trainLabels)
confTest<-table(Predicted=svm.predtest,Reference=testLabels)

confusionMatrix(confTest,positive='TRUE')

print(confTrain)
print(confTest)

Share:
18,329
dreamscollector
Author by

dreamscollector

Updated on June 16, 2022

Comments

  • dreamscollector
    dreamscollector almost 2 years

    I'm using the package e1071 in R in order to build a one-class SVM model. I don't know how to do that and I neither find any example on the Internet.

    Could someone give an example code to characterize, for example, the class "setosa" in the "iris" dataset with a one-class classification model and then test all the examples in the same dataset (in order to check what examples belong to the characterization of the "setosa" class and what examples not)?

  • dreamscollector
    dreamscollector over 9 years
    Thank you very much for your very detailed code, but I think that one-class classification is a different thing. In one-class classification you only provide the examples of one of the classes to train the SVM. The model learns to characterize only this class (in the test phase you can only know if an example belongs or not to this class). I know that I have to use the option tpye = one-classification in the fuction svm, but I don't know how to do that exactly.
  • LyzandeR
    LyzandeR over 9 years
    Yeah. I figured it out now. I updated the answer. This is what you need :). Hope it helps and thanks for your comment before.
  • goangit
    goangit over 9 years
    @dreamscollector, weren't you asking for the classification of the remaining iris types using the model? That is, @LyzandeR, shouldn't your predictions be made as predict(model, subset(iris, select=-Species))?
  • dreamscollector
    dreamscollector over 9 years
    @goangit you are right, there is an error in the last code line. it is as you mentioned
  • goangit
    goangit over 9 years
    @dreamscollector, it's preferred to upvote the comment in that case :-)
  • LyzandeR
    LyzandeR over 9 years
    yeah thank's for the comment. I will fix the answer now. I just wanted to illustrate how to do the 1-class-classification. Didn't really notice that @dreamscollector wanted to test on the whole set. Sorry about that. P.S. If you check my answer you ll see that I mentioned that I test on the train set too. It was an honest mistake :P