Análise de vagas usando clustering

O artigo fornece um método para analisar as vagas para a consulta de pesquisa "Python" usando o modelo de agrupamento Gaussian Mixture Model (GMM). Para cada cluster selecionado, serão apresentadas as competências e faixas salariais mais solicitadas.



Qual foi o objetivo deste estudo? Eu queria saber:



  • Em quais aplicativos o Python é usado
  • Quais conhecimentos são necessários: bancos de dados, bibliotecas, estruturas
  • Quantos especialistas em cada área são solicitados
  • Que salários são oferecidos






Carregando dados



Jobs baixado do site hh.ru , usando a API: dev.hh.ru . A pedido da "Python", foram carregadas as vagas de 1994 (região de Moscou), que foram divididas em suítes de treinamento e teste, na proporção de 80% e 20% . O tamanho do conjunto de treinamento é 1595 , o tamanho do conjunto de teste é 399 . O conjunto de testes será usado apenas nas seções de habilidades Top / Antitop e Classificação de Cargos.



Sinais



Com base no texto das vagas carregadas, foram formados dois grupos dos n-gramas mais comuns de palavras:



  • 2 gramas em cirílico e latim
  • 1 grama em latim


Nas vagas de TI, as principais habilidades e tecnologias são geralmente escritas em inglês, portanto, o segundo grupo incluiu palavras apenas em latim.



Após a seleção de n-gramas, o primeiro grupo continha 81 gramas de 2 e o segundo 98 gramas de 1:

Não. n n-grama Peso Vagas
1 2 em python oito 258
2 2 ci cd oito 230
3 2 compreensão dos princípios oito 221
4 2 conhecimento de sql oito 178
cinco 2 Desenvolvimento e nove 174
... ... ... ... ...
82 1 sql cinco 490
83 1 linux 6 462
84 1 postgresql cinco 362
85 1 docker 7 358
86 1 Java nove 297
... ... ... ... ...


Decidiu-se dividir as vagas em clusters de acordo com os seguintes critérios em ordem de prioridade:

Uma prioridade Critério Peso
1 Campo (direção aplicada), cargo, experiência de

n-gram: "aprendizado de máquina", "administração Linux", "conhecimento excelente"
7-9
2 Ferramentas, tecnologias, software.

n-gramas: "sql", "linux os", "pytest"
4-6
3 Outras habilidades de

n-gram: "educação técnica", "Inglês", "tarefas interessantes"
1-3


A determinação de qual grupo de critérios o n-grama pertence, e que peso atribuir a ele, ocorreu em um nível intuitivo. Aqui estão alguns exemplos:

  1. À primeira vista, "Docker" pode ser atribuído ao segundo grupo de critérios com um peso de 4 a 6. Mas a menção de "Docker" na vaga provavelmente significa que a vaga será para o cargo de "engenheiro DevOps". Portanto, "Docker" caiu no primeiro grupo e recebeu um peso de 7.

  2. «Java» , .. «Java» Java- « Python». «-». , , , «Java» 9.



n- — .





Para os cálculos, cada vaga foi transformada em um vetor com dimensão de 179 (o número de recursos selecionados) de números inteiros de 0 a 9, onde 0 significa que o i-ésimo n-grama está ausente na vaga e os números de 1 a 9 significam a presença do i-ésimo n - gramas e seu peso. Mais adiante no texto, um ponto é entendido como uma vaga representada por tal vetor.

Exemplo:

digamos que uma lista de n-gramas contenha apenas três valores:

Não. n n-grama Peso Vagas
1 2 em python oito 258
2 2 compreensão dos princípios oito 221
3 1 sql cinco 490


Depois, para uma vaga com texto.



Requisitos:



  • Mais de 3 anos de experiência em desenvolvimento python .
  • Bons conhecimentos de sql


o vetor é igual a [8, 0, 5].



Métricas



