-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy path15-viz.tex
executable file
·819 lines (722 loc) · 36.9 KB
/
15-viz.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
% The contents of this file is
% Copyright (c) 2009- Charles R. Severance, All Righs Reserved
\chapter{Visualizando dados}
%\chapter{Visualizing data}
Até agora, aprendemos a linguagem Python, como utilizá-la
para trabalhar com redes e banco de dados para manipular dados.
%So far we have been learning the Python language and then
%learning how to use Python, the network, and databases
%to manipulate data.
Neste capítulo, serão apresentadas três aplicações completas
que utilizarão todos estes conceitos para gerenciar e visualizar
dados. Você pode utilizar estas aplicações como exemplo de código
que podem ajudar na solução de problemas reais.
%In this chapter, we take a look at three
%complete applications that bring all of these things together
%to manage and visualize data. You might use these applications
%as sample code to help get you started in solving a
%real-world problem.
Cada uma das aplicações é um arquivo ZIP que você pode fazer
download, extrair para o seu computador e executar.
%Each of the applications is a ZIP file that you can download
%and extract onto your computer and execute.
\section{Construindo um mapa no Google a partir de dados geocodificados}
\index{Google!map}
\index{Visualização!mapas}
%\section{Building a Google map from geocoded data}
%\index{Google!map}
%\index{Visualization!map}
Neste projeto, utilizaremos a API de geocodificação do
Google para obter algumas localizações geográficas informadas
pelos usuários de nomes de universidades e colocar os dados
em um mapa no Google.
%In this project, we are using the Google geocoding API
%to clean up some user-entered geographic locations of
%university names and then placing the data on a Google
%map.
\beforefig
\centerline{\includegraphics[height=2.25in]{figs2/google-map.eps}}
\afterfig
%\beforefig
%\centerline{\includegraphics[height=2.25in]{figs2/google-map.eps}}
%\afterfig
Para iniciar, faça o download da aplicação em:
%To get started, download the application from:
\url{www.py4inf.com/code/geodata.zip}
O primeiro problema a ser resolvido é que a API gratuita de
geocodificação do Google limita o número de requisições por dia.
Se você tiver muitos dados, você pode precisar parar e reiniciar
o processo de busca muitas vezes. Nós podemos quebrar o problema
em duas fases.
%The first problem to solve is that the free Google geocoding
%API is rate-limited to a certain number of requests per day. If you have
%a lot of data, you might need to stop and restart the lookup
%process several times. So we break the problem into two
%phases.
\index{cache}
Na primeira fase nós faremos uma ``'pesquisa'' nos dados do arquivo
{\bf where.data} e então ler uma linha por vez, retornando a informação
geocodificada do Google e armazenar em um banco de dados {\bf geodata.sqlite}.
Antes de efetuar a pesquisa no Google, utilizando a API, para cada localização
informada pelo usuário, nós vamos checar para ver se já existe este dado
para a localização informada. O banco de dados está funcionando como um
``cache'' local dos nossos dados de localização para ter certeza que nunca
buscaremos no Google duas vezes pelo mesmo dado.
%\index{cache}
%In the first phase we take our input ``survey'' data in the file
%{\bf where.data} and read it one line at a time, and retrieve the
%geocoded information from Google and store it
%in a database {\bf geodata.sqlite}.
%Before we use the geocoding API for each user-entered location,
%we simply check to see if we already have the data for that
%particular line of input. The database is functioning as a
%local ``cache'' of our geocoding data to make sure we never ask
%Google for the same data twice.
Você pode reiniciar o processo a qualquer hora deletando o arquivo
{\bf geodata.sqlite}.
%You can restart the process at any time by removing the file
%{\bf geodata.sqlite}.
Execute o programa {\bf geoload.py}. Este programa fará a leitura das linhas
do arquivo {\bf where.data} e para cada linha checar se o dado já existe no
banco de dados. Se nós não tivermos o dado para a localização, será utilizada
a API para retornar o dado e armazená-lo no banco de dados.
%Run the {\bf geoload.py} program. This program will read the input
%lines in {\bf where.data} and for each line check to see if it is already
%in the database. If we don't have the data for the location, it will
%call the geocoding API to retrieve the data and store it in
%the database.
Aqui está uma simples execução após a coleta de alguns dados no
banco de dados:
%Here is a sample run after there is already some data in the
%database:
\beforeverb
\begin{verbatim}
Found in database Northeastern University
Found in database University of Hong Kong, ...
Found in database Technion
Found in database Viswakarma Institute, Pune, India
Found in database UMD
Found in database Tufts University
Resolving Monash University
Retrieving http://maps.googleapis.com/maps/api/
geocode/json?sensor=false&address=Monash+University
Retrieved 2063 characters { "results" : [
{u'status': u'OK', u'results': ... }
Resolving Kokshetau Institute of Economics and Management
Retrieving http://maps.googleapis.com/maps/api/
geocode/json?sensor=false&address=Kokshetau+Inst ...
Retrieved 1749 characters { "results" : [
{u'status': u'OK', u'results': ... }
...
\end{verbatim}
\afterverb
%
As primeiras cinco execuções já estão no banco de dados e então serão
ignoradas. O programa encontra o ponto onde parou e então continua
o trabalho recuperando novas informações.
%The first five locations are already in the database and so they
%are skipped. The program scans to the point where it finds new
%locations and starts retrieving them.
O programa {\bf geoload.py} pode ser parado a qualquer hora, há um
contador que você pode utilizar para limitar o número de chamadas para a
API de geocodificação a cada execução. Dado o arquivo {\bf where.data}, que
possui algumas centenas de itens, você não consegue ultrapassar o limite diário,
mas pode fazer várias execuções em vários dias diferentes para ir pegando
aos poucos todos os dados que você precisa.
%The {\bf geoload.py} program can be stopped at any time, and there is a counter
%that you can use to limit the number of calls to the geocoding
%API for each run. Given that the {\bf where.data} only has a few hundred
%data items, you should not run into the daily rate limit, but if you
%had more data it might take several runs over several days to
%get your database to have all of the geocoded data for your input.
Uma vez que você tiver alguns dados carregados em {\bf geodata.sqlite},
você pode visualizá-los utilizando o programa {\bf geodump.py}.
Este programa lê o banco de dados e escreve no arquivo {\bf where.js}
com a localização de latitude e longitude em um formato de código
JavaScript.
%Once you have some data loaded into {\bf geodata.sqlite}, you can
%visualize the data using the {\bf geodump.py} program. This
%program reads the database and writes the file {\bf where.js}
%with the location, latitude, and longitude in the form of
%executable JavaScript code.
Segue uma execução do programa {\bf geodump.py}:
%A run of the {\bf geodump.py} program is as follows:
\beforeverb
\begin{verbatim}
Northeastern University, ... Boston, MA 02115, USA 42.3396998 -71.08975
Bradley University, 1501 ... Peoria, IL 61625, USA 40.6963857 -89.6160811
...
Technion, Viazman 87, Kesalsaba, 32000, Israel 32.7775 35.0216667
Monash University Clayton ... VIC 3800, Australia -37.9152113 145.134682
Kokshetau, Kazakhstan 53.2833333 69.3833333
...
12 records written to where.js
Open where.html to view the data in a browser
\end{verbatim}
\afterverb
%
O arquivo {\bf where.html} consiste de um HTML e um JavaScript para visualizar
um mapa Google. Ele lê os dados mais recentes em {\bf where.js} para pegar
os dados a serem visualizados. Aqui está um formato do arquivo {\bf where.js}.
%The file {\bf where.html} consists of HTML and JavaScript to visualize
%a Google map. It reads the most recent data in {\bf where.js} to get
%the data to be visualized. Here is the format of the {\bf where.js} file:
\beforeverb
\begin{verbatim}
myData = [
[42.3396998,-71.08975, 'Northeastern Uni ... Boston, MA 02115'],
[40.6963857,-89.6160811, 'Bradley University, ... Peoria, IL 61625, USA'],
[32.7775,35.0216667, 'Technion, Viazman 87, Kesalsaba, 32000, Israel'],
...
];
\end{verbatim}
\afterverb
%
Esta é uma variável JavaScript que contém uma lista de listas.
A sintaxe para representação de listas em JavaScript é muito similar
ao Python, sendo assim, deve ser familiar para você também.
%This is a JavaScript variable that contains a list of lists.
%The syntax for JavaScript list constants is very similar to
%Python, so the syntax should be familiar to you.
Simplemente abra o arquivo {\bf where.html} em um browser para ver as
localizações. Você pode passar o mouse por cima de cada um dos pontos
do mapa para encontrar a localização que a API de geocodificação retornou
para uma entrada do usuário. Se você não puder ver qualquer dado quando
abrir o arquivo {\bf where.html}, você pode querer checar o console do
desenvolvedor (JavaScript) de seu browser e ver se encontra algum erro.
%Simply open {\bf where.html} in a browser to see the locations. You
%can hover over each map pin to find the location that the
%geocoding API returned for the user-entered input. If you
%cannot see any data when you open the {\bf where.html} file, you might
%want to check the JavaScript or developer console for your browser.
\section{Visualizando redes e interconexões}
\index{Google!page rank}
\index{Visualização!redes}
\index{Visualização!page rank}
%\section{Visualizing networks and interconnections}
%\index{Google!page rank}
%\index{Visualization!networks}
%\index{Visualization!page rank}
Nesta aplicação, vamos realizar algumas das funções de um motor de busca.
Primeiramente, vamos extrair um pequeno pedaço da web e rodar
uma versão simplificada do algoritmo de page rank do Google para determinar
quais páginas estão altamente conectadas, e então visualizar o page rank
e a conectividade de nosso pequeno pedaço da web.
Utilizaremos a biblioteca de visualização JavaScript D3 \url{http://d3js.org/}
para produzir a saída da visualização.
%In this application, we will perform some of the functions of a search
%engine. We will first spider a small subset of the web and run
%a simplified version of the Google page rank algorithm to
%determine which pages are most highly connected, and then visualize
%the page rank and connectivity of our small corner of the web.
%We will use the D3 JavaScript visualization library
%\url{http://d3js.org/} to produce the visualization output.
Você pode fazer download e extrair esta aplicação de:
%You can download and extract this application from:
\url{www.py4inf.com/code/pagerank.zip}
\beforefig
\centerline{\includegraphics[height=2.25in]{figs2/pagerank.eps}}
\afterfig
O primeiro programa ({\bf spider.py}) vasculha páginas web e grava
uma série de páginas no banco de dados ({\bf spider.sqlite}), gravando
as ligações entre as páginas. Você pode reiniciar o processo a qualquer
momento, deletando o arquivo {\bf spider.sqlite} e reexecutando o {\bf spider.py}.
%The first program ({\bf spider.py}) program crawls a web
%site and pulls a series of pages into the
%database ({\bf spider.sqlite}), recording the links between pages.
%You can restart the process at any time by removing the
%{\bf spider.sqlite} file and rerunning {\bf spider.py}.
\beforeverb
\begin{verbatim}
Enter web url or enter: http://www.dr-chuck.com/
['http://www.dr-chuck.com']
How many pages:2
1 http://www.dr-chuck.com/ 12
2 http://www.dr-chuck.com/csev-blog/ 57
How many pages:
\end{verbatim}
\afterverb
%
Neste exemplo de execução, pedimos ao programa para extrair e
retornar duas páginas. Se você reiniciar o programa e pedir a ele para
obter mais páginas, não irá pegar novamente as mesmas páginas que já
estão no banco de dados. Após o restart ele vai sortear randomicamente
páginas e começar de lá. Assim, cada execução sucessiva do {\bf spider.py}
é um aditivo.
%In this sample run, we told it to crawl a website and retrieve two
%pages. If you restart the program and tell it to crawl more
%pages, it will not re-crawl any pages already in the database. Upon
%restart it goes to a random non-crawled page and starts there. So
%each successive run of {\bf spider.py} is additive.
\beforeverb
\begin{verbatim}
Enter web url or enter: http://www.dr-chuck.com/
['http://www.dr-chuck.com']
How many pages:3
3 http://www.dr-chuck.com/csev-blog 57
4 http://www.dr-chuck.com/dr-chuck/resume/speaking.htm 1
5 http://www.dr-chuck.com/dr-chuck/resume/index.htm 13
How many pages:
\end{verbatim}
\afterverb
%
Você pode ter múltiplos pontos de start no mesmo banco de dados, dentro
do programa, eles são chamados ``webs''. O programa escolhe randomicamente
um dos links que ainda não foi visitado através de toda a web como sendo
a próxima página a ser visitada.
%You can have multiple starting points in the same database---within
%the program, these are called ``webs''. The spider
%chooses randomly amongst all non-visited links across all
%the webs as the next page to spider.
Se você quer visualizar o conteúdo do arquivo {\bf spider.sqlite}, você pode
rodar o programa {\bf spdump.py}, como segue:
%If you want to dump the contents of the {\bf spider.sqlite} file, you can
%run {\bf spdump.py} as follows:
\beforeverb
\begin{verbatim}
(5, None, 1.0, 3, u'http://www.dr-chuck.com/csev-blog')
(3, None, 1.0, 4, u'http://www.dr-chuck.com/dr-chuck/resume/speaking.htm')
(1, None, 1.0, 2, u'http://www.dr-chuck.com/csev-blog/')
(1, None, 1.0, 5, u'http://www.dr-chuck.com/dr-chuck/resume/index.htm')
4 rows.
\end{verbatim}
\afterverb
%
Isto mostra o número de links visitados, o antigo page rank, o novo page
rank, o id da página, e a url da página. O programa {\bf spdump.py} mostra somente
páginas que tem pelo menos um link que já foi visitado.
%This shows the number of incoming links, the old page rank, the new page
%rank, the id of the page, and the url of the page. The {\bf spdump.py} program
%only shows pages that have at least one incoming link to them.
Uma vez que você tem algumas páginas no banco de dados, você pode rodar o page
rank nas páginas usando o programa {\bf sprank.py}. Você apenas diz quantas
iterações de páginas devem ser executadas.
%Once you have a few pages in the database, you can run page rank on the
%pages using the {\bf sprank.py} program. You simply tell it how many page
%rank iterations to run.
\beforeverb
\begin{verbatim}
How many iterations:2
1 0.546848992536
2 0.226714939664
[(1, 0.559), (2, 0.659), (3, 0.985), (4, 2.135), (5, 0.659)]
\end{verbatim}
\afterverb
%
Você pode analisar o banco de dados novamente para ver se o page rank foi
atualizado:
%You can dump the database again to see that page rank has been updated:
\beforeverb
\begin{verbatim}
(5, 1.0, 0.985, 3, u'http://www.dr-chuck.com/csev-blog')
(3, 1.0, 2.135, 4, u'http://www.dr-chuck.com/dr-chuck/resume/speaking.htm')
(1, 1.0, 0.659, 2, u'http://www.dr-chuck.com/csev-blog/')
(1, 1.0, 0.659, 5, u'http://www.dr-chuck.com/dr-chuck/resume/index.htm')
4 rows.
\end{verbatim}
\afterverb
%
Você pode rodar o {\bf sprank.py} quantas vezes quiser, isto irá apenas refinar
o page rank cada vez que você executar. Pode até mesmo rodar o {\bf sprank.py} um
pequeno número de vezes e então recuperar mais algumas páginas com o {\bf spider.py}
e então rodar o {\bf sprank.py} para recuperar os valores do page rank. Um motor de
pesquisa geralmente roda os programas de recuperação e rankeamento ao mesmo tempo.
%You can run {\bf sprank.py} as many times as you like and it will simply refine
%the page rank each time you run it. You can even run {\bf sprank.py} a few times
%and then go spider a few more pages sith {\bf spider.py} and then run {\bf sprank.py}
%to reconverge the page rank values. A search engine usually runs both the crawling and
%ranking programs all the time.
Se você quiser reiniciar os cálculos de page rank sem fazer a extração das páginas
web novamente, você pode usar o {\bf spreset.py} e então reiniciar o {\bf sprank.py}.
%If you want to restart the page rank calculations without respidering the
%web pages, you can use {\bf spreset.py} and then restart {\bf sprank.py}.
\beforeverb
\begin{verbatim}
How many iterations:50
1 0.546848992536
2 0.226714939664
3 0.0659516187242
4 0.0244199333
5 0.0102096489546
6 0.00610244329379
...
42 0.000109076928206
43 9.91987599002e-05
44 9.02151706798e-05
45 8.20451504471e-05
46 7.46150183837e-05
47 6.7857770908e-05
48 6.17124694224e-05
49 5.61236959327e-05
50 5.10410499467e-05
[(512, 0.0296), (1, 12.79), (2, 28.93), (3, 6.808), (4, 13.46)]
\end{verbatim}
\afterverb
%
Para cada iteração do algoritmo de page rank, ele imprime a média
de modificações no page rank por página. A rede inicia-se
desbalanceada e então os valores do page rank individual mudam
com velocidade entre as iterações. Mas em poucas iterações, o page rank
coverge. Você deve rodar o {\bf prank.py} por tempo suficiente para
que os valores de page rank possam convergir.
%For each iteration of the page rank algorithm it prints the average
%change in page rank per page. The network initially is quite
%unbalanced and so the individual page rank values change wildly between
%iterations. But in a few short iterations, the page rank converges. You
%should run {\bf prank.py} long enough that the page rank values converge.
Se você quiser visualizar as primeiras páginas no rank, rode o {\bf spjson.py}
para ler o banco de dados e escrever os dados dos links com maior pontuação
no formato JSON para serem vistos no web browser.
%If you want to visualize the current top pages in terms of page rank,
%run {\bf spjson.py} to read the database and write the data for the
%most highly linked pages in JSON format to be viewed in a
%web browser.
\beforeverb
\begin{verbatim}
Creating JSON output on spider.json...
How many nodes? 30
Open force.html in a browser to view the visualization
\end{verbatim}
\afterverb
%\beforeverb
%\begin{verbatim}
%Creating JSON output on spider.json...
%How many nodes? 30
%Open force.html in a browser to view the visualization
%\end{verbatim}
%\afterverb
%
Você pode visualizar este dado abrindo o arquivo {\bf force.html} em seu web
browser. Isto mostra um layout automático de nós e links. Você pode clicar e
arrastar qualquer nó e também dar um duplo clique no nó para encontrar a URL
que ele representa.
%You can view this data by opening the file {\bf force.html} in your web browser.
%This shows an automatic layout of the nodes and links. You can click and
%drag any node and you can also double-click on a node to find the URL
%that is represented by the node.
Se você rodar novamente algum script, lembre-se de rodar também o
{\bf spjson.py} e pressionar o botão de refresh no browser para ler
os novos dados do arquivo {\bf spider.json}.
%If you rerun the other utilities, rerun {\bf spjson.py} and
%press refresh in the browser to get the new data from {\bf spider.json}.
\section{Visualizando dados de e-mail}
%\section{Visualizing mail data}
Até este ponto do livro, esperamos que você já tenha se familiarizado com os
nossos arquivos de dados, {\bf mbox-short.txt} e {\bf mbox.txt}. Agora
é hora de levar a nossa análise de e-mails para um próximo nível.
%Up to this point in the book, you have become quite familiar with our
%{\bf mbox-short.txt} and {\bf mbox.txt} data files. Now it is time to take
%our analysis of email data to the next level.
No mundo real, às vezes você tem que baixar dados de e-mails dos servidores.
Isto pode levar um bom tempo e talvez o dado seja inconsistente, com erros
de preenchimento, e precisem de muitas limpezas e ajustes. Nesta seção, nós
trabalharemos com uma aplicação que é muito complexa e baixa aproximadamente
um gigabyte de dados e faz a leitura.
%In the real world, sometimes you have to pull down mail data from servers.
%That might take quite some time and the data might be inconsistent,
%error-filled, and need a lot of cleanup or adjustment. In this section, we
%work with an application that is the most complex so far and pull down nearly a
%gigabyte of data and visualize it.
\beforefig
\centerline{\includegraphics[height=2.50in]{figs2/wordcloud.eps}}
\afterfig
Você pode fazer o download desta aplicação em:
%You can download this application from:
\url{www.py4inf.com/code/gmane.zip}
Nós utilizaremos dados de um serviço de arquivamento de listas de e-mails
gratuita chamado \url{www.gmane.org}. Este serviço é muito popular em projetos
open source porque disponibiliza uma vasta coleção pesquisável de arquivos sobre
a atividade de e-mail deles. Eles também tem uma política liberal em relação
ao acesso de seus dados através de sua API. Não tem taxas de limites, mas pedem
para que você não sobrecarregue os seus serviços e pegue apenas os dados
que você precise. Você pode ler os termos e condições do gname nesta página:
%We will be using data from a free email list archiving service called
%\url{www.gmane.org}. This service is very popular with open source
%projects because it provides a nice searchable archive of their
%email activity. They also have a very liberal policy regarding accessing
%their data through their API. They have no rate limits, but ask that you
%don't overload their service and take only the data you need. You can read
%gmane's terms and conditions at this page:
\url{http://gmane.org/export.php}
{\em É muito importante que você faça uso dos dados do gname.org com
responsabilidade adicionando delays no acesso ao serviço deles e
espalhando tarefas de longa duração em um longo período de tempo.
Não abuse deste serviço gratuito, arruinando-o para o resto de nós.}
%{\em It is very important that you make use of the gmane.org data
%responsibly by adding delays to your access of their services and spreading
%long-running jobs over a longer period of time. Do not abuse this free service
%and ruin it for the rest of us.}
Quando os dados de e-mail do Sakai foram vasculhados usando este software,
produziu aproximadamente um Gigabyte de dados e executou muitas vezes
durante vários dias.
O arquivo {\bf README.txt} no arquivo ZIP acima, pode ter instruções sobre
como você pode fazer download de uma cópia preparada previamente através do
arquivo {\bf content.sqlite} para a maioria dos corpos dos e-mails Sakai, assim
você não precisa coletar os dados por cinco dias apenas para rodar seus programas.
Se você baixar conteúdos pré preparados, você ainda pode rodar o processo de coleta
para pegar mensagens mais recentes.
%When the Sakai email data was spidered using this software, it produced nearly
%a Gigabyte of data and took a number of runs on several days.
%The file {\bf README.txt} in the above ZIP may have instructions as to how
%you can download a pre-spidered copy of the {\bf content.sqlite} file for
%a majority of the Sakai email corpus so you don't have to spider for
%five days just to run the programs. If you download the pre-spidered
%content, you should still run the spidering process to catch up with
%more recent messages.
O primeiro passo é fazer uma coleta no repositório gname. A URL base
está fixa dentro do arquivo {\bf gmane.py} e está apontando para a lista
de desenvolvedores do Sakai. Você pode coletar outro repositório apenas
mudando a url base. Certifique-se de deletar o arquivo {\bf content.sqlite}
se você trocar a url base.
%The first step is to spider the gmane repository. The base URL
%is hard-coded in the {\bf gmane.py} and is hard-coded to the Sakai
%developer list. You can spider another repository by changing that
%base url. Make sure to delete the {\bf content.sqlite} file if you
%switch the base url.
O arquivo {\bf gmane.py} funciona como um cache spider responsável,
executando lentamente e retornando uma mensagem de e-mail por segundo,
não sendo bloqueado desta forma pelo site gname. Ele armazena todos os
seus dados em um banco de dados e pode ser interrompido e reiniciado
quantas vezes forem necessárias. Pode levar muitas horas para baixar
todos os dados. Você pode precisar reiniciar muitas vezes.
%The {\bf gmane.py} file operates as a responsible caching spider in
%that it runs slowly and retrieves one mail message per second so
%as to avoid getting throttled by gmane. It stores all of
%its data in a database and can be interrupted and restarted
%as often as needed. It may take many hours to pull all the data
%down. So you may need to restart several times.
Aqui está uma execução do {\bf gmane.py} retornando as últimas cinco
mensagens da lista de desenvolvedores do Sakai:
%Here is a run of {\bf gmane.py} retrieving the last five messages of the
%Sakai developer list:
\beforeverb
\begin{verbatim}
How many messages:10
http://download.gmane.org/gmane.comp.cms.sakai.devel/51410/51411 9460
nealcaidin@sakaifoundation.org 2013-04-05 re: [building ...
http://download.gmane.org/gmane.comp.cms.sakai.devel/51411/51412 3379
samuelgutierrezjimenez@gmail.com 2013-04-06 re: [building ...
http://download.gmane.org/gmane.comp.cms.sakai.devel/51412/51413 9903
da1@vt.edu 2013-04-05 [building sakai] melete 2.9 oracle ...
http://download.gmane.org/gmane.comp.cms.sakai.devel/51413/51414 349265
m.shedid@elraed-it.com 2013-04-07 [building sakai] ...
http://download.gmane.org/gmane.comp.cms.sakai.devel/51414/51415 3481
samuelgutierrezjimenez@gmail.com 2013-04-07 re: ...
http://download.gmane.org/gmane.comp.cms.sakai.devel/51415/51416 0
Does not start with From
\end{verbatim}
\afterverb
%
O programa escaneia o {\bf content.sqlite} e inicia a execução a partir da primeira
mensagem que ainda não foi processada. Ele continua coletando até chegar ao número
desejado de mensagens ou atingir uma página que possuir uma mensagem fora do padrão.
%The program scans {\bf content.sqlite} from one up to the first message number not
%already spidered and starts spidering at that message. It continues spidering
%until it has spidered the desired number of messages or it reaches a page
%that does not appear to be a properly formatted message.
Às vezes o \url{gmane.org} perde alguma mensagem. Seja pelos administradores que deletaram
uma mensagem ou então porque se perdeu mesmo. Se seu programa para, e parece que ele perdeu alguma
mensagem, vá para o administrador SQLite e adicione uma linha com o id que está faltando,
deixando todos os outros campos em branco e reinicie o {\bf gmane.py}. Isto irá liberar o
seu programa para continuar a execução. Estas mensagens vazias serão ignoradas na próxima
fase do processo.
%Sometimes \url{gmane.org} is missing a message. Perhaps administrators can delete messages
%or perhaps they get lost. If your spider stops, and it seems it has hit
%a missing message, go into the SQLite Manager and add a row with the missing id leaving
%all the other fields blank and restart {\bf gmane.py}. This will unstick the
%spidering process and allow it to continue. These empty messages will be ignored in the next
%phase of the process.
Uma coisa legal é que uma vez que você coletou todas as mensagens e tem elas dentro do
{\bf content.sqlite}, você pode rodar o {\bf gmane.py} novamente para pegar as últimas
mensagens novas enviadas para a lista.
%One nice thing is that once you have spidered all of the messages and have them in
%{\bf content.sqlite}, you can run {\bf gmane.py} again to get new messages as
%they are sent to the list.
Os dados do {\bf content.sqlite} são um pouco crus, com um modelo de dados ineficiente
e não comprimido.
Isto é intencional, pois permite a você olhar o conteúdo do {\bf content.sqlite}
no SQLite Manager para depurar problemas que ocorreram no processo de coleta.
Seria uma má ideia rodar qualquer tipo de consulta neste banco de dados, pois
poderia demorar.
%The {\bf content.sqlite} data is pretty raw, with an inefficient data model,
%and not compressed.
%This is intentional as it allows you to look at {\bf content.sqlite}
%in the SQLite Manager to debug problems with the spidering process.
%It would be a bad idea to run any queries against this database, as they
%would be quite slow.
O segundo processo é rodar o programa {\bf gmodel.py}. Este programa lê os dados crus do
{\bf content.sqlite} e produz uma versão bem modelada dos dados no arquivo {\bf index.sqlite}.
Este arquivo será muito menor (quase 10 vezes menor) do que o {\bf index.sqlite}, porque
comprime o corpo e o cabeçalho do texto.
%The second process is to run the program {\bf gmodel.py}. This program reads the raw
%data from {\bf content.sqlite} and produces a cleaned-up and well-modeled version of the
%data in the file {\bf index.sqlite}. This file will be much smaller (often 10X
%smaller) than {\bf content.sqlite} because it also compresses the header and body text.
Cada vez que o {\bf gmodel.py} roda, ele deleta e refaz o arquivo {\bf index.sqlite},
permitindo a você ajustar os parâmetros e editar as tabelas de mapeamento no {\bf content.sqlite}
para ajustar o processo de limpeza dos dados. Esta é uma amostra da execução do {\bf gmodel.py}.
Ele imprime uma linha por vez, 250 mensagens de e-mail são processadas, assim você pode ver
algum progresso acontecendo, como este programa pode rodar por um longo tempo, é muito
fácil conseguir um arquivo de e-mail de um Gigabyte de dados.
%Each time {\bf gmodel.py} runs it deletes and rebuilds {\bf index.sqlite}, allowing
%you to adjust its parameters and edit the mapping tables in {\bf content.sqlite} to tweak the
%data cleaning process. This is a sample run of {\bf gmodel.py}. It prints a line out each time
%250 mail messages are processed so you can see some progress happening, as this program may
%run for a while processing nearly a Gigabyte of mail data.
\beforeverb
\begin{verbatim}
Loaded allsenders 1588 and mapping 28 dns mapping 1
1 2005-12-08T23:34:30-06:00 ggolden22@mac.com
251 2005-12-22T10:03:20-08:00 tpamsler@ucdavis.edu
501 2006-01-12T11:17:34-05:00 lance@indiana.edu
751 2006-01-24T11:13:28-08:00 vrajgopalan@ucmerced.edu
...
\end{verbatim}
\afterverb
%
O programa {\bf gmodel.py} trata um número de tarefas de limpeza de dados.
%The {\bf gmodel.py} program handles a number of data cleaning tasks.
Nomes de domínios são truncados para dois níveis para .com, .org, .edu, e .net.
Outros nomes de domínios são truncados para três níveis. Assim si.umich.edu
se transforma em umich.edu e caret.cam.ac.uk se transforma em cam.ac.uk.
Endereços de e-mail também são forçados para minúsculo, seguem alguns endereços
do @gmane.org, por exemplo:
%Domain names are truncated to two levels for .com, .org, .edu, and .net.
%Other domain names are truncated to three levels. So si.umich.edu becomes
%umich.edu and caret.cam.ac.uk becomes cam.ac.uk. Email addresses are also
%forced to lower case, and some of the @gmane.org address like the following
\beforeverb
\begin{verbatim}
arwhyte-63aXycvo3TyHXe+LvDLADg@public.gmane.org
\end{verbatim}
\afterverb
%
são convertidos para endereços reais a qualquer hora que ocorrer um encontro
real de endereço de e-mail em qualquer lugar no corpo da mensagem.
%are converted to the real address whenever there is a matching real email
%address elsewhere in the message corpus.
No banco de dados {\bf content.sqlite}, há duas tabelas que permitem a você
mapear ambos os nomes de domínio e os endereços de e-mail individuais que mudam
ao longo do tempo da lista. Por exemplo, Steve Githens usou os seguintes endereços
de e-mail conforme foi mudando de emprego na lista de desenvolvedores Sakai:
%In the {\bf content.sqlite} database there are two tables that allow
%you to map both domain names and individual email addresses that change over
%the lifetime of the email list. For example, Steve Githens used the following
%email addresses as he changed jobs over the life of the Sakai developer list:
\beforeverb
\begin{verbatim}
s-githens@northwestern.edu
sgithens@cam.ac.uk
swgithen@mtu.edu
\end{verbatim}
\afterverb
%
Nós podemos adicionar duas entradas na tabela de mapeamento em {\bf content.sqlite},
assim o {\bf gmodel.py} irá mapear todos os três para um único endereço:
%We can add two entries to the Mapping table in {\bf content.sqlite} so
%{\bf gmodel.py} will map all three to one address:
\beforeverb
\begin{verbatim}
s-githens@northwestern.edu -> swgithen@mtu.edu
sgithens@cam.ac.uk -> swgithen@mtu.edu
\end{verbatim}
\afterverb
%
Você pode criar entradas similares na tabela de mapeamento DNS se possuir múltiplos
nomes DNS mapeados para um DNS simples. O seguinte mapeamento foi adicionado para os
dados Sakai:
%You can also make similar entries in the DNSMapping table if there are multiple
%DNS names you want mapped to a single DNS. The following mapping was added to the Sakai data:
\beforeverb
\begin{verbatim}
iupui.edu -> indiana.edu
\end{verbatim}
\afterverb
%
assim todas as contas de vários campus da Universidade de Indiana são atreladas juntas.
%so all the accounts from the various Indiana University campuses are tracked together.
Você pode reexecutar o {\bf gmodel.py} de novo e de novo conforme olhar para os dados e
adicionar mapeamentos para tornar os dados mais limpos. Quando você acabar, terá uma
agradável versão indexada dos e-mails em {\bf index.sqlite}. Este é o arquivo para se fazer
análise dos dados. Com este arquivo, a análise dos dados será muito rápida.
%You can rerun the {\bf gmodel.py} over and over as you look at the data, and add mappings
%to make the data cleaner and cleaner. When you are done, you will have a nicely
%indexed version of the email in {\bf index.sqlite}. This is the file to use to do data
%analysis. With this file, data analysis will be really quick.
A primeira, análise simples dos dados é para determinar "quem enviou mais e-mails?" e
"qual organização enviou mais e-mails?" Isto é feito usando o {\bf gbasic.py}:
%The first, simplest data analysis is to determine "who sent the most mail?" and "which
%organization sent the most mail"? This is done using {\bf gbasic.py}:
\beforeverb
\begin{verbatim}
How many to dump? 5
Loaded messages= 51330 subjects= 25033 senders= 1584
Top 5 Email list participants
steve.swinsburg@gmail.com 2657
azeckoski@unicon.net 1742
ieb@tfd.co.uk 1591
csev@umich.edu 1304
david.horwitz@uct.ac.za 1184
Top 5 Email list organizations
gmail.com 7339
umich.edu 6243
uct.ac.za 2451
indiana.edu 2258
unicon.net 2055
\end{verbatim}
\afterverb
%
Observe quão mais rápido o {\bf gbasic.py} executa quando comparado ao {\bf gmane.py}
ou até mesmo ao {\bf gmodel.py}. Eles todos trabalham no mesmo dado, mas o {\bf gbasic.py}
está usando dados normalizados e comprimidos em {\bf index.sqlite}. Se você tiver
muitos dados para gerenciar, um processo multi-passos assim como estes nesta aplicação
podem levar mais tempo para serem desenvolvidos, mas irão economizar muito tempo
quando você começar a explorar e visualizar os seus dados.
%Note how much more quickly {\bf gbasic.py} runs compared to {\bf gmane.py}
%or even {\bf gmodel.py}. They are all working on the same data, but
%{\bf gbasic.py} is using the compressed and normalized data in
%{\bf index.sqlite}. If you have a lot of data to manage, a multistep
%process like the one in this application may take a little longer to develop,
%but will save you a lot of time when you really start to explore
%and visualize your data.
Você pode produzir uma simples visualização da frequência das palavras nas
linhas do arquivo {\bf gword.py}:
%You can produce a simple visualization of the word frequency in the subject lines
%in the file {\bf gword.py}:
\beforeverb
\begin{verbatim}
Range of counts: 33229 129
Output written to gword.js
\end{verbatim}
\afterverb
%
Isto produz o arquivo {\bf gword.js}, o qual você pode visualizar usando
o {\bf gword.htm} para produzir uma nuvem de palavras similares àquelas
no início desta seção.
%This produces the file {\bf gword.js} which you can visualize using
%{\bf gword.htm} to produce a word cloud similar to the one at the beginning
%of this section.
Uma segunda visualização foi produzida pelo {\bf gline.py}. Ele computa a
participação das organizações por e-mail ao longo do tempo.
%A second visualization is produced by {\bf gline.py}. It computes email
%participation by organizations over time.
\beforeverb
\begin{verbatim}
Loaded messages= 51330 subjects= 25033 senders= 1584
Top 10 Oranizations
['gmail.com', 'umich.edu', 'uct.ac.za', 'indiana.edu',
'unicon.net', 'tfd.co.uk', 'berkeley.edu', 'longsight.com',
'stanford.edu', 'ox.ac.uk']
Output written to gline.js
\end{verbatim}
\afterverb
%
Sua saída é escrita para {\bf gline.js}, o qual é visualizada usando {\bf gline.htm}.
%Its output is written to {\bf gline.js} which is visualized using {\bf gline.htm}.
\beforefig
\centerline{\includegraphics[height=2.50in]{figs2/mailorg.eps}}
\afterfig
Esta é uma aplicação relativamente complexa e sofisticada e têm características
para se fazer uma coleta real de dados, limpeza e visualização.
%This is a relatively complex and sophisticated application and
%has features to do some real data retrieval, cleaning, and visualization.