User Tools

Site Tools


nilles:solution_homework2

Pixel-oriented visualization of the BrightKite data based on Moore's curve

Thierry Nilles & Eric Dehau


  • Note: 5/5
  • Code clair
  • Excellente discussion

Guy Melançon 2012/04/17 16:14


L'ensemble des fichiers tulip/python est disponible à cette adresse : http://dl.free.fr/oM4njBIXB (n'ayant pas trouvé comment uploader un fichier sur le wiki…)

Méthodologie

Un échantillon de 934 personnes (et des liaisons d'amitié correspondant) a été extraite grâce au programme d'extraction fourni. Une propriété nombre d'amis a été générée grâce au degré de chaque noeud. Différents sous-graphes ont été générés en mappant les noeuds sur un une courbe de Moore (par rapport à une propriété) et en coloriant les noeuds selon une autre propriété (avec un dégradé uniforme). Cela a été fait de manière à ce que chaque propriété puisse être comparée à chaque autre (niveau de corrélation).

Le script

Le script génère plusieurs sous-graphes afin d'étudier les corrélations entre chaque properties.

moore.py
# Powered by Java 2.7
 
 
from tulip import *
 
class Moore:
 
	def __init__(self,graph,property,niv=1,viewPattern=0):
		self.cleanInit()
		self.setNbAmis()
		self.viewPattern=viewPattern
		self.property=graph.getProperty(property)
		self.currentgraph=graph
		self.axiom="LFL+F+LFL"
		self.L="-RF+LFL+FR-"
		self.R="+LF-RFR-FL+"
		self.niv=niv
		self.dirList=list()
		self.nodesByValue=dict()
		self.properties=["nbAmis","maxDistance","lastCheckin","firstCheckin","numCheckins"]
		#Generation par L-system
		for i in range(niv):
				self.axiom=self.axiom.replace('L','*').replace('R',self.R).replace('*',self.L)
 
		count=1
		#Generation des différents graphes(sous graphe pour que chaque property soit comparé avec chaque property)
		for i in self.properties:
			temp=tlp.newCloneSubGraph(graph,i)
			#Juste pour avoir un exemple de corrélation parfaite(même property)
			if(count==1):
				self.currentgraph=tlp.newCloneSubGraph(temp,"color : "+self.properties[0])
				self.currentgraph.delLocalProperty("viewLayout")
				self.property=graph.getLocalDoubleProperty(i)
				self.viewLayout =  self.currentgraph.getLocalLayoutProperty("viewLayout")
				self.sortByProperty(self.property)			
				self.render()		
			#Pour chaque property comparer avec ceux indice inférieur
			for j in range(count-1):			
				self.currentgraph=tlp.newCloneSubGraph(temp,"color : "+self.properties[j])
				self.currentgraph.delLocalProperty("viewLayout")
				self.property=graph.getLocalDoubleProperty(i)
				self.viewLayout =  self.currentgraph.getLocalLayoutProperty("viewLayout")
				#Trier selon unee propriété et effectuer le rendu
				self.sortByProperty(self.property)			
				self.render()
 
			count+=1
 
	#Nombre d'amis à partir du degré
	def setNbAmis(self):
		nbAmisProp=graph.getDoubleProperty("nbAmis")
		for i in graph.getNodes():
			nbAmisProp.setNodeValue(i,float(graph.indeg(i)))
 
	#Suppression des sous-graphes
	def cleanInit(self):
		for i in graph.getSubGraphs():
			graph.delAllSubGraphs(i)
	#Afficher selon une courbe de Moore
	def render(self):
		iterator=iter(self.getDirList())	
		curentPos=0+0j		
		precJ=""
 
		for i in sorted(self.nodesByValue):
			for j in self.nodesByValue[i]:				
				self.viewLayout.setNodeValue(j,tlp.Coord(curentPos.real,curentPos.imag,0))
				if(self.viewPattern):
					curentPos+=(iterator.next()*8)
					if(precJ!=""):
						self.currentgraph.addEdge(precJ,j)
						precJ=j
				else:curentPos+=(iterator.next())
 
 
	#Crée un dictionnaire key=valeur de la prop et value=liste des noeuds correspondant
	def sortByProperty(self,property):
		self.nodesByValue=dict()
		for n in self.currentgraph.getNodes():			
			key=self.property.getNodeValue(n)			
			if(key not in self.nodesByValue):
				self.nodesByValue[key]=[]
			self.nodesByValue[key].append(n)
 
	#Génére les directions à suivre à partir de la chaine de Moore
	def getDirList(self):		
		dir=0#haut
		for i in self.axiom:
			if i=="F":	
				temp=0
				if(dir==0):temp=complex(0,1)
				if(dir==1):temp=complex(1,0)
				if(dir==2):temp=complex(0,-1)
				if(dir==3):temp=complex(-1,0)
				self.dirList.append(temp)				
			elif i=="+":#droite
				dir=(dir+1)%4			
			elif i=="-":#gauche
				dir=(dir-1+4)%4
		return self.dirList
 
 
 
 
def main(graph) : 
	moore=Moore(graph,"numCheckins",4)		

Les corrélations

Corrélation nombre d'amis - nombre d'amis

Il s'agit juste d'un test qui montre bien que deux variables identiques sont fortement corrélées et que notre système de visualisation a du sens!

Corrélation Distance maximale - nombre d'amis

Ici on observe que le graphe peut être séparé en deux parties (pattern gauche droite) : à gauche on retrouve les personnes qui ont le moins d'amis, elles correspondent à celles qui sont les moins mobiles et inversement.

Corrélation Nombre de checkin - Dernier checkin

Encore une fois, on constate une séparation du graphe en deux parties. A gauche les gens qui n'ont pas fait beaucoup de checkins sont aussi ceux qui ont fait leur dernier checkin il y a longtemps (on peut donc déduire que ce sont des personnes peu actives sur le réseau et qui l'ont abandonné). Et inversement, à droite, on constate une corrélation entre “beaucoup de checkins” et “dernier checkin récent”.

Autres sous-graphes

Corrélation Premier checkin - Dernier checkin

Corrélation Premier checkin - Distance maximale

Corrélation Premier checkin - Nombre d'amis

Corrélation Dernier checkin - Distance maximale

Corrélation Dernier checkin - Nombre d'amis

Corrélation Nombre de checkins - Premier checkin

Corrélation Nombre de checkins - Distance maximale

Corrélation Nombre de checkins - Nombre d'amis

/net/html/perso/melancon/Visual_Analytics_Course/data/pages/nilles/solution_homework2.txt · Last modified: 2012/04/17 16:14 by melancon