Bias is a systematic, often unconscious inclination that favors or disfavors a person, group, object, or idea in decisions, perceptions, actions, or judgments. It can arise from beliefs, stereotypes, discrimination, cultural preferences, what is treated as normal, and the data or algorithms behind an AI system. In data work, bias can also enter through a misleading representation: raw counts may favor larger populations even when the underlying rate is lower. section 10.1.2 section 5.1.1
A useful first question is: compared with what? Absolute values answer a question about totals, while normalized values answer a question about prevalence relative to a common base. Mixing those questions can make a chart appear persuasive while obscuring the situation that matters. section 5.1.1
Raw counts can reverse the practical conclusion
Consider two regions. One has 30 homeless people in a population of 100; the other has 8 homeless people in a population of 10. A chart of counts ranks the first region higher. Rates show 30% versus 80%, making the second region the more affected one. Joining homeless and population data, then computing homeless/population × 1,000, produces a comparison designed for population size rather than raw scale. section 5.1.1
Listing 5.3 Listing 5.3 The improved bar chart in Altair
import pandas as pd
import altair as alt
df = pd.read_csv('source/homeless.csv')
df['Territory'] = df['Territory'].str.replace('Trentino Alto Adige',
'Trentino-Alto Adige/Südtirol') #1
df = df[(df['Age'] == 'TOTAL') & (df['Sex'] == 'T') & (df['Citizenship']
== 'TOTAL')] #2
df = df[['Value', 'ITTER107']]
df_pop = pd.read_csv('source/population.csv')
df_pop = df_pop[(df_pop['Age'] == 'TOTAL') & (df_pop['Sex'] == 'T')] #3
df_pop = df_pop[['Value', 'ITTER107','Territory']]
df_tot = df_pop.set_index('ITTER107').join(df.set_index('ITTER107'),
lsuffix='_pop', rsuffix='_hom').reset_index()
df_tot['Ratio'] = df_tot['Value_hom']/df_tot['Value_pop']*1000
chart = alt.Chart(df_tot).mark_bar().encode(
y = alt.Y('Territory',
sort='-x',
axis=alt.Axis(title='')),
x = alt.X('Ratio',
axis=alt.Axis(tickCount=4,title='')),
color=alt.condition(alt.datum.Ratio > 2,
alt.value('#80C11E'),
alt.value('lightgray'))
).properties(
width=500,
title='Number of homeless people in a population of 1,000'
)
The listing makes the normalization explicit: it joins population and homelessness records, calculates a per-1,000 ratio, and encodes that ratio in the bar chart. section 5.1.1
Generative AI can reproduce patterns and limitations in human-produced training data. Large datasets do not guarantee diverse representation: some groups may be underrepresented, while prevalent cultural patterns may dominate. Bias may also stem from choices in algorithm design, coding, implementation, feature selection, or model complexity. Even idealized data would not guarantee an unbiased system because design and language-processing limitations can still shape outputs. section 10.1.2
When generative AI contributes to a data story, treat bias as a practical risk rather than a purely technical label:
- Watch for outputs that disadvantage minority populations or turn stereotypes into plausible-looking stories. section 10.1
- Consider whether repeated generated images or language represent only a narrow pattern as if it were universal. section 10.1
- Account for possible harms before sharing AI-assisted work, especially when the audience may act on the story. section 10.1
A repeated image pattern
Prompts for a woman in a red dress, a woman in an orange sweater drinking coffee, and a man on a yellow chair can yield people with notably similar features, such as dark hair. One image may be a minor concern; repeated use at scale can create biased representation by presenting a narrow appearance as the default. section 10.1



