Para trabalhar com dados, você precisa entendê-los. No nosso caso, gostaria de ver se há algum agrupamento de pontos, que consideraremos como agrupamento. Para fazer isso, usei o algoritmo t-SNE para traduzir todos os vetores no espaço 2D. 



A essência do método é reduzir a dimensão dos dados, mantendo ao máximo as proporções das distâncias entre os pontos do conjunto. É muito difícil entender como o t-SNE funciona a partir das fórmulas. Mas gostei de um exemplo encontrado em algum lugar da Internet: digamos que temos bolas no espaço tridimensional. Conectamos cada bola com todas as outras bolas por molas invisíveis que não se cruzam de forma alguma e não interferem uma com a outra durante o cruzamento. As molas atuam em duas direções, ou seja, eles resistem tanto à distância quanto à aproximação das bolas entre si. O sistema está em um estado estável, as bolas estão paradas. Se pegarmos uma das bolas, puxá-la de volta e depois soltá-la, ela voltará ao seu estado original devido à força das molas. Em seguida, pegamos dois pratos grandes e esprememos as bolas em uma camada fina,embora não interfira com as bolas para se mover no plano entre as duas placas. As forças das molas começam a agir, as bolas se movem e eventualmente param quando as forças de todas as molas se equilibram. As molas agirão de forma que as esferas que estavam próximas uma da outra permaneçam relativamente próximas e planas. Também com bolas removidas - elas serão removidas umas das outras. Com o auxílio de molas e placas, convertemos o espaço tridimensional em bidimensional, preservando de alguma forma a distância entre os pontos!Também com bolas removidas - elas serão removidas umas das outras. Com a ajuda de molas e placas, convertemos o espaço tridimensional em bidimensional, preservando de alguma forma a distância entre os pontos!Também com bolas removidas - elas serão removidas umas das outras. Com a ajuda de molas e placas, convertemos o espaço tridimensional em bidimensional, preservando de alguma forma a distância entre os pontos!



O algoritmo t-SNE foi usado por mim apenas para visualizar um conjunto de pontos. Ele ajudou a escolher uma métrica, bem como selecionar os pesos dos recursos.



Se usarmos a métrica euclidiana que usamos em nossa vida diária, então a localização das vagas ficará assim:





A figura mostra que a maioria dos pontos estão concentrados no centro, e há pequenos ramos nas laterais. Com essa abordagem, algoritmos de agrupamento que usam as distâncias entre os pontos não produzirão nada de bom.



Existem muitas métricas (maneiras de determinar a distância entre dois pontos) que funcionarão bem com os dados que você está explorando. Escolhi a distância de Jaccard como medida , levando em consideração os pesos de n-gramas. A medida de Jaccard é fácil de entender, mas funciona bem para resolver o problema em consideração.

:

1 n-: « python», «sql», «docker»

2 n-: « python», «sql», «php»

:

« python» — 8

«sql» — 5

«docker» — 7

«php» — 9

(n- 1- 2- ):  « python», «sql» = 8 + 5 = 13

( n- 1- 2- ):  « python», «sql», «docker», «php» = 8 + 5 + 7 + 9 = 29

=1 — ( / ) = 1 — (13 / 29) = 0.55


A matriz de distâncias entre todos os pares de pontos foi calculada, o tamanho da matriz é 1595 x 1595. No total, 1.271.215 distâncias entre pares únicos. A distância média acabou sendo 0,96, entre 619 659 a distância é 1 (ou seja, não há nenhuma semelhança). O gráfico a seguir mostra que, em geral, há pouca semelhança entre os empregos:





Usando a métrica Jaccard, nosso espaço agora se parece com isto:





Apareceram quatro áreas de densidade distintas e dois pequenos aglomerados de baixa densidade. Pelo menos é assim que meus olhos veem!



Clustering



O Gaussian Mixture Model (GMM) foi escolhido como o algoritmo de agrupamento . O algoritmo recebe dados como vetores como entrada, e o parâmetro n_components é o número de clusters em que o conjunto deve ser dividido. Você pode ver como o algoritmo funciona aqui (em inglês). Usei uma implementação GMM pronta da biblioteca scikit -learn: sklearn.mixture.GaussianMixture .



