Alle persone che hanno deciso di partecipare al sondaggio è stata fatta la stessa domanda: "cosa faresti in ognuna delle seguenti situazioni"
Ogni persona si è trovata davanti a 3 situazioni:
Switch: se si dovesse decidere di intervenire si andrebbe a uccidere una persona salvandone 5. Nel caso in cui non si dovesse intervenire 5 persone morirebbero.
Loop: caso molto simile al precedente fatta eccezione per una differenza ed è il fatto che nel caso in cui si dovesse tirare la leva la morte della persona è strettamente necessaria per poter fermare il treno e salvare le altre persone. Anche in questo caso se non si dovesse intervenire 5 persone morirebbero.
Footbride: caso completamente diverso dagli altri 2. Infatti qua ci troviamo sopra un ponte e dobbiamo decidere se spingere giu la persona oppure no. Nel caso in cui si dovesse decidere di spingere giu la persona salverebbe la vita agli altri fermando il treno.
I dati presenti nel dataset provengono da Moral Machine un sito creato dal MIT dove chiunque può provare a fare questi o altri tipi di test. Al termine di questo test alle persone è stato proposto di compilare un sondaggio per poter ottenere dei dati demografici, politici e religiosi. dataset
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objs as go
import country_converter as coco
import seaborn as sns
from matplotlib.ticker import PercentFormatter
import requests
df = pd.read_csv("data/Shared_data_responses_demographics.csv")
df
UserIP_Anonymized | Scenario | survey.age | survey.gender | survey.education | survey.political | survey.religious | country_code | Outcome | Continent | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0002ae2d | Footbridge | 19 | Women | College | 0.56 | 0.00 | GB | 0 | Europe |
1 | 0002ae2d | Loop | 19 | Women | College | 0.56 | 0.00 | GB | 1 | Europe |
2 | 0002ae2d | Switch | 19 | Women | College | 0.56 | 0.00 | GB | 1 | Europe |
3 | 00065336 | Footbridge | 19 | Men | College | 0.00 | 0.68 | FR | 1 | Europe |
4 | 00065336 | Loop | 19 | Men | College | 0.00 | 0.68 | FR | 0 | Europe |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
59154 | ffef6123 | Footbridge | 27 | Men | College | 0.34 | 0.53 | SG | 0 | Asia |
59155 | ffef6123 | Loop | 23 | Men | College | 1.00 | 0.00 | SG | 1 | Asia |
59156 | ffef6123 | Loop | 27 | Men | College | 0.34 | 0.53 | SG | 1 | Asia |
59157 | ffef6123 | Switch | 23 | Men | College | 1.00 | 0.00 | SG | 1 | Asia |
59158 | ffef6123 | Switch | 27 | Men | College | 0.34 | 0.53 | SG | 1 | Asia |
59159 rows × 10 columns
Come si nota dalla colonna UserIP_Anonymized ogni persona è stata registrata 3 volte: una per ognuna delle diverse situazioni. Se si guarda con attenzione le ultime 5 righe che vengono riportate nel grafico soprastante sembra che una persona abbia votato più volte, noi crediamo che sia dato dal fatto che le persone che hanno eseguito il test siano uscite con lo stesso IP come se lo avessero fatto per esempio dallo stesso edificio.
Con questa tabella di contingenza abbiamo voluto mostrare quante persone divise per sesso e per continente hanno partecipato al sondaggio
df_renamed = df.rename(columns={"survey.gender":"Gender",
"survey.education": "Education"});
df_renamed.groupby(["Continent","Gender"]).size().unstack()
Gender | Men | Women |
---|---|---|
Continent | ||
Americas | 12348 | 4892 |
Asia | 5160 | 1559 |
Europe | 25641 | 8163 |
Oc. | 1017 | 379 |
Con quest'altra tabella di contingenza invece abbiamo deciso di vedere quante persone hanno frequentato il college divise per sesso
df_renamed.groupby(["Gender","Education"]).size().unstack()
Education | College | No College |
---|---|---|
Gender | ||
Men | 32345 | 11821 |
Women | 10747 | 4246 |
Le persone che hanno partecipato a questo studio hanno risposto a delle domande e in base alla loro risposta hanno ottenuto un valore. Non sappiamo quali siano state queste domande quindi non sappaimo se il valore associato alla religiosità prende in considerazione qualsiasi religione o solo quelle occidentali. Per quanto riguarda il valore associato all'attività politica non sappiamo se tiene in considerazione lo schieramento politico (se di destra o di sinistra).
Nei seguenti grafici possiamo vedere quante persone rientrano in quale range nei casi presentati precedentemente.
sorted_religiuos = df.sort_values(by='survey.religious')
sorted_religiuos["believer"] = "0" # non credente
sorted_religiuos.loc[(df["survey.religious"] > 0) & (sorted_religiuos["survey.religious"] < 0.4) , "believer"] = "(0; 0.4)" #poco credente
sorted_religiuos.loc[(df["survey.religious"] >= 0.4) & (sorted_religiuos["survey.religious"] < 0.7), "believer"] = "[0.4; 0.7)" #credente
sorted_religiuos.loc[df["survey.religious"] >= 0.7, "believer"] = "[0.7; 1)" # molto credente
px.histogram(sorted_religiuos, x="believer",
labels={"believer": "Believer"})
sorted_political = df.sort_values(by='survey.political')
sorted_political["Political Activity"] = "0" # non attivo
sorted_political.loc[(df["survey.political"] > 0) & (sorted_political["survey.political"] < 0.4) , "Political Activity"] = "(0; 0.4)" #poco attivo
sorted_political.loc[(df["survey.political"] >= 0.4) & (sorted_political["survey.political"] < 0.7), "Political Activity"] = "[0.4; 0.7)" #attivo
sorted_political.loc[df["survey.political"] >= 0.7, "Political Activity"] = "[0.7; 1)" #molto attivo
px.histogram(sorted_political, x="Political Activity")
Inizialmente ci siamo chiesti se le persone religiose intervengono in modo diverso rispetto alle persone non religiose in questo tipo di situazioni.
Abbiamo deciso di suddividere le persone nel seguente modo:
Possiamo quindi vedere dal grafico sottostante come non ci sia nessuna differenza fra le persone religiose e quelle non religiose.
df["outcome_str"] = df["Outcome"].map({0 : "Omission", 1: "Commission"})
df["outcome_str"]
df.loc[df["survey.religious"] == 0.0, "religion"] = 'Religious'
df.loc[df["survey.religious"] != 0.0, "religion"] = 'Not religious'
fig = px.histogram(df,
orientation="v",
x="religion",
barmode="group",
barnorm='percent',
color="outcome_str",
facet_col="Scenario",
title="Outcome by religiosity",
labels={"outcome_str": "Outcome"},
category_orders={"outcome_str": ["Commission","Omission"],
"religion": ["Religious","Not religious"]},
color_discrete_sequence=['indianred', '#1f77b4'])
fig.update_yaxes(title_text='')
fig.update_xaxes(title_text='')
fig.update_yaxes(ticksuffix='%')
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig
Anche in questo caso ci siamo chiesti se essere attivi politicamente potesse influenzare sulla scelta di intervenire oppure no.
Abbiamo deciso di suddividere le persone nel seguente modo:
Abbiamo deciso di prendere in considerazione solo gli estremi cosi da avere due casi diametralmente opposti: attivo e non attivo. Pur facendo cosi il grafico non mostra nessuna differenza di scelta fra i due tipi di persone.
df.loc[df["survey.political"] > 0.9, "activity"] = 'Active'
df.loc[df["survey.political"] < 0.1, "activity"] = 'Not Active'
fig = px.histogram(df,
orientation="v",
x="activity",
barmode="group",
barnorm='percent',
color="outcome_str",
facet_col="Scenario",
title="Outcome by political activity",
labels={"outcome_str": "Outcome"},
category_orders={"outcome_str": ["Commission","Omission"],
"political": ["Active","Not Active"]},
color_discrete_sequence=['indianred', '#1f77b4'])
fig.update_yaxes(title_text='')
fig.update_xaxes(title_text='')
fig.update_yaxes(ticksuffix='%')
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig
Giunti a questo punto ci sembrava interessante anche vedere la differenza tra uomini e donne e capire se il sesso potesse influenzare la scelta di intervenire oppure no. Come possiamo notare non c'è nessuna correlazione tra le scelte fatte e il sesso.
fig = px.histogram(df,
orientation="v",
x="survey.gender",
barmode="group",
barnorm='percent',
color="outcome_str",
facet_col="Scenario",
title="Outcome by gender",
labels={"outcome_str": "Outcome"},
category_orders={"outcome_str": ["Commission","Omission"]},
color_discrete_sequence=['indianred', '#1f77b4'])
fig.update_yaxes(title_text='')
fig.update_xaxes(title_text='')
fig.update_yaxes(ticksuffix='%')
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.update_yaxes()
fig
Un'altro studio che abbiamo fatto è basato sulla scelta delle persone in base alla loro educazione. Abbiamo quindi messo a confronto la scelta fatta da chi ha frequentato il College e chi no. Nello scenario del Footbridge possiamo notare la differenza, infatti chi ha frequentato il college è più propenso a non intervenire (non spingere la persona giu dal ponte). La differenza scompare completamente negli altri 2 casi infatti come si può vedere la scelta è praticamente uguale.
fig = px.histogram(df,
orientation="v",
x="survey.education",
barmode="group",
barnorm='percent',
color="outcome_str",
facet_col="Scenario",
title="Outcome by education",
labels={"outcome_str": "Outcome"},
category_orders={"outcome_str": ["Commission","Omission"]},
color_discrete_sequence=['indianred', '#1f77b4'])
fig.update_yaxes(title_text='')
fig.update_xaxes(title_text='')
fig.update_yaxes(ticksuffix='%')
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.update_yaxes()
fig
In queso grafico abbiamo deciso di raggruppare tutte le persone in gruppi di età di 4 anni e osservare le diverse scelte fatte.
fig = px.histogram(df,
orientation="v",
x="survey.age",
color="outcome_str",
barmode="stack",
barnorm='fraction',
facet_row="Scenario",
title="Outcome by age",
nbins=20,
labels={"outcome_str": "Outcome",
"survey.age": "Age"},
category_orders={"outcome_str": ["Commission","Omission"]},
color_discrete_sequence=['indianred', '#1f77b4'])
fig.update_yaxes(tickformat='%')
fig.update_yaxes(title_text='')
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig
Abbiamo pensato che sarebbe stato interessante vedere se c'è qualche differenza fra le varie nazioni del mondo. Dal grafico sottostante si possono notare che:
total_list = df.groupby("country_code")["Outcome"].mean().tolist()
count_list = df.groupby("country_code")["Outcome"].count().tolist()
country_list = df["country_code"].tolist()
country_set = set(country_list)
country_list = list(country_set)
country_list.sort()
country_list = coco.convert(names=country_list, to='name_short')
new_df = pd.DataFrame(list(zip(country_list, total_list, count_list)),
columns =['Country', 'percent', 'count'])
fig = go.Figure(data=go.Choropleth(
locationmode = "country names",
locations = new_df['Country'],
z = new_df['percent'],
autocolorscale=False,
reversescale=False,
colorbar_title = 'Percantage commision',
))
fig.update_layout(
title_text='Percentage commision by country',
)
fig.update_traces(colorbar_tickformat='%')
fig.show()
Visto il risultato interessante ottenuto nel grafico precedente, dove i paesi asiatici avevano un grado di intervento più basso, abbiamo deciso di fare un grafico tenendo in considerazione i continenti invece delle singole nazioni. Si può notare quindi che:
ax = sns.pointplot(x = 'Outcome',
y = 'Scenario',
hue="Continent",
ci =10,
data = df,
join = False)
ax.set_title('Outcome by continent')
ax.set(xlabel='Percentage commission')
ax.xaxis.set_major_formatter(PercentFormatter(1))
ax.plot()
[]
Ho pensato ci potesse essere una differenza tra le scelte di abitanti di paesi ricchi e abitanti di paesi meno ricchi. Ho quindi pensato di fare uno scatter plot fra l'indice di qualità della vità e la percentuale di intervento, per cercare se ci fosse una correlazione. I dati utilizzati provengono dal sito Quality of Life Index by Country
url = 'https://www.numbeo.com/quality-of-life/rankings_by_country.jsp'
crypto_url = requests.get(url)
crypto_data = pd.read_html(crypto_url.text)
quality=crypto_data[1]
result = pd.merge(new_df, quality, on='Country', how='left')
resultClean = result.drop(columns="Rank").dropna()
fig = px.scatter(resultClean, x="percent", y="Quality of Life Index", size="count", hover_name="Country",
title="Relation between commission and quality of life index",
labels={"percent": "Percentage commission"},
range_y=(80,200),
range_x=(0.4,0.8))
fig.update_xaxes(tickformat='%')
fig.show()
print('Indice di correlazione lineare fra tutte le nazioni: {value:.2f}'
.format(value=np.corrcoef(
resultClean["Quality of Life Index"],
resultClean["percent"])[0,1]))
print('Indice di correlazione lineare fra le nazioni con più di 200 osservazioni: {value:.2f}'
.format(value=np.corrcoef(
resultClean.loc[resultClean["count"] > 200, "Quality of Life Index"],
resultClean.loc[resultClean["count"] > 200, "percent"])[0,1]))
Indice di correlazione lineare fra tutte le nazioni: 0.25 Indice di correlazione lineare fra le nazioni con più di 200 osservazioni: 0.28
Visto che l'indice di qualità della vita non ci ha mostrato una correlazione evidente ho pensato che ci potesse essere un indice che più si avvicinava agli elementi che possono influenzare una scelta come quella presa in considerazione da questo studio. Ho quindi trovato il World Index of Moral Freedom, questo indice prende in considerazione aspetti che riguardano la libertà delle persone (si possono trovare più dettagli nel link mostrato precedentemente). Facendo lo scatter plot si possono notare alcune cose interessanti:
url = 'https://en.wikipedia.org/wiki/World_Index_of_Moral_Freedom'
freedreq = requests.get(url)
freed = pd.read_html(freedreq.text)
freed=freed[4]
resultfreed = pd.merge(new_df, freed, on='Country', how='left')
resultfreed = resultfreed.dropna()
fig = px.scatter(resultfreed, x="percent", y="2020 score", size="count", hover_name="Country",
title="Relation between Commission and World Index of Moral Freedom",
labels={"percent": "Percentage commission",
"2020 score": "World Index of Moral Freedom"},
range_y=(30,100),
range_x=(0.4,0.8)
)
fig.update_xaxes(tickformat='%')
fig.show()
print('Indice di correlazione lineare fra tutte le nazioni: {value:.2f}'.format(value=np.corrcoef(resultfreed["2020 score"], resultfreed["percent"])[0,1]))
print('Indice di correlazione lineare fra le nazioni con più di 200 osservazioni: {value:.2f}'.format(value=np.corrcoef(resultfreed.loc[resultfreed["count"] > 200, "2020 score"],
resultfreed.loc[resultfreed["count"] > 200, "percent"])[0,1]))
Indice di correlazione lineare fra tutte le nazioni: 0.24 Indice di correlazione lineare fra le nazioni con più di 200 osservazioni: 0.65