我正在使用两个单独的训练和测试集在python中构建预测模型。训练数据包含数字类型分类变量,例如,邮政编码,[91521,23151,12355,...],以及字符串分类变量,例如,城市['芝加哥','新约克'洛杉矶',...]。
为了训练数据,我首先使用' pd.get_dummies'获取这些变量的虚拟变量,然后使用转换的训练数据拟合模型。
我对测试数据进行相同的转换,并使用训练模型预测结果。但是,我收到了错误' ValueError:模型的要素数必须与输入匹配。模型n_features为1487,输入n_features为1345' 。原因是测试数据中的虚拟变量较少,因为它的城市数量较少。和' zipcode'。
我该如何解决这个问题?例如,' OneHotEncoder'将仅编码所有数字类型分类变量。 ' DictVectorizer()'只会编码所有字符串类型的分类变量。我在线搜索并看到一些类似的问题,但没有一个能真正解决我的问题。
Handling categorical features using scikit-learn
https://www.quora.com/What-is-the-best-way-to-do-a-binary-one-hot-one-of-K-coding-in-Python
答案 0 :(得分:36)
您还可以获取缺失的列并将其添加到测试数据集中:
# 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]
此代码还确保将删除测试数据集中的类别但未显示在训练数据集中的列
答案 1 :(得分:23)
假设您在火车和测试数据集中具有相同的要素名称。您可以从火车和测试生成连锁数据集,从连锁数据集中获取虚拟数据并将其拆分为训练和测试。
你可以这样做:
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:]
结果,您具有相同数量的训练和测试数据集的功能。
答案 2 :(得分:7)
train2,test2 = train.align(test, join='outer', axis=1, fill_value=0)
train2和test2具有相同的列。 Fill_value指示用于丢失列的值。
答案 3 :(得分:1)
这是一个相当老的问题,但是如果您打算使用scikit学习API,则可以使用以下DummyEncoder类:https://gist.github.com/psinger/ef4592492dc8edf101130f0bf32f5ff9
它的作用是利用类别dtype来指定要创建的假人,如此处所述:Dummy creation in pipeline with different levels in train and test set
答案 4 :(得分:1)
在训练和测试集上都运行过get_dummies之后,我过去就拥有这个
X_test = X_test.reindex(columns = X_train.columns, fill_value=0)
显然,对个别情况有一些调整。但是,它会丢弃测试集中的新值,并填充测试中缺失的值,在这种情况下,这些值全为零。