python 在训练和测试数据中保持相同的虚拟变量

m3eecexj  于 2023-03-06  发布在  Python
关注(0)|答案(6)|浏览(253)

我正在用python构建一个预测模型,它有两个独立的训练集和测试集,训练数据包含数值类型的分类变量,例如邮政编码[91521,23151,12355,...],也包含字符串类型的分类变量,例如城市[“芝加哥”,“纽约”,“洛杉矶”,...]。
为了训练数据,我首先使用'pd.get_dummies'得到这些变量的哑变量,然后用转换后的训练数据拟合模型。
我对我的测试数据做了同样的转换,并使用训练好的模型预测结果,但是,我得到了误差

ValueError: Number of features of the model must  match the input. Model n_features is 1487 and  input n_features is 1345

原因是因为测试数据中的“city”和“zipcode”较少,所以虚拟变量较少。
我如何解决这个问题?例如,'OneHotEncoder'将只编码所有数值类型的分类变量。'DictVectorizer()'将只编码所有字符串类型的分类变量。我在网上搜索,看到一些类似的问题,但没有一个真正解决我的问题。
Handling categorical features using scikit-learn
https://www.quora.com/If-the-training-dataset-has-more-variables-than-the-test-dataset-what-does-one-do
https://www.quora.com/What-is-the-best-way-to-do-a-binary-one-hot-one-of-K-coding-in-Python

oyjwcjzk

oyjwcjzk1#

您也可以只获取缺少的列,并将它们添加到测试数据集中:

# Get missing columns in the training test
missing_cols = set( train.columns ) - set( test.columns )
# Add a missing column in test set with default value equal to 0
for c in missing_cols:
    test[c] = 0
# Ensure the order of column in the test set is in the same order than in train set
test = test[train.columns]

此代码还确保删除由测试数据集中的类别生成但在训练数据集中不存在的列

pxyaymoc

pxyaymoc2#

假设您在训练和测试数据集中有相同的特征名称。您可以从训练和测试生成连接数据集,从连接数据集获取虚拟数据并将其拆分以进行训练和测试。
您可以这样做:

import pandas as pd
train = pd.DataFrame(data = [['a', 123, 'ab'], ['b', 234, 'bc']],
                     columns=['col1', 'col2', 'col3'])
test = pd.DataFrame(data = [['c', 345, 'ab'], ['b', 456, 'ab']],
                     columns=['col1', 'col2', 'col3'])
train_objs_num = len(train)
dataset = pd.concat(objs=[train, test], axis=0)
dataset_preprocessed = pd.get_dummies(dataset)
train_preprocessed = dataset_preprocessed[:train_objs_num]
test_preprocessed = dataset_preprocessed[train_objs_num:]

因此,训练数据集和测试数据集的特征数相等。

mgdq6dx1

mgdq6dx13#

train2,test2 = train.align(test, join='outer', axis=1, fill_value=0)

train2和test2具有相同的列。Fill_value指示用于缺失列的值。

ycggw6v2

ycggw6v24#

我过去在训练集和测试集上运行get_dummies后遇到过这种情况

X_test = X_test.reindex(columns = X_train.columns, fill_value=0)

很明显,对于个别情况需要做一些调整。但是,它会丢弃测试集中的新值,并填充测试中缺失的值,在本例中为全零。

wtlkbnrh

wtlkbnrh5#

这是一个相当古老的问题,但如果您的目标是使用scikit learn API,您可以使用以下DummyEncoder类:https://gist.github.com/psinger/ef4592492dc8edf101130f0bf32f5ff9
它所做的是利用dtype类别来指定要创建哪些虚拟对象,下面也将详细说明:Dummy creation in pipeline with different levels in train and test set

bf1o4zei

bf1o4zei6#

这是一个很老的问题,但是由于sklearn OneHotEncoder的最新版本现在可以对字符串数据进行编码,因此可以很容易地使用它:

from sklearn.preprocessing import OneHotEncoder
import pandas as pd

X_train = pd.DataFrame({
    'zip' : [23151, 12355],
    'city' : ['New York', 'Los Angeles']
})

X_test = pd.DataFrame({
    'zip' : [91521, 23151],
    'city' : ['Chicago', 'New York']
})

ohe = OneHotEncoder(handle_unknown='ignore', sparse_output=False) # New in version 1.2: sparse was renamed to sparse_output
X_train_ohe = ohe.fit_transform(X_train)
X_test_ohe = ohe.transform(X_test)

如果我们想要一个带有相应列名的干净Dataframe(类似于pd.get_dummies):
x一个一个一个一个x一个一个二个x

相关问题