'한글'에 해당되는 글 6건

  1. 2017.07.20 [한글유니코드] 한글자모와 호환용 한글자모 코드
  2. 2016.11.25 [Elasticsearch] elasticsearch-analysis-arirang 5.0.1 플러그인 개발기
  3. 2016.03.17 [Elasticsearch] Elasticsearch에 Arirang 외부 사전 등록하기
  4. 2015.11.20 [arirang] 사전 데이터 등록 예제
  5. 2015.11.19 [자모분석기] 초성, 중성, 종성 남의 코드 가져다 구현해 보기.
  6. 2013.01.23 루씬 한글형태소 분석기 로컬 테스트

[한글유니코드] 한글자모와 호환용 한글자모 코드

ITWeb/개발일반 2017. 7. 20. 18:01

한글 유니코드를 이용해서 한글 자모 분리에 사용하게 됩니다.

일반 한글자모 코드와 호환용 한글자모 코드가 있는데요.


제가 기존에 구현했던건 호환용 코드였습니다.

그러다 보니 자모만 구성된 처리에 있어서 약간의 문제가 있었습니다.

이번에 한글자모 코드로 변경 하면서 혹시라도 필요 하신 분들이 계시거나 제가 기억 못할까봐 기록해 봅니다.


참고문서)

https://namu.wiki/w/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C

https://namu.wiki/w/%ED%95%9C%EA%B8%80%20%EC%9E%90%EB%AA%A8



한글자모 기반 유니코드)


  // {'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'}

  private final char[] CHOSUNG =

    {0x1100, 0x1101, 0x1102, 0x1103, 0x1104, 0x1105, 0x1106, 0x1107, 0x1108, 0x1109, 0x110A, 0x110B, 0x110C, 0x110D, 0x110E, 0x110F, 0x1110, 0x1111, 0x1112};


  // {'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'}

  private final char[] JUNGSUNG =

    {0x1161, 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, 0x116A, 0x116B, 0x116C, 0x116D, 0x116E, 0x116F, 0x1170, 0x1171, 0x1172, 0x1173, 0x1174, 0x1175};


  // {' ', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'}

  private final char[] JONGSUNG =

    {0x0000, 0x11A8, 0x11A9, 0x11AA, 0x11AB, 0x11AC, 0x11AD, 0x11AE, 0x11AF, 0x11B0, 0x11B1, 0x11B2, 0x11B3, 0x11B4, 0x11B5, 0x11B6, 0x11B7, 0x11B8, 0x11B9, 0x11BA, 0x11BB, 0x11BC, 0x11BD, 0x11BE, 0x11BF, 0x11C0, 0x11C1, 0x11C2};



호환용 한글자모 기반 유니코드)


  // {'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'}

  private final char[] CHOSUNG =

    {0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142, 0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e};


  // {'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'}

  private final char[] JUNGSUNG =

    {0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163};


  // {' ', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'}

  private final char[] JONGSUNG =

    {0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e};


※ Java 로 코드 변환 시 낱자로 사용하게 되면 한글자모 기반 유니코드가 아닌 호환용 한글자모 기반 유니코드를 사용하게 됩니다.

:

[Elasticsearch] elasticsearch-analysis-arirang 5.0.1 플러그인 개발기

Elastic/Elasticsearch 2016. 11. 25. 12:31

Elasticsearch cluster 업그레이드를 위해 먼저 한글형태소 분석기 업그레이드가 필요합니다.

기본적으로 한글형태소 분석기 플러그인을 만들기 위해서는 아래의 내용을 어느 정도는 잘 알고 다룰수 있어야 합니다.


- Elasticsearch

- Lucene

- Arirang


Arirang 은 아래 링크를 통해서 소스와 jar 파일을 구하실 수 있습니다.


최근에 수명님 이외 mgkaki 님이 컨트리뷰션을 해주시고 계신듯 합니다. :)


Lucene & Arirang 변경 사항)

- lucene 6.1 과 6.2 의 패키지 구조가 변경이 되고 클래스도 바뀌었습니다.

- arirang 에서 제공하던 pairmap 관련 버그가 수정되었습니다. (그전에 수정이 되었을수도 있습니다. ^^;)

- lucene 에서 제공 되던 CharacterUtils 가 refactoring 되었습니다.

- arirang 에서 KoreanTokenizer 에 선언된 CharacterUtils 를 변경된 내용에 맞게 고쳐주어야 합니다.


Remove CharacterUtils.getInstance()

CharacterUtils.codePointAt(...) to Character.codePointAt(...)


- arirang 6.2 source를 내려 받으시면 위 변경 내용이 반영 되어 있습니다.

- arirang.morph 1.1.0 을 내려 받으셔야 합니다.


Elasticsearch Plugin 변경 사항)

