propósito de criação
Internamente, existem muitas ferramentas de código aberto para cálculo de similaridade de texto.
No entanto, para o cálculo da semelhança entre dois caracteres chineses, há basicamente um espaço em branco na China. Existem muito poucos materiais de referência nacionais, e o mesmo é verdade para documentos estrangeiros relacionados.
O objetivo deste projeto é lançar tijolos e iniciar o jade, realizar uma ferramenta básica de cálculo de similaridade e contribuir um pouco para o NLP de caracteres chineses.
Leitura recomendada:
Forma chinesa de PNL perto da ideia de cálculo de similaridade de palavras
Qual é o caractere chinês mais caro da China contemporânea?
Forma de código aberto de NLP perto do plano de conclusão do algoritmo de palavras (final)
PNL Open Source Algoritmo de Forma Perto de Palavra Lista de Forma Perto de Palavras (Extra)
precisar
Às vezes, não precisamos retornar a semelhança de dois caracteres, mas precisamos retornar uma lista semelhante de caracteres chineses.
Ideias de implementação
Podemos calcular a semelhança entre todos os caracteres chineses separadamente e, em seguida, manter os 100 maiores e colocá-los no dicionário.
Em seguida, consulte o dicionário em tempo real.
Método para realizar
bihuashu_2w.txt
O que precisamos principalmente são os caracteres chineses comuns de 2W correspondentes.
hanzi_similar_list.txt
Ele é usado para armazenar o relacionamento de mapeamento entre caracteres chineses e caracteres semelhantes.
inicialização de dados
public static void main(String[] args) {
final String path = "D:\\code\\coin\\nlp-hanzi-similar\\src\\main\\resources\\hanzi_similar_list.txt";
// 读取列表
List<String> lines = FileUtil.readAllLines("D:\\code\\coin\\nlp-hanzi-similar\\src\\main\\resources\\nlp\\bihuashu_2w.txt");
// 所有的单词
Set<String> allWordSet = new HashSet<>();
for(String line : lines) {
String word = line.split(" ")[0];
allWordSet.add(word);
}
// 循环对比
for(String word : allWordSet) {
List<String> list = getSimilarListData(word, allWordSet);
String line = word +" " + StringUtil.join(list, "");
FileUtil.append(path, line);
}
}
复制代码
- A fila de prioridade leva os primeiros 100
Armazenamos via fila prioritária:
private static List<String> getSimilarListData(String word, Set<String> wordSet) {
PriorityQueue<SimilarListDataItem> items = new PriorityQueue<>(new Comparator<SimilarListDataItem>() {
@Override
public int compare(SimilarListDataItem o1, SimilarListDataItem o2) {
// 相似度大的放在前面
return -o1.getRate().compareTo(o2.getRate());
}
});
for(String other : wordSet) {
if(word.equals(other)) {
continue;
}
// 对比
double rate = HanziSimilarHelper.similar(word.charAt(0), other.charAt(0));
SimilarListDataItem item = new SimilarListDataItem(other, rate);
items.add(item);
}
final int limit = 100;
List<String> wordList = new ArrayList<>();
for(SimilarListDataItem item : items) {
wordList.add(item.getWord());
if(wordList.size() >= limit) {
break;
}
}
return wordList;
}
复制代码
obter palavras semelhantes
Depois de inicializar os dados, tudo se torna muito simples:
- Definição de interface
/**
* 数据接口-相似列表
* @author binbin.hou
* @since 1.3.0
*/
public interface IHanziSimilarListData {
/**
* 返回数据信息
* @param word 单词
* @return 结果
* @since 1.3.0
*/
List<String> similarList(String word);
}
复制代码
- coleção de dados
public class HanziSimilarListData implements IHanziSimilarListData {
private static volatile Map<String, List<String>> map = Guavas.newHashMap();
@Override
public List<String> similarList(String word) {
if(MapUtil.isEmpty(map)) {
initDataMap();
}
return map.get(word);
}
private void initDataMap() {
if(MapUtil.isNotEmpty(map)) {
return;
}
//DLC
synchronized (map) {
if(MapUtil.isEmpty(map)) {
List<String> lines = StreamUtil.readAllLines("/hanzi_similar_list.txt");
for(String line : lines) {
String[] words = line.split(" ");
// 后面的100个相近词
List<String> list = StringUtil.toCharStringList(words[1]);
map.put(words[0], list);
}
}
}
}
}
复制代码
conveniência
Para conveniência dos usuários, adicionamos 2 métodos de classe de ferramentas HanziSimilarHelper
em :
/**
* 相似的列表
* @param hanziOne 汉字一
* @param limit 大小
* @return 结果
* @since 1.3.0
*/
public static List<String> similarList(char hanziOne, int limit) {
return HanziSimilarBs.newInstance().similarList(hanziOne, limit);
}
/**
* 相似的列表
* @param hanziOne 汉字一
* @return 结果
* @since 1.3.0
*/
public static List<String> similarList(char hanziOne) {
return similarList(hanziOne, 10);
}
复制代码
efeito de teste
Vamos usá-lo para ver o efeito:
Vamos dar uma olhada nos personagens semelhantes de "amor".
List<String> list = HanziSimilarHelper.similarList('爱');
Assert.assertEquals("[爰, 爯, 受, 爭, 妥, 憂, 李, 爳, 叐, 雙]", list.toString());
复制代码
endereço de código aberto
A fim de tornar mais fácil para todos usar e aprender, o projeto foi de código aberto.
resumo
A forma de um personagem pode fazer muitas coisas interessantes, depende da imaginação de cada um.
O método de implementação não é difícil e o núcleo é o cálculo da similaridade.
Eu sou um cavalo velho, ansioso para conhecê-lo na próxima vez.