Observe que o GMM não usa uma métrica, mas separa os dados apenas por um conjunto de recursos e seus pesos. No artigo, a distância de Jaccard é usada para visualizar dados, calcular a compactação dos clusters (tomei a distância média entre os pontos do cluster para compactação) e determinaro ponto central do cluster (vacância típica) - o ponto com a menor distância média aos demais pontos do cluster. Muitos algoritmos de agrupamento usam exatamente a distância entre os pontos. A seção Outros métodos falará sobre outros tipos de agrupamento que são baseados em métricas e também fornecem bons resultados.



Na seção anterior, foi determinado a olho nu que provavelmente haverá seis clusters. É assim que os resultados do agrupamento são exibidos com n_components = 6:







Na figura com a saída dos clusters separadamente, os clusters são organizados em ordem decrescente do número de pontos da esquerda para a direita, de cima para baixo: o cluster 4 é o maior, o cluster 5 é o menor. A compactação de cada cluster é indicada entre colchetes.



Aparentemente, o agrupamento acabou não sendo muito bom, mesmo se considerarmos que o algoritmo t-SNE não é perfeito. Ao analisar os clusters, o resultado também não foi animador.



Para encontrar o número ideal de clusters n_components, usaremos os critérios AIC e BIC, sobre os quais você pode ler aqui . O cálculo desses critérios é incorporado ao método sklearn.mixture.GaussianMixture . É assim que o gráfico de critérios se parece:





Quando n_components = 12, o critério BIC tem o menor (melhor) valor, o critério AIC também tem um valor próximo ao mínimo (mínimo quando n_components = 23). Vamos dividir as vagas em 12 clusters:







Os clusters são agora mais compactos, tanto em aparência quanto em termos numéricos. Durante a análise manual, as vagas foram divididas em grupos de características para a compreensão de uma pessoa. A figura mostra os nomes dos clusters. Os clusters numerados 11 e 4 são marcados como <Lixeira 2>:



  1. No cluster 11, todos os recursos têm aproximadamente os mesmos pesos totais.
  2. O cluster 4 é dedicado a Java. No entanto, existem poucas vagas para o cargo de Desenvolvedor Java no cluster, o conhecimento de Java é muitas vezes necessário, pois "será uma vantagem adicional."


Clusters



Depois de remover dois clusters não informativos numerados 11 e 4, o resultado é 10 clusters:





Para cada cluster, existe uma tabela de recursos e 2 gramas que são mais encontrados nas vagas do cluster.



Legenda:



S - proporção de vagas em que o traço é encontrado, multiplicado pelo peso do traço

% - porcentagem de vagas em que o traço / 2 grama é encontrado Vaga

típica do cluster - vaga, com a menor distância média para outros pontos do cluster



Analista de informações



Número de empregos: 299 Trabalho



típico: 35.805.914

Não. Assine com peso S Placa % 2 gramas %
1 excel 3,13 sql 64,55 conhecimento de sql 18,39
2 r 2,59 excel 34,78 em desenvolvimento 14.05
3 sql 2,44 r 28,76 python r 14.05
4 conhecimento de sql 1,47 bi 19,40 com grande 13,38
cinco análise de dados 1,17 quadro 15,38 Desenvolvimento e 13,38
6 quadro 1.08 Google 14,38 análise de dados 13,04
7 com grande 1.07 vba 13,04 conhecimento de python 12,71
oito Desenvolvimento e 1.07 Ciência 9,70 armazém analítico 11,71
nove vba 1.04 dwh 6,35 experiência de desenvolvimento 11,71
dez conhecimento de python 1.02 oráculo 6,35 bases de dados 11,37


Desenvolvedor C ++



Número de empregos: 139 Trabalho

típico: 39.955.360

