为何OpenCV的KNearest在K=3时返回结果为4而非5?
OpenCV KNN中K=3时返回结果不符合预期的原因分析
运行的Python代码
import cv2 as cv import numpy as np trainFeaturesData = [ [2,2,2,2], [3,3,3,3], [4,4,4,4], [5,5,5,5], [6,6,6,6], [7,7,7,7], ] trainFeatures = np.array(trainFeaturesData, dtype = np.float32) trainLabelsData = [ 2, 3, 4, 5, 6, 7 ]; trainLabels = np.array(trainLabelsData, dtype = np.float32) knn = cv.ml.KNearest_create() knn.train(trainFeatures, cv.ml.ROW_SAMPLE, trainLabels) testFeatureData = [[ 5, 5, 5, 5, ]] testFeature = np.array(testFeatureData, dtype = np.float32) for k in [1, 3]: print("------------ k = {} --------------\n".format(k)); ret, results, neighbours ,dist = knn.findNearest(testFeature, k) print( "result: {}\n".format(results) ) print( "neighbours: {}\n".format(neighbours) ) print( "distance: {}\n".format(dist) )
运行输出
------------ k = 1 -------------- result: [[5.]] neighbours: [[5.]] distance: [[0.]] ------------ k = 3 -------------- result: [[4.]] <= Why?? neighbours: [[5. 4. 6.]] distance: [[0. 4. 4.]]
原因分析
核心原因是OpenCV的KNN实现中,当出现投票平局时,会选择训练数据中最早出现的类别。
在这个案例里,K=3时,最近的三个邻居对应的标签是5、4、6,三者的投票数都是1票,形成平局。此时OpenCV会从这些平局的类别里,挑选在训练标签列表中最先出现的那个——训练标签里4的位置在5之前,所以最终返回结果为4。
你可以调整训练数据的顺序验证这个逻辑:比如把标签5对应的样本移到标签4的前面,重新运行代码,K=3时的结果就会变成5。
内容的提问来源于stack exchange,提问作者codeDom
相关产品推荐
相关产品推荐

