二.貝葉斯分類器根據姓名判別男女 -python
項目github地址:https://github.com/observerss/ngender
先說一下主要思路,我們日常從一個人的名字中,基本上能大致判斷這個名字的主人是男是女。比如李大志,這個名字一聽就很男性。爲什麼呢?因爲大字和志字男性名字用得比較多。雖然機器一眼看不出來,但它可以通過統計信息來判斷。如果有足夠多的數據,我們就可以統計出大字和志字用作男性名字的比例,計算概率信息。然後就可以用這些概率,運用上述的貝葉斯公式來進行計算,判定性別。
代碼其實不難,各個字的統計數據已經計算好,在項目中給出。我們只需要讀取文件數據,存儲到 python 的字典中,計算出概率,然後預測的時候進行計算即可。我們先看核心代碼,稍後會有例子說明。
裏面核心代碼文件爲:
這裏主要講一下核心代碼的內容:https://github.com/observerss/ngender/blob/master/ngender/ngender.py
如果你對python感興趣,我這有個學習Python基地,裏面有很多學習資料,感興趣的+Q羣:688244617
class Guesser(object):
//初始化函數,調用下面的_load_model()函數
def __init__(self):
self._load_model()
//初始化一些參數
def _load_model(self):
self.male_total = 0
self.female_total = 0
self.freq = {}
//這裏加載charfreq.csv文件,這個文件存放的是一些漢字是男女的統計信息
with open(os.path.join(os.path.dirname(__file__),
'charfreq.csv'),
'rb') as f:
# skip first line
next(f)
//將文件中的信息存儲,累加,以便稍後計算概率
for line in f:
line = line.decode('utf-8')
char, male, female = line.split(',')
char = py2compat(char)
//計算男性總數
self.male_total += int(male)
//計算女性總數
self.female_total += int(female)
//一個漢字對應的那女數量
self.freq[char] = (int(female), int(male))
self.total = self.male_total + self.female_total
//一個漢字是男女概率
for char in self.freq:
female, male = self.freq[char]
self.freq[char] = (1. * female / self.female_total,
1. * male / self.male_total)
def guess(self, name):
name = py2compat(name)
//去掉姓氏
firstname = name[1:]
//過濾掉不在這個unicode編碼範圍內的字符
for char in firstname:
assert u'\u4e00' <= char <= u'\u9fa0', u'姓名必須爲中文'
//貝葉斯分類器,分別計算出男的概率和女的概率
pf = self.prob_for_gender(firstname, 0)
pm = self.prob_for_gender(firstname, 1)
//若名字爲男的概率較大,則分類爲男,反之則爲女
if pm pf:
return ('male', 1. * pm / (pm + pf))
elif pm < pf:
return ('female', 1. * pf / (pm + pf))
else:
return ('unknown', 0)
//貝葉斯公式的應用
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
guesser = Guesser()
上述代碼還是比較簡單的,首先在初始化的時候會調用 _load_model() 函數,這個函數完成的是一些概率計算工作,比如先將每個字對應是男是女的概率計算好存儲在字典中。
然後在計算的時候,先過濾掉姓氏。然後分別計算出這個名字是男是女的概率,比如計算 P(男|李大志)和P(女|李大志),,對比哪個概率大一些,然後進行男女分類。
這裏放上一個例子:判斷
P(gender=男|name=本山)
= P(name=本山|gender=男) * P(gender=男) / P(name=本山)
= P(name has 本|gender=男) * P(name has 山|gender=男) * P(gender=男) / P(name=本山)
公式原理爲貝葉斯公式,下面對公式中中各個項進行解答,首先明確我們已經統計得到P(gender=男),P(gender=女)的概率。
怎麼算 P(name has 本|gender=男)?
“本”在男性名字中出現的次數 / 男性字出現的總次數
怎麼算 P(gender=男)?
男性名出現的次數 / 總次數
怎麼算 P(name=本山)?
這個概率對男女來說都是一樣的,所以沒必要算出來,即我們只需要比較P(name=本山|gender=男) * P(gender=男)和P(name=本山|gender=女) * P(gender=女)兩部分誰比較大即可做出判斷。
以上就是貝葉斯分類器介紹的全部內容啦。