Récemment, la vague de Deep se précipite dans la région de la PNL, alors certaines personnes peuvent dire: «Je n'utilise pas KNP de nos jours». Cependant, si vous ne disposez pas de données correctes et que vous ne pouvez pas utiliser de méthodes courantes, ou si vous souhaitez essayer les résultats basés sur des règles avant d'essayer la méthode approfondie, il existe de nombreux résultats d'analyse de cas et diverses fonctionnalités. KNP est toujours utile car il vous donne beaucoup d'informations.
D'un autre côté, il ne peut pas être utilisé comme une bibliothèque comme Sudachi, donc cela peut être un problème à utiliser dans un programme (en particulier dans des langages autres que Python avec pyKNP).
Donc, cette fois, j'ai créé une bibliothèque Wrapper qui appelle KNP (et Human ++) à partir de Java. (https://github.com/Natsuume/knp4j) ~~ Je voulais le publier dans le référentiel Maven, mais je n'ai pas pu le faire à temps, donc je le publierai bientôt dans le référentiel Maven. ~~
~~ De plus, bien que nous ayons confirmé l'opération dans une certaine mesure, il est possible que des problèmes surviennent parce que nous n'avons pas écrit un test approprié ~~
Publié dans Maven Central. Maintenant disponible sur Maven, Gradle, etc.
pom.xml
<dependency>
<groupId>dev.natsuume.knp4j</groupId>
<artifactId>knp4j</artifactId>
<version>1.1.3</version>
</dependency>
build.gradle
implementation 'dev.natsuume.knp4j:knp4j:1.1.3'
C'est presque comme README.md sur github.
Sample.java
//Builder pour créer KNPWrapper
ResultParser<KnpResult> knpResultParser = new KnpResultParser();
KnpWrapperBuilder<KnpResult> knpWrapperBuilder = new KnpWrapperBuilder<>();
KnpWrapper<KnpResult> wrapper = knpWrapperBuilder
.setJumanCommand(List.of("bash", "-c", "jumanpp")) //Commande d'exécution Juman
.setKnpCommand(List.of("bash", "-c", "knp -tab -print-num -anaphora")) //Commande d'exécution KNP(Actuellement"-tab」「-print-num」「-option anaphora "requise)
.setJumanMaxNum(1) //Nombre maximum de processus humains à démarrer en même temps
.setJumanStartNum(1) //Nombre de processus humains à démarrer à l'initialisation
.setKnpMaxNum(1) //Nombre maximum de processus KNP à démarrer en même temps
.setKnpStartNum(1) //Nombre de processus KNP démarrés à l'initialisation
.setRetryNum(0) //Nombre de tentatives si l'acquisition des résultats échoue
.setResultParser(knpResultParser) //Liste des résultats de sortie<String>Définissez Parser pour qu'il se convertisse en n'importe quelle classe
.start();
var texts = List.of(
"Texte de test 1",
"Texte de test 2",
"Texte de test 3"
);
texts.parallelStream().map(wrapper::analyze)
.flatMap(List::stream)
.map(KnpResult::getSurfaceForm)
.forEach(System.out::println);
Donnez divers paramètres avec KnpWrapperBuilder
et générez et démarrez KnpWrapper pour la première fois avec start ()
.
Donnez à setJumanCommand
, setKnpCommand
les mêmes commandes que vous donnez à ProcessBuilder
.
Selon l'environnement, il peut être possible d'exécuter uniquement avec les chemins JUMAN et KNP.
(Dans mon environnement, j'ai dû appeler JUMANPP, KNP sur WSL, donc j'ai donné une commande comme l'exemple ci-dessus)
Pour les paramètres autres que setResultParser ()
, le contenu de l'exemple ci-dessus est les valeurs par défaut.
Configurez plusieurs processus et réutilisez-les. Le nombre de processus qui peuvent être configurés en même temps peut être librement défini pour chacun des JUMAN et KNP.
JUMAN et KNP ont un mode serveur, mais ce n'est pas actuellement pris en charge (sera pris en charge à l'avenir).
Fondamentalement, on suppose qu'il ne sera pas utilisé, mais lorsque ʻIOException ou ʻInterruptedException
se produisent dans une série de traitements, le processus dans lequel l'exception s'est produite est arrêté et un autre processus tente d'analyser à nouveau.
Tout analyseur qui implémente l'interface ResultParser
peut être utilisé comme analyseur de sortie.
Les deux types de méthodes suivants sont définis pour ResultParser
.
ResultParser.java
public interface ResultParser<OutputT> {
/**
*Renvoie une instance arbitraire avec le résultat de l'analyse de Knp en entrée.
*
* @Liste de paramètres Résultat de l'analyse Knp
* @return Instance représentant le résultat de l'analyse
*/
OutputT parse(List<String> list);
/**
*Renvoie l'instance à utiliser si l'analyse échoue.
*
* @renvoyer l'instance à renvoyer en cas d'échec de l'analyse
*/
OutputT getInvalidResult();
}
getInvalidResult ()
est une méthode qui retourne une instance lorsqu'un résultat d'analyse normal ne peut pas être obtenu.
Il est utilisé lorsque la réexécution à l'exception ci-dessus échoue, ou lorsque KNP ne parvient pas à analyser (KNP ne parvient pas à analyser si la demi-largeur «+», «*» est incluse).
Changez jumanMaxNum
, knpMaxNum
avec le code ci-dessous et comparez le temps d'exécution (ms).
Dans l'environnement expérimental, le processeur est Ryzen 7 3700x et la taille du tas est de 32 Go.
Dans l'environnement expérimental, JUMAN et KNP de WSL sont appelés. (On dit que WSL est lent IO, donc il peut être un peu plus rapide dans d'autres environnements?)
public static void main(String[] args) {
long time = System.currentTimeMillis();
KnpWrapperBuilder<KnpResult> knpWrapperBuilder = new KnpWrapperBuilder<>();
int jumanMaxNum = 1;
int knpMaxNum = 1;
int textSize = 100;
KnpWrapper<KnpResult> wrapper =
knpWrapperBuilder
.setJumanMaxNum(jumanMaxNum)
.setKnpMaxNum(knpMaxNum)
.setResultParser(new KnpResultParser())
.start();
var sampleText = "Je me suis inscrit au calendrier de l'Avent avec Nori,"
+ "Je ne vois aucun signe du temps donc aujourd'hui%Vous ne pouvez dormir qu'après avoir travaillé pendant d heures.";
var texts =
IntStream.range(0, textSize)
.mapToObj(i -> String.format(sampleText, i))
.collect(Collectors.toList());
var results =
texts
.parallelStream()
.map(wrapper::analyze)
.flatMap(List::stream)
.collect(Collectors.toList());
System.out.println("time: " + (System.currentTimeMillis() - time));
System.exit(0);
}
jumanMaxNum | knpMaxNum | Première fois | Deuxième fois | Troisième fois | 4e | 5ème fois | moyenne |
---|---|---|---|---|---|---|---|
1 | 1 | 17297 | 17320 | 17241 | 17159 | 17421 | 17287.6 |
1 | 5 | 2808 | 2764 | 2858 | 2791 | 2789 | 2802 |
5 | 1 | 20334 | 20211 | 19974 | 20037 | 20189 | 20149 |
Pour le moment, j'ai trouvé que JUMAN et KNP sont plus rapides lorsque KNP est exécuté dans plusieurs processus que lorsqu'ils sont exécutés dans un seul processus. En revanche, contrairement à KNP, qui est le goulot d'étranglement, le côté JUMAN semble ralentir s'il est trop augmenté.
Afin de voir à quel point le résultat diffère en fonction du nombre de processus de JUMAN et KNP, le nombre de textes a été augmenté de 100 à 500 et les combinaisons suivantes ont également été mesurées.
jumanMaxNum | knpMaxNum | Première fois | Deuxième fois | Troisième fois | 4e | 5ème fois | moyenne |
---|---|---|---|---|---|---|---|
1 | 5 | 27953 | 27590 | 27674 | 27999 | 27669 | 27777 |
1 | 10 | 15825 | 16366 | 15118 | 15632 | 14931 | 15574.4 |
5 | 10 | 18704 | 17778 | 17355 | 16134 | 17254 | 17445 |
10 | 10 | 19514 | 19265 | 20459 | 19891 | 19233 | 19672.4 |
1 | 15 | 14533 | 22271 | 14187 | 21838 | 19794 | 18524.6 |
5 | 15 | 14149 | 14584 | 14929 | 15709 | 15228 | 14919.8 |
10 | 15 | 19313 | 17903 | 15478 | 18219 | 16740 | 17530.6 |
1 | 20 | 21620 | 14489 | 21960 | 20456 | 15671 | 18839.2 |
5 | 20 | 15899 | 15820 | 15713 | 14720 | 17053 | 15841 |
10 | 20 | 18850 | 15850 | 18461 | 18200 | 16357 | 17543.6 |
~~ Je ne sais pas. ~~ Pour le moment, la combinaison moyenne la plus rapide dans cet environnement était une combinaison de 5 processus pour JUMAN et 15 processus pour KNP. Cependant, j'estime que les combinaisons autour de [1, 10], [5, 15], [5, 20] sont dans la plage d'erreur.
Essayez également le résultat de la saisie de la commande suivante sur le terminal WSL.
time echo "Je l'ai enregistré sur le calendrier de l'Avent, mais je n'en vois aucun signe à temps, je dois donc travailler une heure aujourd'hui avant de pouvoir dormir." | jumanpp | knp -tab -print-num -anaphora
résultat | Première fois | Deuxième fois | Troisième fois | 4e | 5ème fois | moyenne |
---|---|---|---|---|---|---|
real | 220 | 223 | 234 | 219 | 234 | 226 |
user | 78 | 78 | 63 | 109 | 94 | 84.4 |
sys | 125 | 125 | 141 | 78 | 125 | 118.8 |
C'est amusant de voir le processeur tourner
Recommended Posts