我正在使用包含标称值和数值的NSL-KDD数据集,并且我想将所有标称值转换为数值。我尝试了get_dummiespython中的NominalToBinary方法和WEKA中的方法,但问题是一些标称特征包含64个值,因此转换大大增加了数据的维数,这会给分类器带来问题。
我的问题是我是否可以通过在名义特征的每个类别与整数值序列之间建立对应关系来转换名义属性,例如protocol_type {tcp=0, udp=1, icmp=2...etc}?这会改变结果数据集的可信度吗?
我正在使用包含标称值和数值的NSL-KDD数据集,并且我想将所有标称值转换为数值。我尝试了get_dummiespython中的NominalToBinary方法和WEKA中的方法,但问题是一些标称特征包含64个值,因此转换大大增加了数据的维数,这会给分类器带来问题。
我的问题是我是否可以通过在名义特征的每个类别与整数值序列之间建立对应关系来转换名义属性,例如protocol_type {tcp=0, udp=1, icmp=2...etc}?这会改变结果数据集的可信度吗?
如您所述,通过将名义属性转换为单个数字属性,您隐含地在名义标签上引入排序,这是数据的不良表示,并且可能导致分类器产生不良影响。说 UDP 应该介于 TCP 和 ICMP 之间是否有意义?(不!)想象一下你正在训练一个-NN 模型在这个数据上。说 ICMP 应该比 UDP 离 TCP“更远”是没有意义的,但是如果你采用了你建议的映射,那么数据的表示就会内置这个假设。或者,如果您正在训练基于决策树的模型怎么办?通常,在决策树中,为数字属性选择二进制分割点。您的训练数据中可能存在一些随机性,其中在数字属性的某些值处拆分会导致对噪声的过度拟合。
通常,将名义属性转换为数字时,会为每个名义标签创建一个数字属性。如果设置了相应的标称标签,则每个属性都设置为 1,否则设置为 0。例如,如果名为的名义属性protocol具有标签 { tcp, udp, icmp},则此数据集:
可以转换如下:
这就是NominalToBinary过滤器在 WEKA 中的作用。正如您所提到的,这样做的缺点是如果不同标称值的数量很高,则可以引入大量附加属性。
如果转换后的维数太高,您可能需要考虑使用降维技术,例如随机投影、PCA、t-SNE 等。注意这会降低模型的可解释性。您还可以使用特征选择技术来删除一些不太有用的属性。某些标称标签可能对您的模型没有用处,您可以通过删除它们来提高性能。您可以尝试的另一件事是使用您的领域知识来减少类别的数量。例如,TCP 和 UDP 都是传输协议,也许对于您的应用程序来说,TCP 和 UDP 之间的区别并不那么重要,您可以使用协议放置实例{ tcp, udp} 进入一个新类别,删除旧类别。
对于具有高基数(即具有大量级别)的分类变量的编码,您可能需要尝试所谓的影响编码。
主要思想非常简单,您只需通过感兴趣的变量(在您的案例中为“协议”)将数据集分成不重叠的桶,并计算每个桶的响应变量的平均值。然后,分类变量的值可以用特定桶的平均值代替。
Avg(response | protocol=”tcp”)
Avg(response | protocol=”icmp”)
Avg(response | protocol=”udp”)
棘手的部分是避免数据泄漏,这可以通过将整个数据集分成几个子集(例如“编码”、“训练”、“验证”……)并仅使用“编码”数据集中的数据作为标称- 到数值的转换。
我从Win-Vector博客和他们的论文中了解到这种方法: vtreat: a data.frameProcessor for Predictive Modeling,我强烈推荐。