Olá a todos! Este ano, a Sibur Digital sediou novamente um grande campeonato de análise de dados (em comparação com outros russos). Meu amigo e eu participamos dele e gostaríamos de compartilhar com os leitores da Habr nossa decisão e experiência adquirida com a participação. Claro, é improvável que abramos a América com este artigo, mas alguns iniciantes em competições de pressão arterial definitivamente serão capazes de aprender algo útil para si mesmo.
Quem somos nós?
Somos alunos apaixonados por DS e ML. Aprendemos sobre essa área pela primeira vez na conferência AI Journey realizada em nossa universidade. Desde aquele momento, passamos por mais de um, e não dois, e não três cursos (da Omsk State Technical University a Andrew NG) e agora participamos constantemente de hackathons e competições (em algumas até ganhamos prêmios), paralelamente estamos procurando um estágio.
Sobre a tarefa
Aceitamos o segundo desafio da competição - "correspondência de nomes".
A essência é a seguinte: a Sibur trabalha com um grande número de novas empresas e, para otimizar o fluxo de trabalho, seria útil que elas entendessem que estão trabalhando com uma holding anteriormente familiar. Por exemplo, Sibur Neftekhim e SIBUR IT são da mesma holding e, ao trabalhar com uma dessas empresas, seria útil utilizar as informações acumuladas anteriormente na holding SIBUR.
Vamos parafrasear o problema na linguagem DS. Dois nomes foram dados, pelos quais devemos determinar se as empresas pertencem a uma só holding ou não.
name_1 |
nome_2 |
is_duplicate |
Japan Synthetic Rubber Co |
Elastômero Jsr Bst |
1 |
JSR Corporation |
BST ELASTOMERS CO. |
0 |
Essa é a aparência do conjunto de dados.
Pré-processamento de dados
Em primeiro lugar, convertemos os dados para o alfabeto latino usando o módulo unidecode mágico. Em seguida, eles trouxeram para a caixa baixa, removeram qualquer lixo na forma de sinais de pontuação desnecessários, espaços duplos, etc.
from unidecode import unidecode
import re
def preprocess(text: str):
text = unidecode(text)
text = text.lower()
text = re.sub(r'[\.,]+', '', text)
text = re.sub(r"\(.*\)", ' ', text)
text = re.sub(r"[^\w\s]", ' ', text)
text = re.sub(r'\b\w\b', ' ', text)
text = ' '.join(text.split())
return text
. , pycountry( ) , .
. , , , . " " "shanghai", , , . .
, , - ( , ).
, : "" , .
" ". 0.3 . , .
. . .
, , . .
, , :
,
()
: , ,
tfidf - ( )
ngram
( )
,
,
, , XGBoost, . ~ 0.59 .
, - . (, , !), , 0.69 . , , .
- , , , .
, . , fit_predict, . ( ). , -.
?
Foi possível levar em conta a semântica das palavras ou dar pesos às palavras: se uma palavra em dois nomes coincidiu e é útil (refere-se ao nome da empresa) - tem peso, consideramos automaticamente que é igualmente prejudicial na "diferença" das palavras; usar o máximo possível de dados externos com nomes de empresas, etc. Além disso, não se esqueça de analisar as observações em que o modelo está errado (Falso Positivo, Falso Negativo), e com base nisso, construir novos recursos.
PS
Se você deseja entrar em contato conosco: matnik2001@gmail.com, domonion@list.ru