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].

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

È 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

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

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
Gruppi Ribelli
Milizie Politiche
Milizie Identitarie
Sommossa
Manifestanti
Civili
Forze Esterne/Altre Forze

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

  1. Analisi dei dati ACLED interattiva: immergiti nei dati di conflitto del mondo reale e ottieni informazioni.
  2. Le mappe interattive visualizzano le dinamiche spaziali e temporali dei conflitti.
  3. Rileva l’importanza della visualizzazione e dell’analisi dei dati per una comprensione efficace.
  4. L’individuazione degli attori principali rivela le entità chiave che plasmano il panorama del conflitto.
  5. 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.