
No YouScan , processamos cerca de 100 milhões de mensagens por dia, nas quais muitas regras e várias funções inteligentes são aplicadas. Para o trabalho correto, é necessário determinar corretamente o idioma, porque nem todas as funções podem ser agnósticas em relação ao idioma. Neste artigo, falaremos brevemente sobre nosso estudo desse problema e mostraremos uma avaliação de qualidade em um conjunto de dados de redes sociais. redes.
Resumo do artigo
- Problemas de definição de idioma
- Soluções Públicas Acessíveis
- Detector de idioma compacto 2
- Texto rápido
- Avaliação da qualidade
- Conclusões
1. Problemas de definição de linguagem
A definição de linguagem é um problema bastante antigo e muitos tentam resolvê-lo no âmbito do multilinguismo de seus produtos. Abordagens mais antigas usam soluções baseadas em n-gramas, quando o número de ocorrências de um certo n-grama é considerado e, com base nisso, a "velocidade" para cada idioma é calculada, após o que o idioma mais provável é selecionado de acordo com o nosso modelo. A principal desvantagem desses modelos é que o contexto não é absolutamente levado em consideração; portanto, a definição de uma linguagem para grupos de idiomas semelhantes é difícil. Porém, devido à simplicidade dos modelos, acabamos com uma alta velocidade de determinação, que economiza recursos para sistemas altamente carregados. Outra opção, uma mais moderna, é uma solução em redes neurais recorrentes. Essa solução já se baseia não apenas em n gramas, mas também leva em consideração o contexto, o que deve aumentar a qualidade do trabalho.
A complexidade de criar sua própria solução reside na coleta de dados para treinamento e no próprio processo de aprendizado. A solução mais óbvia é treinar o modelo nos artigos da Wikipedia, porque sabemos o idioma com certeza e há textos verificados de alta qualidade que são relativamente fáceis de compilar. E para treinar seu modelo, você precisa gastar muito tempo para montar o conjunto de dados, processá-lo e escolher a melhor arquitetura. Provavelmente alguém já fez isso antes de nós. No próximo bloco, veremos as soluções existentes.
2. Soluções públicas disponíveis
Detector de idioma compacto 2
O CLD2 é um modelo probabilístico baseado em aprendizado de máquina (classificador Naive Baessian) que pode definir 83 idiomas diferentes para texto no formato UTF-8 ou html / xml. Para idiomas mistos, o modelo retorna os três principais idiomas, onde a probabilidade é calculada como uma porcentagem aproximada do texto do número total de bytes. Se o modelo não tiver certeza de sua resposta, retornará a tag "unc".
A precisão e integridade deste modelo estão em um nível bastante bom, mas a principal vantagem é a velocidade. Os criadores reivindicam cerca de 30kb em 1ms, em nossos testes do wrapper Python que recebemos de 21 a 26kb em 1ms (70.000 a 85.000 mensagens por segundo, cujo tamanho médio é de 0,8kb e a mediana é de 0,3kb).
Esta solução é muito fácil de usar. Primeiro você precisa instalar seu wrapper python ou usar nossa janela de encaixe .
Para fazer uma previsão, basta importar a biblioteca pycld2
e escreva uma linha de código adicional:
Definindo um idioma usando cld2 import pycld2 as cld2 cld2.detect("Bonjour, Habr!")
A resposta do detector é uma tupla de três elementos:
- idioma é definido ou não;
- número de caracteres;
- tupla dos três idiomas mais prováveis, onde o nome completo vem primeiro,
a segunda é a abreviação de acordo com os códigos ISO 3166, a terceira é a porcentagem de caracteres pertencentes a esse idioma e a quarta é o número de bytes.
Texto rápido
O FastText é uma biblioteca criada pelo Facebook para aprendizado e classificação eficazes de textos. No âmbito deste projeto, a Pesquisa do Facebook apresentou incorporações para 157 idiomas que mostram resultados de última geração para várias tarefas, bem como um modelo para determinar o idioma e outras tarefas de supervisão.
Para o modelo de definição de linguagem, eles usaram dados da Wikipedia, Tatoeba e SETimes e, como classificador, usaram sua solução de texto rápido.
Os desenvolvedores da pesquisa no Facebook fornecem dois modelos:
- lid.176.bin , que é um pouco mais rápido e mais preciso que o segundo modelo, mas pesa 128Mb;
- lid.176.ftz - uma versão compactada do modelo original.
Para usar esses modelos em python, primeiro você precisa instalar o wrapper python para o fasttext . Pode ser difícil instalá-lo, então você precisa seguir cuidadosamente as instruções no github ou usar nossa janela de encaixe . Também é necessário fazer o download do modelo no link acima. Usaremos a versão original neste artigo.
Classificar uma linguagem usando um modelo do Facebook é um pouco mais complicado, para isso precisamos de três linhas de código:
Definindo um idioma usando o modelo FastText from pyfasttext import FastText model = FastText('../model/lid.176.bin') model.predict_proba(["Bonjour, Habr!"], 3)
O modelo FastText'a permite prever a probabilidade de n-idiomas, onde por padrão n = 1, mas neste exemplo deduzimos o resultado para os três principais idiomas. Para este modelo, essa já é a probabilidade geral de previsão de idioma para o texto, e não o número de caracteres que pertencem a um idioma específico, como foi o caso no modelo cld2. A velocidade também é bastante alta - mais de 60.000 mensagens por segundo.
3. Avaliação da qualidade
Avaliaremos a qualidade dos algoritmos usando dados de redes sociais para tempo aleatório retirados do sistema YouScan (aproximadamente 500 mil referências), portanto, a amostra terá mais idiomas russo e inglês, 43% e 32%, respectivamente, ucraniano, espanhol e português - sobre 2% de cada um dos idiomas restantes, menos de 1%. Para o destino correto, faremos a marcação pelo google translate, pois no momento o Google é muito bom em gerenciar não apenas a tradução, mas também a definição do idioma dos textos. Obviamente, sua marcação não é ideal, mas na maioria dos casos pode ser confiável.
As métricas para avaliar a qualidade das definições de idioma são precisão, integridade e f1. Vamos contá-los e exibir na tabela:
Comparação da qualidade de dois algoritmos with open("../data/lang_data.txt", "r") as f: text_l, cld2_l, ft_l, g_l = [], [], [], [] s = '' for i in f: s += i if ' |end\n' in s: text, cld2, ft, g = s.strip().rsplit(" ||| ", 3) text_l.append(text) cld2_l.append(cld2) ft_l.append(ft) g_l.append(g.replace(" |end", "")) s='' data = pd.DataFrame({"text": text_l, "cld2": cld2_l, "ft": ft_l, "google": g_l}) def lang_summary(lang, col): prec = (data.loc[data[col] == lang, "google"] == data.loc[data[col] == lang, col]).mean() rec = (data.loc[data["google"] == lang, "google"] == data.loc[data["google"] == lang, col]).mean() return round(prec, 3), round(rec, 3), round(2*prec*rec / (prec + rec),3) results = {} for approach in ["cld2", "ft"]: results[approach] = {} for l in data["google"].value_counts().index[:20]: results[approach][l] = lang_summary(l, approach) res = pd.DataFrame.from_dict(results) res["cld2_prec"], res["cld2_rec"], res["cld2_f1"] = res["cld2"].apply(lambda x: [x[0], x[1], x[2]]).str res["ft_prec"], res["ft_rec"], res["ft_f1"] = res["ft"].apply(lambda x: [x[0], x[1], x[2]]).str res.drop(columns=["cld2", "ft"], inplace=True) arrays = [['cld2', 'cld2', 'cld2', 'ft', 'ft', 'ft'], ['precision', 'recall', 'f1_score', 'precision', 'recall', 'f1_score']] tuples = list(zip(*arrays)) res.columns = pd.MultiIndex.from_tuples(tuples, names=["approach", "metrics"])
modelo | | cld2 | | | ft | | | ans | |
---|
métricas | prec | rec | f1 | prec | rec | f1 | prec | rec | f1 |
ar | 0,992 | 0,725 | 0.838 | 0,918 | 0,697 | 0,793 | 0,968 | 0,788 | 0.869 |
az | 0,95 | 0,752 | 0.839 | 0,888 | 0,547 | 0,677 | 0,914 | 0,787 | 0.845 |
bg | 0,529 | 0,136 | 0,217 | 0,286 | 0,178 | 0,219 | 0,408 | 0,214 | 0,281 |
en | 0,949 | 0.844 | 0,894 | 0,885 | 0.869 | 0.877 | 0,912 | 0,925 | 0,918 |
es | 0.987 | 0,653 | 0,786 | 0,709 | 0.814 | 0,758 | 0.828 | 0.834 | 0.831 |
fr | 0,991 | 0,713 | 0.829 | 0,53 | 0,803 | 0,638 | 0,713 | 0,81 | 0,758 |
id | 0,763 | 0,543 | 0,634 | 0,481 | 0,404 | 0,439 | 0,659 | 0,603 | 0,63 |
isso | 0,975 | 0,466 | 0,631 | 0,519 | 0,778 | 0,622 | 0,666 | 0,752 | 0,706 |
ja | 0,994 | 0.899 | 0,944 | 0,602 | 0.842 | 0,702 | 0.847 | 0,905 | 0.875 |
ka | 0,962 | 0,995 | 0,979 | 0,959 | 0,905 | 0,931 | 0,958 | 0,995 | 0,976 |
kk | 0,908 | 0,653 | 0,759 | 0,804 | 0,584 | 0,677 | 0.831 | 0,713 | 0,767 |
ko | 0,984 | 0,886 | 0,933 | 0,94 | 0,704 | 0,805 | 0,966 | 0,91 | 0,937 |
ms | 0,801 | 0,578 | 0,672 | 0,369 | 0,101 | 0,159 | 0,73 | 0,586 | 0,65 |
pt | 0,968 | 0,753 | 0.847 | 0,805 | 0,771 | 0,788 | 0.867 | 0.864 | 0.865 |
ru | 0.987 | 0,809 | 0,889 | 0,936 | 0,933 | 0,935 | 0,953 | 0,948 | 0,95 |
sr | 0,093 | 0,114 | 0,103 | 0,174 | 0,103 | 0,13 | 0,106 | 0,16 | 0,128 |
th | 0,989 | 0,986 | 0.987 | 0,973 | 0,927 | 0,95 | 0,979 | 0,986 | 0,983 |
tr | 0,961 | 0,639 | 0,768 | 0,607 | 0,73 | 0,663 | 0,769 | 0,764 | 0,767 |
Reino Unido | 0,949 | 0,671 | 0,786 | 0,615 | 0,733 | 0,669 | 0,774 | 0,777 | 0,775 |
uz | 0,666 | 0,512 | 0,579 | 0,77 | 0,169 | 0,278 | 0,655 | 0,541 | 0,592 |
Os resultados mostram claramente que a abordagem cld2 tem uma precisão muito alta na determinação do idioma, apenas para idiomas impopulares ela fica abaixo de 90% e em 90% dos casos o resultado é melhor que o do texto rápido. Com aproximadamente a mesma integridade para as duas abordagens, f1 é mais rápido em cld2.
A peculiaridade do modelo cld2 é que ele fornece uma previsão apenas para as mensagens em que é confiante o suficiente, o que explica a alta precisão. O modelo fasttext'a fornece uma resposta para a maioria das mensagens; portanto, a precisão é significativamente menor, mas é estranho que a integridade não seja significativamente maior e, na metade dos casos, menor. Mas se você "torcer" o limite do modelo de texto rápido, poderá melhorar a precisão.
4. Conclusões
Em geral, ambos os modelos apresentam bons resultados e podem ser usados para resolver o problema de determinar o idioma em diferentes domínios. Sua principal vantagem é a alta velocidade, o que torna possível criar o chamado "conjunto" e adicionar o pré-processamento necessário para melhorar a qualidade.
Você pode encontrar todo o código para reproduzir experimentos e testar as abordagens acima em nosso repositório .
Você também pode ver o teste dessas soluções em outro artigo , que compara precisão e velocidade em 6 idiomas da Europa Ocidental.