无需使用train_test_split方法即可对sklearn的SVM进行数据预处理

时间:2019-02-05 01:39:40

标签: pandas scikit-learn svm

我使用了Inception并为大约11000个视频生成了1000个特征(对象的概率)。这些视频已按流派分类,我希望SVM可以预测视频属于哪个流派。

我想将SVM应用于这些特征向量,但是到目前为止,我阅读的每个教程都使用了train_test_split中的sklearn.model_selection方法。

我的数据看起来如何:

  • 我已将我的数据集分为两个csv文件,它们具有〜9000个训练和〜2000个测试(每个具有1000个功能)记录。格式为videoId,feature1,feature2,...,feature1000

  • 我有流派作为标题的文件,例如Training/education.txt用于培训,Testing/education.txt用于测试。每个文件包含videoId个属于该流派的文件。

我对数据科学和诸如熊猫,sklearn等图书馆不熟悉,因此我对如何准备这些数据一无所知。我一直在关注this guide

import pandas as pd  

bankdata = pd.read_csv("D:/Datasets/bill_authentication.csv")  
X = bankdata.drop('Class', axis=1)  
y = bankdata['Class']  
from sklearn.model_selection import train_test_split  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)  

我该如何获得自己所拥有的X_trainX_testy_trainy_test?由于目前的数据设置方式,我无法使用诸如train_test_split之类的方法。

1 个答案:

答案 0 :(得分:2)

所有教程都建议您使用train_test_split中的sklearn.model.selection的原因是因为它们假设您将要评估学习模型的性能,并可能在最终使用它之前对其进行超参数调整在您的测试数据集上生成预测。

这种做法称为“交叉验证”设置。为此,您暂时保持测试集不变,实际上将其拆分为训练集的20%。您在训练集的80%的行上训练模型,并使用该模型对训练集的其余20%生成预测。

您可以选择一个指标,例如accuracy,以判断模型的性能。通常,此时您需要尝试为模型的hyperparameters尝试不同的值,并查看其在验证集(训练集的最后20%)上的得分是否有所提高

train_test_split方法只是将训练数据分为这80/20部分的一种简单方法。我建议您不要跳过此步骤。原因是,如果您在观察模型在实际测试集上的表现后要更改其模型或超参数,您将失去了解模型在全新,真实模型上的性能的基础。世界数据。

这称为“对测试集的过度拟合”,它是一种常见的实践错误,导致机器学习模型在一组先前收集的数据上确实表现良好,但最终(令其创建者感到惊讶)这些模型最终投入生产后,它们所看到的真实数据表现得非常糟糕。

总而言之,您的想法是:

  1. 训练80%的火车数据。
  2. 评估20%的火车数据。
  3. 更改模型,直到对步骤(2.)中使用的数据的评分方式感到满意为止。
  4. 最后,仅在最后,使用模型对实际测试数据进行预测。

顺便说一句,Sklearn对方法train_test_split的命名有些混乱,因为该方法的目的是创建一个验证集。 (在我看来train_val_split是一个更直观的名称...)

以下是代码中的步骤,我想您会根据特定情况(数据分散在多个.txt文件中)进行操作:

  1. 导入模块和所有训练的.csv文件:
import pandas as pd
import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split

X_edu = pd.read_csv('Training/education.txt')
X_hor = pd.read_csv('Training/horror.txt')
...
  1. 在每种类型的数据框中创建一个Genre列,然后将所有这些连接到一个数据框中:
train_dfs = [X_edu, X_hor, ...]
genres = ['edu', 'hor', ...]
for i, genre in enumerate(genres):
    train_dfs[i]['Genre'] = genre

X = pd.concat[train_dfs].reset_index(drop=True) # reset the index so each row has a unique index
                                                # important so we can be sure we can properly match each row with its label
  1. 从训练数据中提取标签(我假设标签位于标题为Genre或类似名称的列中)并删除videoID列(因为它似乎并不具有预测意义功能):
y = X['Genre']
X = X.drop(['Genre', 'videoID'], axis=1)
  1. 使用train_test_split创建训练和验证集(不错的奖励:train_test_split在拆分之前会自动对整个训练数据帧的行进行混洗,因此您不必担心某些类型的内容在您的验证集中):
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.20)
  1. 将模型拟合到X_train并在X_val上进行预测:
clf = SVC()
clf.fit(X_train, y_train)
preds = clf.predict(X_val)
  1. 根据对验证集所做的这些预测来确定模型的性能(我在这里使用准确性,但是您可以使用任何想要的度量标准-Sklearn可能有一个您想使用的任何度量标准的类。)
val_acc = accuracy_score(y_val, preds)
  1. 为您的SVM学习者的hyperparameters使用不同的值的实验,然后重复上述步骤(5.)和(6.)。当您对模型的性能感到满意时,就该对实际测试数据生成预测了。

    您可以为每种类型的测试文件加载.csv文件,并将它们全部组装到一个数据框中,就像您对上面的训练数据所做的那样:

test_edu = pd.read_csv('Training/education.txt')
test_hor = pd.read_csv('Training/horror.txt')
...

test_dfs = [test_edu, test_hor, ...]
for i, genre in enumerate(genres):
    test_dfs[i]['Genre'] = genre

test = pd.concat[test_dfs].reset_index(drop=True) # reset the index so each row has a unique index
y_test = test['Genre']
X_test = test.drop(['Genre', 'videoID'], axis=1)
test_preds = clf.predict(X_test)
test_acc = accuracy_score(y_test, test_preds)

如果要求我们对从未见过的全新视频进行预测,那么此测试集准确性得分应该可以让您对模型的票价做出最现实的估算。