Я использую хеширование объектов для преобразования строковых переменных в хеш для целей классификации.После некоторых исследований я заметил, что, хотя реализация хэширования функций 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" в 12-м.Это происходит последовательно.Теперь давайте запустим эквивалентный код на Python.Обратите внимание, что в Python есть несколько способов ввода хеша объектов в виде dict или в виде списка списков.Я пробовал несколько, и они дают мне один и тот же результат.
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 хэширует разные результаты между реализацией Python и Java , но я не знаю достаточно об этом.Одна вещь, которую я заметил, это то, что в R, если вы используете опцию create.mapping и затем запускаете
hash.mapping(fhash)
#xB_D xA_C
#12 5
, когда она печатается, она ставит «x» (имя переменной) перед строкой, поэтому ядумал, что это может быть причиной проблемы.Но затем я попытался повторно запустить приведенный выше код Python, кроме как с помощью
data_tmp = [["xA_C"],["xB_D"]]
, но хотя я получил результаты, отличные от предыдущих, он не соответствовал отображению R.Может быть, это нечто внутреннее в том, как Python хранит имена переменных?Заранее спасибо, я бы очень хотел это выяснить.