Não. Assine com peso S Placa % 2 gramas %
1 c ++ 9,00 c ++ 100,00 experiência de desenvolvimento 44,60
2 Java 3,30 linux 44,60 c c ++ 27,34
3 linux 2,55 Java 36,69 c ++ python 17,99
4 c # 1,88 sql 23,02 em c ++ 16,55
cinco vai 1,75 c # 20,86 desenvolvimento em 15,83
6 desenvolvimento em 1,27 vai 19,42 estruturas de dados 15,11
7 bom conhecimento 1,15 unix 12,23 experiência de escrita 14,39
oito estruturas de dados 1.06 tensorflow 11,51 programação em 13,67
nove tensorflow 1.04 bash 10,07 em desenvolvimento 13,67
dez experiência de programação 0,98 postgresql 9,35 linguagens de programação 12,95


Engenheiro Linux / DevOps



Número de vagas de trabalho: 126 Trabalho

típico: 39.533.926

Não. Assine com peso S Placa % 2 gramas %
1 ansible 5,33 linux 84,92 ci cd 58,73
2 docker 4,78 ansible 76,19 experiência de administração 42,06
3 bash 4,78 docker 74,60 bash python 33,33
4 ci cd 4,70 bash 68,25 tcp ip 39,37
cinco linux 4,43 Prometeu 58,73 experiência de customização 28,57
6 Prometeu 4,11 zabbix 54,76 monitoramento e 26,98
7 nginx 3,67 nginx 52,38 prometheus grafana 23,81
oito experiência de administração 3,37 grafana 52,38 sistemas de monitoramento 22,22
nove zabbix 3,29 postgresql 51,59 com docker 16,67
dez alce 3,22 Kubernetes 51,59 gerenciamento de configurações 16,67


Desenvolvedor Python



Número de vagas de trabalho: 104 Trabalho

típico: 39.705.484

Não. Assine com peso S Placa % 2 gramas %
1 em python 6,00 docker 65,38 em python 75,00
2 django 5,62 django 62,50 desenvolvimento em 51,92
3 frasco 4,59 postgresql 58,65 experiência de desenvolvimento 43,27
4 docker 4,24 frasco 50,96 frasco de django 04,24
cinco desenvolvimento em 4,15 redis 38,46 api resto 23,08
6 postgresql 2,93 linux 35,58 python de 21,15
7 aiohttp 1,99 coelhomq 33,65 bases de dados 18,27
oito redis 1,92 sql 30,77 experiência de escrita 18,27
nove linux 1,73 Mongodb 25,00 com docker 17,31
dez coelhomq 1,68 aiohttp 22,12 com postgresql 16,35


Cientista de dados



Número de empregos: 98 Trabalho

típico: 38 071 218

Não. Assine com peso S Placa % 2 gramas %
1 pandas 7,35 pandas 81,63 aprendizado de máquina 63,27
2 entorpecido 6,04 entorpecido 75,51 pandas entorpecidos 43,88
3 aprendizado de máquina 5,69 sql 62,24 análise de dados 29,59
4 pytorch 3,77 pytorch 41,84 ciência de dados 26,53
cinco ml 3,49 ml 38,78 conhecimento de python 25,51
6 tensorflow 3,31 tensorflow 36,73 cigano entorpecido 24,49
7 análise de dados 2,66 faísca 32,65 python pandas 23,47
oito scikitlearn 2,57 scikitlearn 28,57 em python 21,43
nove ciência de dados 2,39 docker 27,55 estatística matemática 20,41
dez faísca 2,29 hadoop 27,55 algoritmos de máquina 20,41


Desenvolvedor Frontend



Número de empregos: 97 Trabalho

típico: 39.681.044