플러그인 개발 변경 사항은 기본 구조 변경이 많이 되었기 때문에 수정 사항이 많습니다.

보기에 따라서 적을 수도 있지만 판단은 각자의 몫으로 ^^


- arirang.lucene-analyzer 와 arirang-morph 업데이트가 되어야 합니다.

- 기존에 binding 하던 AnalysisBinderProcessor를 사용하지 않습니다.

- 이제는 Plugin, AnalysisPlugin 에서 등록을 진행 합니다.


public class AnalysisArirangPlugin extends Plugin implements AnalysisPlugin {

  @Override

  public Map<String, AnalysisProvider<TokenFilterFactory>> getTokenFilters() {

    return singletonMap("arirang_filter", ArirangTokenFilterFactory::new);

  }


  @Override

  public Map<String, AnalysisProvider<TokenizerFactory>> getTokenizers() {

    Map<String, AnalysisProvider<TokenizerFactory>> extra = new HashMap<>();

    extra.put("arirang_tokenizer", ArirangTokenizerFactory::new);


    return extra;

  }


  @Override

  public Map<String, AnalysisProvider<AnalyzerProvider<? extends Analyzer>>> getAnalyzers() {

    return singletonMap("arirang_analyzer", ArirangAnalyzerProvider::new);

  }

}


- AnalyzerProvider, TokenFilterFactory, TokenizerFactory 내 생성자 argument 가 바뀌었습니다.

IndexSettings indexSettings, Environment env, String name, Settings settings


- assemble 하기 위한 plugin.xml 내 outputDirectory 가 elasticsearch 로 변경이 되었습니다. 

- outputDirectory 가 elasticsearch 로 작성되어 있지 않을 경우 에러가 발생 합니다.


이 정도 변경 하고 나면 이제 빌드 및 설치를 하셔도 됩니다.

이전 글 참고) [Elasticsearch] Lucene Arirang Analyzer Plugin for Elasticsearch 5.0.1


※ 플러그인을 만들면서 우선 lucene 6.1 과 6.2 가 바뀌어서 살짝 당황 했었습니다.

당연히 6.x 간에는 패키지 구조에 대한 변경은 없을거라는 기대를 했었는데 이게 잘못이였던 것 같습니다.

역시 lucene 5.x 에서 6.x 로 넘어 가기 때문에 elasticsearch 5.x 는 많이 바뀌었을 거라는 생각은 했었구요.

그래도 생각했던 것 보다 오래 걸리지는 않았지만 역시 참고할 만한 문서나 자료는 어디에도 없더라구요.

소스 보는게 진리라는건 변하지 않는 듯 싶내요. 작성하고 보니 이게 개발기인지 애매하내요. ^^;


소스코드)

https://github.com/HowookJeong/elasticsearch-analysis-arirang

:

[Elasticsearch] Elasticsearch에 Arirang 외부 사전 등록하기

Elastic/Elasticsearch 2016. 3. 17. 12:49

arirang 한글 형태소 분석기를 적용하고 사전 데이터를 업데이트 할 일들이 많이 생깁니다.

jar 안에 들어 있는 사전 데이터는 패키지 빌드 후 재배포하고 클러스터 재시작까지 해줘야 하는데요.

이런 과정 없이 사전 데이터만 외부에서 파일로 업데이트 및 관리하고 재시작 없이 바로 적용했으면 합니다.


기본적으로 이전 글에서 사전 데이터를 reload 하는 REST API를 구현해 두었습니다.

이 기능으로 일단 기능 구현은 완료가 된 것입니다.


이전 글 보기)


그럼 elasticsearch에서 어디에 사전 파일을 두고 관리를 해야 적용이 가능 할까요?

이전 글을 보시면 기본적으로 수명님이 만드신 arirang.morph 에서 classpath 내  org/apache/lucene/analysis/ko/dic 과 같이 생성 및 배치 시키시면 먼저 이 파일을 읽어 들이게 되어 있습니다.


이전 글 보기)


단, elasticsearch 실행 시 classpath 정보에 생성한 경로를 추가하지 않으시면 사전 파일들을 찾을 수 없으니 이점 유의 하시기 바랍니다.


elasticsearch classpath 설정)

elasticsearch에서 가이드 하는 것은 수정하지 마라 입니다. 하지만 수정 없이는 이를 활용할 수 없으니 이런건 수정해줘야 합니다.


$ vi bin/elasticsearch.in.sh

.....

ES_CLASSPATH="$ES_HOME/lib/elasticsearch-2.2.0.jar:$ES_HOME/lib/*:$ES_HOME/설정하신경로입력"

.....


이렇게 수정하신 후 재시작 하시고 직접 사전 정보 업데이트 후 reload api 를 이용해서 적용되는지 확인해 보시면 되겠습니다.


참고 정보 - 간단 요약)

