二元分类模型的数据拆分

数据挖掘 机器学习 分类
2022-02-17 23:37:09

我正在尝试建立一个二元分类模型,该模型将告诉谁会购买产品,谁不会。我听说在准备输入数据时,将数据集分成两个不同的子集是一种常用方法。

[ ================ 训练数据 80% ================= ] [ ==== 测试集 20% == == ]

它只是像上面那样按一定比例盲目地分割一大块数据集吗?就这么简单吗?

想象一下,我在下面有这个简单的数据集。

UserId,UserName,AppId,Purchased
1,Lianne,1,1
1,Lianne,2,1
1,Lianne,3,1
1,Lianne,4,1
1,Lianne,5,1
1,Lianne,6,0
1,Lianne,7,0
1,Lianne,8,0
1,Lianne,9,0
1,Lianne,10,0   

作为常见的推荐方式,我将其分为两组。

// Training Data Set
UserId,UserName,AppId,Purchased
1,Lianne,1,1
1,Lianne,2,1
1,Lianne,3,1
1,Lianne,4,1
1,Lianne,5,1
1,Lianne,6,0
1,Lianne,7,0
1,Lianne,8,0

// Test Set
UserId,UserName,AppId,Purchased
1,Lianne,9,0
1,Lianne,10,0

这行得通吗?好吧,它似乎没有,事实证明它实际上没有。该模型对 6、7、8、9 的 appId 进行预测是错误的。它认为第一用户会以略高的机会购买它们。指标看起来像...

  • TP : 5
  • FP : 4
  • FN : 1
  • 准确度:0.5
  • Auc : NaN
  • F1Score : NaN
  • 精度:0
  • 负精度:1
  • 负面召回:0.5

为了制作一个合适的模型,我的测试数据集在这个样本训练数据上应该是什么样子?

3个回答

假设发布的数据集只是一个说明性示例(因此很小):

问题是您的测试数据与您的训练数据相比,因变量的分布非常不同(在您的示例拆分中:它不包含任何第 1 类的示例)。

将数据拆分为训练集和测试集时,您需要包含一些随机性来解决此问题。然而,在如此小的数据集中,可能仍会导致关于训练和测试数据的经验分布非常不同。

您可以做的是应用拆分,以使训练和测试数据的目标变量的分布保持相同(即,两个集合将具有相同的示例份额y==1y==0)。

Scikit Learnstratify为此提供了参数(我将您的数据复制到了 CSV 文件):

import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split

raw_data = pd.read_csv('binary classification examples')
data = pd.get_dummies(raw_data)
X = data[["UserId", "UserName_Lianne", "AppId"]]
y = data[["Purchased"]]
X_train, X_test, y_train, y_test = train_test_split(
        X, y, stratify=y, test_size=0.2)

我已经强制拆分在stratify=y火车和测试拆分中保持每个 y 类的相同份额:

>>> y_train
Out[40]: 
   Purchased
7          0
3          1
0          1
5          0
1          1
9          0
8          0
4          1

>>> y_test
Out[41]: 
   Purchased
2          1
6          0 

如您所见,训练和测试数据现在包含 50% 的项目,其中y==0y==1有了这些数据,aDecisionTreeClassifier可以轻松正确地对训练和测试数据进行分类:

model = DecisionTreeClassifier()
model.fit(X_train, y_train)
print("Train score: {}\tTest score: {}".format(
        model.score(X_train, y_train),
        model.score(X_test, y_test)))

给出以下分数:

Train score: 1.0        Test score: 1.0

我的 2 美分:这里使用的数据集中的记录数非常少。如果我们查看数据集,我们可以看到目标变量拆分正好是 50:50,这意味着概率是一半。这就像抛硬币得到正面或反面一样。

训练集包含一个已知的输出,模型在此数据上学习,以便稍后推广到其他数据。因变量和自变量应该在 splatted 中,然后进行训练测试拟合。

您也可以使用 scikit learn 中的库 from sklearn.model_selection import train_test_split

如果这就是你的数据看起来的样子,将用户分成训练示例和测试示例是个好主意,训练示例将包含具有所有相关应用程序信息的用户,并且在测试数据中,你会为你的模型提供大约 80% 的信息用户和模型必须填充 20%,在某些情况下,您必须以特定于问题的方式拆分数据