반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
05-19 00:03
관리 메뉴

ImJay

[Java Gradle] Python 코드를 Java 로 실행시키기 본문

자바

[Java Gradle] Python 코드를 Java 로 실행시키기

ImJay 2023. 4. 4. 16:11
반응형

자연어 처리를 통한 가공된 텍스트가 필요했다.

AI 는 Python 에서만 다루기 때문에, Python 에서 작업 후 값을 Java 로 값을 넘겨 받아야했다.

다양한 방법이 존재했지만 간단하고 쉬운 방법을 찾아서 소개해보려고 한다.

 

implementation 'org.apache.commons:commons-exec:1.3'

1. build.gradle 에 해당 코드를 추가하고, 빌드해준다.

 

package ParkLab.VMap.model.Service.textrank;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class CallTextRank {
    public static void main(String[] args)  {
        System.out.println("Python Call");
        String[] command = new String[3];
        // command[0] = "python";
        command[0] = "C:/Users/xenon/AppData/Local/Programs/Python/Python310/python.exe";
        command[1] = "D:/users/GitHub/V-Map/python/textrank.py";
        command[2] = "D:/users/GitHub/V-Map/data/test.txt";
        try {
            execPython(command);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void execPython(String[] command) throws IOException, InterruptedException {
        CommandLine commandLine = CommandLine.parse(command[0]);
        for (int i = 1, n = command.length; i < n; i++) {
            commandLine.addArgument(command[i]);
        }

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(outputStream);
        DefaultExecutor executor = new DefaultExecutor();
        executor.setStreamHandler(pumpStreamHandler);
        int result = executor.execute(commandLine);
        System.out.println("result: " + result);
        System.out.println("output: " + outputStream);
    }

}

2. 해당 Java 코드를 자신의 상황에 맞게 수정한다.

- command[0] : Python 의 절대 경로

- command[1] : 실행할 python 파일의 절대 경로

- command[2] ~ : 인자로 넘길 값

 

from krwordrank.word import KRWordRank
from krwordrank.sentence import keysentence
from krwordrank.sentence import make_vocab_score
from krwordrank.sentence import MaxScoreTokenizer
from krwordrank.hangle import normalize
import sys


def get_texts_scores(a):
    with open(a, encoding='utf-8') as f:
        docs = [doc.lower().replace('\n', '') for doc in f]
        if not docs:
            return []
        return docs

def main(argv):
   
    filename = argv[1]
    #filename = '../data/test.txt'

    texts = get_texts_scores(filename)

    wordrank_extractor = KRWordRank(
        min_count = 1, # 단어의 최소 출현 빈도수 (그래프 생성 시)
        max_length = 5, # 단어의 최대 길이
        verbose = False
        )

    beta = 0.85  # PageRank의 decaying factor beta
    max_iter = 10
    keywords, rank, graph = wordrank_extractor.extract(texts, beta, max_iter, num_keywords=10)

    print(keywords)

    stopwords = {'어', '네 ', '이제', '그런', '예', '또', '그',
                 '지금', '이렇게', '이제', '이런'}

    vocab_score = make_vocab_score(keywords, stopwords, scaling=lambda x:1)
    tokenizer = MaxScoreTokenizer(vocab_score)

    print(vocab_score)

    penalty = lambda x: 0 if 10 <= len(x) <= 50 else 1

    sents = keysentence(
        vocab_score, texts, tokenizer.tokenize,
        penalty=penalty,
        diversity=0.5,
        topk=5
    )
   

    with open('D:/users/GitHub/V-Map/data/result.txt', 'w', encoding='utf-8') as f:
        for sent in sents:
            f.write("%s\n" % sent)


    for sent in sents:
        print(sent)



if __name__ == "__main__":
    main(sys.argv)

3. sys.argv 를 통해 인자들을 넘겨준다.

파이썬에서 argv[1] 이 자바에서는 command[2] 와 일치한다.

이 때 파이썬에서 경로를 이용한 작업을 진행할 때는 절대경로를 사용해주어야 함을 주의하자.

 

4. 보시다시피 한글이 깨지는 모습이다.

Java 코드, Python 코드 모두 utf-8 로 인코딩을 한 상태이고 인텔리제이 터미널도 확인했고, 자바 버전도 확인했고..

할 수 있는 방법은 다 해봤지만 해결을 아직 못했고

차선책으로 파이썬에서 텍스트파일로 값을 저장하는 형태로 코드를 작성했다.

다행히 텍스트 파일 안에서는 한글이 깨지지 않았고, 이제 자바에서 이 텍스트 파일의 값을 추출하여 값으로 사용할 수 있을 것 같다.

 

5. bootWar 로 서버 배포시에도 정상적으로 작동할지는 걱정되지만, 잘 되길 빌어야겠다.

반응형
Comments