Predicting probabilities in a raster using SVM

rraster

I trained a SVM (Support Vector Machine) model using e1071 package as follows:

svm <- svm(class ~ ., data=train, type="C-classification", kernel="radial")

Now I am trying to predict the values and probabilities in a raster. Following the same approach as when I use randomForest. The following code correctly predicts the values:

r_pred <- raster::predict(model=svm, object=img)

However when using

r_prob <- raster::predict(model=svm, object=img, type="prob", index=1:length(unique(train[[1]])))

I get a RasterBrick with values from 1 to 3 (my labels) instead of 0 to 1 (probabilities).

> r_prob
class      : RasterBrick 
dimensions : 11276, 8878, 100108328, 3  (nrow, ncol, ncell, nlayers)
resolution : 1, 1  (x, y)
extent     : 744560, 753438, 4308462, 4319738  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=30 +ellps=GRS80 +units=m +no_defs 
source     : r_tmp_2021-11-22_125836_11220_94025.grd 
names      : layer.1, layer.2, layer.3 
min values :       1,       1,       1 
max values :       3,       3,       3 

Any solution without having to convert the RasterStack of predictors to data.frame and vice versa?

Best Answer

You have to at least fit and predict the model with probability=TRUE. Without it:

> svm = svm(class ~ ., data=train, type="C-classification", kernel="radial")
> p = predict(svm, data.frame(x0=runif(100)), probability=TRUE)
Warning message:
In predict.svm(svm, data.frame(x0 = runif(100)), probability = TRUE) :
  SVM has not been trained using `probability = TRUE`, probabilities not available for predictions.

So no probs:

> str(p)
Factor w/ 3 levels "A","B","C": 2 2 2 2 2 2 2 2 2 2 ...
 - attr(*, "names")= chr [1:100] "1" "2" "3" "4" ...

Try with:

> svm = svm(class ~ ., data=train, type="C-classification", kernel="radial",probability=TRUE)
> p = predict(svm, data.frame(x0=runif(100)), probability=TRUE)
> str(p)
 Factor w/ 3 levels "A","B","C": 2 2 2 2 2 2 2 2 2 2 ...
 - attr(*, "names")= chr [1:100] "1" "2" "3" "4" ...
 - attr(*, "probabilities")= num [1:100, 1:3] 0.414 0.409 0.39 0.389 0.412 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:100] "1" "2" "3" "4" ...
  .. ..$ : chr [1:3] "B" "C" "A"

and there's probabilities.

Note this is all not with raster::predict but you'll need to make this work in plain data first.

It looks to me like predict returns the predicted class but with the probabilities as attributes which might mean feeding an svm to raster::predict even with probability calculation on won't work, so you'll have to resort to predicting using the raster values as a data frame and then building an output raster from the probability attribute of the predict method on that data frame.

Related Question