Não. Assine com peso S Placa % 2 gramas %
1 javascript 9,00 javascript 100 html css 27,84
2 django 2,60 html 42,27 experiência de desenvolvimento 25,77
3 reagir 2,32 postgresql 38,14 em desenvolvimento 17,53
4 nodejs 2,13 docker 37,11 conhecimento de javascript 15,46
cinco a parte dianteira 2,13 css 37,11 e suporte 15,46
6 docker 2.09 linux 32,99 python e 14,43
7 postgresql 1,91 sql 31,96 css javascript 13,40
oito linux 1,79 django 28,87 bases de dados 12,37
nove html css 1,67 reagir 25,77 em python 12,37
dez php 1,58 nodejs 23,71 design e 11,34


Desenvolvedor de back-end



Número de empregos: 93 Trabalho

típico: 40.226.808

Não. Assine com peso S Placa % 2 gramas %
1 django 5,90 django 65,59 python django 26,88
2 js 4,74 js 52,69 experiência de desenvolvimento 25,81
3 reagir 2,52 postgresql 40,86 conhecimento de python 20,43
4 docker 2,26 docker 35,48 em desenvolvimento 18,28
cinco postgresql 2.04 reagir 27,96 ci cd 17,20
6 compreensão dos princípios 1,89 linux 27,96 conhecimento confiante 16,13
7 conhecimento de python 1,63 Processo interno 22,58 api resto 15.05
oito Processo interno 1,58 redis 22,58 html css 13,98
nove ci cd 1,38 sql 20,43 habilidade de entender 10,75
dez a parte dianteira 1,35 mysql 19,35 em um estranho 10,75


DevOps Engineer



Número de empregos: 78 Trabalho

típico: 39634258

Não. Assine com peso S Placa % 2 gramas %
1 devops 8,54 devops 94,87 ci cd 51,28
2 ansible 5,38 ansible 76,92 bash python 30,77
3 bash 4,76 linux 74,36 experiência de administração 24,36
4 Jenkins 4,49 bash 67,95 e suporte 23,08
cinco ci cd 4,10 Jenkins 64,10 docker kubernetes 20,51
6 linux 3,54 docker 50,00 Desenvolvimento e 17,95
7 docker 2,60 Kubernetes 41,03 experiência de escrita 17,95
oito Java 2.08 sql 29,49 e personalização 17,95
nove experiência de administração 1,95 oráculo 25,64 Desenvolvimento e 16,67
dez e suporte 1,85 abertura 24,36 script 14,10


Engenheiro de dados



Número de empregos: 77 Trabalho

típico: 40.008.757

Não. Assine com peso S Placa % 2 gramas %
1 faísca 6,00 hadoop 89,61 processamento de dados 38,96
2 hadoop 5,38 faísca 85,71 big data 37,66
3 Java 4,68 sql 68,83 experiência de desenvolvimento 23,38
4 colmeia 4,27 colmeia 61,04 conhecimento de sql 22,08
cinco escala 3,64 Java 51,95 Desenvolvimento e 19,48
6 big data 3,39 escala 51,95 faísca hadoop 19,48
7 etl 3,36 etl 48,05 java scala 19,48
oito sql 2,79 fluxo de ar 44,16 qualidade de dados 18,18
nove processamento de dados 2,73 kafka 42,86 e processamento 18,18
dez kafka 2,57 oráculo 35,06 colmeia hadoop 18,18


Engenheiro de QA



Número de empregos: 56 Trabalho

típico: 39630489

Não. Assine com peso S Placa % 2 gramas %
1 automação de teste 5,46 sql 46,43 automação de teste 60,71
2 experiência de teste 4,29 qa 42,86 experiência de teste 53,57
3 qa 3,86 linux 35,71 em python 41,07
4 em python 3,29 selênio 32,14 experiência de automação 35,71
cinco Desenvolvimento e 2,57 rede 32,14 Desenvolvimento e 32,14
6 sql 2.05 docker 30,36 experiência de teste 30,36
7 linux 2.04 Jenkins 26,79 experiência de escrita 28,57
oito selênio 1,93 Processo interno 26,79 testando em 23,21
nove rede 1,93 bash 21,43 teste automatizado 21,43
dez Processo interno 1,88 ui 19,64 ci cd 21,43




Salários



