[Yasomi-commits] r45 - in trunk/yasomi: . R inst/doc man src tests
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Apr 30 19:02:39 CEST 2011
Author: frossi
Date: 2011-04-30 19:02:38 +0200 (Sat, 30 Apr 2011)
New Revision: 45
Added:
trunk/yasomi/inst/doc/grids.Rnw
Modified:
trunk/yasomi/ChangeLog
trunk/yasomi/R/annealing.R
trunk/yasomi/R/generic.R
trunk/yasomi/R/kernel.R
trunk/yasomi/R/relational.R
trunk/yasomi/R/slow-versions.R
trunk/yasomi/R/som.R
trunk/yasomi/R/tune.R
trunk/yasomi/TODO
trunk/yasomi/man/batchsom.Rd
trunk/yasomi/man/batchsom.default.Rd
trunk/yasomi/man/batchsom.dist.Rd
trunk/yasomi/man/batchsom.kernelmatrix.Rd
trunk/yasomi/man/som.tunecontrol.Rd
trunk/yasomi/src/neighborhood.c
trunk/yasomi/src/neighborhood.h
trunk/yasomi/src/som.c
trunk/yasomi/tests/kernel.R
trunk/yasomi/tests/relational.R
Log:
Added a new neighbourhood kernel (zero one) and harmonized radius definition. Added supported for the kernel everywhere. Started to documented kernels and grids.
Modified: trunk/yasomi/ChangeLog
===================================================================
--- trunk/yasomi/ChangeLog 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/ChangeLog 2011-04-30 17:02:38 UTC (rev 45)
@@ -1,5 +1,53 @@
2011-04-30 Fabrice Rossi <Fabrice dot Rossi at apiacoa dot org>
+ * R/annealing.R (radius.exp): modified to accomodate for min.radius=0
+
+ * src/som.c: added the new kernel.
+
+ * tests/relational.R: added cut=0.
+
+ * tests/kernel.R: added cut=0.
+
+ * man/batchsom.Rd: added the new kernel.
+
+ * man/batchsom.kernelmatrix.Rd: added the new kernel.
+
+ * man/batchsom.dist.Rd: added the new kernel.
+
+ * man/batchsom.default.Rd: added the new kernel.
+
+ * man/som.tunecontrol.Rd: added the new kernel.
+
+ * R/tune.R (som.tunecontrol): added the new kernel.
+
+ * R/stochastic.R (ssom.default.R): added the new kernel.
+ (ssom.default): ditto.
+
+ * R/som.R (batchsom.default): added the new kernel.
+
+ * R/relational.R (batchsom.dist): added the new kernel.
+
+ * R/kernel.R (batchsom.kernelmatrix): added the new kernel.
+
+ * R/generic.R (batchsom): added the new kernel.
+ (batchsom.control): ditto.
+
+ * R/annealing.R (batchsom.control.default): added support for the zero one kernel and fix default min.radius to accomodate the revised kernel formulae.
+
+ * R/slow-versions.R (neighborhood): transmits now the radius to kernel functions.
+ (kernel.gaussian): rewritten to reflect the vignette.
+ (kernel.linear): rewritten to reflect the vignette.
+ (kernel.zeroone): new kernel.
+ (batchsom.R): added support for the new zero one kernel.
+
+ * inst/doc/grids.Rnw: new vignette about structures and neighbourhoods
+
+ * src/neighborhood.c (neighborhood): fixed formulas and added the new kernel.
+ (neighborhood_single): ditto.
+
+ * src/neighborhood.h (enum): added a new kernel type (zero one)
+ (GAUSSIAN_COEFF): normalisation constant for the gaussian kernel
+
* src/neighborhood.c (neighborhood_single): new function that computes the neighborhood values around a single unit rather than around all units.
* src/neighborhood.h: header of the new function (see above).
Modified: trunk/yasomi/R/annealing.R
===================================================================
--- trunk/yasomi/R/annealing.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/annealing.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -1,5 +1,5 @@
radius.exp <- function(min,max,steps) {
- max*(min/max)^(seq(0,1,length.out=steps))
+ max*((min+1)/max)^(seq(0,1,length.out=steps))-1
}
radius.lin <- function(min,max,steps) {
@@ -10,26 +10,26 @@
mode = c("continuous","stepwise"),
min.radius, max.radius, steps,
decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"),
+ kernel = c("gaussian", "linear", "zeroone"),
normalised,
assignment = c("single", "heskes"),
cut = 1e-07,...)
{
mode <- match.arg(mode,c("continuous","stepwise"))
decrease <- match.arg(decrease,c("power","linear"))
- kernel <- match.arg(kernel,c("gaussian","linear"))
+ kernel <- match.arg(kernel,c("gaussian","linear","zeroone"))
assignment <- match.arg(assignment,c("single", "heskes"))
if(missing(max.radius)) {
max.radius <- 2/3*somgrid$diam+1
}
if(missing(min.radius)) {
- min.radius <- switch(kernel,"gaussian"=0.5,"linear"=1)
+ min.radius <- 0
}
if(max.radius<=min.radius) {
stop("max.radius must be larger than min.radius")
}
- if(min.radius<=0) {
- stop("min.radius must be positive")
+ if(min.radius<0) {
+ stop("min.radius must be non negative")
}
if(missing(steps)) {
steps <- switch(mode,
Modified: trunk/yasomi/R/generic.R
===================================================================
--- trunk/yasomi/R/generic.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/generic.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -26,7 +26,7 @@
mode = c("continuous","stepwise"),
min.radius, max.radius, steps,
decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"), normalised,
assignment = c("single", "heskes"),
cut = 1e-07,
verbose=FALSE,keepdata=TRUE,...) {
@@ -46,7 +46,7 @@
mode = c("continuous","stepwise"),
min.radius, max.radius, steps,
decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"),
+ kernel = c("gaussian", "linear", "zeroone"),
normalised,
assignment = c("single", "heskes"),
cut = 1e-07,...) {
Modified: trunk/yasomi/R/kernel.R
===================================================================
--- trunk/yasomi/R/kernel.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/kernel.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -365,7 +365,8 @@
mode = c("continuous","stepwise"),
min.radius, max.radius, steps,
decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"),
+ normalised,
assignment = c("single", "heskes"),
cut = 1e-07,
verbose=FALSE,keepdata=TRUE,...) {
@@ -379,7 +380,7 @@
}
the.call[[1]] <- batchsom.control
control <- eval(the.call,envir = parent.frame())
- control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear)
+ control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear,"zeroone"=kernel.zeroone)
if(!missing(weights)) {
if(length(weights)!=nrow(data)) {
stop("'weights' and 'data' have different dimensions")
Modified: trunk/yasomi/R/relational.R
===================================================================
--- trunk/yasomi/R/relational.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/relational.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -410,7 +410,8 @@
mode = c("continuous","stepwise"),
min.radius, max.radius, steps,
decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"),
+ normalised,
assignment = c("single", "heskes"),
cut = 1e-07,
verbose=FALSE,keepdata=TRUE,...) {
@@ -425,7 +426,7 @@
# the.call[[1]] <- as.name("batchsom.control")
the.call[[1]] <- batchsom.control
control <- eval(the.call,envir = parent.frame())
- control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear)
+ control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear,"zeroone"=kernel.zeroone)
if(!missing(weights)) {
if(length(weights)!=nrow(data)) {
stop("'weights' and 'data' have different dimensions")
Modified: trunk/yasomi/R/slow-versions.R
===================================================================
--- trunk/yasomi/R/slow-versions.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/slow-versions.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -1,5 +1,5 @@
-neighborhood <- function(somgrid,T,kernel,normalised=TRUE) {
- raw <- kernel(somgrid$dist/T)
+neighborhood <- function(somgrid,R,kernel,normalised=TRUE) {
+ raw <- kernel(R,somgrid$dist)
if(normalised) {
sweep(raw,1,rowSums(raw),"/")
} else {
@@ -7,14 +7,12 @@
}
}
-kernel.gaussian <- function(x) {
- exp(-(3*x)^2/2)
+kernel.gaussian <- function(R,x) {
+ exp(-4.605170185988090914009*(x/(R+1))^2)
}
-kernel.linear <- function(x) {
- pre <- sapply(x,function(x) {
- if(x<1) {1-x} else {0}
- })
+kernel.linear <- function(R,x) {
+ pre <- ifelse(x<R+1,1-x/(R+1),0)
if(is.matrix(x)) {
matrix(pre,ncol=ncol(x),nrow=nrow(x))
} else {
@@ -22,6 +20,10 @@
}
}
+kernel.zeroone <- function(R,x) {
+ ifelse(x<=R,1,0)
+}
+
bmu.R <- function(prototypes,data,weights) {
distances <- dist(prototypes,data)
clusters <- apply(distances,2,which.min)
@@ -46,14 +48,15 @@
}
batchsom.R <- function(data,somgrid,init=c("pca","random"),prototypes,
- weights,
- mode = c("continuous","stepwise"),
- min.radius, max.radius, steps,
- decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
- assignment = c("single", "heskes"),
- cut = 1e-07,
- verbose=FALSE,keepdata=TRUE,...) {
+ weights,
+ mode = c("continuous","stepwise"),
+ min.radius, max.radius, steps,
+ decrease = c("power", "linear"), max.iter,
+ kernel = c("gaussian", "linear", "zeroone"),
+ normalised,
+ assignment = c("single", "heskes"),
+ cut = 1e-07,
+ verbose=FALSE,keepdata=TRUE,...) {
## process parameters and perform a few sanity checks
if(class(somgrid)!="somgrid") {
stop("'somgrid' is not of somgrid class")
@@ -67,7 +70,7 @@
if(control$mode=="continuous") {
stop("continuous annealing mode is unsupported in batchsom.R")
}
- control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear)
+ control$kernel.fun <- switch(control$kernel,"gaussian"=kernel.gaussian,"linear"=kernel.linear,"zeroone"=kernel.zeroone)
if(!missing(weights)) {
if(length(weights)!=nrow(data)) {
Modified: trunk/yasomi/R/som.R
===================================================================
--- trunk/yasomi/R/som.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/som.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -125,7 +125,8 @@
mode = c("continuous","stepwise"),
min.radius, max.radius, steps,
decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"),
+ normalised,
assignment = c("single", "heskes"),
cut = 1e-07,
verbose=FALSE,keepdata=TRUE,...) {
@@ -139,7 +140,7 @@
the.call[[1]] <- batchsom.control
control <- eval(the.call,envir = parent.frame())
control$assignment.int <- switch(control$assignment,"single"=0,"heskes"=1)
- control$kernel.int <- switch(control$kernel,"gaussian"=0,"linear"=1)
+ control$kernel.int <- switch(control$kernel,"gaussian"=0,"linear"=1,"zeroone"=2)
if(!missing(weights)) {
if(length(weights)!=nrow(data)) {
stop("'weights' and 'data' have different dimensions")
@@ -336,7 +337,7 @@
cat(" grid: ",object$somgrid$topo," grid of size ",
object$somgrid$xdim,"x",object$somgrid$ydim," with diameter ",
object$somgrid$diam,"\n",sep="")
- cat(" kernel: ",object$control$kernel,
+ cat(" kernel:",object$control$kernel,
if(!object$control$normalised) {" not normalised"} else {" normalised"},
"\n",sep="")
cat(" assignment:",object$control$assignment,"\n")
Modified: trunk/yasomi/R/tune.R
===================================================================
--- trunk/yasomi/R/tune.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/R/tune.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -14,7 +14,8 @@
innernradii=innernradii,
maxiter=maxiter,
annealing=match.arg(annealing,c("power","linear"),several.ok = TRUE),
- kernel=match.arg(kernel,c("gaussian","linear"),several.ok = TRUE),
+ kernel=match.arg(kernel,c("gaussian","linear", "zeroone"),
+ several.ok = TRUE),
criterion=criterion)
}
Modified: trunk/yasomi/TODO
===================================================================
--- trunk/yasomi/TODO 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/TODO 2011-04-30 17:02:38 UTC (rev 45)
@@ -21,6 +21,7 @@
- possibly in predict.* (for the error calculation)
- fix the border "problem" in plot.somgrid
- do we need a final assigment in the continuous annealing case?
+- neighborhood kernels are not documented
+ Long term R goals:
- move to S4 classes
Added: trunk/yasomi/inst/doc/grids.Rnw
===================================================================
--- trunk/yasomi/inst/doc/grids.Rnw (rev 0)
+++ trunk/yasomi/inst/doc/grids.Rnw 2011-04-30 17:02:38 UTC (rev 45)
@@ -0,0 +1,102 @@
+%% -*- ispell-dictionary: "british" -*-
+% \VignetteIndexEntry{Prior structures and neighbourhoods in YASOMI}
+% \VignetteDepends{e1071, proxy, colorspace}
+% \VignetteKeyword{Self Organising Map}
+% \VignetteKeyword{Self Organizing Map}
+% \VignetteKeyword{Neighbourhoods}
+% \VignetteKeyword{Neighborhoods}
+% \VignetteKeyword{Clustering}
+
+\documentclass[a4paper]{article}
+\usepackage{amsmath}
+
+\begin{document}
+\title{Prior structures and neighbourhoods in YASOMI}
+\author{Fabrice Rossi}
+
+\SweaveOpts{width=7,height=5}
+
+\maketitle
+
+\section{Prior structures}
+
+\section{Neighbourhoods}
+Self Organising Map fitting is based on a form of annealing implemented by a
+shrinking neighbour influence in the prior structure: when the prototype
+associated to cell $i$ (in the prior structure) is updated, then all other
+prototypes are updated similarly but with an update magnitude that decreases
+with the distance between cell $i$ and the cell of the updated prototype. For
+instance, in the stochastic SOM, the update of prototype $j$ at step $t$ is
+given by
+\[
+p^{(t)}_j=p^{(t-1)}_j+\varepsilon^{(t)}N^{(t)}(i,j)\left(x^{(t)}-p^{(t-1)}_i\right),
+\]
+where $x^{(t)}$ is the data point considered at step $t$, $i$ is the best
+matching unit for this data point, $\varepsilon^{(t)}$ the learning rate and
+$N^{(t)}(i,j)$ the neighbouring influence between cells $i$ and $j$.
+
+The classical form for $N^{(t)}(i,j)$ is
+\[
+N^{(t)}(i,j)=K(R^{(t)},d_p(i,j)),
+\]
+where $d_p$ is a distance between units in the prior structure (see previous
+Section for details, $R^{(t)}$ is a radius of influence, which decreases
+during the fitting process, and $K(R,.)$ is a so-called \emph{kernel function}
+which maps $[0,\infty[$ to $[0,1]$. $K(R,.)$ should be decreasing from $1$ to
+$0$ at a speed specified by $R$.
+
+To make the last assumption precise, yasomi uses the following conventions:
+\begin{enumerate}
+\item $K(R,.)$ is decreasing;
+\item $K(R,0)=1$;
+\item $K(R,R+1)\leq 0.01$.
+\end{enumerate}
+There are currently three kernel included in yasomi:
+\begin{description}
+\item[zero one] this kernel has binary outputs, that is
+ $K_{01}(R,.)\in\{0,1\}$. The $R$ parameter gives the radius of influence of the
+ kernel which is simply defined as follows:
+\[
+K_{01}(R,d)=
+\begin{cases}
+0 & \text{if $d>R$},\\
+1 & \text{if $d\leq R$}.
+\end{cases}
+\]
+\item[linear] this kernel replaces the strong one to zero jump of the previous
+ kernel by a linear decrease. In this case, $R+1$ gives the end of influence
+ of the kernel. It is defined has follows:
+\[
+K_{lin}(R,d)=
+\begin{cases}
+0 & \text{if $d\geq R+1$},\\
+1-\frac{d}{R+1} & \text{if $d<R+1$}.
+\end{cases}
+\]
+\item[gaussian] this kernel is a smooth version of the linear kernel and uses
+ the same convention that $R+1$ is the end of influence. The kernel is given
+ by
+\[
+K_{gaussian}(R,d)=\exp^{b\frac{d^2}{(R+1)^2}},
+\]
+with $b=\ln(0.01)$.
+\end{description}
+Figure \ref{fig:kernels} shows the behaviour of the three kernels for $R=2$.
+
+\begin{figure}[htbp]
+ \begin{center}
+<<echo=FALSE,fig=TRUE>>=
+distances <- seq(0,5,length.out=101)
+R <- 2
+b <- log(0.01)
+plot(distances,ifelse(distances<=R,1,0),type="l",lwd=2,main="R=2",ylab="kernel function")
+lines(distances,ifelse(distances<=R+1,1-distances/(R+1),0),col="red",lwd=2)
+lines(distances,exp(b*(distances/(R+1))^2),col="blue",lwd=2)
+legend("topright",legend=c("zero one","linear","gaussian"),lwd=2,col=c("black","red","blue"))
+@
+\end{center}
+
+\caption{Three kernel functions computed for $R=2$}
+\label{fig:kernels}
+\end{figure}
+\end{document}
Modified: trunk/yasomi/man/batchsom.Rd
===================================================================
--- trunk/yasomi/man/batchsom.Rd 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/man/batchsom.Rd 2011-04-30 17:02:38 UTC (rev 45)
@@ -8,7 +8,7 @@
batchsom(data, somgrid, init=c("pca","random"), prototypes, weights,
mode = c("continuous","stepwise"), min.radius, max.radius,
steps, decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"), normalised,
assignment = c("single", "heskes"), cut = 1e-07,
verbose = FALSE, keepdata = TRUE, \dots)
}
@@ -39,8 +39,8 @@
}
}
\item{min.radius}{the minimum neighbourhood influence radius. If
- missing, the value depends on the one of \code{kernel} but ensures
- in practice a local learning only (see details)}
+ missing, the value might depend on the one of \code{kernel} but ensures
+ in practice a local learning only (currently defaults to one)}
\item{max.radius}{the maximal neighbourhood influence radius. If missing
two third of the prior structure diameter plus one}
\item{steps}{the number of radii to use during annealing}
Modified: trunk/yasomi/man/batchsom.default.Rd
===================================================================
--- trunk/yasomi/man/batchsom.default.Rd 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/man/batchsom.default.Rd 2011-04-30 17:02:38 UTC (rev 45)
@@ -10,7 +10,7 @@
prototypes,weights,
mode = c("continuous","stepwise"), min.radius, max.radius,
steps, decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"), normalised,
assignment = c("single", "heskes"), cut = 1e-07,
verbose = FALSE, keepdata = TRUE, \dots)
}
@@ -42,8 +42,8 @@
}
}
\item{min.radius}{the minimum neighbourhood influence radius. If
- missing, the value depends on the one of \code{kernel} but ensures
- in practice a local learning only (see details)}
+ missing, the value might depend on the one of \code{kernel} but ensures
+ in practice a local learning only (currently defaults to one)}
\item{max.radius}{the maximal neighbourhood influence radius. If missing
two third of the prior structure diameter plus one}
\item{steps}{the number of radii to use during annealing}
Modified: trunk/yasomi/man/batchsom.dist.Rd
===================================================================
--- trunk/yasomi/man/batchsom.dist.Rd 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/man/batchsom.dist.Rd 2011-04-30 17:02:38 UTC (rev 45)
@@ -10,7 +10,7 @@
prototypes,weights,
mode = c("continuous","stepwise"), min.radius, max.radius,
steps, decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"), normalised,
assignment = c("single", "heskes"), cut = 1e-07,
verbose = FALSE, keepdata = TRUE, \dots)
}
@@ -46,8 +46,8 @@
}
}
\item{min.radius}{the minimum neighbourhood influence radius. If
- missing, the value depends on the one of \code{kernel} but ensures
- in practice a local learning only (see details)}
+ missing, the value might depend on the one of \code{kernel} but ensures
+ in practice a local learning only (currently defaults to one)}
\item{max.radius}{the maximal neighbourhood influence radius. If missing
two third of the prior structure diameter plus one}
\item{steps}{the number of radii to use during annealing}
Modified: trunk/yasomi/man/batchsom.kernelmatrix.Rd
===================================================================
--- trunk/yasomi/man/batchsom.kernelmatrix.Rd 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/man/batchsom.kernelmatrix.Rd 2011-04-30 17:02:38 UTC (rev 45)
@@ -10,7 +10,7 @@
prototypes,weights,
mode = c("continuous","stepwise"), min.radius, max.radius,
steps, decrease = c("power", "linear"), max.iter,
- kernel = c("gaussian", "linear"), normalised,
+ kernel = c("gaussian", "linear", "zeroone"), normalised,
assignment = c("single", "heskes"), cut = 1e-07,
verbose = FALSE, keepdata = TRUE, \dots)
}
@@ -45,8 +45,8 @@
}
}
\item{min.radius}{the minimum neighbourhood influence radius. If
- missing, the value depends on the one of \code{kernel} but ensures
- in practice a local learning only (see details)}
+ missing, the value might depend on the one of \code{kernel} but ensures
+ in practice a local learning only (currently defaults to one)}
\item{max.radius}{the maximal neighbourhood influence radius. If missing
two third of the prior structure diameter plus one}
\item{steps}{the number of radii to use during annealing}
Modified: trunk/yasomi/man/som.tunecontrol.Rd
===================================================================
--- trunk/yasomi/man/som.tunecontrol.Rd 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/man/som.tunecontrol.Rd 2011-04-30 17:02:38 UTC (rev 45)
@@ -34,7 +34,8 @@
fitting (see \code{\link{batchsom}})}
\item{annealing}{annealing scheme with valid values \code{"power"}
(exponential like annealing) and \code{"linear"} (linear scheme)}
- \item{kernel}{kernel chosen between \code{"gaussian"} and \code{"linear"}}
+ \item{kernel}{kernel chosen between \code{"gaussian"}, \code{"linear"}
+ and \code{"zeroone"}}
\item{criterion}{an error criterion, i.e., a function that evaluate
the quality of a fitted som on a dataset}
}
Modified: trunk/yasomi/src/neighborhood.c
===================================================================
--- trunk/yasomi/src/neighborhood.c 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/src/neighborhood.c 2011-04-30 17:02:38 UTC (rev 45)
@@ -4,7 +4,7 @@
/* Neighborhood function calculation. The kernel functions are defined such
that neighborhood(x,y) is approximatly zero when the distance between x and
- y is higher than the radius parameter.
+ y is higher or equal to the radius parameter plus one.
When normalized, a row major approach is used to preserve memory locality. */
void neighborhood(double *distances,double *nv,int nbUnit,double radius,
@@ -18,19 +18,25 @@
switch(eKernelType) {
case gaussian:
/* Gaussian kernel */
- radius /= 3;
for(i = 0 ; i < size; i++) {
- tmp = distances[i]/radius;
- nv[i] = exp (-0.5*tmp*tmp);
+ tmp = distances[i]/(radius+1);
+ nv[i] = exp (GAUSSIAN_COEFF*tmp*tmp);
}
break;
case linear:
/* Linear kernel */
for(i = 0 ; i < size; i++) {
tmp = distances[i];
- nv[i] = tmp < radius ? (1-tmp/radius) : 0;
+ nv[i] = tmp < radius + 1 ? (1-tmp/(radius+1)) : 0;
}
break;
+ case zeroone:
+ /* Zero one kernel */
+ for(i = 0 ; i < size; i++) {
+ tmp = distances[i];
+ nv[i] = tmp <= radius ? 1 : 0;
+ }
+ break;
}
if(isNormalized) {
for(i = 0 ; i < nbUnit; i++) {
@@ -58,19 +64,25 @@
switch(eKernelType) {
case gaussian:
/* Gaussian kernel */
- theRadius /= 3;
for(i = 0 ; i < nb; i++) {
- tmp = distances[i]/theRadius;
- nv[i] = exp (-0.5*tmp*tmp);
+ tmp = distances[i]/(theRadius+1);
+ nv[i] = exp (GAUSSIAN_COEFF*tmp*tmp);
}
break;
case linear:
/* Linear kernel */
for(i = 0 ; i < nb; i++) {
tmp = distances[i];
- nv[i] = tmp < theRadius ? (1-tmp/theRadius) : 0;
+ nv[i] = tmp < theRadius + 1 ? (1-tmp/(theRadius+1)) : 0;
}
break;
+ case zeroone:
+ /* Zero one kernel */
+ for(i = 0 ; i < nb; i++) {
+ tmp = distances[i];
+ nv[i] = tmp <= theRadius ? 1 : 0;
+ }
+ break;
}
if(*isNormalized) {
tmp = 0;
Modified: trunk/yasomi/src/neighborhood.h
===================================================================
--- trunk/yasomi/src/neighborhood.h 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/src/neighborhood.h 2011-04-30 17:02:38 UTC (rev 45)
@@ -3,9 +3,12 @@
typedef enum {
gaussian = 0,
- linear = 1
+ linear = 1,
+ zeroone = 2
} kernel_type;
+#define GAUSSIAN_COEFF -4.605170185988090914009
+
void neighborhood(double *distances,double *nv,int nbUnit,double radius,
int kernelType,int isNormalized);
Modified: trunk/yasomi/src/som.c
===================================================================
--- trunk/yasomi/src/som.c 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/src/som.c 2011-04-30 17:02:38 UTC (rev 45)
@@ -69,6 +69,9 @@
case 1:
Rprintf(" linear kernel");
break;
+ case 2:
+ Rprintf(" zero one kernel");
+ break;
}
switch(assignmentRule) {
case 0:
@@ -217,6 +220,9 @@
case 1:
Rprintf(" linear kernel");
break;
+ case 2:
+ Rprintf(" zero one kernel");
+ break;
}
switch(assignmentRule) {
case 0:
@@ -387,6 +393,9 @@
case 1:
Rprintf(" linear kernel");
break;
+ case 2:
+ Rprintf(" zero one kernel");
+ break;
}
switch(assignmentRule) {
case 0:
Modified: trunk/yasomi/tests/kernel.R
===================================================================
--- trunk/yasomi/tests/kernel.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/tests/kernel.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -25,9 +25,9 @@
kprototypes.final <- ksom$prototypes%*%X
## and now the same thing for the standard vector SOM
-
+## cut=0 is needed as the kernel SOM does not provide the cutting feature
som <- batchsom(X,sg,prototypes=prototypes.init,verbose=TRUE,
- max.radius=radius.max,steps=nb.radii,mode=mode)
+ max.radius=radius.max,steps=nb.radii,mode=mode,cut=0)
stopifnot(all.equal(error.kaskilagus(som),error.kaskilagus(ksom)))
stopifnot(all.equal(error.quantisation(som),error.quantisation(ksom)))
Modified: trunk/yasomi/tests/relational.R
===================================================================
--- trunk/yasomi/tests/relational.R 2011-04-30 12:27:33 UTC (rev 44)
+++ trunk/yasomi/tests/relational.R 2011-04-30 17:02:38 UTC (rev 45)
@@ -25,9 +25,9 @@
rprototypes.final <- rsom$prototypes%*%X
## and now the same thing for the standard vector SOM
-
+## cut=0 is needed as the dissimilarity SOM does not provide the cutting feature
som <- batchsom(X,sg,prototypes=prototypes.init,verbose=TRUE,
- max.radius=radius.max,steps=nb.radii,mode=mode)
+ max.radius=radius.max,steps=nb.radii,mode=mode,cut=0)
stopifnot(all.equal(error.kaskilagus(som),error.kaskilagus(rsom)))
stopifnot(all.equal(error.quantisation(som),error.quantisation(rsom)))
More information about the Yasomi-commits
mailing list