User Tools

Site Tools


moudot_sjolliet:maxime_oudot_simon_jolliet

Projet de fin de semestre - Analyse d'un Dataset avec Tulip


Le problème, les questions posées

Dans un monde où l'insécurité est grandissante, il est nécessaire de pouvoir contrer le terrorisme. Cela peut être fait par l'évolution de l'armement, ou encore des stratégies de batailles ad hoc.
Mais un réel avantage reste de connaître son ennemi.

Dans cette optique, l'on doit disposer de données sur les groupes terroristes et leurs attentats. Il nous sera alors possible de comprendre leurs fonctionnement et de prévoir leurs prochaines actions.
Ces données doivent être exploités en les mettant en corrélation de manière significative. Une manière de les exploiter est de les représenter graphiquement.

Nous voulons donc répondre à trois questions importantes que nous nous sommes posé :

  1. Combien d'incidents y a t-il eu et combien de victimes furent faites, suivant les années et les pays?
  2. Quelles sont les zones d'opération des groupes terroristes et leur mode opératoire?
  3. Quelles sont les zones les plus dangereuses en fonction du présentiel terroriste?

Le jeu de données choisi contient pour chaque année enregistrée de très nombreuses données sur les attentats perpétrés. Les données accessibles sont entre autre la localisation géographique précise, l'année, l'arme utilisée, le groupe terroriste en action…
Ces données sont suffisamment nombreuses et précises pour les entrecouper et répondre à nos questions.

Le jeu de données

Le jeu de données choisi, appelé GTD (Global Terrorism Database, base de données globale du terrorisme) et téléchargeable à l'adresse http://www.start.umd.edu/gtd/, est une base de données maintenue depuis 1970 et répertoriant presque tous les attentats commis depuis lors. Il a été créé en 2001 après que des chercheurs de l'université du Maryland aient obtenu une grande base de données des attentats de 1970 à 1997, collectés par des agents des services secrets.
Il contient presque toutes les données existantes sur les attentats. Le recoupement de ces informations permet d'analyser l'évolution du terrorisme au fil du temps, et de prévoir son évolution future.

Le GTD se présente sous la forme d'un fichier XLS (tableur) d'une taille d'environ 40Mo, contenant un attentat par ligne, et les données correspondantes sur de très nombreuses colonnes.
En tout, les attentats répertoriés vont de l'année 1970 jusqu'à l'année 2011. Une très grande variété d'informations sont disponibles : l'année, le lieu (latitude, longitude) le pays, l'arme, le nombre de morts, le groupe terroriste…

Afin de pouvoir exploiter les données importées dans l'outil graphique, il a été nécessaire de renommer certains champs afin de s'affranchir d'écrasements provoqués par des champs mal nommés par rapport à leur syntaxe ou à leur duplicité.
Il a fallu de plus modifier la façon dont les données sont perçues par le logiciel, en changeant leur type. Par exemple, en qualifiant les champs « latitude » et « longitude » contenus dans le DataSet en type Metric, Tulip les affiche automatiquement sur la GeoView de GoogleMap.

Les réponses trouvées

L'exploitation que nous avons fait du jeu de données nous a permit de répondre à nos questions :

  1. Au fil des années, les attentats, suivant les pays, furent souvent de plus en plus nombreux et de plus en plus meurtriers (notamment avec un accès à des armes de plus en plus mortelles) alors que l'inverse est peu vrai.

    Graphe du nombre de morts en fonction du nombre d'attentats suivant les années.

  2. Les zones d'opérations des groupes terroristes sont alors facilement repérables, même si leurs limites sont granulaires.

    Geoview (google map) des attentats effectués ces dernières années en Europe, en Asie et en Amérique du nord (en points rouges).

    Il est d'ailleurs aussi possible de repérer la zone d'action d'un groupe terroriste particulier, grace à la colorisation de celui-çi parmis les autres (la coloration devient difficile avec un grand nombre de groupes présents en même temps).

    Geoview de la coloration des attentats en fonction des groupes terroristes les ayant perpétrés.

  3. Les zones les plus dangereuses ne sont pas nécessairement (bien que souvent) celles où les attentats sont les plus nombreux : en effet, il faut considérer les armes utilisés ainsi que les répercussions des attentats sur la zone environnante (civil, environnemental, économique…). Un nombre de paramètres différents entre en jeu, et leur mise en corrélation n'est pas forcément probante.

