问题1 :
在wide_n_deep_tutorial.py
中,hash_bucket_size
和tf.feature_column.categorical_column_with_hash_bucket
方法都有一个名为tf.feature_column.crossed_column
的超参数,值为hash_bucket_size=1000
。
但为什么1000?如何设置此参数?
问题2 :
关于crossed_columns
的第二个问题,即
crossed_columns = [
tf.feature_column.crossed_column( ["education", "occupation"], hash_bucket_size=1000),
tf.feature_column.crossed_column( [age_buckets, "education", "occupation"], hash_bucket_size=1000),
tf.feature_column.crossed_column( ["native_country", "occupation"], hash_bucket_size=1000) ]
,
为什么选择wide_n_deep_tutorial.py
,["education", "occupation"]
和[age_buckets, "education", "occupation"]
作为["native_country", "occupation"]
,是否有任何经验法则?
答案 0 :(得分:5)
关于hash_bucket_size
:如果将其设置得太低,则将发生许多哈希冲突,其中不同类别将映射到同一存储桶,从而迫使神经网络使用其他功能来区分它们。如果将其设置得太高,则将无用的RAM大量使用:我假设您将categorical_column_with_hash_bucket()
包装在embedding_column()
中(通常应该如此),在这种情况下,{{ 1}}将确定嵌入矩阵的行数。
如果有k个类别,则发生碰撞的概率大约等于:hash_bucket_size
(source),因此,如果有40个类别并且您使用1 - exp(-k*(k-1)/2/hash_bucket_size)
,则发生碰撞的可能性令人惊讶高:约54%!为了说服自己,请尝试运行hash_bucket_size=1000
几次(它会选择0至999之间的40个随机数,并计算有多少个唯一数),您会发现结果通常少于40。您可以使用该方程式可以选择不会引起太多冲突的len(np.unique(np.random.randint(1000, size=40)))
值。
也就是说,如果只有几次碰撞,在实践中可能不会太糟,因为神经网络仍将能够使用其他功能来区分碰撞类别。最好的选择是尝试使用不同的hash_bucket_size
值来查找会开始降低性能的值,然后再提高10-20%以确保安全。
答案 1 :(得分:2)
对于hash_bucket
一般的想法是,理想情况下,散列函数的结果不应导致任何冲突(否则您/算法将无法区分两种情况)。因此,在这种情况下1000就是'只是'一个值。如果你查看职业和国家(16和43)的唯一条目,你会发现这个数字足够高:
edb@lapelidb:/tmp$ cat adult.data | cut -d , -f 7 | sort | uniq -c | wc -l
16
edb@lapelidb:/tmp$ cat adult.data | cut -d , -f 14 | sort | uniq -c | wc -l
43
功能交叉
我认为经验法则是,如果特征的组合实际上具有意义,则交叉是有意义的。在这个例子中,教育和职业是相互联系的至于第二个,将人们定义为具有博士学位的初级工程师可能是有意义的。 vs没有学位的高级清洁人员'。你经常看到的另一个典型例子是经度和纬度的交叉,因为它们比单独的更有意义。