opencv的机器学习之SVM和KNn的多分类

之前练习了svm hog分类ministi数字集,效果不是很好,先记录一篇有帮助的文章。

1:KNN最近邻算法
简单理解:从数据集中找到距离当前样本最近的k个样本,投票决定当前样本类别,这里k一般为奇数。不好的地方就是每次预测都要用整个数据集来进行距离计算,慢并且存储大,假设有10亿样本的话,就自己脑补吧。
knn = cv.ml.KNearest_create()
knn.train(train, cv.ml.ROW_SAMPLE, train_labels)
ret,result,neighbours,dist = knn.findNearest(test,k=5)

微信截图_20210419143226.png微信截图_20210419143239.png

如上图结果所示,第一列是真实标签,第二列是距离最近的k=5个样本标签,第三列是预测标签(投票决定)。
分类准确率:91.76。
2:SVM支持向量机分类算法
这里有两种情况:
(1)线性可分:寻找具有最大分类间隔的分割线。
(2)非线性可分:核函数变换低维空间转换到高维空间,使其线性可分;加入惩罚因子和松弛变量处理错分样本。
训练模型需要注意下最好是对特征进行归一化,省的你用RBF核函数训练模型发现模型预测准确率很低,还以为是算法很差呢,其实是特征处理的问题。
模型训练保存:
svm = cv.ml.SVM_create()
svm.setKernel(cv.ml.SVM_LINEAR)
svm.setType(cv.ml.SVM_C_SVC)
svm.setC(2.67)
svm.setGamma(5.383)
svm.train(trainData, cv.ml.ROW_SAMPLE, responses)
svm.save('svm_data.dat')
模型预测:

result = svm.predict(testData)[1]

微信截图_20210419143346.png

上述蓝色部分是对不同核函数所做的测试,绿色部分是对RBF核函数手动调参的最优结果,可以看出SVM比KNN算法有了很大提升,这里其实也有特征的关系,KNN的特征用的就是整幅图像的像素值,SVM用的是64维的hog特征。


这里svm的惩罚因子和gamma的不同是可以改变模型的预测值的。

下篇文章简单测试下。


sitemap