[NLP] Java 금칙어 생성법

    금칙어는 자연어 처리(NLP)에서 원치 않는 데이터를 제거하기 위한 방법중 가장 효과가 좋은 방법입니다. 형태소 분석으로 생성된 품사라든지, 개체명 사전에서 생성된 개체명이 마음에 들지 않을 경우 금칙어 사전을 만들어서 대응을 하는 것이죠.

     

    품사 사전이나 개체명 사전에서 지우면 되는 것이 아니냐 할 수 있는데 사전이라는 것은 다양한 곳에서 활용이 될 수 있으며, 특정 서비스에서만 제거가 필요한 경우가 있을 수 있기 때문이고, 제대로 추출이 되었지만 필요가 없을 수도 있기 때문입니다.

     

    [NLP] Java 금칙어 생성법


    금칙어 예제 소스

    private Set<String> STOP_KWD;
    
    public void action() {
        setStopKwd();
    
        Komoran komoran = new Komoran(DEFAULT_MODEL.FULL);
        String document = "어제 시장에서 어떤 가게가 가장 잘 팔리는지 조사를 하기 위해 갔는데 시장해서 식당에 먼저 들어갔다";
    
        KomoranResult analyzeResultList = komoran.analyze(document);
        System.out.println(analyzeResultList.getNouns());
    
        List<String> filterNounList = new ArrayList<>();
        for(String noun : analyzeResultList.getNouns()) {
            if(STOP_KWD.contains(noun)) continue;
            filterNounList.add(noun);
        }
    
        System.out.println(filterNounList);
    }
    
    public void setStopKwd() {
        STOP_KWD = new HashSet<>();
        try {
            BufferedReader inFiles = new BufferedReader(new InputStreamReader(
                    new FileInputStream("stop.dic"), StandardCharsets.UTF_8));
    
            String line = null;
            while ((line = inFiles.readLine()) != null) {
                if(line.trim().length() > 0) STOP_KWD.add(line.trim());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        System.out.println("set stop kwds->" + STOP_KWD.size());
    }

    stop.dic 파일

    시장
    

    소스 실행 결과

    set stop kwds->1
    [시장, 가게, 조사, 시장, 식당]
    [가게, 조사, 식당]

     

    위 예제는 시장이라는 단어가 market이라는 시장과 hungry라는 의미의 시장으로도 쓰일 수 있어서 아예 금칙어로 지정을 한 케이스입니다. 동음이의어의 경우 원치 않는 단어가 나올 수 있고, 혹은 너무 짧은 단어는 분석 결과를 와전시켜서 분석 품질에 영향을 주는 경우가 있기에 제거를 하는 경우들이 종종 있습니다.

     

     

    소스 설명

    금칙어는 동일한 단어가 들어갈 필요가 없고, 탐색이 빨라야 하기 때문에 Hashset을 자료형으로 선택하였습니다. 처음 action을 메소드를 실행하게 되면, action에서 제일 처음 금칙어 사전을 읽어서 Hashset 형태의 STOP_KWD 변수에 사전 안에 있는 단어들을 Add하게 됩니다.

     

    이때 공백이 들어갈 수도 있기 때문에 line.trim().length 체크를 하여 문자가 한글자 이상 포함이 된 경우에만 금칙어 사전에 넣게 되어 있으며 사전에 있는 "시장"이라는 단어가 STOP_KWD에 포함이 됩니다.

     

    사전을 세팅 하였으면 우선 형태소 분석을 수행합니다. 이 금칙어는 형태소 분석 자체를 변경하는 것이 아니라 후처리를 하는 것임을 이해해주시기 바랍니다.

     

    Komoran komoran = new Komoran(DEFAULT_MODEL.FULL);
    String document = "어제 시장에서 어떤 가게가 가장 잘 팔리는지 조사를 하기 위해 갔는데 시장해서 식당에 먼저 들어갔다";
    
    KomoranResult analyzeResultList = komoran.analyze(document);
    System.out.println(analyzeResultList.getNouns());

     

    위와 같이 기존 코모란으로 형태소 분석을 수행한 후 getNouns 즉 명사만 뽑을 경우 "[시장, 가게, 조사, 시장, 식당]"라는 단어가 출력됩니다.

     

    List<String> filterNounList = new ArrayList<>();
    for(String noun : analyzeResultList.getNouns()) {
        if(STOP_KWD.contains(noun)) continue;
        filterNounList.add(noun);
    }
    
    System.out.println(filterNounList);

    5개의 뽑힌 단어를 다시 Loop를 돌린 후, 각각의 단어가 STOP_KWD안에 포함이 되어 있는지 체크를 해서 포함이 되어 있으면 continue를 해서 다음 단어로 이동합니다. STOP_KWD에 없을 경우 filterNounList라는 List<String> 형태에 단어를 담습니다.

     

    최종적으로 filterNounList를 출력하며 결과는 시장이 빠진 "[가게, 조사, 식당]" 입니다.

     

    다음에는 금칙어와 함께 형태소 분석을 풍성하게 해줄 수 있는 기본적인 개체명 분석에 대해서 포스팅 해보도록 하겠습니다.

    댓글

    Designed by JB FACTORY