arirang.morph 에서 properties 파일과 dic 파일 loading flow


Step 1)

load external korean.properties into classpath.

dic files are same.


Step 2)

if not exist, load korean.properties into jar.

dic files are same.


사전 데이터는 어떻게 등록 할 수 있는지 궁금하신 분은 이전 글 참고하세요.


사전 데이터 등록 예제)

:

[arirang] 사전 데이터 등록 예제

ITWeb/검색일반 2015. 11. 20. 15:15

arirang analyzer 를 사용하면서 사전 활용을 위해서는 사전 파일이 어떻게 구성이 되어 있고 관리가 되어야 하는지 알아야 합니다.

아래 공식 카페에 들어가시면 많은 정보들이 있으니 참고 하시면 되겠습니다.


[공식카페]


[형태소분석 사전 구성 및 사용법]


[사전 등록 예시]

# 위 구성 및 사용법 에서와 같이 인덱스 순서가 이렇게 되어 있습니다.

명사 동사 기타품사 하여(다)동사 되어(다)동사 '내'가붙을수있는명사 na na na 불규칙변형


# 엘사는 명사이고 동사, 기타품사, 불규칙이 아니다, 라고 가정하면 아래와 같이 표현이 됩니다.

엘사,100000000X


# 노래는 명사이고 하여 동사가 됩니다.

노래,100100000X


# 소리는 명사이고 소리내다와 같이 내가 붙을 수 있는 명사 입니다.

소리,100001000X


[사전작업 후 리로딩]

arirang-morph 패키지에서 DictionaryUtil.java 내 loadDictionary() 호출을 통해 다시 올려 줍니다.

▶ 별도 구현이 필요합니다.


[불규칙변형 태그]

원문) http://cafe.naver.com/korlucene/135

# 위에서 제일 마지막에 'X' 라는 문자가 있습니다. 이 부분에 대한 설명 입니다.

B : ㅂ 불규칙

H : ㅎ 불규칙

L : 르 불규칙

U : ㄹ 불규칙

S : ㅅ 불규칙

D : ㄷ 불규칙

R : 러 불규칙

X : 규칙


:

[자모분석기] 초성, 중성, 종성 남의 코드 가져다 구현해 보기.

ITWeb/검색일반 2015. 11. 19. 15:44

구글님을 통해서 한글 초성검색 또는 초성, 중성, 종성 이런식으로 검색 하시면 엄청난 자료들이 나옵니다.

지금은 어느 검색 포털이나 쇼핑몰 검색에서 흔히 사용되는 기술이죠.

오픈 된 소스가 많이 있기 때문에 잘 작성된 코드 보고 원리를 이해하고 자신의 서비스에 맞게 적용하시면 될 것 같습니다.


저는 늘 그렇듯이 맨날 잊어버려서 복습 차원에서 또 블로깅을 해봅니다. :)


보통 시작하기에 앞서 한글의 초성, 중성, 종성을 먼저 정리 하게 됩니다.

하고 싶은게 초중종을 분리 하는 것이기 때문에 당연한 것이라고 생각 됩니다.

저 같은 경우는 내가 하고 싶은걸 먼저 적고 그걸 어떻게 구현 할 수 있을까 를 고민 하면서 스케치를 합니다.

그런 다음 고민한 내용을 기반으로 직접 구현 할 것인지 오픈소스를 가져다 사용할 것인지를 또 정리 합니다.


이미 잘 작성된 오픈 소스가 있다면 당연히 비용을 줄이는 차원에서 가져다 사용을 합니다.

단, 사용하는 오픈 소스나 도구의 동작 원리와 내부 구성이 어떻게 되어 있는지는 잘 분석하고 시작을 해야 한다고 생각 합니다.

그래야 시행착오를 줄일 수 있지 않을까 생각 하거든요.


암튼 이제 살펴 보겠습니다.


[초성/자음] - 19자

{'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'}


[중성/모음] - 21자

{'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'}


[종성/받침] - 28자 (채움문자 포함)

{' ', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'}


[초성 유니코드]

{0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142, 0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e}


[중성 유니코드]

{0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163}


[종성 유니코드]

{0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e}


아래는 국립국어연구원에서 발췌한 글 입니다.


[한글의 자모로 조합 가능한 글자의 수는 11,172개]


우리가 조합형 한글 코드로 조합하여 만들 수 있는 글자의 수는 얼마나 될까? 초성과 중성에 쓰이는 자음과 모음의 숫자는 한글 맞춤법 규정과 다를 것이 없다. 그러나 받침의 경우는 사정이 조금 다르다. 우리말은 받침이 없는 경우가 있기 때문에 받침이 없는 경우에도 한글 한 글자에 해당하는 2바이트(16비트)를 만들기 위한 5비트의 종성을 채워줄 수 있는 채움 문자가 필요하다. 그래서 조합할 수 있는 받침의 수는 한글 맞춤법에 나온 27자에 채움 문자 한 글자가 더 들어간 28자로 계산하여야 한다. 따라서 조합형 한글 코드로 만들어 낼 수 있는 글자의 수는 19(초성)×21(중성)×28(종성)=11,172개이다. 물론 이는 이론적으로 가능한 숫자이고 조합 가능한 모든 글자가 실생활에서 쓰이는 것은 아니다.


여기서 이렇게 한글만 정리 하면 영어 같은 경우는 어떻게 할 수 있을까요?

영어는 그냥 글자 자체로 초성으로 취급 하면 되지 않겠습니까?

이렇게 한글에 대한 분리와 분리된 자모를 다시 합치기 위한 공식이 나오게 됩니다.

당연히 누군가 만들어 놓은 공식을 사용하였습니다.

단, 왜 이렇게 나왔는지를 이해하고 사용하시면 좋겠습니다.


[분리 기본 공식]

    초성 = ( ( (글자 - 0xAC00) - (글자 - 0xAC00) % 28 ) ) / 28 ) / 21

    중성 = ( ( (글자 - 0xAC00) - (글자 - 0xAC00) % 28 ) ) / 28 ) % 21

    종성 = (글자 - 0xAC00) % 28


[합치기 기본 공식]

    원문 = 0xAC00 + 28 * 21 * (초성의 index) + 28 * (중성의 index) + (종성의 index)


    각 index 정보는 CHOSUNG, JUNGSUNG, JONGSUNG char[]에 정의한 index 입니다.

    하지만 아래 코드에서는 원문이 필요 없기 때문에 합치기 위한 로직은 포함 되어 있지 않습니다


자 그럼 초성, 중성, 종성 알아봤고, 공식까지 확인했으니 구현만 하면 되겠습니다.

실제 구현한 코드는 아래 링크에서 확인 하시면 됩니다.


[소스코드 Repository]

https://github.com/HowookJeong/hanguel-jamo-analyzer


[사용방법]

public static void main(String args[]) {
String query = "Nike 청바지";
HanguelJamoMorphTokenizer tokenizer = HanguelJamoMorphTokenizer.getInstance();

String chosung = tokenizer.tokenizer(query, HanguelJamoType.CHOSUNG);
String jungsung = tokenizer.tokenizer(query, HanguelJamoType.JUNGSUNG);

String jongsung = tokenizer.tokenizer(query, HanguelJamoType.JONGSUNG);


System.out.println("원문 : [" + query + "]");
System.out.println("초성 : [" + chosung + "]");
System.out.println("중성 : [" + jungsung + "]");
System.out.println("종성 : [" + jongsung + "]");
}


[실행결과]

원문 : [Nike 청바지]

초성 : [Nikeㅊㅂㅈ]

중성 : [Nikeㅓㅏㅣ]

종성 : [Nikeㅇ]


이제 활용만 하면 될 것 같습니다.

어떻게?

그건 각 서비스 요구사항에 맞춰서 하셔야죠. ^^

:

루씬 한글형태소 분석기 로컬 테스트

Elastic/Elasticsearch 2013. 1. 23. 16:09

이런.. 아래 코드는 2.X 용이내요.. 
3.X 에서는 동작 하지 않습니다.
그냥 새로 짜야겠내요.. ^^;

--------------------------------------------------------------

Special Thanks to : 이창민

한글형태소 분석기 로컬 테스트.


http://cafe.naver.com/korlucene 카페에 보면 krmorph-20091117.war파일

한국어 형태소분석 파일을 테스트 해볼수 있는 파일을 개발자님이 직접 올려주셨네요. (공모전에 출품작이였던 것 같습니다.;)

첨부한 파일은 : 공모전에 출품하려고 개발자가 매뉴얼을 작성한 것 같습니다. 프로그램에 대해 자세하게 적혀있습니다.(카페에서 찾았습니다.)



krmorph-20091117.war

 

해당 파일을 실행시키는 방법

1. 이클립스에서 마우스 오른쪽 버튼 -> Import -> WAR file

2. 다운받은 krmorph-2091117.war파일 선택

3. 프로젝트 import 완료

4. 프로젝트 선택후 오른쪽 버튼 -> Run As -> Run On Server (기존에 톰캣이 셋팅 되어 있어야 함. & 일반 웹프로젝트 톰캣셋팅과 동일함)

5. 톰캣 재시작


※ 접속 URL : http://localhost:8080/krmorph-20091117/


형태소 분석기 소스를 받아서 고치거나 사전 업데이트 후 실제 어떻게 동작 하는지 테스트 할때 사용하면 유용할 것 같내요.
어제 stopwords 잘 안되던거 테스트 하기 위해서 필요 했는데. ㅎㅎ 창민군 고마워요.. :)


: