通过查看
kernelMatrix
和
stringdot
的源代码,可以了解您的输入正在发生什么。
当一个列表作为
x
传递给
kernelMatrix
时,它会执行以下操作:
if (is(x, "list"))
x <- sapply(x, paste, collapse = "")
在您的情况下,这意味着您的
lst
输入变为
c("123", "321")
。
kernelMatrix
然后取这个向量,并生成具有以下模式的矩阵(其中
sk
是stringkernel函数):
sk("123", "123") sk("123", "321")
sk("321", "321")
下左角的单元格随后被填充为上右角,然后整个矩阵通过除以左上角单元格乘以右下角单元格的平方根来进行归一化。
您可以通过执行以下操作检查各个值是否匹配:
stringdot(type = "exponential", lambda = 1.2)(123, 321)
值得注意的是,在
type =“ exponential”
下,
length
参数没有任何作用。每种类型的
stringkernel
只有零个或一个参数,对于
exponential
,它是给出衰减的
lambda
。子字符串权重随着匹配子字符串变短而衰减,而
lambda
是衰减因子。
如手册所述,
stringdot(type =“ spectrum”)
使用
length
,仅匹配长度至少为该长度的子序列。由于
123
和
321
之间没有匹配的子字符串> = 2个字符,因此比较结果为零。
还应注意,换行符(
"\n"
)附加到每个字符串,并且即使是单个字符匹配,使用
type =“ exponential”
也将产生> 0的结果,因此不可能获得零的结果。例如:
stringdot(type = "exponential", lambda = 1.2)("blowfish", "mage")
最后,看起来@Rahul想要一个
Lodhi's 2002 algorithm的R语言实现。
kernlab
并没有实现这个算法,我也不知道是否有R包可以实现。似乎
github上有一个Python实现,但我还没有检查代码是否能运行,更别说是否能得到所需的输出了。如果有人有兴趣,可以重新在R中实现Python代码,如果觉得有用/必要的话。
针对评论的补充编辑:
归一化字符串核函数的结果取决于每个字符串与其自身相似的程度。
sk_u <- stringdot(type = "exponential", lambda = 1.2, normalized = FALSE)
sk_n <- stringdot(type = "exponential", lambda = 1.2, normalized = TRUE)
lapply(list(unnormalised = sk_u, normalised = sk_n), function(f) {
c(
"ab,xyzabqr" = f("ab", "xyzabqr"),
"ab,abpmnop" = f("ab", "abpmnop"),
"ab,ab" = f("ab"),
"xyzabqr,xyzabqr" = f("xyzabqr"),
"abpmnop,abpmnop" = f("abpmnop")
)
})
可以看出,未经归一化的情况下,两种比较的结果是相同的。然而,由于归一化的结果等于(例如)
sk_u("ab", "xyzabqr") / sqrt(sk_u("ab") * sk_u("xyzabqr"))
,因此
sk_n("ab", "xyzabqr")
得分更高的原因与
"abpmnop"
中有两个p有关。