Os salários são indicados apenas em 261 (22%) vagas de 1.167 nos clusters.



Ao calcular salários:



  1. Se o intervalo "de ... a ..." foi especificado, o valor médio foi usado
  2. Se apenas "de ..." ou apenas "para ..." foi indicado, então este valor foi tomado
  3. Os cálculos usaram (ou foram dados) salário após impostos (NET)


No gráfico:



  1. Os clusters são classificados em ordem decrescente do salário médio
  2. Barra vertical na caixa - mediana
  3. Box - intervalo [Q1, Q3], onde Q1 (25%) e Q3 (75%) são percentis. Essa. 50% dos salários caem na caixa
  4. O "bigode" inclui salários na faixa [Q1 - 1,5 * IQR, Q3 + 1,5 * IQR], onde IQR = Q3 - Q1 - intervalo interquartil
  5. Os pontos individuais são anomalias que não caíram no bigode. (Existem anomalias não incluídas no diagrama)




Habilidades superiores / antitop



Os gráficos foram construídos para todas as vagas de 1994 carregadas. Os salários são indicados em 443 (22%) vagas. Para o cálculo de cada recurso, foram selecionadas as vagas em que esse recurso está presente e com base nelas foi calculado o salário médio.







Classificação do trabalho



O agrupamento poderia ser muito mais fácil sem recorrer a modelos matemáticos complexos: compilar os principais cargos e dividi-los em grupos. Em seguida, analise cada grupo quanto aos melhores n-gramas e salários médios. Não há necessidade de destacar recursos e atribuir pesos a eles.



Essa abordagem funcionaria bem (até certo ponto) para uma consulta "Python". Mas para o pedido "Programador 1C" esta abordagem não funcionará, porque para programadores 1C, configurações 1C ou áreas aplicadas raramente são indicadas nos nomes das vagas. E há muitas áreas onde 1C é usado: contabilidade, cálculo de salários, cálculo de impostos, cálculo de custos em empresas industriais, contabilidade de depósito, orçamento, sistemas ERP, varejo, contabilidade gerencial, etc.



Para mim, vejo duas tarefas para a análise de vagas:



  1. Entenda onde uma linguagem de programação sobre a qual conheço pouco é usada (como neste artigo).
  2. Filtrar novos empregos publicados.


O agrupamento é adequado para resolver o primeiro problema, para resolver o segundo - vários classificadores, florestas aleatórias, árvores de decisão, redes neurais. No entanto, eu queria avaliar a adequação do modelo escolhido para o problema de classificação de cargos.



Se você usar o método predict () embutido no sklearn.mixture.GaussianMixture , então nada de bom acontecerá. Ele atribui a maioria das vagas a grandes clusters, e dois dos três primeiros clusters não são informativos. Usei uma abordagem diferente: 



  1. Aproveitamos a vaga que queremos classificar. Nós o vetorizamos e obtemos um ponto em nosso espaço.
  2. Calculamos a distância deste ponto a todos os clusters. Abaixo da distância entre um ponto e um cluster, tomei a distância média deste ponto para todos os pontos no cluster.
  3. O cluster com a menor distância é a turma prevista para a vaga selecionada. A distância até o cluster indica a confiabilidade de tal previsão.
  4. Para aumentar a precisão do modelo, escolhi 0,87 como a distância limite, ou seja, se a distância até o cluster mais próximo for maior que 0,87, o modelo não classifica a vaga.


Para avaliar o modelo, 30 vagas foram selecionadas aleatoriamente do conjunto de testes. Na coluna de veredicto:



N / a: o modelo não classificou o trabalho (distância> 0,87)

+: classificação correta

-: classificação incorreta  

