用贝叶斯猜中文名性别
用贝叶斯公式从名字推测性别的小想法。
发布 2017年4月12日 标签
#javascript
#experiments
~/posts/gender-by-name $ cat post.md
最早是两年前在某个仓库看到有人用 Python 把名字猜成性别,打算用 JS 再实现一遍。
原理是贝叶斯定理:
各项含义:
P(A|B)是已知 B 发生后 A 的条件概率,也叫 A 的后验概率(来自 B 的取值)。P(B|A)是已知 A 发生后 B 的条件概率,也叫 B 的后验概率。P(A)是 A 的先验概率(或边缘概率)。“先验”是因为它不考虑任何 B 方面的因素。P(B)是 B 的先验概率。
参考的 Python 实现:
def prob_for_gender(self, firstName, gender=0):
p = 1. * self.female_total / self.total \
if gender == 0 \
else 1. * self.male_total / self.total
for char in firstName:
p *= self.freq.get(char, (0, 0))[gender]
return p
这种逐字相乘的实现有几个明显短板。比如”翁胜男”,三个字都偏男性,但连起来其实大概率是女性名字;又比如”刘璇”,“璇”虽然偏女性,但整名读起来偏中性。要把这个项目做完整,要补的至少有:
- 整理一份姓名 → 性别的数据集,建立字 / 词级别的频率库。
- 用贝叶斯,但以”整名”而非”逐字”为单位估计概率,并配合字一级的回退。
暂时停在这一步。