# Here are the feature distributions grouped by sex
plot_cdfs(subset, 'Culmen Length (mm)', by='Sex')
plot_cdfs(subset, 'Culmen Depth (mm)', by='Sex')
plot_cdfs(subset, 'Flipper Length (mm)', by='Sex')
plot_cdfs(subset, 'Body Mass (g)', by='Sex')
# Here are the norm maps for the features, grouped by sex
culmen_map = make_norm_map(subset, 'Culmen Length (mm)', by='Sex')
flipper_map = make_norm_map(subset, 'Flipper Length (mm)', by='Sex')
depth_map = make_norm_map(subset, 'Culmen Depth (mm)', by='Sex')
mass_map = make_norm_map(subset, 'Body Mass (g)', by='Sex')
# And here are the sequences we need for `update_naive`
norm_maps4 = [culmen_map, flipper_map, depth_map, mass_map]
colnames4 = ['Culmen Length (mm)', 'Flipper Length (mm)',
'Culmen Depth (mm)', 'Body Mass (g)']
# Here's the prior
hypos = culmen_map.keys()
prior = Pmf(1/2, hypos)
prior
FEMALE 0.5
MALE 0.5
dtype: float64
# And the update
subset['Classification'] = "None"
for i, row in subset.iterrows():
data_seq = row[colnames4]
posterior = update_naive(prior, data_seq, norm_maps4)
subset.loc[i, 'Classification'] = posterior.max_prob()
# This function computes accuracy
def accuracy_sex(df):
"""Compute the accuracy of classification.
Compares columns Classification and Sex
df: DataFrame
"""
valid = df['Classification'].notna()
same = df['Sex'] == df['Classification']
return same.sum() / valid.sum()
# Using these features we can classify Gentoo penguins by
# sex with almost 92% accuracy
accuracy_sex(subset)
0.9186991869918699
# Here's the whole process in a function so we can
# classify the other species
def classify_by_sex(subset):
"""Run the whole classification process.
subset: DataFrame
"""
culmen_map = make_norm_map(subset, 'Culmen Length (mm)', by='Sex')
flipper_map = make_norm_map(subset, 'Flipper Length (mm)', by='Sex')
depth_map = make_norm_map(subset, 'Culmen Depth (mm)', by='Sex')
mass_map = make_norm_map(subset, 'Body Mass (g)', by='Sex')
norm_maps4 = [culmen_map, flipper_map, depth_map, mass_map]
hypos = culmen_map.keys()
prior = Pmf(1/2, hypos)
subset['Classification'] = "None"
for i, row in subset.iterrows():
data_seq = row[colnames4]
posterior = update_naive(prior, data_seq, norm_maps4)
subset.loc[i, 'Classification'] = posterior.max_prob()
return accuracy_sex(subset)
# Here's the subset of Adelie penguins
# The accuracy is about 88%
adelie = df['Species2']=='Adelie'
subset = df[adelie].copy()
classify_by_sex(subset)
0.8807947019867549
# And for Chinstrap, accuracy is about 92%
chinstrap = df['Species2']=='Chinstrap'
subset = df[chinstrap].copy()
classify_by_sex(subset)
0.9264705882352942
# It looks like Gentoo and Chinstrap penguins are about equally
# dimorphic, Adelie penguins a little less so.
# All of these results are consistent with what's in the paper.