Vaga de emprego Cluster mais próximo Distância Veredito
37637989 Engenheiro Linux / DevOps 0,9464 N / D
37833719 Desenvolvedor C ++ 0,8772 N / D
38324558 Engenheiro de dados 0,8056 +
38517047 Desenvolvedor C ++ 0,8652 +
39053305 Lixo 0,9914 N / D
39210270 Engenheiro de dados 0,8530 +
39349530 Desenvolvedor Frontend 0,8593 +
39402677 Engenheiro de dados 0,8396 +
39415267 Desenvolvedor C ++ 0,8701 N / D
39734664 Engenheiro de dados 0,8492 +
39770444 Desenvolvedor de back-end 0,8960 N / D
39770752 Cientista de dados 0,7826 +
39795880 Analista de informações 0,9202 N / D
39947735 Desenvolvedor Python 0,8657 +
39954279 Engenheiro Linux / DevOps 0,8398 -
40008770 DevOps Engineer 0,8634 -
40015219 Desenvolvedor C ++ 0,8405 +
40031023 Desenvolvedor Python 0,7794 +
40072052 Analista de informações 0,9302 N / D
40112637 Engenheiro Linux / DevOps 0,8285 +
40164815 Engenheiro de dados 0,8019 +
40186145 Desenvolvedor Python 0,7865 +
40201231 Cientista de dados 0,7589 +
40211477 DevOps Engineer 0,8680 +
40224552 Cientista de dados 0,9473 N / D
40230011 Engenheiro Linux / DevOps 0,9298 N / D
40241704 Lixo 2 0,9093 N / D
40245997 Analista de informações 0,9800 N / D
40246898 Cientista de dados 0,9584 N / D
40267920 Desenvolvedor Frontend 0,8664 +


Total: 12 vagas sem resultado, 2 vagas - classificação errada, 16 vagas - classificação correta. Completude do modelo - 60%, precisão do modelo - 89%.



Lados fracos



O primeiro problema - vamos pegar duas vagas:

Vaga 1 -

Requisitos para " Programador C ++ Líder" ":



  • 5+ anos de experiência em desenvolvimento C ++.
  • Conhecimento de Python será uma vantagem adicional. "


Vaga 2 -

Requisitos para " Programador Python Líder" ":

  • Mais de 5 anos de experiência em desenvolvimento Python.
  • Conhecimento de C ++ será uma vantagem adicional "
Do ponto de vista do modelo, essas vagas são idênticas. Tentei ajustar os pesos dos recursos pela ordem de sua ocorrência no texto. Isso não levou a nada de bom.



O segundo problema é que o GMM agrupa todos os pontos de um conjunto, como muitos algoritmos de agrupamento. Os clusters não informativos não são um problema por si só. Mas os clusters informativos também contêm outliers. No entanto, isso pode ser facilmente resolvido limpando os clusters, por exemplo, removendo os pontos mais atípicos que têm a maior distância média para o resto dos pontos do cluster.



Outros métodos



A página de comparação de cluster demonstra bem os vários algoritmos de cluster. GMM é o único que deu bons resultados.

O resto dos algoritmos não funcionou ou deu resultados muito modestos.



Daqueles implementados por mim, os bons resultados foram em dois casos:



  1. Pontos com alta densidade foram selecionados em uma determinada vizinhança, localizados a uma distância distante uns dos outros. Os pontos tornaram-se os centros dos aglomerados. Então, a partir dos centros, iniciou-se o processo de formação dos agrupamentos - a junção de pontos vizinhos.
  2. O agrupamento aglomerativo é uma fusão iterativa de pontos e clusters. A biblioteca scikit-learn apresenta esse tipo de agrupamento, mas não funciona bem. Em minha implementação, alterei a matriz de junção após cada iteração da mesclagem. O processo parou quando alguns parâmetros de limite foram alcançados - na verdade, os dendrogramas não ajudam a entender o processo de fusão se 1.500 elementos estão agrupados.


Conclusão



A pesquisa que fiz me deu as respostas para todas as perguntas no início do artigo. Tive experiência prática com clustering enquanto implementava variações de algoritmos conhecidos. Eu realmente espero que o artigo motive o leitor a realizar sua pesquisa analítica e, de alguma forma, ajude nesta lição emocionante.



All Articles