User Tools

Site Tools


egachet_ngillet:emilie_gachet_noel_gillet

Projet de Visualisation / Emilie Gachet & Noël Gillet

Le Problème

Jeu de données

La problématique majeure de notre projet consiste à étudier les flux financiers sur une période donnée, et plus particulièrement détecter d'éventuelles transactions frauduleuses. Nous avons choisi un jeu de données qui se trouve sur le site : http://www.cs.umd.edu/hcil/semvast/GTdatasets/FinancialTransactions/download.htm Ce jeu de données concerne les transactions financières entre des comptes bancaires. Il peut être précisé l'origine (pays) des comptes ou encore le domaine des transactions. Les données que nous avons sont :

  • des mots-clés représentant soit le pays soit le domaine
  • les comptes bancaires
  • les transactions de la forme : numéro du compte émetteur, numéro du compte récepteur, montant, date, nombre de mots clés, numéro des mots clés

Grâce aux transactions nous pouvons faire le liens entre les comptes, émetteur et récepteur, et des pays ou des domaines. En effet une transaction possède un ou plusieurs mot-clés qui correspondent à un pays ou un domaine. Nous avons conclu que :

  1. si il n'y a qu'un mot-clé, alors ce mot-clé est attribué aux deux comptes. Si ce mot-clé est un pays alors les deux comptes viennent du même pays. Il en est de même pour les domaines.
  2. si il y a deux mot-clé :
    1. si ceux sont des mots-clés de même catégorie (deux domaines ou deux pays), alors le premier mot-clé est attribué au premier compte de la transaction (compte émetteur), et le deuxième mot-clé est attribué au deuxième mot-clé.
    2. si ceux sont deux mots-clés de catégories différentes, donc cela signifie qu'il y a un domaine et un pays, alors on attribut aux deux comptes le domaine et le pays.

Et ainsi de suite si il y a plus de deux mots-clés la répartition se fait de la même façon. Cependant nous avons découvert quelques informations incohérentes. En regardant de plus près les transactions et les comptes, nous nous sommes aperçu que certains comptes étaient associés à plusieurs pays ou domaines différents.

Pour simplifier l'opération de parsage, nous avons décidé de ré-ordonner les mots-clés en 2 catégories : les pays et les domaines des transactions. Cependant, les transactions n'utilisent pas le nom du compte ou des mots-clés, mais leur numéro. Pour pouvoir ré-ordonner nos mots-clés, sans modifier les transactions, nous avons dû ajouter le numéro de chaque mot-clé à son nom, séparé par une virgule; exemple : “0,South-Africa” pour le premier compte. La virgule nous aidera à traiter les deux champs différents dans nos algorithmes. Ainsi nous pouvons séparer les mots-clés en deux parties, tout en gardant l'ordonnancement de départ.


Résultats

A partir de notre graphe nous pouvons clairement identifier les comptes douteux, grâce au niveau de transparence des noeuds. Cependant le manque d'informations n'a pas toujours permit de les localiser géographiquement. En effet les noeuds dont le pays n'est pas renseigné se trouvent au milieu de la carte, position 0° 0' 0''. Il est donc difficile de définir si certaines régions du monde se livrent plus que d'autres à des activités financières illégales. De plus la base de données était plutôt restreinte et ne nous aurait de toute façon pas permit d'établir des statistiques fiables.

Extraction des données et visualisation

Construction du graphe et représentation

Les noeuds représentent les comptes bancaires, et les arêtes représentent les transactions. Chaque arête possédera comme label le montant de la transaction, sa date ainsi que son domaine. Les noeuds sont libellés par le nom du compte, tel qu'il est dans le fichier data.txt qui regroupe nos données, ainsi que le pays.

Il est possible d'appliquer un code couleur pour les arrêtes, ce code couleur correspond au montant de la transaction. Nous avons choisi une couleur, le bleue, et selon la somme du montant le bleu est plus ou moins transparent. Si le trait est opaque alors la somme est élevée. Il y a un très gros écart entre le plus petit montant et le plus grand, c'est pourquoi il y a beaucoup d'arêtes quasi transparentes.

Nous avons mis en place deux types de représentation pour notre graphe. La première consiste à appliquer le layout “Bubble Tree” disponible dans Tulip. Ce layout permet en effet de distinguer sans effort non seulement les composantes connexes du graphe mais également les noeuds de fort degré. Allié à la coloration d'arête décrite précédemment, on peut identifier les zones denses en matière d'échanges d'argents. La deuxième représentation utilise le plugin “Geo view” et est décrite plus en détail dans la section suivante.


