有时候在做数据科学的项目时,会遇到这样的问题:在某些分类型的feature之下,存在一些类别,训练集中和测试集中不对等。要么test中有这个类别,但train中没有;或者train中有这个类别,test中没有。比如,在“性别”这个类别下,train的数据有“男”有“女”,而test的数据中全是“男”。这样的问题会导致在建立dummy variable或者进行one-hot编码的时候,编码后的train和test中的feature数量不一致,导致没法直接进行模型训练。
要解决这个问题,最好的办法当然是多收集一些数据,保证测试集中的每一条信息都曾在训练集中被训练过。
但是有时候客观上我们是无法多收集数据的(比如在打一个开狗竞赛)。所以还有一个办法就是把测试集和训练集先合并,做统一的数据处理,最后一起get_dummies, 得到一致的列以后再把这两个数据集分开。但是这样做就涉及一个问题:数据泄露。因为合起来以后做统一的数据处理,对于某一些特征来说相当于提前把测试集的信息应用到了训练集中。这样以来很有可能发生过拟合。
顺着如上思路,我们可以先分别处理train 和 test 中的其他变量,处理完后再合并train 和 test, 合并后再get_dummies(),之后再将两个df分开。这样做是可行的,但为了建立一次虚拟变量就要合并再分开两个df,显得有点麻烦。
今天我们讨论另一个方案。这个方案比起上述的方法不一定简便,但这个方案可以帮我们对这个问题进行一个深入思考。
我们知道,pandas中的getdummies()的方法可以很快地给train 和 test分别进行dummy variable的编码(这个dummy variable 本质上和one-hot一致,但少一个自由度)。但是当某一个feature下的类别在train和test中不一致的时候,对train和test分别做get_dummies就会出问题,很有可能dummy完了以后,train 有100列而test有108列;或者train有100列而test只有98列。遇到这个问题怎么办呢?如上述,我们可以合并train和test处理后,再分开。
但这只是解决方案之一。事实上,sklearn中的模块帮我们从另一个角度