Bien que la mise en corrélation des données permette d'obtenir de nouvelles informations sur les groupes terroristes, elle ne permet pas de pouvoir considérer toute l'ampleur de certains aspects, dont l'évaluation ne peut pas être faîte uniquement par des chiffres, ni leur mise en corrélation uniquement logique.

La préparation du jeu de données

Les données du GTD sont délivrées dans un format de tableur excel (XLS) qui n'est pas un format reconnu par le logiciel Tulip.
Après la vérification de l'utilité des données contenues dans le fichier, il nous a fallu transformer le format des données en un format compréhensible par Tulip. Pour celà, nous avons converti le XLS en CSV (Comma-Separated Values, valeurs séparées par des virgules) pour pouvoir importer les données grace au module CSV de Tulip et pouvoir les exploiter au sein du logiciel.

L'utilisation des données et la visualisation

C'est la coloration en fonction des groupes terroristes qui nous a posé le plus de problèmes. En effet, elle comporte de multiples limitations. Temporelle d'abord. Les groupes terroristes ne sont généralement pas actifs pendant 40 ans, nous n'avons pas eu le temps d'implémenter une barre permettant de scroller en fonction des années. Au niveau géographique, les groupes terroristes n’opèrent pas forcément dans une seule et même région, comme par exemple Al-Qaïda. L'exemple de l'ETA prouve cependant que cela est possible. Dernièrement, le dataset comporte plus de 3000 groupes terroristes différents. La coloration dans ce cas est extrêmement complexe. La meilleure solution serait surement de croiser les données en attribuant un poids à chaque groupe terroriste en fonction des dégâts, humains ou matériels, la durée d’existence du groupe, le nombre d'attentat, etc.

Conclusion

L'exploitation des données par leur mise en corrélation graphique a permit de répondre aux questions que nous nous sommes posées avant de choisir ce jeu de données, ainsi qu'à de nombreuses autres questions.

Cependant, certaines réponses restent incomplètent, voire incertaines. En effet, le jugement humain ainsi que les règles qu'il édicte ne sont pas entièrement représentables lors d'une visualisation de données. De plus, des résultats différents peuvent être produits en ayant une approche différente de l'utilisation des données et de leur représentation graphique, voire en utilisant d'autres données.

Des améliorations de la visualisation sont possibles avec plus de temps et des algorithmes plus perfectionnés, intégrants d'autres règles et d'autres paramètres qui peuvent être extérieurs au jeu de données.

Liens

presentation_visualisation_jolliet_oudot.pdf

jolliet_oudot.py
# Powered by Python 2.7

# To cancel the modifications performed by the script
# on the current graph, click on the undo button.

# Some useful keyboards shortcuts : 
#   * Ctrl + D : comment selected lines.
#   * Ctrl + Shift + D  : uncomment selected lines.
#   * Ctrl + I : indent selected lines.
#   * Ctrl + Shift + I  : unindent selected lines.
#   * Ctrl + Return  : run script.
#   * Ctrl + F  : find selected text.
#   * Ctrl + R  : replace selected text.
#   * Ctrl + Space  : show auto-completion dialog.

from tulip import *
import time


# the updateVisualization(centerViews = True) function can be called
# during script execution to update the opened views

# the pauseScript() function can be called to pause the script execution.
# To resume the script execution, you will have to click on the "Run script " button.

# the runGraphScript(scriptFile, graph) function can be called to launch another edited script on a tlp.Graph object.
# The scriptFile parameter defines the script name to call (in the form [a-zA-Z0-9_]+.py)

# the main(graph) function must be defined 
# to run the script on the current graph

