I am trying to implement feature hashing in Java. For this I am trying to use Hashing functions from guava.
This is how I am doing it now:
//seed is any integer.
HashFunction hf = Hashing.murmur3_32(seed);
//key is the input int and hd is the hashed dimension.
int hash = Hashing.consistentHash(hf.hashInt(key), hd);
I have another method for sign, not shown in this question.
To measure the performance, I am doing something like below:
int min = 0, max = 2000000, sampleSize = 3000000;
int[] hds = { 2000, 5000, 6000, 10000, 20000, 500000, 1000000, 2000000 };
List<Double> guavaCollisons = new ArrayList<>();
UniformIntegerDistribution runif = new UniformIntegerDistribution(min, max);
Arrays.stream(hds)
.forEach(hd -> {
int seed = runif.sample();
HashFunction hf = Hashing.murmur3_32(seed);
Map<Integer, Set<Integer>> guava = new HashMap<>();
Arrays.stream(runif.sample(sampleSize))
.forEach(key -> {
int guavaHash = Hashing.consistentHash(hf.hashInt(key), hd);
if (!guava.containsKey(guavaHash))
guava.put(guavaHash, new HashSet<Integer>());
guava.get(guavaHash).add(key);
});
double guavaCollisionHd = guava.entrySet()
.stream()
.mapToInt(entry -> entry.getValue()
.size())
.average()
.getAsDouble();
guavaCollisons.add(guavaCollisionHd);
System.out.println("Available buckets = " + hd
+ ", unutilized = " + (hd - guava.keySet().size())
+ ", guava collision = " + guavaCollisionHd);
});
double guavaCollision = Stats.meanOf(guavaCollisons);
System.out.println("Average collision = " + guavaCollision);
My questions are:
- Is this a correct way to implement the 'hash' part of feature hashing?
- Is this a correct way to measure the collision rate of the hashing technique?