我正在使用功能哈希将字符串变量转换为哈希以进行分类。经过一番挖掘,我注意到尽管MurmurHash3的R和Python实现均具有功能哈希(R:FeatureHashing:hashed.model.matrix和Python:sklearn.feature_extraction.FeatureHasher),但结果在功能放置位置方面有所不同。我认为MurmurHash应该是确定性的,因为当您在同一系统上运行相同的操作时,会得到相同的结果哈希。但是,在实现之间可能存在种子问题?正如其他人指出的那样,这给我带来了一个问题,因为我的分类模型(我意识到xgboost在R和Python之间存在问题)在相同数据上的结果可能不同。但是,我似乎已经弄清楚了那部分。
以下是R中的代码示例:
library(FeatureHasher)
#create a single-feature dataframe
data_tmp <- data.frame(x=c("A_C","B_D"))
#> data_tmp
# x
#1 A_C
#2 B_D
#create feature hash. R by default includes an intercept, so remove that
#with ~x -1
fhash <- hashed.model.matrix(~x -1, data=data_tmp, hash.size=16, create.mapping=TRUE)
as.matrix(fhash)
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#[1,] 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
#[2,] 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
如您所见,R将“ A_C”放在第五列,将“ B_D”放在十二列。这些始终如一地发生。现在,让我们在Python中运行等效代码。请注意,有多种输入方式来输入Python中的特征哈希值,如字典或列表列表。我尝试了几次,他们给了我相同的结果。
from sklearn.feature_extraction import FeatureHasher
import pandas as pd
#create as a list of two single-element lists
data_tmp = [["A_C"],["B_D"]]
#can also do this, does the same thing
#pd.DataFrame(data_tmp)
#set up feature hash with same settings above
feature_hash = FeatureHasher( alternate_sign = False, n_features = 16, input_type="string")
fhash = feature_hash.transform( data_tmp )
fhash.todense()
#matrix([[0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
# [0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
在这里,“ A_C”和“ B_D”不仅映射到与以前不同的索引,而且都映射到同一列。这意味着此功能已发生冲突,因为无法再区分值1代表不同的功能了,这将降低分类器的功能。
这里是否有明显的我想念的东西?例如,我看到了这篇文章:Murmur3 hash different result between Python and Java implementation,但是我对此并不了解。我注意到的一件事是在R中,如果您使用create.mapping选项然后运行
hash.mapping(fhash)
#xB_D xA_C
#12 5
当它打印出来时,会在字符串前放置一个“ x”(变量名),所以我认为这可能是引起问题的原因。但是后来我尝试重新运行上面的Python代码,除了
data_tmp = [["xA_C"],["xB_D"]]
但是尽管我得到的结果与以前不同,但它与R的映射不匹配。也许这是Python如何存储变量名的内部原因?预先感谢,我真的很想弄明白这一点。