Python SVM在测试子集上运行良好,但在整个数据集上失败

Python 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

我使用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_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行
    。我们进行常规的
    测试\u train\u split
    并训练我们的模型(在我们的例子中,它是一个分类模型),并确保准确率为95%。由于我们的模型非常完美,我们部署了它,几天后我们注意到它的预测不如我们训练时预测的那么好。原因是数据是倾斜的。即使当模型预测“label0”错误时,准确度仍然会增加,因为“label1”预测占主导地位,我认为这正是你的数据发生的情况

  • 一旦我们做了预测,我们就可以检查这一点。混淆矩阵评估我们模型的性能。我们还有其他指标,例如,也非常有用

  • 我们可以通过让数据进入正确的分布来解决这个问题。但大多数时候,我们缺乏数据,我们拥有的所有数据都是这种扭曲的数据。在这种情况下,我们可以做一件叫做


我的问题是,我的模型在测试数据上运行良好,在测试数据+训练数据上失败,所以整个数据集都失败了。我还检查了F1分数,对于label1和label0的数据,F1分数分别为99%和50%。我觉得奇怪的是,这个模型在它训练过的数据和它预测的数据上失败了,这些数据基本上纠正了我的第一个函数。我将尝试你的第二点,只选择用于训练的数据的平衡卡盘,看看会发生什么。因为你说过,总体数据有更多的label1,所以可以安全地假设,当你进行训练测试分割时,分割测试数据有更多的label1。现在想象一下,当它正确预测了90%的label1,但失败了10%的label0时,准确度会是多少。是的,准确度会更高,但没用。现在,试着用一些平衡的数据,让我知道它是如何进行的。我很好奇每一步的准确度,还有混淆矩阵,但这是以后的事了。无论如何,记住要经常做一些快速的事情来避免这样的事情。平衡数据可以大大提高预测,你应该知道这一点。我在每一步都查看了混淆矩阵,结果发现对label0的预测对label1来说是非常糟糕和非常好的。我想知道的是,modell在每一步都至少有一些正确的label0预测,那么为什么它在不进行拆分的情况下预测相同的点是错误的呢?无论如何,非常感谢你的帮助。