-
Sistemas de Processamento de Linguagem Natural na Prática
Lições aprendidas na busca por insights em dados não
estruturados
William Colen
Head de IA @ Stilingue (www.stilingue.com.br)
Member @ Apache SF (www.apache.org)
PMC/Commiter @ Apache
OpenNLP (opennlp.apache.org)
[email protected]
@wcolen
slideshare: wcolen
https://github.com/wcolen/qconsp2018-opennlp-flink-example
http://www.stilingue.com.brhttp://www.apache.orghttp://opennlp.apache.orgmailto:[email protected]
-
1Motivação NLP Como fazer em Português
2 3Indo um pouco mais profundo
4Analisando
a Internet
5
-
1Motivação NLP Como fazer em Português
2 3Indo um pouco mais profundo
4Analisando
a Internet
5
-
Mas o que é Natural Language Processing?
-
Línguas Naturais
-
Línguas Naturais
Aquelas que evoluem naturalmente por humanos devido ao uso e
repetição sem planejamento ou
premeditação.
-
Línguas Estruturadas
Aquelas construídas ou formais, como as utilizadas para
programar um computador, ou a linguagem
matemática.
-
Boa parte do conhecimento humano está em documentos difíceis de
serem interpretados por computadores
-
Boa parte do conhecimento humano está em documentos difíceis de
serem interpretados por computadores
-
Boa parte do conhecimento humano está em documentos difíceis de
serem interpretados por computadores
Informação de alto valor
e mais atualizada
Mas… com muito ruído, semântica oculta e busca ineficiente
-
Boa parte do conhecimento humano está em documentos difíceis de
serem interpretados por computadores
Informação de alto valor e mais atualizada
Mas… com muito ruído, semântica oculta e busca ineficiente
Processamento de Linguagem Natural
-
O QUE?QUEM?
ONDE?
QUANDO?
-
FALARAM SOBRE CERVEJA NO FERIADO DO DIA DO TRABALHADOR?
O QUE?
-
Ranking/Evolução - Publicações cerveja durante o feriado
prolongado Dia do Trabalhador
-
Cerveja x Tema - Publicações cerveja durante o feriado
prolongado Dia do Trabalhador
-
Sentimento - Publicações cerveja durante o feriado prolongado
Dia do Trabalhador
-
Termos Correlacionados - Publicações cerveja durante o feriado
prolongado Dia do Trabalhador
-
Sunburst Termos - Publicações cerveja durante o feriado
prolongado Dia do Trabalhador
-
#comoEuConsigo
-
Resolvendo um problema simples de cada vez
-
1Motivação NLP Como fazer em Português
2 3Indo um pouco mais profundo
4Analisando
a Internet
5
-
Desafio: ambiguidade
O sr. Mendonça chegou.
Quem casa quer casa.
Eu preparei o pato dela.
-
|O|sr.|Paulo|chegou|.|||Vamos|?||
|O|sr.|Paulo|chegou|.| ART ABR N VERB PU
|O sr. Paulo |chegou Sintagma Nominal Sintagma Verbal
O sr. Paulo está chegando . | Sujeito | Predicado
O sr. Paulo chegou . | Vamos ?||Sentence
Detector
Tokenizer
POS Tagger
Chunker
Shallow Parser
O sr. Paulo chegou . Vamos ?||
-
PipelineLanguage
Detector
Sentence
Detector Tokenizer POS Tagger Chunker
Lemmatizer
Name Finder
Sentiment
Entity Linker
Index
-
PipelineLanguage
Detector
Sentence
Detector Tokenizer POS Tagger Chunker
Lemmatizer
Name Finder
Sentiment
Entity Linker
Index
SegmentaçãoSeleção Anotação Anotação++
-
Desafios em trabalhar com português
Escassos recursos linguísticos
Dicionários, corpus, ferramentas e modelos
-
Desafios em trabalhar com portuguêsEscassos recursos
linguísticos
Dicionários, corpus, ferramentas e modelos
-
1Motivação NLP Como fazer em Português
2 3Indo um pouco mais profundo
4Analisando
a Internet
5
-
Desafios em trabalhar com portuguêsEscassos recursos
linguísticos
Dicionários, corpus, ferramentas e modelos
-
Dicionários
LéxicosOrtográficos Semânticos
-
Dicionários
Ortográficos
Hunspell pt-BR (corretor ortográfico do LibreOffice)
esse comercial da #brama, em são paulo c/ mulheres cantando por
homens q bebe +
conscientemente e ótm :P
Esse comercial da Brahma em São Paulo com mulheres cantando por
homens que bebem mais
conscientemente e ótimo.
-
Dicionários
LéxicosOrtográficos Semânticos
-
Dicionários
Léxicos
JSpell.Br (CoGrOO USP/SP)
Podem ajudar em anotadores, como
POS Tagging e Lematização
https://github.com/cogroo/jspell.br
-
Dicionários
LéxicosOrtográficos Semânticos
-
Dicionários
Semânticos
Podem ajudar em termos, entidades e conceitos
Entidades na Stilingue
-
Semânticos
-
Analise de sentimento
Semânticos
-
PipelineLanguage
Detector
Sentence
Detector Tokenizer POS Tagger Chunker
Lemmatizer
Name Finder
Sentiment
Entity Linker
Index
-
Desafios em trabalhar com portuguêsEscassos Recursos
linguísticos
Dicionários, corpus, ferramentas e modelos
-
Corpus
DocumentoNão Anotado Tokens
-
Corpus
Não Anotado
Wikipedia
• Servem como exemplos de uso da língua
• Criação simples: crawler de notícias, coletar tweets
• Corpus livre e aberto: Wikipedia Dumps
https://dumps.wikimedia.org
https://dumps.wikimedia.orghttps://dumps.wikimedia.org
-
Corpus
DocumentoNão Anotado Tokens
-
Corpus
Documentopos eu curti pos eu bebo todas e adoroooo neg ressaca
braba com essa cerva de milho neg mano essa cerva ta quente
Outros exemplos
- Pares - Pares …
-
Corpus
DocumentoNão Anotado Tokens
-
Corpus
Tokens
Floresta (Linguateca)Summit (PUC-RS)
0 A o art F=S _ _ _ _ 1 equipe _ n F=S 0 _ _ _ 2 de de prp _ _ _
_ _ 3 Peter_Savolainen _ prop M=S 0 (PER) (5) _ 4 , _ , _ _ _ _ _ 5
de de prp _ _ _ _ _ 6 o o art M=S _ _ _ _ 7
Instituto_Real_de_Tecnologia _ prop M=S 0 (ORG) (5) _ 8 , _ , _ _ _
_ _ 9 de de prp _ _ _ _ _ 10 Estocolmo Estocolmo prop M=S 0 (PLC) _
_ 11 , _ , _ _ _ _ _ 12 Suécia Suécia prop F=S 0 (PLC) _ _ 13 , _ ,
_ _ _ _ _ 14 constatou constatar v-fin PS=3S=IND _ _ _ _ 15 que que
conj-s _ _ _ _ _ 16 a o art F=S _ _ _ _ 17 diversidade diversidade,
diverso n F=S 0 _ _ _ 18 genética genético adj F=S _ _ _ _ 19 era
ser v-fin IMPF=3S=IND _ _ _ _ 20 maior maior adj F=S _ _ _ _ 21
entre entre prp _ _ _ _ _ 22 os o art M=P _ _ _ _ 23 cães cão n M=P
0 _ _ _ 24 de de prp _ _ _ _ _ 25 o o art M=S _ _ _ _ 26 leste
leste n M=S 0 _ _ _ 27 asiático asiático adj M=S _ _ _ _ 28 . . . _
_ _ _ _
Summit (PUC-RS)
-
PipelineLanguage
Detector
Sentence
Detector Tokenizer POS Tagger Chunker
Lemmatizer
Name Finder
Sentiment
Entity Linker
Index
-
Desafios em trabalhar com portuguêsEscassos Recursos
linguísticos
Dicionários, corpus, ferramentas e modelos
-
Ferramentas
Machine Learning + DL Deep Learning
-
Ferramentas
Machine Learning + DL NLTK (Python)
spaCy (Python)
Apache OpenNLP (Java)Stanford Core NLP (Java)
CoGrOO (Java)
Centradas em Machine Learning.
Podem usar DL para partes
específicas.
Ex.: OpenNLP pode usar Word Embeddings como features
-
Ferramentas
Machine Learning + DL
CoGrOO https://github.com/cogroo/cogroo4/wiki/API-CoGrOO-4
-
Ferramentas
Machine Learning + DL Deep Learning
-
Ferramentas
Deep Learning
Tensor FlowApache MXNetEclipse DL4J
PyTorch
-
Ferramentas
Deep Learning
Tensor FlowApache MXNetEclipse DL4J
PyTorch
-
Desafios em trabalhar com portuguêsEscassos Recursos
linguísticos
Dicionários, corpus, ferramentas e modelos
-
Modelos
Prateleira Tailor Made
-
Modelos
• CoGrOO
(https://github.com/cogroo/cogroo4/wiki/API-CoGrOO-4)
• Apache OpenNLP (http://opennlp.apache.org/models.html)
• NLTK
(http://www.nltk.org/howto/portuguese_en.html)
Prateleira
Sentence Detector | Tokenizer | Named Entity | POS Tagger |
Chunking | Parser
Sentiment | Linking | Word Embeddings
Bons como baseline e para componentes secundários.
https://github.com/cogroo/cogroo4/wiki/API-CoGrOO-4http://www.nltk.org/howto/portuguese_en.html
-
Modelos
Prateleira Tailor Made
-
Modelos
Tailor MadeTreinar um modelo sob medida adequado para o contexto
de aplicação utilizando um corpus criado sob medida.
Bons quando para contextos específicos e quando precisamos de
maior eficácia.
-
Desafios em trabalhar com portuguêsEscassos Recursos
linguísticos
Dicionários, corpus, ferramentas e modelos
-
Como criar modelos customizados para máxima eficácia?
-
1Motivação NLP Como fazer em Português
2 3Indo um pouco mais profundo
4Analisando
a Internet
5
-
Como criar modelos customizados para máxima eficácia?
Ciclo de desenvolvimento
-
Vamos criar um modelo de entidades nomeadas em notícias
Ciclo de desenvolvimento
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um novo modelo
Ciclo de desenvolvimento
-
• Corpus Amazônia:
http://www.linguateca.pt/floresta/ficheiros/gz/amazonia.ad.gz
• Apache OpenNLP:
https://www.apache.org/dyn/closer.cgi/opennlp/opennlp-1.8.4/apache-opennlp-1.8.4-bin.tar.gz
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
http://www.linguateca.pt/floresta/ficheiros/gz/amazonia.ad.gzhttp://www.linguateca.pt/floresta/ficheiros/gz/amazonia.ad.gzhttps://www.apache.org/dyn/closer.cgi/opennlp/opennlp-1.8.4/apache-opennlp-1.8.4-bin.tar.gzhttps://www.apache.org/dyn/closer.cgi/opennlp/opennlp-1.8.4/apache-opennlp-1.8.4-bin.tar.gzhttps://www.apache.org/dyn/closer.cgi/opennlp/opennlp-1.8.4/apache-opennlp-1.8.4-bin.tar.gz
-
A1 STA:cu =CJT:fcl ==ADVL:adv("depois" ) depois
==ACC-PASS:pron-pers("se" M 3P ACC) se ==P:v-fin("encontrar" PR 3P
IND VFIN) encontram ==PIV:pp ===H:prp("com" ) com ===PN:art("o" DET
F S) a ====H:n("dissidência" F S) dissidência ====NN:art("o" DET M
P) os =======H:prop("Bacamarteiros_de_Pinga_Fogo" M P)
Bacamarteiros_de_Pinga_Fogo =, =CO:conj-c("e" ) e =CJT:x ==SUBJ:np
===>N:art("o" DET F S) a ===H:n("festa" F S) festa
==P:v-fin("continuar" PR 3S IND VFIN) continua ==ADVL:pp
===H:prp("por" ) por ===P
-
$ bin/opennlp TokenNameFinderCrossValidator.ad -lang pt
-encoding ISO-8859-1 /
-data amazonia.ad -reportOutputFile
detailed_report.txt /
-misclassified true >
misclassified.txt
detailed_report.txt misclassified.txt
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
-
detailed_report.txt
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Evaluated 275769 samples with 328431 entities; found: 317170
entities; correct: 264015. TOTAL: precision: 83.24%; recall:
80.39%; F1: 81.79%. time: precision: 93.89%; recall: 91.63%; F1:
92.75%. [target: 18338; tp: 16804; fp: 1093] numeric: precision:
90.65%; recall: 89.64%; F1: 90.14%. [target: 15173; tp: 13601; fp:
1403] event: precision: 93.13%; recall: 86.28%; F1: 89.57%.
[target: 50094; tp: 43219; fp: 3189] place: precision: 87.99%;
recall: 80.35%; F1: 83.99%. [target: 52123; tp: 41879; fp: 5718]
person: precision: 79.31%; recall: 81.17%; F1: 80.23%. [target:
85314; tp: 69250; fp: 18069] organization: precision: 78.32%;
recall: 78.67%; F1: 78.50%. [target: 69654; tp: 54798; fp: 15167]
thing: precision: 78.86%; recall: 68.91%; F1: 73.55%. [target:
9915; tp: 6832; fp: 1832] abstract: precision: 73.97%; recall:
66.85%; F1: 70.23%. [target: 11262; tp: 7529; fp: 2650] artprod:
precision: 71.46%; recall: 61.02%; F1: 65.83%. [target: 16558; tp:
10103; fp: 4034]
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Confusion Matrix a b c d e f g h i j k l m n o p q r s |
-
misclassified.txt
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Expected: { " Luz Quartiada " é pura prosa poética que prende o
leitor do começo ao fim quando descreve personagens como " Clarice
" e seus anseios de mulher de um mundo escondido e ameaçado pelo
progresso :} Predicted: { " Luz Quartiada " é pura prosa poética
que prende o leitor do começo ao fim quando descreve personagens
como " Clarice " e seus anseios de mulher de um mundo escondido e
ameaçado pelo progresso :} False positives: { [Luz Quartiada,
Clarice] } False negatives: { [Luz Quartiada, prosa, Clarice] }
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Default feature generator
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Default feature generator
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Feature generator: v01
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Feature generator: v01 x v2Evaluated 275769 samples with 328431
entities; found: 317170 entities; correct: 264015. TOTAL:
precision: 83.24%; recall: 80.39%; F1: 81.79%. time: precision:
93.89%; recall: 91.63%; F1: 92.75%. [target: 18338; tp: 16804; fp:
1093] numeric: precision: 90.65%; recall: 89.64%; F1: 90.14%.
[target: 15173; tp: 13601; fp: 1403] event: precision: 93.13%;
recall: 86.28%; F1: 89.57%. [target: 50094; tp: 43219; fp: 3189]
place: precision: 87.99%; recall: 80.35%; F1: 83.99%. [target:
52123; tp: 41879; fp: 5718] person: precision: 79.31%; recall:
81.17%; F1: 80.23%. [target: 85314; tp: 69250; fp: 18069]
organization: precision: 78.32%; recall: 78.67%; F1: 78.50%.
[target: 69654; tp: 54798; fp: 15167] thing: precision: 78.86%;
recall: 68.91%; F1: 73.55%. [target: 9915; tp: 6832; fp: 1832]
abstract: precision: 73.97%; recall: 66.85%; F1: 70.23%. [target:
11262; tp: 7529; fp: 2650] artprod: precision: 71.46%; recall:
61.02%; F1: 65.83%. [target: 16558; tp: 10103; fp: 4034]
Evaluated 275769 samples with 328431 entities; found: 318807
entities; correct: 265517. TOTAL: precision: 83.28%; recall:
80.84%; F1: 82.05%. time: precision: 93.90%; recall: 92.16%; F1:
93.02%. [target: 18338; tp: 16900; fp: 1098] numeric: precision:
90.30%; recall: 89.68%; F1: 89.99%. [target: 15173; tp: 13607; fp:
1461] event: precision: 93.17%; recall: 86.15%; F1: 89.53%.
[target: 50094; tp: 43158; fp: 3162] place: precision: 87.60%;
recall: 81.33%; F1: 84.35%. [target: 52123; tp: 42392; fp: 6000]
person: precision: 79.87%; recall: 81.05%; F1: 80.46%. [target:
85314; tp: 69146; fp: 17424] organization: precision: 77.89%;
recall: 79.36%; F1: 78.62%. [target: 69654; tp: 55274; fp: 15689]
thing: precision: 81.48%; recall: 67.49%; F1: 73.83%. [target:
9915; tp: 6692; fp: 1521] abstract: precision: 75.70%; recall:
65.60%; F1: 70.29%. [target: 11262; tp: 7388; fp: 2371] artprod:
precision: 70.60%; recall: 66.19%; F1: 68.32%. [target: 16558; tp:
10960; fp: 4564]
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
Feature generator: v2 x v3Evaluated 275769 samples with 328431
entities; found: 318807 entities; correct: 265517. TOTAL:
precision: 83.28%; recall: 80.84%; F1: 82.05%. time: precision:
93.90%; recall: 92.16%; F1: 93.02%. [target: 18338; tp: 16900; fp:
1098] numeric: precision: 90.30%; recall: 89.68%; F1: 89.99%.
[target: 15173; tp: 13607; fp: 1461] event: precision: 93.17%;
recall: 86.15%; F1: 89.53%. [target: 50094; tp: 43158; fp: 3162]
place: precision: 87.60%; recall: 81.33%; F1: 84.35%. [target:
52123; tp: 42392; fp: 6000] person: precision: 79.87%; recall:
81.05%; F1: 80.46%. [target: 85314; tp: 69146; fp: 17424]
organization: precision: 77.89%; recall: 79.36%; F1: 78.62%.
[target: 69654; tp: 55274; fp: 15689] thing: precision: 81.48%;
recall: 67.49%; F1: 73.83%. [target: 9915; tp: 6692; fp: 1521]
abstract: precision: 75.70%; recall: 65.60%; F1: 70.29%. [target:
11262; tp: 7388; fp: 2371] artprod: precision: 70.60%; recall:
66.19%; F1: 68.32%. [target: 16558; tp: 10960; fp: 4564]
Evaluated 275769 samples with 328431 entities; found: 319684
entities; correct: 265738. TOTAL: precision: 83.13%; recall:
80.91%; F1: 82.00%. time: precision: 93.99%; recall: 92.23%; F1:
93.10%. [target: 18338; tp: 16914; fp: 1082] numeric: precision:
91.39%; recall: 89.71%; F1: 90.54%. [target: 15173; tp: 13611; fp:
1283] event: precision: 93.18%; recall: 85.64%; F1: 89.25%.
[target: 50094; tp: 42903; fp: 3141] place: precision: 87.28%;
recall: 81.42%; F1: 84.25%. [target: 52123; tp: 42437; fp: 6183]
person: precision: 79.93%; recall: 82.02%; F1: 80.96%. [target:
85314; tp: 69978; fp: 17571] organization: precision: 77.56%;
recall: 79.26%; F1: 78.40%. [target: 69654; tp: 55206; fp: 15973]
thing: precision: 81.63%; recall: 66.17%; F1: 73.09%. [target:
9915; tp: 6561; fp: 1476] abstract: precision: 73.10%; recall:
65.11%; F1: 68.87%. [target: 11262; tp: 7333; fp: 2699] artprod:
precision: 70.40%; recall: 65.20%; F1: 67.70%. [target: 16558; tp:
10795; fp: 4538]
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
$ bin/opennlp TokenNameFinderTrainer.ad -lang pt -encoding
ISO-8859-1 / -data amazonia.ad -model qcon.bin
Treinar um modelo para homologação
-
Criar um modelo Baseline
Corpus Baseline
Avaliação
Homologação
Engenharia de Features
Anotar mais dados
Criar um modelo
$ bin/opennlp TokenizerMEEvaluator.ad -lang pt -encoding
ISO-8859-1 / -data homologacao.ad -model qcon.bin -detokenizer
portuguese.xml / -misclassified true
Com o modelo treinado, avaliar em dados reais anotados (corpus
ouro)
-
#comoJuntaTudo ou…
como processar a Internet??
-
1Motivação NLP Como fazer em Português
2 3Indo um pouco mais profundo
4Analisando
a Internet
5
-
PipelineLanguage
Detector
Sentence
Detector Tokenizer POS Tagger Chunker
Lemmatizer
Name Finder
Sentiment
Entity Linker
Index
SegmentaçãoSeleção Anotação Anotação++
-
Sentence
Detector Tokenizer POS Tagger Name Finder
Index
Language
Detector
Data
source
NLP em Streaming
-
NLP em Streaming
https://github.com/wcolen/qconsp2018-opennlp-flink-example
final StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();
// Perform
language detection SplitStream articleStream = rawStream .map(new
LanguageDetectorFunction()) .split(new
LanguageSelector(nlpLanguages));
// English NLP pipeline articleStream.select("eng") .map(new
SentenceDetectorFunction(engSentenceModel)) .map(new
TokenizerFunction(engTokenizerModel)) .map(new
POSTaggerFunction(engPosModel)) .map(new
ChunkerFunction(engChunkModel)) .map(new
NameFinderFunction(engNerPersonModel)) .addSink(new
ElasticsearchSink(config, transportAddresses, new
ESSinkFunction()));
// Portuguese NLP pipeline articleStream.select("por") .map(new
SentenceDetectorFunction(porSentenceModel)) .map(new
TokenizerFunction(porTokenizerModel)) .map(new
POSTaggerFunction(porPosModel)) .map(new
ChunkerFunction(porChunkModel)) .map(new
NameFinderFunction(porNerPersonModel)) .addSink(new
ElasticsearchSink(config, transportAddresses, new
ESSinkFunction()));
-
Agradecimentos equipe Apache OpenNLP
Suneel Marthi
@suneelmarthi
Jörn Kottmann
@joernkottmann
Tommaso Teofili
@tteofili
Peter Thygesen
in:thygesen
@pthyge
William Colen
@wcolen
Rodrigo Agerri
@ragerri
Daniel Russ
in:daniel-russ-9541aa15
Koji Sekiguchi
@kojisays
Jeff Zemerick
in:jeffzemerick
Bruno Kinoshita
@kinow
-
Agradecimentos
Equipe de IA da Stilingue
http://www.stilingue.com.br
@Stilingue_API
#contratandoMentesCuriosas e parcerias!!
-
Sistemas de Processamento de Linguagem Natural na Prática
William Colen
Head de IA @ Stilingue (www.stilingue.com.br)
Member @ Apache SF (www.apache.org)
PMC/Commiter @ Apache
OpenNLP (opennlp.apache.org)
[email protected]
@wcolen
slideshare: wcolen
https://github.com/wcolen/qconsp2018-opennlp-flink-example
Obrigado!
Perguntas?
http://www.stilingue.com.brhttp://www.apache.orghttp://opennlp.apache.orgmailto:[email protected]