1==========================================
2Examplos para o processamento do portugu�s
3==========================================
4
5    >>> import nltk
6
7(NB. Este material parte do pressuposto de que o leitor esteja
8familiarizado com o livro do NLTK, dispon�vel em
9``http://nltk.org/index.php/Book``).
10
11Utilizando o Corpus MacMorpho Tagged
12------------------------------------
13
14O NLTK inclui o corpus de not�cias para o portugu�s brasileiro com tags de partes do discurso
15MAC-MORPHO, que conta com mais de um milh�o de palavras de textos jornal�sticos extra�dos
16de dez se��es do jornal di�rio *Folha de S�o Paulo*, do ano de 1994.
17
18Podemos utilizar este corpus como uma seq��ncia de palavras ou de palavras com tags da
19seguinte maneira:
20
21    >>> nltk.corpus.mac_morpho.words()
22    ['Jersei', 'atinge', 'm\xe9dia', 'de', 'Cr$', '1,4', ...]
23    >>> nltk.corpus.mac_morpho.sents()
24    [['Jersei', 'atinge', 'm\xe9dia', 'de', 'Cr$', '1,4', 'milh\xe3o',
25    'em', 'a', 'venda', 'de', 'a', 'Pinhal', 'em', 'S\xe3o', 'Paulo'],
26    ['Programe', 'sua', 'viagem', 'a', 'a', 'Exposi\xe7\xe3o', 'Nacional',
27    'do', 'Zebu', ',', 'que', 'come\xe7a', 'dia', '25'], ...]
28    >>> nltk.corpus.mac_morpho.tagged_words()
29    [('Jersei', 'N'), ('atinge', 'V'), ('m\xe9dia', 'N'), ...]
30
31Tamb�m � poss�vel utiliz�-lo em chunks de frases.
32
33    >>> nltk.corpus.mac_morpho.tagged_sents()
34    [[('Jersei', 'N'), ('atinge', 'V'), ('m\xe9dia', 'N'), ('de', 'PREP'),
35    ('Cr$', 'CUR'), ('1,4', 'NUM'), ('milh\xe3o', 'N'), ('em', 'PREP|+'),
36    ('a', 'ART'), ('venda', 'N'), ('de', 'PREP|+'), ('a', 'ART'),
37    ('Pinhal', 'NPROP'), ('em', 'PREP'), ('S\xe3o', 'NPROP'), ('Paulo', 'NPROP')],
38    [('Programe', 'V'), ('sua', 'PROADJ'), ('viagem', 'N'), ('a', 'PREP|+'),
39    ('a', 'ART'), ('Exposi\xe7\xe3o', 'NPROP'), ('Nacional', 'NPROP'),
40    ('do', 'NPROP'), ('Zebu', 'NPROP'), (',', ','), ('que', 'PRO-KS-REL'),
41    ('come\xe7a', 'V'), ('dia', 'N'), ('25', 'N|AP')], ...]
42
43Estes dados podem ser utilizados para efetuar o treinamento de taggers (como nos
44exemplos abaixo para o Floresta treebank).
45
46
47Utilizando o Floresta Portuguese Treebank
48-----------------------------------------
49
50A distribui��o de dados do NLTK inclui o
51"Floresta Sinta(c)tica Corpus" na vers�o 7.4, dispon�vel em
52``http://www.linguateca.pt/Floresta/``.
53
54Como para a amostra do Penn Treebank, � poss�vel
55utilizar o conte�do deste corpus como uma seq��ncia de palavras com
56informa��es de tags, da seguinte maneira:
57
58    >>> from nltk.corpus import floresta
59    >>> floresta.words()
60    ['Um', 'revivalismo', 'refrescante', 'O', '7_e_Meio', ...]
61    >>> floresta.tagged_words()
62    [('Um', '>N+art'), ('revivalismo', 'H+n'), ...]
63
64As tags s�o constitu�das por certas informa��es sint�ticas, seguidas por
65um sinal
66de mais, seguido por tag costumeira de parte do discurso
67(part-of-speech). Vamos
68remover o conte�do que antecede o sinal de mais:
69
70    >>> def simplify_tag(t):
71    ...     if "+" in t:
72    ...         return t[t.index("+")+1:]
73    ...     else:
74    ...         return t
75    >>> twords = nltk.corpus.floresta.tagged_words()
76    >>> twords = [(w.lower(),simplify_tag(t)) for (w,t) in twords]
77    >>> twords[:10] # doctest: +NORMALIZE_WHITESPACE
78    [('um', 'art'), ('revivalismo', 'n'), ('refrescante', 'adj'), ('o', 'art'), ('7_e_meio', 'prop'),
79    ('\xe9', 'v-fin'), ('um', 'art'), ('ex-libris', 'n'), ('de', 'prp'), ('a', 'art')]
80
81E exibir de maneira mais apropriada as palavras com informa��es de tags:
82
83    >>> print ' '.join(word + '/' + tag for (word, tag) in twords[:10])
84    um/art revivalismo/n refrescante/adj o/art 7_e_meio/prop ?/v-fin um/art ex-libris/n de/prp a/art
85
86Em seguida, vamos contar o n�mero de tokens de palavras e tipos, al�m de
87determinar qual a palavra mais comum:
88
89    >>> words = floresta.words()
90    >>> len(words)
91    211870
92    >>> fd = nltk.FreqDist(words)
93    >>> len(fd)
94    29425
95    >>> fd.max()
96    'de'
97
98Podemos tamb�m listar as 20 tags mais freq�entes, em ordem decrescente de
99freq��ncia:
100
101    >>> tags = [simplify_tag(tag) for (word,tag) in floresta.tagged_words()]
102    >>> fd = nltk.FreqDist(tags)
103    >>> fd.sorted()[:20] # doctest: +NORMALIZE_WHITESPACE
104    ['n', 'prp', 'art', 'v-fin', ',', 'prop', 'adj', 'adv', '.', 'conj-c', 'v-inf',
105    'pron-det', 'v-pcp', 'num', 'pron-indp', 'pron-pers', '\xab', '\xbb', 'conj-s', '}']
106
107Tamb�m podemos ler o corpus agrupado por enunciados:
108
109    >>> floresta.sents() # doctest: +NORMALIZE_WHITESPACE
110    [['Um', 'revivalismo', 'refrescante'], ['O', '7_e_Meio', '\xe9', 'um', 'ex-libris',
111    'de', 'a', 'noite', 'algarvia', '.'], ...]
112    >>> floresta.tagged_sents() # doctest: +NORMALIZE_WHITESPACE
113    [[('Um', '>N+art'), ('revivalismo', 'H+n'), ('refrescante', 'N<+adj')],
114    [('O', '>N+art'), ('7_e_Meio', 'H+prop'), ('\xe9', 'P+v-fin'), ('um', '>N+art'),
115    ('ex-libris', 'H+n'), ('de', 'H+prp'), ('a', '>N+art'), ('noite', 'H+n'),
116    ('algarvia', 'N<+adj'), ('.', '.')], ...]
117    >>> floresta.parsed_sents() # doctest: +NORMALIZE_WHITESPACE
118    [Tree('UTT+np', [Tree('>N+art', ['Um']), Tree('H+n', ['revivalismo']),
119    Tree('N<+adj', ['refrescante'])]), Tree('STA+fcl', [Tree('SUBJ+np',
120    [Tree('>N+art', ['O']), Tree('H+prop', ['7_e_Meio'])]), Tree('P+v-fin', ['\xe9']),
121    Tree('SC+np', [Tree('>N+art', ['um']), Tree('H+n', ['ex-libris']),
122    Tree('N<+pp', [Tree('H+prp', ['de']), Tree('P<+np', [Tree('>N+art', ['a']),
123    Tree('H+n', ['noite']), Tree('N<+adj', ['algarvia'])])])]), Tree('.', ['.'])]), ...]
124
125Para ver uma �rvore de an�lise sint�tica, podemos utilizar o m�todo
126``draw()``, como no exemplo:
127
128    >>> psents = floresta.parsed_sents()
129    >>> psents[5].draw() # doctest: +SKIP
130
131
132Concord�ncia simples
133--------------------
134
135A seguir, apresentamos uma fun��o que recebe uma palavra e uma
136quantidade determinada
137de contexto (medido em caracteres) e gera uma concord�ncia para a mesma.
138
139    >>> def concordance(word, context=30):
140    ...     for sent in floresta.sents():
141    ...         if word in sent:
142    ...             pos = sent.index(word)
143    ...             left = ' '.join(sent[:pos])
144    ...             right = ' '.join(sent[pos+1:])
145    ...             print '%*s %s %-*s' %\
146    ...                 (context, left[-context:], word, context, right[:context])
147
148    >>> concordance("dar") # doctest: +SKIP
149    anduru , foi o suficiente para dar a volta a o resultado .
150                 1. O P?BLICO veio dar a a imprensa di?ria portuguesa
151      A fartura de pensamento pode dar maus resultados e n?s n?o quer
152                          Come?a a dar resultados a pol?tica de a Uni
153    ial come?ar a incorporar- lo e dar forma a um ' site ' que tem se
154    r com Constantino para ele lhe dar tamb?m os pap?is assinados .
155    va a brincar , pois n?o lhe ia dar procura??o nenhuma enquanto n?
156    ?rica como o ant?doto capaz de dar sentido a o seu enorme poder .
157    . . .
158    >>> concordance("vender") # doctest: +SKIP
159    er recebido uma encomenda para vender 4000 blindados a o Iraque .
160    m?rico_Amorim caso conseguisse vender o lote de ac??es de o empres?r
161    mpre ter jovens simp?ticos a ? vender ? chega ! }
162           Disse que o governo vai vender ? desde autom?vel at? particip
163    ndiciou ontem duas pessoas por vender carro com ?gio .
164            A inten??o de Fleury ? vender as a??es para equilibrar as fi
165
166Tagging de partes do discurso
167-----------------------------
168
169Vamos come�ar obtendo os dados dos enunciados marcados com tags e
170simplificando
171estas �ltimas como descrito anteriormente.
172
173    >>> from nltk.corpus import floresta
174    >>> tsents = floresta.tagged_sents()
175    >>> tsents = [[(w.lower(),simplify_tag(t)) for (w,t) in sent] for sent in tsents if sent]
176    >>> train = tsents[100:]
177    >>> test = tsents[:100]
178
179J� sabemos que ``n`` � a tag mais comum; desta forma, podemos criar um
180tagger por default
181que marque toda palavra como substantivo e, em seguida, avaliar seu
182desempenho:
183
184    >>> tagger0 = nltk.DefaultTagger('n')
185    >>> nltk.tag.accuracy(tagger0, test)
186    0.17690941385435169
187
188Como pode-se deduzir facilmente, uma em cada seis palavras � um
189substantivo. Vamos
190aperfei�oar estes resultados treinando um tagger unigrama:
191
192    >>> tagger1 = nltk.UnigramTagger(train, backoff=tagger0)
193    >>> nltk.tag.accuracy(tagger1, test)
194    0.85115452930728241
195
196E, em seguida, um tagger bigrama:
197
198    >>> tagger2 = nltk.BigramTagger(train, backoff=tagger1)
199    >>> nltk.tag.accuracy(tagger2, test)
200    0.86856127886323264
201
202Segmenta��o de frases
203---------------------
204
205O Punkt � uma ferramenta para segmenta��o de frases ling�isticamente independente, o qual
206requer um treinamento em texto puro.
207O texto de origem (obtido do Floresta Portuguese Treebank) cont�m uma frase por linha. Podemos
208ler o texto, dividi-lo em fun��o de suas linhas e ent�o agrupar estas linhas utilizando
209espa�os. Desta forma as informa��es sobre quebras de frases ter�o sido descartadas; podemos
210ent�o dividir este material em dados para treinamento e para verifica��o:
211
212    >>> text = open('floresta.txt').read()
213    >>> lines = text.split('\n')
214    >>> train = ' '.join(lines[10:])
215    >>> test = ' '.join(lines[:10])
216
217� agora poss�vel treinar o segmentador de frases (ou tokenizador de frases) e utiliz�-lo em
218nossas frases de verifica��o. (Para exibir o texto em uma forma leg�vel, pode ser necess�rio
219converter o texto para o UTF-8, utilizando ``print sent.decode('latin-1').encode('utf-8')``.)
220
221    >>> stok = nltk.PunktSentenceTokenizer(train)
222    >>> for sent in stok.tokenize(test):
223    ...     print sent
224
225
226As vers�es do NLTK a partir da 0.9b1 incluem um modelo treinado para a segmenta��o de frases
227em portugu�s, o qual pode ser carregado pela maneira a seguir. � mais r�pido carregar um modelo
228j� treinado do que repetir o treinamento do mesmo.
229
230    >>> stok = nltk.data.load('tokenizers/punkt/portuguese.pickle')
231
232Stemming
233--------
234
235O NLTK inclui o stemmer para o portugu�s RSLP. Vamos demonstrar sua utiliza��o para algumas
236palavras em portugu�s:
237
238    >>> stemmer = nltk.stem.RSLPStemmer()
239    >>> stemmer.stem("copiar")
240    u'copi'
241    >>> stemmer.stem("paisagem")
242    u'pais'
243
244Stopwords
245---------
246
247O NLTK inclui stopword ("palavras limite") para o portugu�s:
248
249    >>> stopwords = nltk.corpus.stopwords.words('portuguese')
250    >>> stopwords[:10]
251    ['a', 'ao', 'aos', 'aquela', 'aquelas', 'aquele', 'aqueles', 'aquilo', 'as', 'at\xe9']
252
253A esta altura, � poss�vel utiliz�-las para filtrar textos. Vamos encontrar as palavras mais
254comuns (� exce��o das stopwords) e list�-las em ordem decrescente de freq��ncia:
255
256    >>> fd = nltk.FreqDist(w.lower() for w in floresta.words() if w not in stopwords)
257    >>> for word in fd.sorted()[:20]:
258    ...     print word, fd[word]
259    , 13444
260    . 7725
261    ? 2369
262    ? 2310
263    ? 1137
264    o 1086
265    } 1047
266    { 1044
267    a 897
268    ; 633
269    em 516
270    ser 466
271    sobre 349
272    os 313
273    anos 301
274    ontem 292
275    ainda 279
276    segundo 256
277    ter 249
278    dois 231
279
280
281Codifica��es de caracteres
282--------------------------
283
284O Python � capaz de lidar com todas a codifica��es de caracteres mais utilizada para o portugu�s, a
285ISO 8859-1 (ISO Latin 1).
286
287    >>> text = open('floresta.txt').read()
288    >>> text[:60]
289    'O 7 e Meio \xe9 um ex-libris da noite algarvia.\n\xc9 uma das mais '
290    >>> print text[:60]
291    O 7 e Meio ? um ex-libris da noite algarvia.
292    ? uma das mais
293    >>> text[:60].decode('latin-1')
294    u'O 7 e Meio \xe9 um ex-libris da noite algarvia.\n\xc9 uma das mais '
295    >>> text[:60].decode('latin-1').encode('utf-8')
296    'O 7 e Meio \xc3\xa9 um ex-libris da noite algarvia.\n\xc3\x89 uma das mais '
297    >>> text[:60].decode('latin-1').encode('utf-8')
298    'O 7 e Meio \xc3\xa9 um ex-libris da noite algarvia.\n\xc3\x89 uma das mais '
299    >>> text[:60].decode('latin-1').encode('utf-16')
300    '\xff\xfeO\x00 \x007\x00 \x00e\x00 \x00M\x00e\x00i\x00o\x00 \x00\xe9\x00 \x00u\x00m\x00 \x00e\x00x\x00-\x00l\x00i\x00b\x00r\x00i\x00s\x00 \x00d\x00a\x00 \x00n\x00o\x00i\x00t\x00e\x00 \x00a\x00l\x00g\x00a\x00r\x00v\x00i\x00a\x00.\x00\n\x00\xc9\x00 \x00u\x00m\x00a\x00 \x00d\x00a\x00s\x00 \x00m\x00a\x00i\x00s\x00 \x00'
301