Python SVM在测试子集上运行良好,但在整个数据集上失败
我使用sklearn在大块数据上迭代训练SVM。每个csv文件都是图像的一部分。我用滑动窗做的。我使用partial_fit()来拟合SVM和定标器。特征是图像的RGBN值,我想将图像分为两个不同的组0和1Python SVM在测试子集上运行良好,但在整个数据集上失败,python,machine-learning,scikit-learn,Python,Machine Learning,Scikit Learn,我使用sklearn在大块数据上迭代训练SVM。每个csv文件都是图像的一部分。我用滑动窗做的。我使用partial_fit()来拟合SVM和定标器。特征是图像的RGBN值,我想将图像分为两个不同的组0和1 def trainSVMIterative(directory): clf= SGDClassifier(learning_rate = 'constant', eta0 = 0.1, shuffle = False,n_iter_no_change = 5, warm_star
def trainSVMIterative(directory):
clf= SGDClassifier(learning_rate = 'constant', eta0 = 0.1, shuffle = False,n_iter_no_change = 5, warm_start = True )
sc = StandardScaler()
firstIter = True
iter = 0
for filename in os.listdir(directory):
if filename.endswith('.csv'):
pixels = pd.read_csv(os.path.join(directory, filename),sep = ',')
#drop columns containing irelevant information
pixels = pixels.drop('x', axis = 1)
pixels = pixels.drop('y', axis = 1)
#dataset
X = pixels.drop('label', axis = 1)
#labels
Y = pixels['label']
#prepare training data
X_train, X_test, y_train, y_test = train_test_split(X,Y,test_size = 0.2, random_state = 42)
#fit scaler
sc = sc.partial_fit(X)
#scale input
X_train = sc.transform(X_train)
X_test = sc.transform(X_test)
#train svm
if firstIter:
clf.partial_fit(X_train,y_train, classes=np.unique(Y))
firstIter = False
else:
clf.partial_fit(X_train,y_train)
testPred = clf.predict(X_test)
print(classification_report(y_test,testPred))
iter+=1
print(iter)
return clf, sc
当我在每次迭代后打印分类报告时,它看起来很好,准确率高达98%。因此,我假设我的分类器正在正确地训练。
为了进行测试,我从原始图像中提取了一个新的数据帧。这一次,没有带标签的列。我将分类器和定标器传递给我的测试函数
def testClassifier(path, classifier, scaler):
#opening the original image, same process as in creating the training data
raster = gdal.Open(path)
array = tifToImgArray(raster, 'uint8')
# select a part of the image to test on
windowSize = 1000
y = 19000
x = 0
window = array[y:y + windowSize,x:x + windowSize]
#create the dataframe
arrayData = []
for i in range(window.shape[0]):
for j in range(window.shape[1]):
arrayData.append([i,j,array[i,j,0],array[i,j,1],array[i,j,2],array[i,j,3]])
dfData = pd.DataFrame(arrayData, columns=['x','y','R','G','B','N'])
#again drop psoition information
pixels = dfData.drop('x', axis = 1)
pixels = pixels.drop('y', axis = 1)
#use scaler
pixels = scaler.transform(pixels)
#make prediction
prediction = classifier.predict(pixels)
image = visualizePrediction(prediction, window, dfData)
return image
我现在的问题是,分类器预测每个像素的标签“1”。我用于测试的数据帧X与我在一次训练运行中使用的数据帧X相同,只是在训练测试数据中没有拆分,我只是使用了整个集合。我真的不明白我做错了什么,因为分类器在X的子集上工作得很好。我想可能是一个问题,有更多的数据点标记为“1”,然后有标记为“0”,我没有对数据使用任何权重。但是,当我将数据集拆分为X_序列和X_测试时,为什么它会起作用呢?因为情况也是如此。
在这个问题上,我非常感谢你的帮助。
问候- 如果我们的模型的精度非常高,那并不一定意味着它一直都做得很好(可能是在训练数据上,但在测试数据上不是)
示例:假设我们有大约100行数据,其中
和label1=90行
。我们进行常规的label0=10行
并训练我们的模型(在我们的例子中,它是一个分类模型),并确保准确率为95%。由于我们的模型非常完美,我们部署了它,几天后我们注意到它的预测不如我们训练时预测的那么好。原因是数据是倾斜的。即使当模型预测“label0”错误时,准确度仍然会增加,因为“label1”预测占主导地位,我认为这正是你的数据发生的情况测试\u train\u split
- 一旦我们做了预测,我们就可以检查这一点。混淆矩阵评估我们模型的性能。我们还有其他指标,例如,也非常有用
- 我们可以通过让数据进入正确的分布来解决这个问题。但大多数时候,我们缺乏数据,我们拥有的所有数据都是这种扭曲的数据。在这种情况下,我们可以做一件叫做