我一直在使用“Kernlab”包中R中可用的stringdot函数。这是我的代码
library(kernlab)
x <- c("1","2","3")
y <- c("3","2","1")
lst <- list(x, y)
sk <- stringdot(length = 2, lambda = 1.2, type = "exponential", normalized = TRUE)
q <- kernelMatrix(sk,lst)
据我所知,指数内核将创建长度为2的子串。例如,这里的字符串将来自第一个向量的1-2,1-3,2-3
和来自第二个向量的3-2,3-1,2-1
。它将尝试通过创建给定长度的各种子字符串来匹配输入,并根据给定的lambda
值减少子字符串的权重。
根据我的预期,输出应包含(x,x)和(y,y)的值1和(x,y)的值0, 因为给定输入之间没有共同的子串,但输出显示(x,y)对的值为0.4723。
我不明白为什么x和y之间的相似性是0.4723。
答案 0 :(得分:2)
通过查看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)
#[1] 0.4723893
值得注意的是length
参数对type = "exponential"
没有任何作用。每种类型的stringkernel
只有零个或一个参数,而exponential
它的lambda
会产生衰减。子串重量随着匹配子串变短而衰减,lambda
为衰减因子。
stringdot(type = "spectrum")
使用length
并且仅匹配至少该长度的子序列。由于123
和321
之间没有匹配的子字符串&gt; = 2个字符,因此比较结果为零。
还应该注意,换行符("\n"
)会附加到每个字符串,即使单个字符匹配也会使用type = "exponential"
得到> 0的结果,所以它&#39;不可能得到零的结果。 e.g。
stringdot(type = "exponential", lambda = 1.2)("blowfish", "mage")
#[1] 0.05274495
最后,看起来@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")
)
})
#$unnormalised
# ab,xyzabqr ab,abpmnop ab,ab xyzabqr,xyzabqr abpmnop,abpmnop
# 3.194444 3.194444 4.467593 20.814201 22.480868
#$normalised
# ab,xyzabqr ab,abpmnop ab,ab xyzabqr,xyzabqr abpmnop,abpmnop
# 0.3312674 0.3187513 1.0000000 1.0000000 1.0000000
可以看出,非标准化,两种比较的结果相同。但是,由于归一化结果等于(例如)sk_u("ab", "xyzabqr") / sqrt(sk_u("ab") * sk_u("xyzabqr"))
,因此sk_n("ab", "xyzabqr")
得分较高的原因与"abpmnop"
中有两个p的事实有关。