Esplorazione delle tendenze e modelli di conflitto Analisi dei dati ACLED di Manipur
'Exploration of conflict trends and patterns. Analysis of ACLED data in Manipur.'
Introduzione
L’analisi e la visualizzazione dei dati sono strumenti potenti che ci permettono di comprendere complessi dataset e comunicare efficacemente le idee che emergono. In questa immersiva esplorazione dei dati reali sui conflitti, ci addentriamo nelle realtà e nelle complessità dei conflitti. Ci concentriamo su Manipur, uno stato del nord-est dell’India, che, purtroppo, è stato segnato da violenze e instabilità prolungate. Utilizzando il dataset del Progetto sulla Localizzazione e gli Eventi dei Conflitti Armati (ACLED) [1], intraprendiamo un viaggio di analisi approfondita dei dati per scoprire la natura multifacetata dei conflitti.
Obiettivi di Apprendimento
- Acquisire competenze nelle tecniche di analisi dei dati per il dataset ACLED.
- Sviluppare competenze nella visualizzazione efficace dei dati per la comunicazione.
- Comprendere l’impatto della violenza sulle popolazioni vulnerabili.
- Acquisire conoscenze sugli aspetti temporali e spaziali dei conflitti.
- Sostenere approcci basati sulla prova per affrontare le esigenze umanitarie.
Questo articolo è stato pubblicato come parte del Data Science Blogathon.
Conflitto di Interessi
Nessuna organizzazione o entità specifica è responsabile dell’analisi e dell’interpretazione presentate in questo blog. Lo scopo è puramente quello di mostrare il potenziale della scienza dei dati nell’analisi dei conflitti. Inoltre, non sono coinvolti interessi personali o pregiudizi in queste conclusioni, garantendo un approccio oggettivo alla comprensione delle dinamiche del conflitto. Promuoviamo l’uso di metodi basati sui dati come strumento per migliorare le conoscenze e informare discussioni più ampie sull’analisi dei conflitti.
Implementazione
Perché il Dataset ACLED?
Sfruttando il potere delle tecniche di scienza dei dati sul dataset ACLED, possiamo estrarre conoscenze che non solo contribuiscono alla comprensione della situazione in Manipur, ma anche gettano luce sugli aspetti umanitari associati alla violenza. Il Codebook ACLED è una guida di riferimento esaustiva che fornisce informazioni dettagliate sullo schema di codifica e le variabili utilizzate in questo dataset [2].
- Accelerare il tempo per ottenere informazioni aziendali con la connessione diretta di Amazon SageMaker Data Wrangler a Snowflake
- Atlante della letteratura biomedica potrebbe aiutare a rintracciare gli studi falsificati.
- Gestione delle dipendenze Python quale strumento scegliere?
L’importanza di ACLED risiede nella sua analisi empatica dei dati, che migliora la nostra comprensione della violenza in Manipur, illumina le esigenze umanitarie e contribuisce ad affrontare e mitigare la violenza. Promuove un futuro pacifico e inclusivo per le comunità colpite.
Attraverso questa analisi basata sui dati, possiamo non solo scoprire conoscenze preziose, ma anche evidenziare il costo umano della violenza in Manipur. Analizzando i dati ACLED, speriamo di gettare luce sull’impatto sulle popolazioni civili, sullo sfollamento forzato e sull’accesso ai servizi essenziali, dipingendo quindi un quadro completo delle realtà umanitarie affrontate nella regione.
Eventi di Conflitto
Come primo passo, esploreremo gli eventi di conflitto in Manipur utilizzando il dataset ACLED. Il frammento di codice qui sotto legge il dataset ACLED per l’India e filtra i dati specificamente per Manipur, ottenendo un dataset filtrato con una forma di (numero di righe, numero di colonne). La forma dei dati filtrati viene quindi stampata.
import pandas as pd
#importare il csv specifico per il paese scaricato da acleddata.com
file_path = './acled_India.csv'
all_data = pd.read_csv(file_path)
# Filtrare i dati per Manipur
df_filtered = all_data.loc[all_data['admin1'] == "Manipur"]
shape = df_filtered.shape
print("Forma dei Dati Filtrati:", shape)
#Output:
#Forma dei Dati Filtrati: (4495, 31)
Il numero di righe nei dati ACLED rappresenta il numero di eventi o incidenti registrati nel dataset. Ogni riga corrisponde tipicamente a un evento specifico, come un conflitto, una protesta o un’occasione di violenza, e contiene vari attributi o colonne che forniscono informazioni sull’evento, come la posizione, la data, gli attori coinvolti e altri dettagli rilevanti.
Contando il numero di righe nel dataset ACLED, è possibile determinare il numero totale di eventi o incidenti registrati nei dati. Filtrando il dataset specificamente per Manipur, abbiamo ottenuto un dataset filtrato contenente informazioni sugli eventi o incidenti registrati dal gennaio 2016 al 9 giugno 2023. Il numero totale di eventi o incidenti registrati in Manipur, che ammontava a 4495 righe, forniva conoscenze sulla portata e l’entità del conflitto o degli eventi monitorati da ACLED.
Come passo successivo, calcoliamo la somma dei valori nulli lungo le colonne (asse=0) nel DataFrame df_filtered. Ciò fornisce informazioni sul conteggio dei valori mancanti in ogni colonna del dataset filtrato.
df_filtered.isnull().sum(axis = 0)
# Output: conteggio dei valori nulli in ogni colonna
# event_id_cnty: 0 valori nulli
# event_date: 0 valori nulli
# year: 0 valori nulli
# time_precision: 0 valori nulli
# disorder_type: 0 valori nulli
# event_type: 0 valori nulli
# sub_event_type: 0 valori nulli
# actor1: 0 valori nulli
# assoc_actor_1: 1887 valori nulli
# inter1: 0 valori nulli
# actor2: 3342 valori nulli
# assoc_actor_2: 4140 valori nulli
# inter2: 0 valori nulli
# interaction: 0 valori nulli
# civilian_targeting: 4153 valori nulli
# iso: 0 valori nulli
# region: 0 valori nulli
# country: 0 valori nulli
# admin1: 0 valori nulli
# admin2: 0 valori nulli
# admin3: 0 valori nulli
# location: 0 valori nulli
# latitude: 0 valori nulli
# longitude: 0 valori nulli
# geo_precision: 0 valori nulli
# source: 0 valori nulli
# source_scale: 0 valori nulli
# notes: 0 valori nulli
# fatalities: 0 valori nulli
# tags: 1699 valori nulli
# timestamp: 0 valori nulli
Il seguente frammento di codice restituisce il numero di valori unici in ogni colonna.
n = df_filtered.nunique(axis=0)
print("Numero di valori unici in ogni colonna:\n", n)
# Output:
# Numero di valori unici in ogni colonna:
# event_id_cnty: 4495
# event_date: 1695
# year: 8
# time_precision: 3
# disorder_type: 4
# event_type: 6
# sub_event_type: 17
# actor1: 66
# assoc_actor_1: 323
# inter1: 8
# actor2: 61
# assoc_actor_2: 122
# inter2: 9
# interaction: 28
# civilian_targeting: 1
# iso: 1
# region: 1
# country: 1
# admin1: 1
# admin2: 16
# admin3: 37
# location: 495
# latitude: 485
# longitude: 480
# geo_precision: 3
# source: 233
# source_scale: 12
# notes: 4462
# fatalities: 10
# tags: 97
# timestamp: 1070
Una mappa interattiva che utilizza la libreria Folium per visualizzare gli eventi ACLED
Il Manipur è geograficamente diviso in due regioni distinte: la regione della valle e la regione collinare. La regione della valle, situata nella parte centrale del Manipur, è relativamente piatta e circondata da colline. È l’area più densamente popolata e produttiva dal punto di vista agricolo dello stato. La regione collinare, d’altra parte, comprende le colline e le montagne circostanti, offrendo un terreno più roccioso e montuoso.
Il codice seguente crea una mappa interattiva utilizzando la libreria Folium per visualizzare gli eventi ACLED che si sono verificati nel Manipur durante gli anni 2022 e 2023. Traccia gli eventi come marcatori circolari sulla mappa, con il colore di ogni marcatore che rappresenta l’anno corrispondente. Aggiunge inoltre uno strato GeoJSON per visualizzare i confini del Manipur e include un titolo della mappa, i crediti e una legenda che indica i codici di colore per gli anni. Infine, la mappa finale viene visualizzata con tutti questi elementi.
import folium
# Filtra i dati per gli anni 2022 e 2023
df_filtered22_23 = df_filtered[(df_filtered['year'] == 2022) | (df_filtered['year'] == 2023)]
# Crea un'istanza di mappa
map = folium.Map(location=[24.8170, 93.9368], zoom_start=8)
# Carica i confini del Manipur dal file GeoJSON
manipur_geojson = 'Manipur.geojson'
# Crea uno strato GeoJSON per i confini del Manipur e aggiungilo alla mappa
folium.GeoJson(manipur_geojson,
style_function=lambda feature: {
'fillColor': 'white',
'color': 'black',
'weight': 2,
'fillOpacity': 1
}).add_to(map)
# Definisci la palette di colori per gli anni diversi
color_palette = {2022: 'red', 2023: 'blue'}
# Traccia gli eventi sulla mappa con colori diversi in base all'anno
for index, row in df_filtered22_23.iterrows():
folium.CircleMarker([row['latitude'], row['longitude']],
radius=3,
color=color_palette[row['year']],
fill=True,
fill_color=color_palette[row['year']],
fill_opacity=0.5).add_to(map)
# Aggiungi le funzionalità della mappa
folium.TileLayer('cartodbpositron').add_to(map)
# Imposta il centro della mappa e il livello di zoom
map.fit_bounds(map.get_bounds())
map.get_root().html.add_child(folium.Element(legend_html))
# Visualizza la mappa
map
Output:
Puoi vedere che una maggiore concentrazione di eventi si osserva nella regione centrale della valle. Ciò potrebbe essere dovuto a vari fattori come la densità di popolazione, l’infrastruttura, l’accessibilità e le dinamiche socio-politiche storiche. La regione centrale della valle, essendo più densamente popolata e sviluppata dal punto di vista economico, potrebbe potenzialmente assistere a più incidenti ed eventi rispetto alle aree collinari.
Tipi di eventi ACLED
Il tipo di evento ACLED si riferisce alla categorizzazione dei diversi tipi di eventi registrati nel dataset ACLED. Questi tipi di eventi raccolgono varie attività e incidenti legati a conflitti, violenze, proteste e altri eventi di interesse. Alcuni dei tipi di eventi nel dataset ACLED includono violenze contro i civili, esplosioni/violenza a distanza, proteste, disordini e altro ancora. Questi tipi di eventi forniscono informazioni sulla natura e sulla dinamica dei conflitti e degli incidenti correlati registrati nel database ACLED.
Di seguito viene generato un grafico a barre con gli eventi raggruppati per anno, visualizzando i tipi di eventi in Manipur, India, nel corso degli anni.
import pandas as pd
import matplotlib.pyplot as plt
df_filteredevent = df_filtered.copy()
df_filteredevent['event_date'] = pd.to_datetime(df_filteredevent['event_date'])
# Group the data by year
df_cross_event = df_filteredevent.groupby(df_filteredevent['event_date'].dt.year)
['event_type'].value_counts().unstack()
# Define the color palette
color_palette = ['#FF5C5C', '#FFC94C', '#FF9633', '#8E8EE1', '#72C472', '#0818A8']
# Plot the bar chart
fig, ax = plt.subplots(figsize=(10, 6))
df_cross_event.plot.bar(ax=ax, color=color_palette)
# Set the x-axis tick labels to display only the year
ax.set_xticklabels(df_cross_event.index, rotation=0)
# Set the legend
ax.legend(title='Tipi di evento', bbox_to_anchor=(1, 1.02), loc='upper left')
# Set the axis labels and title
ax.set_xlabel('Anno')
ax.set_ylabel('Conteggio evento')
ax.set_title('Tipi di evento ACLED in Manipur, India per anno')
# Adjust the padding and layout
plt.tight_layout(rect=[0, 0, 0.95, 1])
# Display the plot
plt.show()
Output:
![Tipi di evento ACLED per anno](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled_r5FPIhO-thumbnail_webp-600x300.webp)
È importante notare che la visualizzazione dei tipi di evento in un grafico a barre evidenzia la dominanza della categoria “Proteste”, il che potrebbe oscurare le differenze relative e rendere difficile confrontare accuratamente gli altri tipi di eventi. La visualizzazione è stata modificata escludendo o separando la categoria “Proteste”, ottenendo così un confronto più chiaro dei tipi di eventi rimanenti.
Il seguente frammento di codice filtra il tipo di evento “Proteste” dai dati. Successivamente raggruppa gli eventi rimanenti per anno e li visualizza in un grafico a barre, escludendo la categoria dominante “Proteste”. La visualizzazione risultante fornisce una vista più chiara dei tipi di eventi per anno.
import pandas as pd
import matplotlib.pyplot as plt
df_filteredevent = df_filtered.copy()
df_filteredevent['event_date'] = pd.to_datetime(df_filteredevent['event_date'])
# Filter out the "Protests" event type
df_filteredevent = df_filteredevent[df_filteredevent['event_type'] != 'Protests']
# Group the data by year
df_cross_event = df_filteredevent.groupby(df_filteredevent['event_date'].dt.year)
['event_type'].value_counts().unstack()
# Define the color palette
color_palette = ['#FF5C5C', '#FFC94C', '#FF9633', '#8E8EE1', '#72C472', '#0818A8']
# Plot the bar chart
fig, ax = plt.subplots(figsize=(10, 6))
df_cross_event.plot.bar(ax=ax, color=color_palette)
# Set the x-axis tick labels to display only the year
ax.set_xticklabels(df_cross_event.index, rotation=0)
# Set the legend
ax.legend(title='Tipi di evento', bbox_to_anchor=(1, 1.02), loc='upper left')
# Set the axis labels and title
ax.set_xlabel('Anno')
ax.set_ylabel('Conteggio evento')
ax.set_title('Tipi di evento ACLED in Manipur, India (esclusi i protesti) per anno')
# Adjust the padding and layout
plt.tight_layout(rect=[0, 0, 0.95, 1])
# Display the plot
plt.show()
Output:
![Tipi di evento ACLED esclusi i protesti per anno](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled_Q5GDzr4-thumbnail_webp-600x300.webp)
Visualizzazione della dinamica degli eventi: mappatura dei tipi e delle frequenze degli eventi
Utilizziamo le mappe interattive per tracciare gli eventi su una mappa con dimensioni e colori del marcatore variabili in base al tipo e alla frequenza dell’evento. Ciò rappresenta la distribuzione spaziale e l’intensità di diversi eventi, consentendo un’identificazione rapida di modelli, hot spot e tendenze. Questo approccio migliora la dinamica geografica degli eventi, facilita la presa di decisioni basate sui dati e consente l’allocazione efficace di risorse e interventi mirati in risposta ai modelli e alle frequenze identificati.
Gli eventi sono tracciati come marcatori circolari sulla mappa, con colore e dimensioni variabili in base al tipo e alla frequenza dell’evento rispettivamente.
import folium
import json
# Filtrare i dati per l'anno 2023
df_filtered23 = df_filtered[df_filtered['anno'] == 2023]
# Calcolare il conteggio degli eventi per ogni posizione
event_counts = df_filtered23.groupby(['latitudine', 'longitudine']).size().
reset_index(name='conteggio')
# Creare un'istanza di mappa
mappa = folium.Map(location=[24.8170, 93.9368], zoom_start=8)
# Caricare i confini di Manipur dal file GeoJSON
with open('Manipur.geojson') as f:
manipur_geojson = json.load(f)
# Creare un layer GeoJSON per i confini di Manipur e aggiungerlo alla mappa
folium.GeoJson(manipur_geojson,
style_function=lambda feature: {
'fillColor': 'bianco',
'color': 'nero',
'weight': 2,
'fillOpacity': 1
}).add_to(map)
# Definire una palette di colori personalizzata ispirata alle categorie tematiche ACLED
event_type_palette = {
'Violenza contro i civili': '#FF5C5C', # Arancione scuro
'Esplosioni / violenza remota': '#FFC94C', # Giallo brillante
'Sviluppi strategici': '#FF9633', # Arancione chiaro
'Battaglie': '#8E8EE1', # Viola
'Proteste': '#72C472', # Verde
'Sommosse': '#0818A8' # Zaffiro
}
# Tracciare gli eventi sulla mappa con dimensioni e colori del marcatore variabili in base al tipo di evento e alla frequenza
for index, row in event_counts.iterrows():
location = (row['latitudine'], row['longitudine'])
count = row['conteggio']
# Ottenere il tipo di evento per la posizione corrente
event_type = df_filtered23[(df_filtered23['latitudine'] == row['latitudine']) &
(df_filtered23['longitudine'] == row['longitudine'])]
['tipo_di_evento'].values[0]
folium.CircleMarker(
location=location,
radius=2 + count * 0.1,
color=event_type_palette[event_type],
fill=True,
fill_color=event_type_palette[event_type],
fill_opacity=0.7
).add_to(map)
# Aggiungere legende per l'anno 2023
legend_html = """
<div style="position: fixed; bottom: 50px; right: 50px; z-index: 1000; font-size: 14px;
background-color: rgba(255, 255, 255, 0.8); padding: 10px; border-radius:
5px;">
<p><strong>Legenda</strong></p>
<p><span style="color: #FF5C5C;">Violenza contro i civili</span></p>
<p><span style="color: #FFC94C;">Esplosioni / violenza remota</span></p>
<p><span style="color: #FF9633;">Sviluppi strategici</span></p>
<p><span style="color: #8E8EE1;">Battaglie</span></p>
<p><span style="color: #72C472;">Proteste</span></p>
<p><span style="color: #0818A8;">Sommosse</span></p>
</div>
"""
map.get_root().html.add_child(folium.Element(legend_html))
# Mostrare la mappa
mappa
Output:
Attori principali del conflitto
In questa fase, otteniamo una panoramica delle diverse entità o gruppi coinvolti nel conflitto o negli eventi in Manipur. Nel dataset ACLED, “actor1” si riferisce all’attore principale coinvolto in un evento registrato. Rappresenta l’entità o il gruppo principale che è responsabile dell’avvio o della partecipazione a un conflitto o evento specifico. La colonna “actor1” fornisce informazioni sull’identità dell’attore principale, come un governo, un gruppo ribelle, una milizia etnica o altre entità coinvolte nel conflitto o evento. Ogni valore univoco nella colonna “actor1” rappresenta un attore o un gruppo distinto coinvolto negli eventi registrati.
Successivamente, viene visualizzato il conteggio dei valori di ‘actor1’ utilizzando lo snippet di codice qui sotto:
Questo codice filtra un DataFrame in base al conteggio dei valori della colonna ‘actor1’, selezionando solo quelli con conteggio maggiore o uguale a 5. Visualizza quindi i dati risultanti.
import matplotlib.pyplot as plt
# Filtra il DataFrame basato sui conteggi dei valori >= 5
filtered_df = df_filtered[(df_filtered['year'] != 2023)]['actor1'].
value_counts().loc[lambda x: x >= 5]
# Crea una figura e degli assi per il grafico a barre orizzontale
fig, ax = plt.subplots(figsize=(8, 6))
# Definisci la palette di colori
color_palette = ['#FF5C5C', '#FFC94C', '#FF9633', '#8E8EE1', '#72C472', '#0818A8']
# Disegna il grafico a barre orizzontale
filtered_df.plot.barh(ax=ax, color=color_palette)
# Aggiungi etichette e titolo
ax.set_xlabel('Conteggio')
ax.set_ylabel('Attore1')
ax.set_title('Conteggio dei valori di Attore1 (>= 5) (gennaio 2016 al 9 dicembre 2022)',
pad=55)
# Imposta le informazioni sulla disponibilità dei dati
data_info = "Accesso il 17 giugno 2023"
# Aggiungi i crediti e le informazioni sulla disponibilità dei dati
plt.text(0.5, 1.1, "Dati accessibili da:", ha='center', transform=ax.transAxes,
fontsize=10)
plt.text(0.5, 1.05, "Progetto dati sulla posizione dei conflitti armati e sugli eventi (ACLED);
www.acleddata.com",
ha='center', transform=ax.transAxes, fontsize=10)
plt.text(0.5, 1.0, data_info, ha='center', transform=ax.transAxes, fontsize=10)
# Mostra il conteggio accanto a ogni barra
for i, v in enumerate(filtered_df.values):
ax.text(v + 3, i, str(v), color='black')
# Mostra i grafici
plt.tight_layout()
plt.show()
Output:
![Conteggio dei valori di Attore1](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled_kiXN6EL-thumbnail_webp-600x300.webp)
Il grafico rappresenta i dati dal gennaio 2016 al 9 dicembre 2022. Inoltre, la condizione “conteggio maggiore o uguale a 5” significa che solo gli attori con una frequenza di occorrenza di 5 o più verranno inclusi nell’analisi e visualizzati nel grafico.
Come mostrato nello snippet di codice sottostante, sono state utilizzate le seguenti visualizzazioni per confrontare il conteggio delle categorie tra il 2022 e il 2023.
import matplotlib.pyplot as plt
import numpy as np
# Filtra il DataFrame per l'anno 2022
filtered_df_2022 = df_filtered[df_filtered['year'] == 2022]['actor1'].
value_counts().loc[lambda x: x >= 10]
# Filtra il DataFrame per l'anno 2023
filtered_df_2023 = df_filtered[df_filtered['year'] == 2023]['actor1'].
value_counts().loc[lambda x: x >= 10]
# Ottieni le categorie univoche che compaiono più di 10 volte in uno dei DataFrame
categories = set(filtered_df_2022.index).union(set(filtered_df_2023.index))
# Crea un dizionario per memorizzare i conteggi delle categorie
category_counts = {'2022': [], '2023': []}
# Itera sulle categorie
for category in categories:
# Aggiungi il conteggio per il 2022 se disponibile, altrimenti aggiungi 0
category_counts['2022'].append(filtered_df_2022.get(category, 0))
# Aggiungi il conteggio per il 2023 se disponibile, altrimenti aggiungi 0
category_counts['2023'].append(filtered_df_2023.get(category, 0))
# Escludi le categorie con conteggio 0
non_zero_categories = [category for category, count_2022, count_2023 in zip
(categories, category_counts['2022'], category_counts['2023']) if count_2022 >
0 or count_2023 > 0]
# Crea una figura e degli assi per il grafico a barre
fig, ax = plt.subplots(figsize=(10, 6))
# Imposta le posizioni sull'asse x
x = np.arange(len(non_zero_categories))
# Imposta la larghezza delle barre
width = 0.35
# Disegna il grafico a barre per il 2022
bars_2022 = ax.bar(x - width/2, category_counts['2022'], width, color=color_palette[0],
label='2022')
# Disegna il grafico a barre per il 2023
bars_2023 = ax.bar(x + width/2, category_counts['2023'], width, color=color_palette[1],
label='2023')
# Imposta le etichette sull'asse x e ruota per una migliore visibilità
ax.set_xticks(x)
ax.set_xticklabels(non_zero_categories, rotation=90)
# Imposta l'etichetta sull'asse y
ax.set_ylabel('Conteggio')
# Imposta il titolo e la legenda
ax.set_title('Confronto delle categorie di Attore1 (>= 10) - 2022 vs 2023')
ax.legend()
# Aggiungi i valori di conteggio sopra ogni barra
for rect in bars_2022 + bars_2023:
height = rect.get_height()
ax.annotate(f'{height}', xy=(rect.get_x() + rect.get_width() / 2, height),
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom')
# Regola lo spaziamento tra le linee
plt.subplots_adjust(top=0.9)
# Mostra il grafico
plt.show()
Output:
Il confronto dei dati ACLED di Manipur per l’anno 2022 e i dati fino al 9 giugno 2023 può essere ottenuto utilizzando il seguente frammento di codice:
import matplotlib.pyplot as plt
import numpy as np
# Filtra il DataFrame per l'anno 2022
filtered_df_2022 = df_filtered[df_filtered['year'] == 2022]['actor1'].
value_counts().loc[lambda x: x >= 10]
# Filtra il DataFrame per l'anno 2023
filtered_df_2023 = df_filtered[df_filtered['year'] == 2023]['actor1'].
value_counts().loc[lambda x: x >= 10]
# Ottieni le categorie univoche che appaiono più di 10 volte in uno dei due DataFrame
categories = set(filtered_df_2022.index).union(set(filtered_df_2023.index))
# Crea un dizionario per memorizzare i conteggi delle categorie
category_counts = {'2022': [], '2023': []}
# Itera sulle categorie
for category in categories:
# Aggiungi il conteggio per il 2022 se disponibile, altrimenti aggiungi 0
category_counts['2022'].append(filtered_df_2022.get(category, 0))
# Aggiungi il conteggio per il 2023 se disponibile, altrimenti aggiungi 0
category_counts['2023'].append(filtered_df_2023.get(category, 0))
# Escludi le categorie con conteggio 0
non_zero_categories = [category for category, count_2022, count_2023 in
zip(categories, category_counts['2022'], category_counts['2023'])
if count_2022 > 0 or count_2023 > 0]
# Crea una figura e degli assi per il grafico a barre
fig, ax = plt.subplots(figsize=(10, 6))
# Imposta le posizioni sull'asse x
x = np.arange(len(non_zero_categories))
# Imposta la larghezza delle barre
width = 0.35
# Disegna il grafico a barre per il 2022
bars_2022 = ax.bar(x - width/2, category_counts['2022'], width,
color=color_palette[0], label='2022')
# Disegna il grafico a barre per il 2023
bars_2023 = ax.bar(x + width/2, category_counts['2023'], width,
color=color_palette[1], label='2023')
# Imposta le etichette sull'asse x e ruotale per una migliore visibilità
ax.set_xticks(x)
ax.set_xticklabels(non_zero_categories, rotation=90)
# Imposta l'etichetta sull'asse y
ax.set_ylabel('Conteggio')
# Imposta il titolo e la legenda
ax.set_title('Confronto delle categorie di Actor1 (>= 10) - 2022 vs 2023')
ax.legend()
# Aggiungi i valori di conteggio sopra ogni barra
for rect in bars_2022 + bars_2023:
height = rect.get_height()
ax.annotate(f'{height}', xy=(rect.get_x() + rect.get_width() / 2, height),
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom')
# Mostra il grafico
plt.show()
Output:
Analisi dell’intensità del conflitto
Il frammento di codice successivo prepara i dati per ulteriori analisi o visualizzazioni convertendo la colonna ‘event_date’ in datetime. Esegue una tabulazione incrociata e ristruttura il DataFrame per facilitare l’interpretazione e l’uso. Utilizza la funzione pd.crosstab() per creare una tabulazione incrociata (tabella di frequenza) tra la colonna ‘event_date’ (convertita in periodi mensili utilizzando dt.to_period(‘m’)) e la colonna ‘inter1’ in ‘df_filtered’. Successivamente, raggruppa il DataFrame filtrato per ‘event_date’ e calcola la somma delle ‘fatalities’ per ogni data. Calcola e aggiungi la somma delle vittime per mese all’esistente DataFrame tabulato incrociato, ottenendo ‘df_conflicts’. Include sia i dati degli eventi categorizzati che le informazioni sulle vittime corrispondenti per ulteriori analisi.
Implementazione del codice
import pandas as pd
# Converti la colonna 'event_date' in datetime
df_filtered['event_date'] = pd.to_datetime(df_filtered['event_date'])
# Esegui l'operazione di tabulazione incrociata
df_cross = pd.crosstab(df_filtered['event_date'].dt.to_period('m'),
df_filtered['inter1'])
# Rinomina le colonne
df_cross.columns = ['Forze statali', 'Gruppi ribelli', 'Militie politiche',
'Militie identitarie', 'Tumultuanti', 'Manifestanti', 'Civili', 'Forze esterne/altro']
# Converti l'indice periodico in data
df_cross['event_date'] = df_cross.index.to_timestamp()
# Reimposta l'indice
df_cross.reset_index(drop=True, inplace=True)
df2 = df_filtered.copy()
df2['event_date'] = pd.to_datetime(df2['event_date'])
fatality_filtered = (df2
.filter(['event_date','fatalities'])
.groupby(['event_date'])
.fatalities
.sum()
)
df_fatality_filtered = fatality_filtered.to_frame().reset_index()
df_fatality_month= df_fatality_filtered.resample('M', on="event_date").sum()
df_fatality_month = df_fatality_month.reset_index()
df_fatalities = df_fatality_month.drop(columns=['event_date'])
df_concat = pd.concat([df_cross, df_fatalities], axis=1)
df_conflicts = df_concat.copy()
Output:
Il codice visualizza l’analisi dell’intensità dei conflitti per eventi mensili in Manipur categorizzati per tipo di attore, ponderati dal numero di morti segnalati. La larghezza delle linee si basa sul numero di morti per ogni tipo di attore. Questo tipo di analisi ci consente di identificare modelli e l’impatto relativo di diversi tipi di attori coinvolti nei conflitti. Fornisce preziose informazioni per ulteriori analisi e decisioni negli studi sui conflitti.
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
name='Forze di Stato',
x=df_conflicts['event_date'].dt.strftime('%Y-%m'),
y=df_conflicts['Forze di Stato'],
mode='markers+lines',
marker=dict(color='darkviolet', size=4),
showlegend=True
))
fig.add_trace(go.Scatter(
name='Peso della mortalità',
x=df_conflicts['event_date'],
y=df_conflicts['Forze di Stato']+df_conflicts['fatalities']/5,
mode='lines',
marker=dict(color="#444"),
line=dict(width=1),
hoverinfo='skip',
showlegend=False
))
fig.add_trace(go.Scatter(
name='Peso della mortalità',
x=df_conflicts['event_date'],
y=df_conflicts['Forze di Stato']-df_conflicts['fatalities']/5,
marker=dict(color="#444"),
line=dict(width=1),
mode='lines',
fillcolor='rgba(68, 68, 68, 0.3)',
fill='tonexty',
hoverinfo='text',
hovertemplate='<br>%{x|%b\n%Y}<br><i>Mortalità: %{text}</i>',
text=['{}'.format(i) for i in df_conflicts['fatalities']],
showlegend=False
))
#similiray insert add_trace for other event types too here...
fig.update_xaxes(
dtick="M3", # Imposta la frequenza di tick a 3 mesi (trimestrale)
tickformat="%b\n%Y"
)
fig.update_layout(
yaxis_title='Numero di eventi',
title={
'text': 'Analisi dell\'intensità dei conflitti: eventi in Manipur categorizzati per tipo di attore, ponderati dal numero di morti segnalati',
'y': 0.95,
'x': 0.5,
'xanchor': 'center',
'yanchor': 'top',
'font': {'size': 20}
},
annotations=[
dict(
text="Gennaio 2016 fino al 9 giugno 2023|Dati accessibili da: Progetto sulla Posizione e sugli Eventi dei Conflitti Armati (ACLED),www.acleddata.com",
xref="paper",
yref="paper",
x=0.5,
y=1.06,
showarrow=False,
font={'size': 12}
)
],
hovermode="x",
xaxis=dict(
showgrid=False
),
yaxis=dict(
showgrid=False
)
)
fig.data[0].marker.size = 4
fig.data[3].marker.size = 4
fig.data[6].marker.size = 4
fig.data[9].marker.size = 4
fig.data[12].marker.size = 4
fig.data[15].marker.size = 4
fig.data[18].marker.size = 4
fig.data[21].marker.size = 4
fig.show()
Output:
Il valore di una variabile superiore (in questo caso “Protesters”) rispetto ad altre in un grafico multilinea. Può distorcere la percezione, rendendo difficile confrontare e interpretare con precisione le tendenze delle diverse variabili. La predominanza di una variabile può ridursi, diventando difficile valutare i cambiamenti relativi e le relazioni tra le altre variabili. La visualizzazione può soffrire, con immagini compressi o affollate, perdita di dettagli nelle variabili di valore inferiore e un’enfasi sbilanciata che può influenzare le interpretazioni.
Per mitigare questi aspetti negativi e avere una chiara visualizzazione dell’intensità del conflitto recente, ho filtrato i dati per gli eventi di conflitto del 2023 e del 2022 e di seguito è riportato l’output:
Imposta la data come indice per l’analisi della tendenza del conflitto utilizzando i dati giornalieri e ottieni il dataframe di seguito per ulteriori analisi.
Medie Mobili e Analisi della Tendenza dei Conflitti
Nell’analisi della tendenza dei conflitti, le finestre di 30 e 7 giorni sono comuni. Sono utilizzati per calcolare le medie mobili o le medie dei dati relativi ai conflitti in un periodo di tempo specifico.
La finestra mobile si riferisce a un intervallo di tempo di dimensioni fisse che si muove lungo la linea temporale, includendo un numero specificato di punti dati all’interno di quell’intervallo. Ad esempio, in una finestra mobile di 30 giorni, l’intervallo include il giorno corrente più i precedenti 29 giorni. In una finestra mobile di 7 giorni, l’intervallo include il giorno corrente più i precedenti 6 giorni, rappresentando una settimana di dati.
La media mobile viene calcolata prendendo la media dei punti dati all’interno della finestra. Fornisce una rappresentazione levigata dei dati, riducendo le fluttuazioni a breve termine e mettendo in evidenza le tendenze a lungo termine.
Calcolando le medie mobili di 30 e 7 giorni nell’analisi dei conflitti, gli analisti possono ottenere informazioni sui pattern e sulle tendenze complessive degli eventi di conflitto nel tempo. Può identificare tendenze a lungo termine e catturare anche fluttuazioni a breve termine nei dati. Queste medie mobili possono aiutare a rivelare modelli sottostanti e fornire una visione più chiara dell’evoluzione della dinamica del conflitto.
Snippet di Codice
Il seguente snippet di codice crea i grafici per ciascuno scenario di conflitto.
import matplotlib.pyplot as plt
import pandas as pd
# Variabili per il calcolo delle medie mobili
variabili = ['Forze Statali', 'Gruppi Ribelli', 'Militie Politiche',
'Militie dell'Identità', 'Sommossa', 'Manifestanti',
'Civili', 'Forze Esterne/Altre']
# Calcolo delle medie mobili per ogni variabile
data_7d_rol = {}
data_30d_rol = {}
for variable in variabili:
data_7d_rol[variabile] = data_ts[variabile].rolling(window=7, min_periods=1).mean()
data_30d_rol[variabile] = data_ts[variabile].rolling(window=30, min_periods=1).mean()
# Creazione di grafici separati per ogni variabile
for variable in variabili:
fig, ax = plt.subplots(figsize=(11, 4))
# Grafico della media mobile di 7 giorni
ax.plot(data_ts.index, data_7d_rol[variabile], linewidth=2, label='Media Mobile 7-giorni')
# Grafico della media mobile di 30 giorni
ax.plot(data_ts.index, data_30d_rol[variabile], color='0.2', linewidth=3,
label='Media Mobile 30-giorni')
# Bellezza del grafico
ax.legend()
ax.set_xlabel('Anno')
ax.set_ylabel('Eventi registrati da ' + variabile)
ax.set_title('Tendenze nei Conflitti ' + variabile)
# Aggiungere il titolo principale e il sottotitolo
fig.suptitle(main_title, fontsize=14, fontweight='bold', y=1.05)
#ax.text(0.5, -0.25, sub_title, transform=ax.transAxes, fontsize=10, color='red', ha='center')
ax.text(0.5, 0.95, sub_title, transform=ax.transAxes, fontsize=10, color='red', ha='center')
plt.tight_layout()
plt.show()
Output:
![Forze Statali](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled_FiuRiSI-thumbnail_webp-600x300.webp)
![Gruppi Ribelli](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled-1_CB8d4A6-thumbnail_webp-600x300.webp)
![Milizie Politiche](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled_kqZkFEx-thumbnail_webp-600x300.webp)
![Milizie Identitarie](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled-1_gxY9MFy-thumbnail_webp-600x300.webp)
![Sommossa](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled_LN8gAkJ-thumbnail_webp-600x300.webp)
![Manifestanti](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled-1_oIxZQRz-thumbnail_webp-600x300.webp)
![Civili](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled_9eJeu2I-thumbnail_webp-600x300.webp)
![Forze Esterne/Altre Forze](https://av-eks-lekhak.s3.amazonaws.com/media/__sized__/article_images/Untitled-1_XdyWMVT-thumbnail_webp-600x300.webp)
Nota : I grafici e le analisi dei dati condotte in questo blog sono solamente a scopo dimostrativo dell’applicazione di tecniche di data science. Queste analisi non traggono conclusioni o interpretazioni definitive riguardo alle dinamiche complesse dei conflitti. Si raccomanda di avvicinarsi all’analisi dei conflitti con cautela, riconoscendo la natura multifacetata dei conflitti e la necessità di una comprensione esaustiva e specifica del contesto al di là del campo di applicazione di questa analisi.
Conclusioni
Il blog esplora gli eventi e i modelli di conflitto in Manipur, India utilizzando l’analisi dei dati ACLED. Per visualizzare gli eventi ACLED in Manipur, utilizzare mappe interattive e altre visualizzazioni. L’analisi dei tipi di evento in Manipur ha rivelato varie attività e incidenti correlati a conflitti, violenza, proteste e altri eventi di interesse. Per comprendere le tendenze negli eventi di conflitto, abbiamo calcolato le medie mobili a 30 e 7 giorni. Queste medie mobili forniscono una rappresentazione liscia dei dati, riducendo le fluttuazioni a breve termine e mettendo in evidenza le tendenze a lungo termine. Nel complesso, queste scoperte possono contribuire a una migliore comprensione delle dinamiche del conflitto nella regione e possono supportare ulteriori processi di ricerca e di decision-making.
Punti chiave
- Analisi dei dati ACLED interattiva: immergiti nei dati di conflitto del mondo reale e ottieni informazioni.
- Le mappe interattive visualizzano le dinamiche spaziali e temporali dei conflitti.
- Rileva l’importanza della visualizzazione e dell’analisi dei dati per una comprensione efficace.
- L’individuazione degli attori principali rivela le entità chiave che plasmano il panorama del conflitto.
- I calcoli della media mobile scoprono le fluttuazioni a breve termine e le tendenze a lungo termine nei conflitti.
Speriamo che tu abbia trovato questo articolo informativo. Non esitare a contattarmi su LinkedIn. Connettiamoci e lavoriamo insieme per sfruttare i dati a favore del cambiamento positivo.
Domande frequenti
Riferimenti
1. Raleigh, Clionadh, Andrew Linke, Håvard Hegre e Joakim Karlsen. (2010). “IntroducingACLED-Armed Conflict Location and Event Data.” Journal of Peace Research 47(5) 651-660.
2. ACLED. (2023). “Armed Conflict Location & Event Data Project (ACLED)Codebook, 2023.
I media mostrati in questo articolo non sono di proprietà di Analytics Vidhya e vengono utilizzati a discrezione dell’autore.