Représentation sur une carte du monde

Nous avons voulu voir ce que donnait les flux financiers sur une carte du monde. Cela nous permet de voir si certaines zone géographique font plus de transactions financières que d'autres, et aussi voir, si on le peut, où sont situé les transactions frauduleuses.

Pour représenter nos flux financiers selon leur position géographique nous avons utilisé l'outil Geo view fournit par Tulip. Nous avons donc utilisé les propriétés suivantes :

viewLatitude = graph.getDoubleProperty("viewLatitude")
viewLongitude = graph.getDoubleProperty("viewLongitude")

Voilà un aperçu du résultat :


Transactions frauduleuses

Nous avons implémenté un algorithme qui nous permet d'établir si une transaction est frauduleuse. Nous avons déterminé trois conditions pour lesquels une transaction est douteuse.

  1. Une même transaction (même transaction veut dire : même émetteur, même récepteur et même montant) à des dates différentes.
  2. Un compte est associé à plusieurs pays.
  3. Un compte ne fait que recevoir ou envoyer de l'argent .

Dès que un de ses critères est rempli, nous attribuons un ou plusieurs points de pénalité au(x) compte(s) concernés. De plus nous avons cherché à nuancer le degré de suspicion. Par exemple si un noeud est associé à trois pays différents alors il aura deux points de pénalités (il ne devrait en avoir qu'un seul).

Ces nuances sont représentés par une coloration des sommets (en rouge dans notre cas) plus ou moins intense. Plus le rouge est transparent, moins le noeud a de pénalité, et inversement.

Voici ce que cela donne en image :

Les critères présentés ci-dessus sont totalement arbitraires, et ne sont fondés sur aucunes études scientifiques. En effet, malgré des recherches sur internet, nous n'avons trouvé aucun algorithme répondant à notre problème.

Conclusion

Notre objectif premier était de pouvoir repérer des activités bancaires douteuses dans une base de données. N'ayant aucune connaissance particulière en matière de fraude fiscale, nous sommes tout à fait conscient que notre algorithme de détection est perfectible. Cependant, nous avons mis en place un outils de visualisation utile pour répondre à cette problématique. Ainsi une personne compétente avec une méthode appropriée sera à même de faire ressortir les transactions douteuses de manière pertinente.

Le jeu de données étant de petite taille, nous n'avons pas utilisé de techniques de visualisation compliquées. Par exemple, comme le graphe est restreint on voit clairement toutes les données sans avoir besoin de sélectionner une zone plus précise, et donc la mise en place d'une hiérarchisation ne nous a pas semblé pas justifié. Nous nous sommes contentés de choisir une mise en page et une coloration appropriées.

Avec un peu plus de temps nous aurions pu arrangé notre code pour qu'il soit un peu plus modulaire et réutilisable. De plus nous n'avons pas exploité les dates des transactions, on aurait par exemple pu montrer l'évolution des flux financiers dans le temps.

Code

Le data set :

14
0,Raw Materials
1,Hardware & Machinery
3,Electronics
4,Pharmaceuticals
5,Cars & Parts
6,Arts & Crafts
8,Minerals & Gems
9,Clothes
10,Software
13,IT Service
15,Financial Service
16,Transportation
19,Food
21,Insurance
15
2,South Africa
7,Thailand
11,Argentina
12,New Zealand
14,India
17,Singapore
18,Japan
20,Spain
22,Kenya
23,Mexico
24,Brazil
25,Egypt
26,Canada
27,Switzerland
28,Poland
181
Account-76
Account-47
Account-14
Account-43
Account-137
Account-61
Account-150
Account-57
Account-136
Account-2
Account-72
Account-152
Account-93
Account-86
Account-127
Account-51
Account-18
Account-149
Account-39
Account-84
Account-0
Account-73
Account-22
Account-12
Account-94
Account-89
Account-54
Account-156
Account-68
Account-66
Account-29
Account-71
Account-55
Account-106
Account-13
Account-91
Account-56
Account-30
Account-105
Account-113
Account-133
Account-28
Account-15
Account-159
Account-8
Account-1
Account-100
Account-122
Account-172
Account-165
Account-131
Account-7
Account-142
Account-98
Account-58
Account-129
Account-60
Account-168
Account-96
Account-45
Account-151
Account-176
Account-115
Account-42
Account-67
Account-53
Account-178
Account-44
Account-166
Account-173
Account-147
Account-141
Account-163
Account-179
Account-119
Account-48
Account-16
Account-164
Account-102
Account-35
Account-109
Account-70
Account-145
Account-124
Account-125
Account-171
Account-120
Account-146
Account-32
Account-75
Account-20
Account-135
Account-130
Account-180
Account-140
Account-175
Account-19
Account-50
Account-34
Account-132
Account-27
Account-121
Account-9
Account-82
Account-26
Account-155
Account-74
Account-161
Account-31
Account-38
Account-24
Account-6
Account-62
Account-23
Account-10
Account-148
Account-88
Account-117
Account-36
Account-4
Account-25
Account-37
Account-21
Account-5
Account-87
Account-174
Account-177
Account-80
Account-153
Account-111
Account-114
Account-41
Account-123
Account-99
Account-83
Account-116
Account-169
Account-108
Account-167
Account-33
Account-101
Account-90
Account-144
Account-3
Account-52
Account-103
Account-49
Account-118
Account-154
Account-143
Account-78
Account-69
Account-128
Account-40
Account-92
Account-85
Account-11
Account-63
Account-112
Account-138
Account-160
Account-107
Account-170
Account-65
Account-81
Account-46
Account-158
Account-95
Account-110
Account-17
Account-126
Account-139
Account-97
Account-77
Account-162
Account-79
Account-157
Account-134
Account-104
Account-59
Account-64
249
7,0,360000.0,2005-10-11,2,1;2
0,1,3000.0,2005-06-21,1,0
0,2,4620.0,2005-03-17,1,0
0,3,66363.0,2005-01-03,1,1
0,4,1348.09,2005-11-30,1,0
0,5,820.0,2004-12-21,1,1
0,6,11000.0,2005-02-11,1,0
0,8,4598.59,2004-11-30,1,0
0,9,16690.0,2005-06-09,1,3
10,11,8675.0,2005-03-16,1,4
12,11,36063.06,2005-12-05,1,5
13,11,19467.91,2005-11-21,2,6;7
13,11,178099.69,2005-04-14,2,6;7
14,11,4000.0,2005-04-26,1,3
15,11,1100.0,2005-09-12,1,4
15,11,1100.0,2005-08-31,1,4
15,11,1100.0,2005-07-27,1,4
15,11,1100.0,2005-06-21,1,4
16,11,11540.0,2005-01-20,1,3
17,11,267260.0,2005-03-15,2,6;7
18,19,3700.0,2005-10-26,1,0
18,20,28750.0,2005-05-25,1,8
21,22,211741.55,2005-07-14,1,1
23,24,885.19,2005-08-08,1,9
23,21,4503.0,2005-06-01,1,9
25,26,5417.0,2005-06-01,1,6
25,26,4912.91,2005-05-17,1,6
25,26,4443.29,2005-04-13,1,6
25,26,4063.16,2005-03-04,1,6
25,26,4058.0,2005-04-01,1,6
27,28,5470.16,2005-11-18,2,0;8
29,30,47739.8,2005-06-09,1,1
31,30,22013.5,2005-08-02,1,1
31,27,2988.83,2005-06-09,1,0
30,32,7000.0,2005-07-11,2,1;3
33,34,82542.1,2005-10-31,1,1
35,33,5957.8,2005-11-15,1,3
36,33,1444.07,2005-01-21,1,3
37,33,11700.0,2005-11-29,1,10
38,33,1175.5,2005-11-28,1,3
39,33,3990.0,2005-02-03,1,3
40,33,25851.0,2005-03-21,2,3;11
41,33,3500.0,2005-05-03,1,3
42,33,1160.7,2005-05-12,1,3
43,33,53733.6,2005-05-19,2,3;12
44,45,575816.25,2005-10-11,2,13;14
44,45,849636.0,2005-09-29,2,13;14
44,46,228070.0,2005-09-28,1,15
44,47,24210.0,2005-08-22,1,16
44,48,605263.0,2005-08-22,1,15
45,49,37882.69,2005-09-30,2,3;14
45,50,45731.3,2005-07-20,3,1;17;14
45,51,906580.8,2005-11-08,3,10;18;14
45,52,907000.5,2005-11-28,3,10;18;14
45,52,301158.0,2005-07-12,3,10;18;14
45,48,100000.0,2005-09-30,2,15;14
52,50,125400.24,2005-12-05,3,10;18;14
52,50,184428.4,2005-08-02,3,10;18;14
52,46,525000.0,2005-06-24,2,15;18
53,54,50000.0,2005-05-18,1,19
53,55,3380.4,2005-06-01,1,19
53,56,112891.4,2005-11-22,2,1;20
53,57,11000.0,2005-08-23,1,6
53,58,30000.0,2004-12-06,1,21
53,59,30000.0,2005-12-02,1,21
60,61,12210.1,2005-11-01,1,16
60,62,1438.49,2005-07-14,1,16
60,63,53000.0,2005-04-28,1,16
60,64,120943.68,2005-09-27,1,16
65,66,25053.88,2005-09-20,2,8;9
65,64,93396.93,2005-05-02,1,9
65,64,63151.6,2005-03-09,1,9
65,64,61471.67,2005-05-18,1,9
65,64,67749.35,2005-03-22,1,9
67,68,8111.77,2005-04-19,2,10;15
69,67,4185.0,2005-03-31,2,10;15
67,70,24572.46,2005-04-21,2,19;15
71,67,390182.03,2005-08-12,2,9;15
67,72,30149.01,2005-10-27,2,9;15
67,73,41259.47,2005-09-08,3,19;6;15
74,67,2000.0,2005-04-29,2,10;15
75,67,107031.42,2005-10-06,3,19;3;15
67,76,71964.27,2005-09-22,2,6;15
67,77,30584.65,2005-11-08,2,6;15
67,78,3750.0,2005-09-01,2,10;15
79,67,12167.72,2005-07-06,2,10;15
67,80,25000.0,2005-09-02,3,6;9;15
67,81,23619.47,2005-11-21,2,9;15
67,82,135649.28,2005-07-21,2,10;15
83,67,98986.48,2005-09-01,2,6;15
67,84,53365.41,2005-11-18,2,9;15
67,85,42881.41,2005-11-07,2,10;15
86,67,190508.52,2005-03-02,2,9;15
67,64,97596.54,2005-11-29,2,9;15
67,87,46933.09,2005-07-11,2,19;15
88,67,163855.81,2005-11-09,2,9;15
89,90,4155.0,2005-06-07,2,0;22
89,91,7350.77,2005-06-21,2,3;22
89,92,19876.01,2005-07-19,2,1;22
89,93,7890.33,2005-08-03,2,16;22
89,94,14180.0,2005-03-24,2,8;22
95,96,7312.5,2005-03-07,1,5
95,97,20316.8,2005-12-06,1,5
95,97,59093.65,2005-11-17,1,5
95,97,17737.5,2005-08-08,1,5
95,98,25631.7,2005-02-08,1,5
95,98,28077.9,2005-01-26,1,5
99,100,17200.0,2005-04-05,2,3;1
97,100,250000.0,2005-10-20,2,5;3
100,101,59447.0,2005-05-05,1,0
100,101,68051.0,2005-01-27,1,0
100,101,2000.0,2004-12-15,1,0
100,101,93580.0,2005-08-04,1,0
100,102,141900.0,2005-08-18,2,8;0
103,104,1000.0,2005-03-22,2,15;23
103,105,10000.0,2005-01-28,1,15
103,106,76000.0,2005-04-08,3,15;24;5
103,106,75735.0,2005-11-08,3,15;24;5
103,107,9750.0,2005-11-18,2,15;20
103,108,500.0,2005-08-24,2,15;23
103,109,950.0,2005-02-23,2,15;23
103,110,5000.0,2005-06-20,2,15;25
103,111,33500.0,2005-09-30,2,15;10
103,112,120000.0,2005-01-13,1,15
103,112,34625.5,2005-07-19,1,15
103,112,35142.62,2005-03-05,1,15
103,113,100000.0,2005-06-07,3,15;19;12
103,114,13050.0,2005-09-30,2,15;2
103,115,9000.0,2005-12-01,2,15;21
103,115,35000.0,2005-08-18,2,15;21
103,116,40912.97,2005-09-23,3,15;1;24
103,117,57514.0,2005-10-14,3,15;19;23
103,118,1000.0,2005-06-09,2,15;26
103,119,12621.44,2005-11-16,2,15;18
103,120,4000.0,2005-10-26,2,15;23
103,121,2995.0,2005-06-01,2,15;23
103,122,1200.0,2005-09-13,2,15;23
103,123,20000.0,2005-07-12,3,15;1;27
103,124,30000.0,2005-05-01,1,15
103,124,1626.44,2005-10-26,1,15
103,124,4000.0,2005-07-20,1,15
103,124,611.95,2005-06-23,1,15
103,125,43240.0,2005-09-24,1,15
103,125,12980.0,2005-02-24,1,15
103,126,15675.36,2005-07-20,1,15
103,126,5035.98,2005-06-22,1,15
123,99,24350.27,2005-08-25,2,1;27
123,99,11561.07,2005-08-10,2,1;27
123,99,16868.77,2005-06-20,2,1;27
123,99,2766.41,2005-08-12,2,1;27
127,128,200010.0,2005-08-03,2,5;15
127,129,27705.4,2005-06-28,2,8;15
127,130,21375.0,2005-02-14,2,1;15
127,131,2500.0,2005-11-04,2,0;15
127,131,39607.0,2005-04-03,2,0;15
127,111,5577.85,2005-08-01,2,10;15
127,132,66848.18,2005-01-30,2,4;15
127,112,159362.6,2005-10-13,2,1;15
127,133,9748.84,2005-10-31,2,9;15
127,133,5103.0,2005-03-13,2,9;15
127,133,61199.49,2005-11-14,2,9;15
127,133,8521.04,2005-10-20,2,9;15
127,133,28802.72,2005-09-13,2,9;15
127,133,94819.15,2005-07-18,2,9;15
127,133,475.0,2005-05-01,2,9;15
127,134,2222.82,2005-08-16,2,6;15
127,135,16688.06,2005-06-13,2,0;15
127,136,11148.0,2005-09-14,2,8;15
127,137,6010.86,2005-08-16,2,9;15
127,137,2820.2,2005-06-21,2,9;15
127,99,4842.0,2005-03-12,2,1;15
127,138,4517.33,2005-08-16,2,6;15
127,139,27895.55,2005-04-02,2,4;15
127,140,1000.0,2005-06-01,2,6;15
127,141,5768.86,2005-06-20,2,9;15
127,124,14817.0,2005-11-17,2,1;15
127,97,100000.0,2005-07-14,2,5;15
127,142,42628.0,2005-05-29,2,19;15
127,125,65694.0,2005-07-12,2,0;15
127,143,16002.47,2005-02-05,2,10;15
127,126,2850.0,2005-09-09,2,9;15
142,144,5363.5,2005-08-09,1,19
142,145,2690.0,2005-08-01,1,19
142,146,4000.0,2005-08-30,1,19
142,147,31060.4,2005-08-31,1,19
148,149,52000.0,2005-08-11,1,3
148,150,320000.0,2005-02-11,2,1;28
148,151,100000.0,2005-07-21,2,0;23
148,151,46000.0,2004-12-23,2,0;23
148,152,446000.0,2005-11-28,2,5;24
148,152,302000.0,2005-10-24,2,5;24
148,152,600000.0,2005-02-07,2,5;24
148,153,80000.0,2005-08-09,1,5
148,153,60000.0,2005-07-25,1,5
148,154,480.0,2005-08-10,1,16
155,156,6285.0,2005-08-01,1,3
155,157,2000.0,2005-04-28,1,0
155,158,222948.2,2005-08-16,2,10;14
155,158,56179.36,2005-07-11,2,10;14
155,159,1054.52,2005-04-21,1,16
155,160,30004.89,2005-07-13,1,0
155,160,45539.81,2005-07-05,1,0
155,160,72596.53,2005-05-06,1,0
161,162,81985.39,2005-06-22,1,3
162,163,1300.0,2005-08-11,1,16
164,162,60100.0,2005-07-26,1,3
162,165,225.15,2005-11-21,1,16
162,166,810000.0,2005-10-14,2,1;20
162,166,200000.0,2005-07-27,2,1;20
162,166,135000.0,2005-06-30,2,1;20
162,166,67500.0,2005-02-10,2,1;20
162,158,685846.75,2005-05-09,2,10;14
162,167,6780.11,2005-08-30,1,1
162,168,1500.0,2005-06-21,1,16
162,169,750.0,2005-07-26,1,16
170,162,11300.0,2005-06-07,1,3
162,171,855000.0,2005-03-09,2,3;12
172,168,350.0,2005-10-25,1,16
172,168,1305.0,2005-09-07,1,16
172,168,870.0,2005-09-07,1,16
172,168,2784.02,2005-08-05,1,16
172,168,1217.99,2005-06-27,1,16
172,168,1653.0,2005-04-01,1,16
172,168,2087.98,2005-03-04,1,16
172,168,1531.19,2005-03-04,1,16
151,173,50000.0,2005-09-05,2,23;4
94,174,14180.0,2005-04-27,2,11;19
175,77,450108.0,2005-11-03,1,6
176,177,15320.0,2005-01-14,1,10
176,177,15320.0,2005-01-31,1,10
176,177,15320.0,2005-02-15,1,10
176,177,15320.0,2005-02-28,1,10
176,177,15320.0,2005-03-15,1,10
176,177,15320.0,2005-03-30,1,10
176,177,750000.0,2005-12-23,1,10
178,81,40400.0,2005-11-18,2,3;9
179,57,20000.0,2005-11-29,1,4
127,146,12000.0,2005-01-07,2,19;15
127,146,20000.0,2005-09-12,2,19;15
127,146,5000.0,2005-08-22,2,19;15
127,146,294000.0,2005-06-30,2,19;15
127,102,930000.0,2005-12-05,2,8;15
127,102,20000.0,2005-11-18,2,8;15
127,102,180000.0,2005-08-09,2,8;15
127,102,96202.34,2005-07-25,2,8;15
127,102,100000.0,2005-03-12,2,8;15
127,102,180000.0,2005-06-20,2,8;15
148,180,20000.0,2005-04-07,1,5
148,180,600000.0,2005-02-04,1,5

Le fichier à exécuter dans tulip est script.py.

script.py
from tulip import *
from utils import *
from parser import *
from algos import *
 
viewColor =  graph.getColorProperty("viewColor")
viewLabel =  graph.getStringProperty("viewLabel")
viewLatitude = graph.getDoubleProperty("viewLatitude")
viewLayout =  graph.getLayoutProperty("viewLayout")
viewLongitude = graph.getDoubleProperty("viewLongitude")
viewSize =  graph.getSizeProperty("viewSize")
viewLabelColor = graph.getColorProperty("viewLabelColor")
 
#Ce script effectue les actions suivantes :
 
#- il parse le dataset data.txt
#- il genere le graphe correspondant
#- il colorie les aretes en fonction du montant ds transactions
#- il colorie les sommets en fonction de la penalite des comptes
#- il renseigne la latitude et la longitude des comptes pour permettre une viualisation avec Geo View Google Map
 
#Pour le parsage, c'est le chemin absolu de data.txt qui doit etre renseigne
 
def main(graph): 
	#p = Parser("/data/Cours/Master/CSB9/ABV/visu/data.txt")
	p = Parser("/net/cremi/ngillet/Master/Semestre9/visu/data.txt")
	p.run()
	graph.clear()
	constructGraph(p)
	c1 = amount_colors(p.transactions)
	c2 = penalities_colors(p.penalitiesByAccount)
	color_edges(c1)
	color_nodes(c2)
	geolocalisation()
 
def constructGraph(p) :
	listKey = []
 
	for a in p.accounts :
		node = graph.addNode()
		viewLabel[node] = a
		viewColor[node] = tlp.Color(128,128,128)
		viewLabelColor[node]=tlp.Color(0,0,0,0)
 
	global nodes
	nodes = listNodes()
 
	for t in p.transactions :
		em = int(t[0])
		re = int(t[1])
		e = graph.addEdge(nodes[em],nodes[re])
		viewLabel[e] = "montant: "+t[2]
		viewLabel[e] += ",date: "+t[3]
		viewLabel[e] += ",domain: "+domainAssignment(p,t)
 
	graph.computeLayoutProperty("Bubble Tree",viewLayout)
 
	countryAssignment(p)
 
def countryAssignment(p):
	listKey = []
	 # on refait notre liste des pays en separant le nom du numero 
	listN = listNodes()
	for t in p.transactions :
		nodes=[]
		nodes.append(listN[int(t[0])])
		nodes.append(listN[int(t[1])])
		listKey = getListKeyInTrans(listKey,t)
		countryTmp = []
		for keyword in listKey:
			k = find(p.countries,keyword)
			if k != None:
				countryTmp.append(k)
		if len(countryTmp)>0:
			viewLabel[nodes[0]]+=",country :"+countryTmp[0]
		 	if len(countryTmp)==1:
				viewLabel[nodes[1]]+=",country :"+countryTmp[0]
			else: 
				viewLabel[nodes[1]]+=",country :"+countryTmp[1]
 
def domainAssignment(p,t):
	domainName = ""
	listKey = []
	listKey = getListKeyInTrans(listKey,t)
	for keyword in listKey:
		k = find(p.domains,keyword)
		if k != None:
			domainName+=k+"."
	return domainName
 
def listNodes():
	l = []
	for n in graph.getNodes():
		l.append(n)
	return l
 
def color_edges(colors):
	i =0
	for e in graph.getEdges():
		viewColor[e] = colors[i]
		i+=1
 
def color_nodes(colors):
	i=0
	for n in graph.getNodes():
		viewColor[n] = colors[i]
		i+=1
 
def geolocalisation():
	for n in graph.getNodes():
		labelTmp =""
		labelTmp = viewLabel[n]
		labelTmp = labelTmp.split(",")
		if len(labelTmp)>1:
			countryTmp = labelTmp[1].split(":")
			c = countryTmp[1]
			if c == "South Africa":
				viewLatitude[n]=-34
				viewLongitude[n]=20
			if c == "Thailand":
				viewLatitude[n]=15
				viewLongitude[n]=100
			if c == "Argentina":
				viewLatitude[n]=-34
				viewLongitude[n]=-64
			if c == "New Zealand":
				viewLatitude[n]=-41
				viewLongitude[n]=174
			if c == "India":
				viewLatitude[n]=22
				viewLongitude[n]=77
			if c == "Singapore":
				viewLatitude[n]=1.3667
				viewLongitude[n]=103.8
			if c == "Japan":
				viewLatitude[n]=36
				viewLongitude[n]=138
			if c == "Spain":
				viewLatitude[n]=40
				viewLongitude[n]=-4
			if c == "Kenya":
				viewLatitude[n]=1
				viewLongitude[n]=38
			if c == "Mexico":
				viewLatitude[n]=19.4
				viewLongitude[n]=-99.15
			if c == "Brazil":
				viewLatitude[n]=-10
				viewLongitude[n]=-55
			if c == "Egypt":
				viewLatitude[n]=27
				viewLongitude[n]=30
			if c == "Canada":
				viewLatitude[n]=60
				viewLongitude[n]=-95
			if c == "Switzerland":
				viewLatitude[n]=47
				viewLongitude[n]=8
			if c == "Poland":
				viewLatitude[n]=52
				viewLongitude[n]=20
parser.py
from utils import *
 
class Parser:
 
 # Cette classe permet de parser notre dataset
 
 
	def __init__(self,file):
		self.file = file
		self.domains = []
		self.countries = []
		self.accounts = []
		self.transactions = []
		self.accountsWithCountries = []
		self.transactionsByAccount = []
		self.countriesByAccount = []
		self.penalitiesByAccount = []
		self.__parseInit__()
 
	def __recupData__(self,f, tab, nb):
		for i in range(nb) :
			k = f.readline().rstrip('\n\r')
			tab.append(k)
 
	def __parseInit__(self):
		fichier = open(self.file, "r")
 
		nbDomain = int(fichier.readline())
		self.__recupData__(fichier,self.domains,nbDomain)
		nbCountry = int(fichier.readline())
		self.__recupData__(fichier,self.countries,nbCountry)
		nbAccount=int(fichier.readline())
		self.__recupData__(fichier,self.accounts,nbAccount)
		nbTransactions = int(fichier.readline())
		self.__recupData__(fichier,self.transactions,nbTransactions)
 
		fichier.close()
 
		self.domains = parseListDomain(self.domains)
		self.transactions= parseTransactions(self.transactions)
		self.countries = parseListCountry(self.countries)
 
		lenght = len(self.accounts)
		self.transactionsByAccount = init_list2D(lenght)
		self.countriesByAccount = init_list2D(lenght)
 
	def __transactionsByAccount__(self):
	  #Recupere la liste des transactions pour chaque noeud
		i = 0
		for t in self.transactions:
			self.transactionsByAccount[int(t[0])].append(i)
			self.transactionsByAccount[int(t[1])].append(i)
			i=i+1
 
	def __countriesByAccount__(self):
	  #Recupere la liste des pays pour chaque noeud
		listKey = []
		for t in self.transactions :
			listKey = getListKeyInTrans(listKey,t)
			countryTmp = []
			for keyword in listKey:
				k = find(self.countries,keyword)
				if k != None:
					countryTmp.append(k)
			if len(countryTmp)>0:
				if not(is_present(self.countriesByAccount[int(t[0])],countryTmp[0])):
					self.countriesByAccount[int(t[0])].append(countryTmp[0])
			 	if len(countryTmp)==1:
					if not(is_present(self.countriesByAccount[int(t[1])],countryTmp[0])):
						self.countriesByAccount[int(t[1])].append(countryTmp[0])
				else: 
					if not(is_present(self.countriesByAccount[int(t[1])],countryTmp[1])):
						self.countriesByAccount[int(t[1])].append(countryTmp[1])
 
	def __accountsWithCountries__(self):
	  #Recupere la liste des comptes ayant au moins un pays associe
 
		for i in range(len(self.countriesByAccount)):
			if len(self.countriesByAccount[i]) > 0:
				self.accountsWithCountries.append(i)
 
	def __getAmountHistory__(self,account):
		history = []
		for t in self.transactionsByAccount[account]:		
			if account == int(self.transactions[t][0]):
				amount = -1*float(self.transactions[t][2])
				history.append(amount)
			if account == int(self.transactions[t][1]):
				amount = float(self.transactions[t][2])
				history.append(amount)
		return history
 
	def addPenalitiesByAccount(self):	
#	  Associer une penalite a chaque compte
		for i in range(len(self.accounts)):
			self.penalitiesByAccount.append(0)
 
		# Deux comptes effectuent la meme transaction plusieurs fois
		for t in self.transactions:
			pen = 0
			for succ in self.transactions:
				if (succ[0]==t[0] and succ[1]==t[1] and succ[2]==t[2] and succ[3]!=t[3]):
					pen=pen+1
			if pen > 1:
				self.penalitiesByAccount[int(t[0])]+= pen
				self.penalitiesByAccount[int(t[1])]+= pen
 
		# Un compte a plusieurs pays d'origine
		for i in range(len(self.countriesByAccount)):
			nb_countries = len(self.countriesByAccount[i])
			if nb_countries > 1:
				self.penalitiesByAccount[i]+= nb_countries
 
		# Un compte ne fait que recevoir/emettre de l'argent
		for i in range(len(self.transactionsByAccount)):
			hist = self.__getAmountHistory__(i)
			neg=0
			pos=0
			for j in hist:
				if j < 0:
					neg+=1
				else:
					pos+=1
			if neg==0 or pos==0:
				self.penalitiesByAccount[i] += len(hist)
 
	def run(self):
		self.__transactionsByAccount__()
		self.__countriesByAccount__()
		self.__accountsWithCountries__()
		self.addPenalitiesByAccount()
algos.py
from tulip import *
 
def amount_colors(transactions):
	colors = []
	for t in transactions:
		amount = float(t[2])
		alpha = int(((amount-500)*255)/(1000000-500))
		colors.append(tlp.Color(0,0,255,alpha))
	return colors
 
def penalities_colors(penalities):
	colors = []
	for p in penalities:
		alpha = (p*255)/41
		colors.append(tlp.Color(255,0,0,alpha))
	return colors
utils.py
def init_list2D(n):
	l = []
	for i in range(n):
		l.append([])
	return l
 
def is_present(l,val):
	for elem in l:
		if elem == val:
			return True
	return False
 
def find(l,i):
	for elem in l:
		if elem[0] == i:
			return elem[1]
 
def parseTransactions(transactions) :
	newTab=[]
	for t in transactions :
		tmp = t.split(",")
		newTab.append(tmp)
	return newTab
 
def parseListKey(listKey):
	for i in listKey :
		l = i.split(";")
		#print(l)
	return l
 
def parseListCountry(countries):
	newTab=[]
	for c in countries :
		l = c.split(",")
		newTab.append(l)
	return newTab
 
def parseListDomain(domains):
	newTab=[]
	for d in domains :
		l = d.split(",")
		newTab.append(l)
	return newTab
 
def getListKeyInTrans(listKey,t):
	listKey.append(t[5])
	listKey = parseListKey(listKey)
	return listKey
/net/html/perso/melancon/Visual_Analytics_Course/data/pages/egachet_ngillet/emilie_gachet_noel_gillet.txt · Last modified: 2013/01/10 14:59 by ngillet