koalanlp / python-support

Python wrapper for KoalaNLP (Korean NLP with Java/Scala)
MIT License
31 stars 9 forks source link

Tagger API를 통해서 문장을 분석하면 원문의 띄어쓰기가 무조건 변경되어 분석의 어려움이 있습니다. #3

Open TaeHwan-Lee opened 5 years ago

TaeHwan-Lee commented 5 years ago

기초정보

재연을 위한 정보

초기화 합니다.

initialize(java_options="-Xmx4g -Dfile.encoding=utf-8", KMR="2.0.6", EUNJEON="2.0.6", DAON="2.0.6")

mecab(은전한닢) 품사분석기

tagger_ej = Tagger(API.EUNJEON)

-> return : koalanlp.data.Sentence

tt = "1989년 2월 15일 여의도 농민 폭력 시위를 주도한 혐의(폭력행위등처벌에관한법률위반)으로 지명수배되었다. 1989년 3월 12일 서울지방검찰청 공안부는 임종석의 사전구속영장을 발부받았다. 같은 해 6월 30일 평양축전에 임수경을 대표로 파견하여 국가보안법위반 혐의가 추가되었다. 경찰은 12월 18일~20일 사이 서울 경희대학교에서 임종석이 성명 발표를 추진하고 있다는 첩보를 입수했고, 12월 18일 오전 7시 40분 경 가스총과 전자봉으로 무장한 특공조 및 대공과 직원 12명 등 22명의 사복 경찰을 승용차 8대에 나누어 경희대학교에 투입했다. 1989년 12월 18일 오전 8시 15분 경 서울청량리경찰서는 호위 학생 5명과 함께 경희대학교 학생회관 건물 계단을 내려오는 임종석을 발견, 검거해 구속을 집행했다. 임종석은 청량리경찰서에서 약 1시간 동안 조사를 받은 뒤 오전 9시 50분 경 서울 장안동의 서울지방경찰청 공안분실로 인계되었다." position = 0 text = '' text_encoding = '' morp_list = [] position_list = [] lemma_list = []

1.문장전체 파싱

tagged_ej = tagger_ej.tagSentence(tt)

1.1.원문장 인코딩

tt_encoding = tt.encode()

2 koalanlp 파싱

for i, sentence in enumerate(taggedej): print(i+1,'번째 문장') print(sentence) #koalanlp.data.Sentence for , word in enumerate(sentence):

2.2.1 위치정보 계산

tt_temp_encoding = tt_encoding

word_surface = word.getSurface()
m_word_encoding = word_surface.encode()
print('word_surface :', word_surface)

tt_len = len(m_word_encoding)

print(tt_temp_encoding.decode())

for j, _ in enumerate(tt_temp_encoding):
  if ( m_word_encoding == tt_encoding[:tt_len] ):
    text += word_surface
    tt_encoding = tt_temp_encoding[tt_len + j:]
    print('OK')
    break
  else if ( m_word_encoding == tt_encoding[:tt_len] ):
    print(j)
    print(tt_temp_encoding[j:j+1])
    text += tt_temp_encoding[j:j+1].decode()
    position += 1
    tt_encoding = tt_temp_encoding[j+1:]

#2-2-3. 각 형태소의 위치 최종위치계산
start_position = position
end_position = start_position + len(word_surface.encode())
position = end_position

#단어의 형태소별로 처리
print(word.surface,'=', word.singleLineString()) #koalanlp.data.Word
morphemes_m = word.morphemes #koalanlp.data.Morpheme    
for _, morp_pos in enumerate(morphemes_m):
  #2-2-4. 품사별로 생성처리
  morp = morp_pos.getSurface() + '/' + str(morp_pos.getTag()) + '/' + str(start_position)
  morp_list.append(morp)
  position_list.append( int(start_position) )
  lemma_list.append( morp_pos.getSurface() )

2-2-5

text += tt_encoding.decode()

tt==text, morp_list, position_list, lemma_list



### 본문
- 아래에 본문을 입력해주세요.
위와 같은 코드를 통해서 Tagger API를 통해 나온 문장과 원문의 문장을 순차적으로
 byte비교하여 형태소/품사/원문에서의 byte 위치를 만드는 전처리를 하고 있습니다.
하지만
-> word_surface : 분경
-> 분 경 서울청량리경찰서는 호위 학생 5명과~
원문은 '분 경'으로 띄어서 처리되어있는데, Tagger API를 통해 분석을 하고나면 '분경'으로 붙어서 처리되어 원문에서의 위치를 찾을 수가 없습니다. Tagger API 통해 분석된 문장이 기존의 띄어쓰기를 유지할 수 있는 option이 있었으면 좋겠습니다.
bgnkim commented 5 years ago

말씀하신 문제는 인지하고 있습니다만 몇가지 구현상의 문제가 있습니다.

당분간 약 한달 정도는 제가 작업이 어려워서, 조금 시일이 걸릴 것 같은데, 임시 방편으로 원래 문장을 저장하신 다음 글자 단위로 순회하면서 index를 찾으시는 건 가능할지요? 제가 기억하고 있는 것이 맞다면, 은전한닢의 경우는 띄어쓰기 이외의 음절 구조는 대체로 유지하는 것으로 알고 있습니다.

TaeHwan-Lee commented 5 years ago

무슨 말씀이신지 이해 했습니다. 원문을 순회하며 처리하는 방식으로 진행해보겠습니다. 빠쁘신일 끝나시면 적용 부탁드리겠습니다.

bgnkim commented 4 years ago

@TaeHwan-Lee 예상보다 늦어져서 죄송합니다. 원문에 있는 띄어쓰기를 복원하는 방법이 여러개가 있어서, 원하시는 기능이 어떤 것인지 다시 확인해보고자 합니다. 다음 두 가지 중 어떤 구현을 생각하고 계신건지요? 예시 문장: "아버지가방에 들어가셨다"