不使用train_test_split方法对sklearn的SVM进行数据预处理

5ar*_*ase 1 svm pandas scikit-learn

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

我想将 SVM 应用于这些特征向量,但到目前为止我读过的每个教程都使用train_test_splitsklearn.model_selection.

我的数据看起来如何:

  • 我将数据集分成两个 csv 文件,其中包含约 9000 个训练记录和约 2000 个测试记录(每个记录有 1000 个特征)。它的格式为videoId,feature1,feature2,...,feature1000

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

我对数据科学和 pandas、sklearn 等库很陌生,所以我不知道应该如何准备这些数据。我一直在遵循本指南

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)  
Run Code Online (Sandbox Code Playgroud)

我将如何利用我所拥有的东西来获得X_train, X_test, y_train, ?由于目前我的数据设置方式,y_test我无法使用类似的方法。train_test_split

小智 5

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

这种做法被称为预留“交叉验证”集。为此,您暂时保持测试集不变,并且实际上分割了训练集大约 20% 的行。您在训练集的 80% 行上训练模型,并使用该模型对训练集的剩余 20% 生成预测。

您可以选择一个指标(例如Accuracy)来判断模型的性能。通常,此时您会想要尝试为模型的超参数尝试不同的值,并查看其在验证集(训练集的最后 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')
...
Run Code Online (Sandbox Code Playgroud)
  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
Run Code Online (Sandbox Code Playgroud)
  1. 从训练数据中提取标签(我假设标签位于标题为Genre或类似内容的列中)并删除videoID列(因为它似乎不是预测功能):
y = X['Genre']
X = X.drop(['Genre', 'videoID'], axis=1)
Run Code Online (Sandbox Code Playgroud)
  1. 用于train_test_split创建训练和验证集(不错的好处:train_test_split在分割之前自动对整个训练数据帧的行进行洗牌,因此您不必担心某些类型不在验证集中):
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.20)
Run Code Online (Sandbox Code Playgroud)
  1. 拟合您的模型X_train并做出预测X_val
clf = SVC()
clf.fit(X_train, y_train)
preds = clf.predict(X_val)
Run Code Online (Sandbox Code Playgroud)
  1. 确定你的模型在验证集上做出的这些预测的性能(我在这里使用准确性,但你可以使用你想要的任何指标——Sklearn 可能有一个适合你想要使用的任何指标的类。)
val_acc = accuracy_score(y_val, preds)
Run Code Online (Sandbox Code Playgroud)
  1. 尝试使用 SVM 学习器的超参数的不同值,并重复上面的步骤 (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)
Run Code Online (Sandbox Code Playgroud)

如果要求模型对以前从未见过的全新视频进行预测,此测试集准确度分数应该可以为您提供最真实的估计,以了解您的模型的表现。