Lernen Sie maschinelles Lernen (DeepLeaning4j) in Java und versuchen Sie, Wörter zu extrahieren, die in hohem Maße mit einem bestimmten Wort zusammenhängen

Dinge die zu tun sind

[Wikipedia-Artikel](https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%82%A4%E3 % 83% B3% E3% 83% 91% E3% 82% AF% E3% 83% 88_ (% E7% AB% B6% E8% B5% B0% E9% A6% AC)) als Trainingsdaten Extrahieren Sie Wörter (Substantive und Verben), die in hohem Maße mit "Deep Impact" zusammenhängen.

Punkt

Text im Voraus vorzubereiten

[Hier](https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%82%A4%E3%83 Fügen Sie den Text entsprechend aus% B3% E3% 83% 91% E3% 82% AF% E3% 83% 88_ (% E7% AB% B6% E8% B5% B0% E9% A6% AC) ein. Als UTF-8 speichern.

Implementierung

So ist es einfach, also in Maven

pom.xml


(Kürzung)

    <repositories>    
        <repository>
            <id>ATILIKA dependencies</id>
            <url>http://www.atilika.org/nexus/content/repositories/atilika</url>
        </repository>    
    </repositories>

(Unterlassung)
        <dependency>
            <artifactId>lucene-core</artifactId>
            <groupId>org.apache.lucene</groupId>
            <version>5.1.0</version>
        </dependency>        
        <dependency>
            <artifactId>lucene-analyzers-kuromoji</artifactId>
            <groupId>org.apache.lucene</groupId>
            <version>5.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.deeplearning4j</groupId>
            <artifactId>deeplearning4j-ui</artifactId>
            <version>0.5.0</version>
        </dependency>

        <dependency>
            <groupId>org.deeplearning4j</groupId>
            <artifactId>deeplearning4j-nlp</artifactId>
            <version>0.5.0</version>
        </dependency>

        <dependency>
            <groupId>org.nd4j</groupId>
            <artifactId>nd4j-native</artifactId>
            <version>0.5.0</version>
        </dependency>    

        <dependency>
            <groupId>org.atilika.kuromoji</groupId>
            <artifactId>kuromoji</artifactId>
            <version>0.7.7</version>
            <type>jar</type>
        </dependency>

Wickeln Sie Kuromojis Tokenizer ein

So wie es ist, kann nur Englisch die Morphologie analysieren, so dass Kuromoji verwendet werden kann. Hier war sehr hilfreich. Oder besser gesagt, fast so wie es ist. Es wurden jedoch einige Änderungen vorgenommen.

KuromojiIpadicTokenizer.java



/**
 *Weil eine japanische morphologische Analyse erforderlich ist
 *Wickeln Sie Kuromojis Tokenizer in die Tokneizer-Oberfläche von dl4j ein
 * @author 
 */
public class KuromojiIpadicTokenizer implements Tokenizer{
    private List<Token> tokens;
    private int index;
    private TokenPreProcess preProcess;

    /**
     *Das Wörterbuch funktioniert einfach nicht ...
     *Stellen Sie den Modus vorerst auf Suchen ein, damit er sich relativ gut anfühlt.
     */
    public KuromojiIpadicTokenizer (String toTokenize) {
      
        try{
            org.atilika.kuromoji.Tokenizer tokenizer 
                = org.atilika.kuromoji.Tokenizer.builder()
                    .userDictionary("D:\\deepleaning\\mydic.txt")
                    .mode(org.atilika.kuromoji.Tokenizer.Mode.SEARCH)
                    .build();
            tokens = tokenizer.tokenize(toTokenize);
            index = (tokens.isEmpty()) ? -1:0;
        } catch (IOException ex) {
            Logger.getLogger(KuromojiIpadicTokenizer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    @Override
    public int countTokens() {
        return tokens.size();
    }

    @Override
    public List<String> getTokens() {
        List<String> ret = new ArrayList<String>();
        while (hasMoreTokens()) {
            ret.add(nextToken());
        }
        return ret;
    }

    @Override
    public boolean hasMoreTokens() {
        if (index < 0)
            return false;
        else
            return index < tokens.size();
    }

    /**
     *Konzentrieren Sie sich auf verwandte Wörter zur Nomenklatur und Verben (Grundform)
     *Eine benutzerdefinierte Nomenklatur kann erforderlich sein, wenn das Benutzerwörterbuch von kuromoji funktioniert
     *Legen Sie andere Teile in Räume halber Breite, um eine Analyse zu vermeiden
     * @return 
     */
    @Override
    public String nextToken() {
        if (index < 0)
        return null;

        Token tok = tokens.get(index);
        index++;
        if(!tok.getPartOfSpeech().startsWith("Substantiv") 
            && !tok.getPartOfSpeech().startsWith("Verb")
            && !tok.getPartOfSpeech().startsWith("Benutzerdefinierte Nomenklatur")){
            return " ";
        } else if (preProcess != null) return preProcess.preProcess(tok.getPartOfSpeech().startsWith("Verb") ? tok.getBaseForm() : tok.getSurfaceForm());
        else return tok.getSurfaceForm();
    }

    @Override
    public void setTokenPreProcessor(TokenPreProcess preProcess) {
        this.preProcess = preProcess;
    }
    
}

KuromojiIpadicTokenizerFactory.java


/**
 *Wickeln Sie Kuromojis Fabrik ein
 * @author 
 */
public class KuromojiIpadicTokenizerFactory implements TokenizerFactory {

    private TokenPreProcess preProcess;

    private static String preValue = "";
    
    @Override
    public Tokenizer create(String toTokenize) {
//        System.out.println(toTokenize);
        if (toTokenize == null || toTokenize.isEmpty()) {
            //Vermeiden Sie Analysen mit Leerzeichen halber Breite, keine Ausnahmen
            //Andernfalls können Sie keine Dokumente mit aufeinander folgenden Zeilenumbrüchen lernen
            toTokenize = " ";
        }
        KuromojiIpadicTokenizer ret = new KuromojiIpadicTokenizer(toTokenize);
        ret.setTokenPreProcessor(preProcess);
        return ret;
    }

    @Override
    public Tokenizer create(InputStream paramInputStream) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setTokenPreProcessor(TokenPreProcess preProcess) {
        this.preProcess = preProcess;
    }

    @Override
    public TokenPreProcess getTokenPreProcessor() {
        return this.preProcess;
    }
    
}

Lassen Sie sie lernen und die Ergebnisse ausgeben

Verwenden Sie diesen Kerl.

WordVecSample.java


/**
 *Wörter aus Sätzen extrahieren
 *Die Relevanz (Wörter, die häufig in engen Positionen vorkommen, sind hochrelevante Theorien, obwohl sie schlampig sind)
 *Probe zum Lernen und Berechnen von hochrelevanten Wörtern
 * @author 
 */
public class WordVecSample {
    public static void main(String[] args) throws IOException{

        /**
         *Ursprünglich für Englisch
         *Der japanische Analysator wird für Stoppwörter verwendet (Wörter, die nicht ausgewertet werden).
         *Obwohl das Bewertungsziel auf Verben (Grundform) und Nomenklatur eingegrenzt ist, ist es schwierig, "aru", "iru" usw. anzuvisieren.
         */
        List<String> stopWords = new ArrayList<>();
        stopWords.addAll(Arrays.asList(JapaneseAnalyzer.getDefaultStopSet().toString().split(", ")));
        //Dieses Mal habe ich auch chinesische Zahlen als Test hinzugefügt
        stopWords.addAll(Arrays.asList("einer","D.","drei","vier","Fünf","Sechs","Sieben","Acht","Neun","Zehn"));
        
        /**
         *Korpus(Sammlung von Sätzen)Lade Daten
         *■ Da die Trainingsdaten diesmal überwiegend klein sind, ist es unmöglich, sie auf dieser Ebene in die Praxis umzusetzen.
         *Bis zur letzten Probe ...
         */
        System.out.println( "Trainingsdaten lesen..." );
        File f = new File( "D:\\deepleaning\\deepImpact.txt" );
        SentenceIterator ite = new LineSentenceIterator( f );
        //Erben Sie den Präprozessor und glätten Sie das Wort
        //An diesem Punkt ist es möglicherweise besser, eine Kana-Konvertierung mit halber Breite einzuschließen
        ite.setPreProcessor((String sentence) -> sentence.toLowerCase().replaceAll("\n", " "));
        
        /**
         *Zerlegen Sie Sätze in Wörter
         *Der Punkt ist, die Notation vor der Token-Teilung in preProcess zu glätten
         *■ Ersetzen Sie es für die morphologische Analyse, damit Kuromoji verwendet wird, da es Japanisch unterstützt.
         */
        final EndingPreProcessor preProcessor = new EndingPreProcessor();
        KuromojiIpadicTokenizerFactory tokenizer = new KuromojiIpadicTokenizerFactory();
        tokenizer.setTokenPreProcessor((String token) -> {
            if(token == null) {
                return " ";
            } else {
                token = token.toLowerCase();
                String base = preProcessor.preProcess( token );
                return base;
            }
        });

        /**
         *Modell erstellen (Tokenizer und verschiedene Einstellungen)
         *Dieses Mal habe ich die Parameter so angepasst, dass ich mit ein paar Sätzen ein solches Ergebnis erzielen kann.
         */
        System.out.println( "Ein Modell bauen..." );
        Word2Vec vec = new Word2Vec.Builder()
            .minWordFrequency( 1 )          //Lernen Sie keine Wörter mit weniger als der angegebenen Anzahl von Erscheinungen. ⇒ Dieses Mal gibt es nur wenige Korsus, daher ist die Einstellung niedrig
            .iterations( 3 )                //Anzahl der Iterationen während des Lernens
            .batchSize( 1000 )              //Maximale Anzahl von Wörtern, die in einer Iteration gelernt werden sollen
            .layerSize( 120 )               //Anzahl der Vektordimensionen von Wörtern
            .learningRate( 0.09 )           //Lernrate
            .minLearningRate( 1e-3 )        //Mindestlernrate
            .useAdaGrad( false )            // http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf nicht verwendet
            .negativeSample( 30 )           //Anzahl der in Skipgram verwendeten umgekehrten Antworten Wenn Sie viel Korsus haben, sollten Sie ihn wahrscheinlich reduzieren.
            .stopWords(stopWords)           //Ausgeschlossene Wörter: Schließen Sie Wörter aus, die an einer beliebigen Stelle erscheinen, z. B. vorhanden sind
            .iterate( ite )                 //Corsus-Modell
            .tokenizerFactory(tokenizer)    //Tokenizer
            .build();

        /**
         *Lernen
         */
        System.out.println( "Lernen..." );
        vec.fit();

        /**
         *Ergebnismodell des Trainings für die Analyse ausgeben
         *In der Tat ist es eine gute Idee, dies mit geeigneten Mitteln fortzusetzen.
         */
        WordVectorSerializer.writeWordVectors( vec , "D:\\words2.txt" );

        /**
         *Ausgabe von Lernergebnissen
         */
        /*
            //Die Ähnlichkeit zwischen zwei Wörtern kann anhand des Kosinusabstands berechnet werden. Da jedoch nur wenige Stichproben vorhanden sind, werden nur Kommentare geschrieben.
            String word1 = "Wort 1";
            String word2 = "Wort 2";
            double similarity = vec.similarity( word1 , word2 );
            System.out.println( String.format( "The similarity between 「%s」 and 「%s」 is %f" , word1 , word2 , similarity ) );
        */

        //Versuchen Sie, 5 Wörter auszuwählen, die einem beliebigen Wort ähnlich sind
        String word = "tiefe Wirkung";
        int ranking = 5;
        Collection<String> similarWords = vec.wordsNearest( word , ranking );
        System.out.println( String.format( "「%Wörter, von denen angenommen wird, dass sie eng mit "s" verwandt sind ⇒%s" , word , similarWords ) );
    }
    
}

Ausgabeergebnis

Ab dem zweiten Mal werden die vorherigen Lernergebnisse nicht mehr vererbt. Ergebnis des Lernens jedes Mal zurückgesetzt

1. Mal


Wörter, von denen angenommen wird, dass sie in engem Zusammenhang mit "Deep Impact" stehen
⇒ [Gerade Linie,Reiter,Baba,Lauf,Symbolil Dorf]

Zweites Mal


Wörter, von denen angenommen wird, dass sie in engem Zusammenhang mit "Deep Impact" stehen
⇒ [Stier,Andre,Schriftsteller,Sieg,Wies darauf hin]

3. Mal


Wörter, von denen angenommen wird, dass sie in engem Zusammenhang mit "Deep Impact" stehen
⇒ [erhalten,Wettkarte,Zum,Vergrößerung,Pferd]

4. Mal


Wörter, von denen angenommen wird, dass sie in engem Zusammenhang mit "Deep Impact" stehen
⇒ [Spiel,Westlicher Text,Auswertung,Hongkong,Selbst]

5. Mal


Wörter, von denen angenommen wird, dass sie in engem Zusammenhang mit "Deep Impact" stehen
⇒ [Noten,Eisen,Lauf,Schirokko,Kommen Sie]

Das erste Mal ist so wie es ist. Das zweite und nachfolgende Mal sind jedoch schrecklich. .. ..

Diesem Ergebnis kann nicht geholfen werden, da es sich um eine Studie mit nur einem Artikel handelt. Ich denke, es wäre schön, die Trainingsdaten zu erhöhen und die Parameter anzupassen.

Es wird jedoch ein Wörterbuch mit Rennpferdenamen hinzugefügt, um die Wortteilung von Pferdenamen zu verhindern. Es scheint notwendig, trotzdem ein paar Stoppwörter hinzuzufügen. Ich frage mich, ob ich kein Verb brauchte.

Recommended Posts

Lernen Sie maschinelles Lernen (DeepLeaning4j) in Java und versuchen Sie, Wörter zu extrahieren, die in hohem Maße mit einem bestimmten Wort zusammenhängen
So testen Sie eine private Methode und verspotten sie teilweise in Java
Java erstellt eine Tabelle in einem Word-Dokument
Versuchen Sie, ein Bulletin Board in Java zu erstellen
[Einführung in die Informatik Nr. 0: Versuchen Sie maschinelles Lernen] Lassen Sie uns die k-Mittelungsmethode in Java implementieren
So konvertieren Sie A in a und a in A mit logischem Produkt und Summe in Java
Versuchen Sie, ein eingeschränktes FizzBuzz-Problem in Java zu lösen
[Beispiel für eine Java-Verbesserung] Erfahrung mit dem Erlernen von Java in 2 Monaten und dem Wechsel von Jobs zu einem Programmierer
So entwickeln und registrieren Sie eine Sota-App in Java