package org.deeplearning4j.examples.nlp.word2vec;

import org.datavec.api.util.ClassPathResource;
import org.deeplearning4j.models.embeddings.loader.WordVectorSerializer;
import org.deeplearning4j.models.word2vec.Word2Vec;
import org.deeplearning4j.text.sentenceiterator.BasicLineIterator;
import org.deeplearning4j.text.sentenceiterator.SentenceIterator;
import org.deeplearning4j.text.tokenization.tokenizer.preprocessor.CommonPreprocessor;
import org.deeplearning4j.text.tokenization.tokenizerfactory.DefaultTokenizerFactory;
import org.deeplearning4j.text.tokenization.tokenizerfactory.TokenizerFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;

/**
 * Utworzony przez agibsonccc 9.10.2014.
 *
 * Sieć neuronowa przekształcająca tekst na wektory słów. Dokładny opis znajduje się na poniższej stronie:
 * https://deeplearning4j.org/word2vec.html
 */
public class Word2VecRawTextExample {

    private static Logger log = LoggerFactory.getLogger(Word2VecRawTextExample.class);

    public static void main(String[] args) throws Exception {

        // Uzyskanie ścieżki do pliku tekstowego.
        String filePath = new ClassPathResource("raw_sentences.txt").getFile().getAbsolutePath();

        log.info("Ładowanie i wektoryzowanie zdań...");
        // Usunięcie spacji z początków i końców wierszy.
        SentenceIterator iter = new BasicLineIterator(filePath);
        // Dzielenie wierszy na słowa rozdzielone spacjami.
        TokenizerFactory t = new DefaultTokenizerFactory();

        /*
         Klasa CommonPreprocessor stosuje następujące wyrażenie regularne dla każdego tokena: [\d\.:,"'\(\)\[\]|/?!;]+.
         W efekcie wszystkie cyfry, znaki interpunkcyjne, symbole i znaki specjalne zostają usunięte.
         Ponadto wszystkie litery w tokenach są zamieniane na małe litery.
        */
        t.setTokenPreProcessor(new CommonPreprocessor());

        log.info("Tworzenie modelu...");
        Word2Vec vec = new Word2Vec.Builder()
                .minWordFrequency(5)
                .iterations(1)
                .layerSize(100)
                .seed(42)
                .windowSize(5)
                .iterate(iter)
                .tokenizerFactory(t)
                .build();

        log.info("Fitting Word2Vec model....");
        vec.fit();

        log.info("Dopasowywanie modelu Word2Vec...");

        // Zapisywanie wektorów słów w pliku tekstowym.
        WordVectorSerializer.writeWordVectors(vec, "pathToWriteto.txt");

        // Wyświetlenie 10 słów o znaczeniu najbliższym słowu „day”. Jest to przykład, co można zrobić za pomocą tego modelu.
        log.info("Najbliższe słowa:");
        Collection<String> lst = vec.wordsNearest("day", 10);
        System.out.println("10 słów najbardziej podobnych do 'day': " + lst);

        // Utworzenie brakującego obiektu UiServer.
        // UiServer server = UiServer.getInstance();
        // System.out.println("Nasłuch na porcie " + server.getPort());
    }
}
