我正在尝试学习SVM中线性SVC的工作原理,并通过使用不同的参数进行训练和测试来复制一个简单的实验。我的问题是我似乎不明白如何使用我的数据来训练和测试线性SVC算法。基本上,我想要做的是使用线性SVC进行图像识别。
我有来自5个不同人的5张图像,每张图像有22个特征。我的目标是简单地获得图像的训练率,我的困惑在于我得到的训练率是100%,而我期望的是大约80%左右的训练率,那么我该如何获得适当的识别率呢?
import sklearnfrom sklearn.svm import SVCfrom sklearn.model_selection import train_test_splitfrom sklearn import metricsdataset = np.asarray(data)target = np.asarray([1]*5 + [2]*5 + [3]*5 + [4]*5 + [5]*5)svc_1 = SVC(kernel='linear')X_train, X_test, y_train, y_test = train_test_split( dataset, target, test_size=0.35, random_state=0)def train_and_evaluate(clf, X_train, X_test, y_train, y_test): clf.fit(X_train, y_train) print ("Accuracy on training set:") print (clf.score(X_train, y_train)) print ("Accuracy on testing set:") print (clf.score(X_test, y_test)) y_pred = clf.predict(X_test) print ("Classification Report:") print (metrics.classification_report(y_test, y_pred)) print ("Confusion Matrix:") print (metrics.confusion_matrix(y_test, y_pred))train_and_evaluate(svc_1, X_train, X_test, y_train, y_test)
这是我的代码,为了便于可视化,我将我的25×22矩阵上传到了pastebin: https://pastebin.com/6hL6Dign
这是我的输出结果:
Accuracy on training set:1.0Accuracy on testing set:1.0Classification Report: precision recall f1-score support 1 1.00 1.00 1.00 1 2 1.00 1.00 1.00 1 3 1.00 1.00 1.00 1 4 1.00 1.00 1.00 3 5 1.00 1.00 1.00 3 accuracy 1.00 9 macro avg 1.00 1.00 1.00 9weighted avg 1.00 1.00 1.00 9
简而言之,我想要做的就是通过减少数据集中的行数或/和列数来降低识别率,但我的识别率始终保持在100%
回答:
问题在于 – 你的数据集在5个类别之间分隔得非常好。
线索#1 – 目标洗牌
洗牌目标后准确率下降了。尝试在目标定义后添加以下代码:
random.shuffle(target) # 需要`import shuffle`
线索#2 – 主成分分析(PCA)
我使用了主成分分析(PCA)来通过减少到两个特征来可视化你的数据:
from sklearn.decomposition import PCAimport matplotlib.pyplot as pltpca = PCA(n_components=2)pca_res = pca.fit_transform(data)plt.scatter(pca_res[:, 0], pca_res[:, 1], color=list(map(' rgbyc'.__getitem__, target)))
结果:
看起来很明显,类别之间分隔得很好 – 组内方差远小于组间方差。显然,即使样本量如此小,SVC也能轻松检测出测试集的正确类别。
编辑
看起来甚至不需要PCA。一个特征(例如第二个特征)就足以实现100%的分离。尝试用以下代码:
dataset = np.asarray(data)[:, 1:2]
并进行可视化:
import seaborn as snssns.boxplot(x=target, y=dataset[:, 1]) # 使用原始数据集
结果: