我正在用sklearn标定knn。这是系统信息。
该基准测试在sklearn MNIST上运行,它具有1797个样本,10个类,8 * 8维度和17个特征。
此样本图像中的每个正方形代表一个像素,总共8 * 8维度。每个像素的范围是0到16。
这是代码。
snippet_1:
n_neighbors=5; n_jobs=1; algorithm = 'brute'
model = KNeighborsClassifier(n_neighbors=n_neighbors, n_jobs=n_jobs, algorithm = algorithm)
model.fit(trainData, trainLabels)
predictions = model.predict(testData)
大约需要0.1s
snippet_2:
n_neighbors=5; n_jobs=1; algorithm = 'kd_tree'
model = KNeighborsClassifier(n_neighbors=n_neighbors, n_jobs=n_jobs, algorithm = algorithm)
model.fit(trainData, trainLabels)
predictions = model.predict(testData)
大约需要0.2s
我多次重复执行基准测试,无论我先运行哪个,snippet_1总是比snippet_2快2倍。
为什么'kd_tree'比'brute'需要更多的时间?
我知道“维数的诅咒”,因为doc清楚地说,我要问的是为什么?
答案 0 :(得分:0)
答案似乎与与模型相关的尺寸有关。维数的诅咒也是众所周知的。当KD-tree的尺寸超过15/20(kinda指数)时,缩放比例非常差,而蛮力似乎遵循了更线性的模式。在GPU上运行时,对于更大的尺寸,蛮力确实可以更快。在这里,另一位研究人员发现了类似的问题:Comparison search time between K-D tree and Brute-force
答案 1 :(得分:0)
通常,如果N < 2**k
(其中k
是维数(在这种情况下为8 * 8 = 64
)中且N
是2**64 = 1.8E19 >> 1797
,则KD-Tree的速度将比蛮力慢。样本数。在这种情况下,N < 2**k
使得KDTree的运行速度慢得多。
基本上,作为第一步,KDTree沿每个维度对数据进行二进制拆分。如果它具有足够的数据来执行此操作,则可以根据它们共有的拆分数目来猜测最接近的邻居。如果为{
"header":
{
"serviceId":"xxx",
"productCode":"xxx",
"transactionId":"xxx"
},
"data":
{
"items":
[
{
"paymentModel":"Retail Banking",
"paymentChannels":
[
{ "name":"A", "status":"Active" },
{ "name":"B", "status":"Active" },
{ "name":"C", "status":"Active" },
{ "name":"D", "status":"Active" }
],
"name":"Internet Banking",
"logoUrl":"xxx"
},
{
"paymentModel":"Retail Banking",
"paymentChannels":
[
{
"bankFeeRate":"0",
"ccIsRequired":true,
"name":"R",
"currency":
[{
"isoCode":"xxx",
"name":"xxx"
}],
"bankFeeType":"xxx",
"paymentChannelId":"9",
"status":"Active",
"acceptedCard":
[
"visa",
"mastercard"
]
},
{
"bankFeeRate":"0",
"ccIsRequired":true,
"name":"M",
"currency":
[{
"isoCode":"xxx",
"name":"xxx"
}],
"bankFeeType":"fixed",
"paymentChannelId":"13",
"status":"Active",
"acceptedCard": [ "amex" ]
}
],
"name":"Credit Card",
"logoUrl":"xxx"
}
],
"metadata": { "count":2 }
},
"status":
{
"code":"200",
"message":"OK"
}
}
,则数据用完之前将要用尽。这样就没有关于其他尺寸的距离信息。毫无疑问,它仍然必须蛮力对待其余维度,从而使KDTree不必要的开销。
可以更here找到有关问题和可能解决方案的更深入讨论。对于此应用程序,建议您首先使用PCA降低尺寸的第三个答案可能是最好的选择。