def main(graph): 
	viewBorderColor =  graph.getColorProperty("viewBorderColor")
	viewBorderWidth =  graph.getDoubleProperty("viewBorderWidth")
	viewColor =  graph.getColorProperty("viewColor")
	viewFont =  graph.getStringProperty("viewFont")
	viewFontSize =  graph.getIntegerProperty("viewFontSize")
	viewLabel =  graph.getStringProperty("viewLabel")
	viewLabelColor =  graph.getColorProperty("viewLabelColor")
	viewLabelPosition =  graph.getIntegerProperty("viewLabelPosition")
	viewLayout =  graph.getLayoutProperty("viewLayout")
	viewMetaGraph =  graph.getGraphProperty("viewMetaGraph")
	viewRotation =  graph.getDoubleProperty("viewRotation")
	viewSelection =  graph.getBooleanProperty("viewSelection")
	viewShape =  graph.getIntegerProperty("viewShape")
	viewSize =  graph.getSizeProperty("viewSize")
	viewSrcAnchorShape =  graph.getIntegerProperty("viewSrcAnchorShape")
	viewSrcAnchorSize =  graph.getSizeProperty("viewSrcAnchorSize")
	viewTexture =  graph.getStringProperty("viewTexture")
	viewTgtAnchorShape =  graph.getIntegerProperty("viewTgtAnchorShape")
	viewTgtAnchorSize =  graph.getSizeProperty("viewTgtAnchorSize")
	latitude = graph.getDoubleProperty("latitude")
	longitude = graph.getDoubleProperty("longitude")
	year = graph.getIntegerProperty("iyear")
	deads = graph.getIntegerProperty("nkill")
	terrorist_group_name = graph.getStringProperty("gname")
		
	#coulours utilisees pour la coloration du graphe
	color_navy_blue = tlp.Color(0,0,128)
	color_dark_green = tlp.Color(0,100,0)	
	color_lawn_green = tlp.Color(124,252,0)
	color_yellow = tlp.Color(255,255,0)
	color_pink = tlp.Color(255,192,203)
	color_dark_orchid = tlp.Color(153,50,204)
	color_cyan = tlp.Color(0,255,255)
	color_black = tlp.Color(0,0,0)
	color_blue = tlp.Color(0,0,255)
	color_dark_kaki = tlp.Color(189,183,107)
	color_medium_purple = tlp.Color(147,112,219)
	color_goldenrod = tlp.Color(218,165,32)
	color_list = [color_goldenrod, color_medium_purple, color_dark_kaki, color_blue, color_navy_blue, color_dark_green, color_lawn_green,color_yellow, color_pink, color_dark_orchid, color_cyan, color_black]
			
	#nombre d'evenements tries par annee
	events_sorted_by_year = {}
	for n in graph.getNodes():
		if year.getNodeValue(n) in events_sorted_by_year:
			old = events_sorted_by_year[year.getNodeValue(n)]
			events_sorted_by_year[year.getNodeValue(n)] = old+1
		else:
			events_sorted_by_year[year.getNodeValue(n)] = 1
		
	events_sorted_by_year_copy2 = sorted(events_sorted_by_year.items())		

	
	#nombre de victimes par annee
	victims_sorted_by_year = {}
			
	for n in graph.getNodes():
		if year.getNodeValue(n) in victims_sorted_by_year:
			old = victims_sorted_by_year[year.getNodeValue(n)]
			victims_sorted_by_year[year.getNodeValue(n)] = old + deads.getNodeValue(n)
		else:
			victims_sorted_by_year[year.getNodeValue(n)] = deads.getNodeValue(n)


	class AutoVivification(dict):
   		def __getitem__(self, item):
      			try:
         			return dict.__getitem__(self, item)
      			except KeyError:
           			value = self[item] = type(self)()
            		return value
            
	terrorist_groups = AutoVivification()
	
	#dictionnaire a deux niveau, avec en cle le nom du groupe terroriste
	#et en valeur la liste des noeuds associes
	for n in graph.getNodes():
		if terrorist_group_name.getNodeValue(n)!= "Unknown":
			if terrorist_group_name.getNodeValue(n)!= "":
				terrorist_groups[terrorist_group_name.getNodeValue(n)][n]
			
	#methode random sale piquee sur un forum pour colorier les noms
	#en fonction du groupe terroriste
	for n in terrorist_groups:
		a = 10
		while a > 9:
				t = time.time()
				a = int(str(t-int(t))[2:])%100 #Keeping only the numbers after the decimal point, otherwise you would get the same "random" number each second
		e = tlp.Color(color_list[a])
		for a in terrorist_groups[n]:
			viewColor[a] = e

#coloration d'un seul groupe terroriste - NON UTILISE
"""
	for n in graph.getNodes():
		viewColor[n] = tlp.Color(255,255,255)
	for n in terrorist_groups:
		if n == "Irish Republican Army (IRA)":
			for a in terrorist_groups[n]:
				viewColor[a] = tlp.Color(255,0,0)				
"""
/net/html/perso/melancon/Visual_Analytics_Course/data/pages/moudot_sjolliet/maxime_oudot_simon_jolliet.txt · Last modified: 2013/01/10 02:50 by sjolliet