Kernels, SVM and a Letter Recognition Example

This article is still about SVM and related parameters, especially the one called Kernel.

We can use different Kernel methods to project or map data into higher dimension space. This would be typically useful for non-linear problems in real life.

screen-shot-2017-03-05-at-8-19-22-pm

The linear kernel does not transform the data at all

screen-shot-2017-03-05-at-8-26-28-pm

The polynomial kernel of degree d adds a simple nonlinear transformation of the data

screen-shot-2017-03-05-at-8-26-31-pm

The sigmoid kernel results in a SVM model somewhat analogous to a neural network using a sigmoid activation function.

screen-shot-2017-03-05-at-8-26-35-pm

The Gaussian RBF kernel is similar to a RBF neural network. The RBF kernel performs well on many types of data and is thought to be a reasonable starting point for many learning tasks:

screen-shot-2017-03-05-at-8-26-40-pm

Now we use SVM function within kernlab package in R to build classifier for hand written letters.

When the glyphs are scanned into the computer, they are converted into pixels and 16 statistical attributes are recorded.

Data source: (http://archive.ics.uci.edu/ml)


hwl<-read.csv("letterdata.csv")
str(hwl)

## 'data.frame':    20000 obs. of  17 variables:
##  $ letter: Factor w/ 26 levels "A","B","C","D",..: 20 9 4 14 7 19 2 1 10 13 ...
##  $ xbox  : int  2 5 4 7 2 4 4 1 2 11 ...
##  $ ybox  : int  8 12 11 11 1 11 2 1 2 15 ...
##  $ width : int  3 3 6 6 3 5 5 3 4 13 ...
##  $ height: int  5 7 8 6 1 8 4 2 4 9 ...
##  $ onpix : int  1 2 6 3 1 3 4 1 2 7 ...
##  $ xbar  : int  8 10 10 5 8 8 8 8 10 13 ...
##  $ ybar  : int  13 5 6 9 6 8 7 2 6 2 ...
##  $ x2bar : int  0 5 2 4 6 6 6 2 2 6 ...
##  $ y2bar : int  6 4 6 6 6 9 6 2 6 2 ...
##  $ xybar : int  6 13 10 4 6 5 7 8 12 12 ...
##  $ x2ybar: int  10 3 3 4 5 6 6 2 4 1 ...
##  $ xy2bar: int  8 9 7 10 9 6 6 8 8 9 ...
##  $ xedge : int  0 2 3 6 1 0 2 1 1 8 ...
##  $ xedgey: int  8 8 7 10 7 8 8 6 6 1 ...
##  $ yedge : int  0 4 3 2 5 9 7 2 1 1 ...
##  $ yedgex: int  8 10 9 8 10 7 10 7 7 8 ...

order<-sample(20000,16000)
hwltrain<-hwl[order,]
hwltest<-hwl[-order,]
# We used e1071 for digits recognition, today we use kernlab for letters
library(kernlab)
#vanilladot is the linear kernel
orc01<-ksvm(letter~.,data=hwltrain,kernel="vanilladot")

##  Setting default kernel parameters

summary(orc01)

## Length  Class   Mode
##      1   ksvm     S4

orc01pr<-predict(orc01,hwltest)
table(orc01pr,hwltest$letter)

##
## orc01pr   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P
##       A 136   1   0   0   0   1   0   0   0   2   0   0   1   0   1   0
##       B   0 124   0   2   2   1   0   3   0   0   1   0   0   0   0   0
##       C   0   0 137   0   5   0  10   3   1   0   0   2   0   0   1   0
##       D   1   1   0 157   0   2   6  10   2   1   1   1   0   3   4   0
##       E   0   1   4   0 134   1   3   1   0   0   3   6   0   0   0   1
##       F   0   1   0   0   0 153   1   8   4   0   0   0   0   0   0  10
##       G   0   1   6   0   5   0 129   0   0   0   3   5   0   0   1   4
##       H   0   1   1   3   0   0   0  94   0   1   0   0   0   3  10   0
##       I   0   0   0   0   0   1   0   0 130   3   0   0   0   0   0   0
##       J   0   2   0   0   0   1   0   2   9 124   0   0   0   0   0   0
##       K   1   1   6   2   1   0   2   5   0   0 115   0   1   0   0   0
##       L   0   0   1   0   2   0   2   0   1   0   3 123   0   0   0   0
##       M   1   0   0   0   0   0   2   0   0   0   0   0 134   3   1   0
##       N   0   0   0   3   0   0   0   0   0   1   0   0   0 159   0   0
##       O   0   0   1   1   0   0   1   2   0   0   0   0   0   1 101   3
##       P   0   0   0   2   0   0   1   2   0   0   0   0   0   0   0 149
##       Q   0   0   0   0   1   0   4   3   0   0   0   4   0   0   0   0
##       R   0   5   0   2   1   1   0   6   0   0   9   0   1   2   3   0
##       S   1   0   0   0   5   2   3   0   3   3   0   2   0   0   0   0
##       T   0   0   1   0   1   4   0   0   0   0   0   0   0   0   0   0
##       U   1   0   0   1   0   1   0   2   0   0   1   0   3   1   0   0
##       V   0   1   0   0   0   0   4   0   0   0   0   0   1   1   0   0
##       W   0   0   0   0   0   0   1   0   0   0   1   0   2   0   5   0
##       X   0   1   0   0   2   0   1   1   3   1   5   1   0   0   0   0
##       Y   2   0   0   0   0   0   0   0   0   0   0   0   0   0   0   6
##       Z   0   0   0   0   3   0   0   0   1   1   0   0   0   0   0   0
##
## orc01pr   Q   R   S   T   U   V   W   X   Y   Z
##       A   1   1   2   0   1   0   0   0   0   2
##       B   4  10  10   0   0   3   0   1   0   0
##       C   0   0   0   0   0   0   0   0   0   0
##       D   0   1   0   0   0   0   0   2   1   0
##       E   7   0   6   2   0   0   0   0   0   3
##       F   0   0   2   3   0   0   0   0   2   0
##       G   9   1   3   2   0   0   1   0   0   0
##       H   1   5   0   2   2   3   0   1   1   0
##       I   0   0   6   0   0   0   0   2   0   1
##       J   1   0   2   0   0   0   0   0   0   4
##       K   0   5   0   1   0   1   0   5   0   0
##       L   1   0   2   0   0   0   0   1   0   0
##       M   0   1   0   0   1   1   3   0   0   0
##       N   0   2   0   0   0   1   1   0   1   0
##       O   6   1   0   0   3   0   2   1   0   0
##       P   1   0   0   0   0   0   0   0   0   0
##       Q 119   0   5   0   0   0   0   0   1   1
##       R   0 119   1   0   0   2   0   1   0   0
##       S  13   0 104   1   0   0   0   0   0  11
##       T   0   0   5 151   0   1   0   1   9   0
##       U   0   0   0   0 155   0   0   0   1   0
##       V   0   0   0   0   0 139   0   0   4   0
##       W   0   0   0   0   1   2 155   0   0   0
##       X   0   1   2   0   0   0   0 131   1   0
##       Y   1   0   0   1   0   2   0   0 119   0
##       Z   0   0  16   4   0   0   0   0   0 120

orc01error<-(sum(orc01pr!=hwltest$letter)/nrow(hwltest))
orc01error

## [1] 0.14725

print(paste0("Accuary(Precision) of Ksvm with linear kernel: ",1-orc01error))

## [1] "Accuary(Precision) of Ksvm with linear kernel: 0.85275"

# Tune with RBF to project data into Gaussian space
orc02<-ksvm(letter~.,data=hwltrain,kernel="rbfdot")
summary(orc02)

## Length  Class   Mode
##      1   ksvm     S4

orc02pr<-predict(orc02,hwltest)
table(orc02pr,hwltest$letter)

##
## orc02pr   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P
##       A 139   0   0   0   0   0   0   0   0   0   0   0   1   0   0   0
##       B   0 132   0   2   4   1   0   2   0   0   0   0   1   0   0   0
##       C   1   0 147   0   1   0   2   0   1   0   1   1   0   0   0   0
##       D   1   2   0 162   0   0   5   4   0   1   1   0   0   0   2   0
##       E   0   0   3   0 147   0   1   0   0   0   0   4   0   0   0   2
##       F   0   1   0   0   0 161   0   2   4   0   0   0   0   0   0   4
##       G   0   1   4   0   5   0 154   0   0   0   0   4   0   0   0   2
##       H   0   1   0   4   0   2   1 118   0   0   0   0   0   0   0   1
##       I   0   0   0   0   0   1   0   0 140   1   0   0   0   0   0   0
##       J   0   0   0   0   0   0   0   0   5 129   0   0   0   0   0   0
##       K   0   0   0   0   0   0   0   1   0   0 129   0   0   0   0   0
##       L   0   0   0   0   0   0   0   0   0   0   0 132   0   0   0   0
##       M   1   0   0   0   0   0   1   0   0   0   0   0 141   2   0   0
##       N   0   0   0   1   0   0   0   0   0   1   0   0   0 162   0   0
##       O   0   0   2   1   0   0   3   1   0   0   0   0   0   5 120   1
##       P   0   0   0   1   0   1   0   3   0   0   0   0   0   0   0 161
##       Q   0   0   0   0   1   0   0   3   0   0   0   1   0   0   1   0
##       R   0   2   1   2   0   0   1   7   0   0   6   0   0   3   2   0
##       S   0   0   0   0   1   1   0   0   1   2   0   0   0   0   0   0
##       T   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
##       U   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
##       V   0   0   0   0   0   0   1   1   0   0   0   0   0   0   0   0
##       W   0   0   0   0   0   0   1   0   0   0   1   0   0   1   2   0
##       X   0   1   0   0   0   0   0   0   2   2   4   2   0   0   0   0
##       Y   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   2
##       Z   0   0   0   0   3   0   0   0   1   1   0   0   0   0   0   0
##
## orc02pr   Q   R   S   T   U   V   W   X   Y   Z
##       A   0   0   1   0   0   0   0   0   0   1
##       B   2   3   2   0   0   8   0   1   0   0
##       C   0   0   0   0   0   0   0   0   0   0
##       D   0   0   0   0   0   0   0   2   0   0
##       E   3   0   0   0   0   0   0   0   0   1
##       F   0   0   2   2   0   0   0   0   0   0
##       G   2   0   0   1   0   0   1   0   0   0
##       H   1   2   0   1   0   1   0   0   0   0
##       I   0   0   0   0   0   0   0   1   0   0
##       J   0   0   0   0   0   0   0   0   0   1
##       K   0   1   0   1   0   0   0   3   0   0
##       L   0   0   0   0   0   0   0   0   0   0
##       M   0   0   0   0   0   0   2   0   0   0
##       N   0   2   0   0   0   0   0   0   0   0
##       O   6   0   0   0   0   0   3   0   0   0
##       P   0   0   0   0   0   0   0   0   1   0
##       Q 148   0   0   0   0   0   0   1   0   1
##       R   0 139   0   0   0   0   0   0   0   0
##       S   2   0 160   1   0   0   0   0   0   0
##       T   0   0   0 161   0   0   0   0   2   0
##       U   0   0   0   0 160   1   0   0   1   0
##       V   0   0   0   0   1 145   0   0   0   0
##       W   0   0   0   0   2   0 156   0   0   0
##       X   0   0   1   0   0   0   0 138   0   0
##       Y   0   0   0   0   0   0   0   0 136   0
##       Z   0   0   0   0   0   0   0   0   0 138

orc02error<-(sum(orc02pr!=hwltest$letter)/nrow(hwltest))
orc02error

## [1] 0.06125

print(paste0("Accuary(Precision) of Ksvm with RBF kernal: ",1-orc02error))

## [1] "Accuary(Precision) of Ksvm with RBF kernal: 0.93875"

# Tune with ploynomial Kernel to project data into ploynomial space
orc03<-ksvm(letter~.,data=hwltrain,kernel="polydot")

##  Setting default kernel parameters

summary(orc03)

## Length  Class   Mode
##      1   ksvm     S4

orc03pr<-predict(orc03,hwltest)
table(orc03pr,hwltest$letter)

##
## orc03pr   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P
##       A 136   1   0   0   0   1   0   0   0   2   0   0   1   0   1   0
##       B   0 124   0   2   2   1   0   3   0   0   1   0   0   0   0   0
##       C   0   0 137   0   5   0  10   3   1   0   0   2   0   0   1   0
##       D   1   1   0 157   0   2   6  10   2   1   1   1   0   3   4   0
##       E   0   1   4   0 134   1   3   1   0   0   3   6   0   0   0   1
##       F   0   1   0   0   0 153   1   8   4   0   0   0   0   0   0  10
##       G   0   1   6   0   5   0 129   0   0   0   3   5   0   0   1   4
##       H   0   1   1   3   0   0   0  94   0   1   0   0   0   3  10   0
##       I   0   0   0   0   0   1   0   0 130   3   0   0   0   0   0   0
##       J   0   2   0   0   0   1   0   2   9 124   0   0   0   0   0   0
##       K   1   1   6   2   1   0   2   5   0   0 115   0   1   0   0   0
##       L   0   0   1   0   2   0   2   0   1   0   3 123   0   0   0   0
##       M   1   0   0   0   0   0   2   0   0   0   0   0 134   3   1   0
##       N   0   0   0   3   0   0   0   0   0   1   0   0   0 159   0   0
##       O   0   0   1   1   0   0   1   2   0   0   0   0   0   1 101   3
##       P   0   0   0   2   0   0   1   2   0   0   0   0   0   0   0 149
##       Q   0   0   0   0   1   0   4   3   0   0   0   4   0   0   0   0
##       R   0   5   0   2   1   1   0   6   0   0   9   0   1   2   3   0
##       S   1   0   0   0   5   2   3   0   3   3   0   2   0   0   0   0
##       T   0   0   1   0   1   4   0   0   0   0   0   0   0   0   0   0
##       U   1   0   0   1   0   1   0   2   0   0   1   0   3   1   0   0
##       V   0   1   0   0   0   0   4   0   0   0   0   0   1   1   0   0
##       W   0   0   0   0   0   0   1   0   0   0   1   0   2   0   5   0
##       X   0   1   0   0   2   0   1   1   3   1   5   1   0   0   0   0
##       Y   2   0   0   0   0   0   0   0   0   0   0   0   0   0   0   6
##       Z   0   0   0   0   3   0   0   0   1   1   0   0   0   0   0   0
##
## orc03pr   Q   R   S   T   U   V   W   X   Y   Z
##       A   1   1   2   0   1   0   0   0   0   2
##       B   4  10  10   0   0   3   0   1   0   0
##       C   0   0   0   0   0   0   0   0   0   0
##       D   0   1   0   0   0   0   0   2   1   0
##       E   7   0   6   2   0   0   0   0   0   3
##       F   0   0   2   3   0   0   0   0   2   0
##       G   9   1   3   2   0   0   1   0   0   0
##       H   1   5   0   2   2   3   0   1   1   0
##       I   0   0   6   0   0   0   0   2   0   1
##       J   1   0   2   0   0   0   0   0   0   4
##       K   0   5   0   1   0   1   0   5   0   0
##       L   1   0   2   0   0   0   0   1   0   0
##       M   0   1   0   0   1   1   3   0   0   0
##       N   0   2   0   0   0   1   1   0   1   0
##       O   6   1   0   0   3   0   2   1   0   0
##       P   1   0   0   0   0   0   0   0   0   0
##       Q 119   0   5   0   0   0   0   0   1   1
##       R   0 119   1   0   0   2   0   1   0   0
##       S  13   0 104   1   0   0   0   0   0  11
##       T   0   0   5 151   0   1   0   1   9   0
##       U   0   0   0   0 155   0   0   0   1   0
##       V   0   0   0   0   0 139   0   0   4   0
##       W   0   0   0   0   1   2 155   0   0   0
##       X   0   1   2   0   0   0   0 131   1   0
##       Y   1   0   0   1   0   2   0   0 119   0
##       Z   0   0  16   4   0   0   0   0   0 120

orc03error<-(sum(orc03pr!=hwltest$letter)/nrow(hwltest))
orc03error

## [1] 0.14725

print(paste0("Accuary(Precision) of Ksvm with polynomial kernel: ",1-orc03error))

## [1] "Accuary(Precision) of Ksvm with polynomial kernel: 0.85275"

By using a more complex kernel function, we can map the data into a higher dimensional space, and potentially obtain a better model fit.  It can be challenging, however, to choose from the many different kernel functions. A popular convention is to begin with the Gaussian RBF kernel, which has been shown to perform well for many types of data.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s