2016-12-26 85 views
8

我正在使用两个单独的训练和测试集建立python中的预测模型。训练数据包含数字类型的分类变量,例如邮政编码[91521,23151,12355,...],以及字符串分类变量,例如城市['芝加哥','纽约','洛杉矶' ...]。为了训练数据,我首先使用'pd.get_dummies'来获得这些变量的虚拟变量,然后用变换后的训练数据拟合模型。在训练和测试数据中保持相同的虚拟变量

我对测试数据做了相同的转换,并使用训练好的模型预测结果。但是,我得到了错误'ValueError:模型的特征数量必须与输入匹配。模型n_特征是1487,输入n_特征是1345'。原因是测试数据中的虚拟变量较少,因为它具有较少的“城市”和“邮编”。

我该如何解决这个问题?例如,'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

回答

10

假设你有相同功能的火车和测试数据集的名称。您可以从火车和测试中生成连接的数据集,从连接的数据集中获取虚拟模型并将其拆分为训练和测试。

你可以这样来做:

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:] 

在结果,你有特点的训练和测试数据集数目相等。

11

你也可以得到缺少的列,并将其添加到测试数据集:

# 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
train2,test2 = train.align(test, join='outer', axis=1, fill_value=0) 

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

相关问题