2010년 12월 9일 목요일

13. Artificial Intelligence

Natural Language Processing


 한국어, 영어 등과 같이 인간사회의 형성과 함께 자연발생적으로 생겨나고 진화하고 의사소통을  행하기 위한 수단으로서 사용되고 있는 언어를 자연어 (Natural Language) 라고 말한다. 컴퓨터의 세계에서 "언어"라고 말하면 거의 프로그램 언어, 즉 FORTRAN, COBOL등의 인공어 (Artificial Language) 를 가리키고 있다. 그래서 이 인공어와는 다른 언어라는 의미로 자연어라는 말을 사용한다.
한국어에는 한국어 고유의 법칙, 영어에는 영어 고유의 법칙이 존재하고 있다. 모든 언어에 공통이면서 보편적으로 존재하고 있는 법칙도 있다고 생각할 수 있다. 자연어에 포함할 수 있는 이들 법칙을 주로 연구하는 학문을 언어학 (Linguistics) 라고 부르고 있다. 그리고 그 법칙을 문법 (Grammar) 이라고 부른다. 전산언어학 (Computational Linguistics) 은 인간의 언어 능력을 컴퓨터 관점에서 바라보는 언어학과 컴퓨터 과학의 중간 쯤에 있는 학문이다. 자연어에 관한 문제는 철학 (Philosophy)논리학 (Logic) 에서도 관심의 대상이며, 인지과학 (Cognitive Science) 에서는 자연어의 연구가 하나의 큰 기둥이 되고 있다.
자연어 처리는 크게 두 가지 작업으로 나눌 수 있다. 첫째는 실세계의 필요한 정보뿐만 아니라 언어에 있어서의 어휘, 구문, 의미에 관한 지식 (lexical, syntactic, semantic knowledge) 을 사용해서 문어 (written text) 를 처리하는 것이다. 둘째는 위에 더하여 음성에서 발생되는 애매함을 비롯한 음성학 (Phonology) 에 대한 부가적인 지식을 필요로하는 구어 (spoken language) 를 처리하는 것이다.


자연어 처리 - 자동 번역기 만들기


1. 문법을 수학적으로 표현하기

일단 자연 언어의 문법을 수학적으로 표현하는 방법을 먼저 보자. 2가지 방법이 있다. 단어를 표현할 때 주로 사용하는 정규식이라는 것이 있고, 문법을 표현할 때 주로 사용하는 문맥자유문법이라는 것이 있다. 춈스키라는 미국 언어학자가 만든 표기법이다. 후자로 전자를 대신할 수도 있다. 둘은 거의 차이가 없다. 이런 것은 수학 기호를 활용해서 언어를 표현하는 방법들이다. 다른 방법이 있으면 개발을 해도 좋다.

문장1 → 접속사 + 문장2
문장2 → 주어 + 술어1
술어1 → 술어2 + 조동사
술어2 → 목적어 + 동사

위와 같은 문법이 있을 때 이런 표현을 생성 문법이라고 한다. 좌측의 것이 우측의 것으로 대치된다고 그렇게 부른다. 단순한 것이 구체적인 것으로 확장되기 때문에 생성을 하는 것이다. 작문을 할 때 이런 과정을 밟는다. 좌측의 것은 추상적이며 아직 끝나지 않았다고 넌터미널이라고 하고 우측의 것 중에 구체적인 것은 더 이상 풀이할 필요가 없어서 끝났다고 터미널이라고 부른다. 수학의 덧셈 기호를 사용하지만 단어들이 붙어 있다는 의미일 뿐 다른 뜻은 없다. 문형을 해석할 때는 반대로 우측의 모양을 보고 좌측으로 바꾸는 과정을 밟는다. 위와 같은 문법 표현을 문맥자유문법이라고 부른다. 아마도 의미에 관한 정보가 없이 형태적인 면만을 표현하기 때문일 것이다. “춈스키”라는 유대인 언어학자가 있는데 언어학에 관심을 가지면서 알게 되었다. 관심 있으면 찾아보라. 이외에도 문법을 여러 단계로 나누는 내용을 책에서 봤는데 설명이 부족하여 이해를 못 했다. 정규식이 가장 단순한 문법이고, 그 다음이 문맥 자유문법이란다. 기억력에서 차이가 있는데 정규식은 현재 상태만 기억하고, 문맥자유문법은 스택이라는 것이 있어서 괄호 형태의 짝이 맞는 것을 기억한다. 이를 통해서 수학의 수식과 같은 컴퓨터 언어를 표현하는 것이 가능하다. 그런데 우리가 사용하는 자연어는 문맥에 따라 문법 해석이 달라진다. 그래서 문맥 자유문법이 아니다.

단어1 → [A-Z][a-z]*                            예) About
단어2 → [a-z]+                                    예) about
숫자 → [0-9]^3(,[0-9]^3)*{.[0-9]*}        예) 123,456,789.1234567

예를 들어 위와 같은 형태의 문법에서 우측의 수식처럼 된 것을 정규식이라고 부른다. 정규식에는 추상적인 넌터미널 같은 것이 없다. 모두 구체적인 문자들로 되어 있다. [A-Z]라는 것은 대문자 A~Z 중에 하나를 선택하라는 의미고, * 표시는 없거나 계속 반복할 수 있다는 의미다. 마치 수학에서 곱하기와 제곱 기호를 사용하는 것과 비슷하다. + 표시는 최소 1개 이상이 반복되는 것을 말한다. 즉, *는 0승에서 무한까지이고 +는 1승에서 무한까지이다. ^3은 3번 반복한다는 의미다. (~)는 묶어서 한 단위로 움직인다는 의미고, {~}는 생략할 수도 있다는 의미다. 여기 표현은 표준 같은 것이 아니다. 수학 공식에 표준이라는 것이 없듯이 각자 자신만의 표현을 만들어 사용하면 된다. 이런 단어 표현 수식은 문법보다는 어떤 패턴(무늬)을 찾아내는 것에 더 유리하다. 요즘 컴퓨터 언어에선 각자 정규식을 표현하는 방법을 제공한다. 또는 책마다 약간 다른 표기법이 있을 수 있다. 이런 정규식을 이용해서 어떤 특징을 지닌 단어만을 검색 할 수 있다.





2. 문법 분석하기

위에서 본 바와 같이 수학 기호를 활용해서 단어와 문법을 표현할 수가 있다. 좋다! 문법을 수학적으로 표현하는 방법을 배웠다. 문법을 적용해서 문장을 해석하는 방법을 보도록 하자!

만약 네가 나를 좋아하고 싶다면, 어쩌고저쩌고...

위와 같은 문장을 해석하면 아래와 같이 분석된다. 문법이 맞는지는 중요하지 않다. 일단 맞다고 보자!

만약+(네가+((나를+좋아하고)+싶다면))

이렇게 양파 껍질처럼 계층을 이루는 것을 조직도(하이어라키), 나무 가지 구조(Tree)라고 부른다. 특징은 뿌리 하나에서 시작해서 가지가 서로 만나지 않고 계속 갈라지는 형상이다. 단어들이 어떻게 서로 뭉쳐서 조립이 되는지 나타내고 있다. 실제로는 다음과 같은 식으로 문형 분석이 된다.

만약 → 접속사! 그럼 다음은 문장2이겠지?
만약 +(네가 → 역시 주어가 왔다. 그럼 술어1이 나온다.
만약 +(네가 + (나를 → 술어1의 시작은 술어2이다. 술어 2는 목적어로 시작한다.
만약 +(네가 + (나를 + 좋아하고) → 술어2 확보!
만약 +(네가 + ((나를 + 좋아하고) + 싶다면)) → 술어1 확보! 문장2 확보! 문장1 확보!

문형을 해석할 때 문법을 예측하는 것을 알 수 있다. 미리 예측한다고 해서 예측 문법이라고 부른다. 나올 수 있는 가능성을 미리 예측하고 그 속에서 문형을 판독해 가는 것이다. 그런데 문장2에서 술어1로 거기서 술어2로 깊이 들어갔다가 마지막에 모든 것이 해결된다. 이런 식으로 깊이 탐색하는 것이 아주 흔하다. 이런 식으로는 복잡한 문장에서 다음 단어들을 예측하는 것이 어렵다. 뭔가 계속 판단 보류, 판단 보류, 판단 보류 하는 식으로 해결되지 않고 누적되는 것이 있다. 이런 식의 문법 해석을 Top-Down 방식이라고 부른다. 문법 지식을 추상적인 단계로부터 구체적인 단계로 적용하기 때문이다. 그 반대로 Bottom-Up 방식은 구체적인 것을 보고 문형을 찾아가는 것이다. 예측 문법은 제일 앞의 단어가 문형을 대표하는 특징 있는 구체적인 단어일수록 유리하다. 다시 말해서 다음에 올 구체적인 단어를 보고 문형을 추측할 수 있다. 이런 문법과 밀접한 단어들을 키워드라고 부른다. 접속사, 조동사, 조사, 대명사, 동사 같은 기본적인 단어들은 문형 파악에 힌트를 줄 수 있는 키워드가 될 수 있다. 이런 단어들은 그대로 터미널 단어로 사용한다. 대체로 부사, 형용사, 명사의 용법이나 번역이 단순하니 이런 것은 키워드로 사용하지 않는다. 반면에 동사, 조동사, 조사, 전치사, 접속사, 대명사 등은 문형을 만들고 상황에 따라 번역이 다르니 키워드로 사용하는 것이 더 좋다. 문형에 따라 해석법이 다르기 때문이다.

문장1 → 접속사 + 문장2
문장2 → 주어 + 술어1
술어1 → 목적어 + 술어2
술어2 → 동사 + 조동사

문법을 위와 같이 수정해서 첫 단어는 구체적인 것이 되도록 고친다고 하자! 그러면 다음과 같이 분석이 될 것이다.

만약 → 접속사! 그럼 다음은 문장2이거나 다른 것?
만약 +(네가 → 주어가 왔다. 그럼 문장2일 가능성이 있다. 
만약 +(네가 + (나를 → 목적어가 왔다. 술어1일 가능성이 있다. 
만약 +(네가 + (나를 + (좋아하고 → 동사가 왔다. 술어2일 가능성 있다.
만약 +(네가 + (나를 + (좋아하고 + 싶다면))) → OK!

차이가 뭘까? 처음 것이 문법적으로 적당한 표현인데 예측해서 해석하기에는 불리하다. 왜냐하면 실제로는 그 다음에 올 문형들의 후보자들이 너무 많다. 예측을 하려면 구체적인 문형이 필요한데 모든 추상적인 문형들을 구체적인 문형으로 바꾸어주는 작업을 즉석에서 할 수가 없다. 가능성이 너무 많아서 예측이 힘들다. 후자의 경우는 구체적인 단어가 앞에 나오기 때문에 문형 예측하기에는 편리한데 문법 표현이 엉망이다. 이 문법은 확실히 부적절하다. 문법 분석을 해 보면 나무 가지가 우측으로만 깊게 뻗어 나가는 것을 알 수 있다. 괄호가 우측에 몰려 있다. 여하튼 모든 문법 표현에서 제일 앞에 구체적인 단어들로 시작하도록 문법을 변형해야 한다. 이 작업은 즉석에서 할 수 있는 것이 아니라 미리 해 놓는 것이다. 고로 문법을 고치면 이런 변형 문법도 새로 만들어야 한다. 이 방법을 바로 사용할 수 없다.

머리1 → 접속사 + 주어
머리2 → 머리1 + 목적어
머리3 → 머리2 + 동사
문장 → 머리3 + 조동사

위와 같은 괴상한 문법으로 고쳤다고 하자! 그럼 뭐가 편할까? 해석해 보자!

만약 → 접속사! 일치 문형 아직 없음!
만약 +네가 → 머리1이다! 다음은 목적어!
(만약 +네가) + 나를 → 머리2이다! 다음은 동사!
((만약 +네가) + 나를) + 좋아하고 → 머리3이다! 다음은 조동사!
((만약 +네가) + 나를) + 좋아하고) + 싶다면 → 문장 OK!

이 경우는 예측도 쉽고 기다림이나 판단 보류가 없다. 그런데 문법 구조를 보면 말도 안 되는 형식이다. 예측이 쉽다는 것은 앞의 것이 뒤의 것을 예측하기 좋도록 힌트를 주는 형식으로 되어 있다는 뜻이다. 그리고 이미 읽은 것은 바로 구조가 판단되고 마음 편하게 다음 것을 읽을 수 있다. 문법 분석 나무를 보면 좌측으로 깊게 뻗어간다. 좌측에 괄호가 몰려 있다. 그럼 여기서 정리를 해 보자! 단어를 읽으면서 바로 문법이 적합한지 지연 없이 해석을 하려면 Bottom-Up 방식이 적당하다. 그리고 먼저 나오는 단어가 문형을 이끌어야 한다. 먼저 읽은 것을 통해 나중에 나올 것을 예측 가능해야 한다. 그런데 이 방식으로 문법을 예측하여 해석하려면 거기에 적합한 변형 문법이 필요하다는 것이다. 이 변태적인 변형 문법은 문장의 문법 적합성을 판단하는데 이용될 뿐 문장 구조를 표현하지 못한다. 적절한 문장 구조를 표현하는 문형으로 대체 되어야 한다. 한국어 어순보다 영어식 어순이 더 논리적이라고 말하는 것은 바로 이런 예측이 쉽다는 면에서 의미가 있다. 물론 영어도 이런 면에서 완벽한 어순은 아니다. 한국어는 문장이 끝나야 문장이 해석된다. 영어는 예측을 할 수 있다. (내 개인적 의견으로는 한국인 조상이 머리가 좋고, 서양인 조상이 머리가 나쁘기 때문에 이런 어순이 되었을 것이라 생각한다. 머리가 나쁜 사람들은 기억력이 짧기 때문에 바로바로 풀이가 되어야 한다.)

I know your thought, that's very dangerous.
나 알아 너의 생각 그것 매우 위험해.(영어식 직역 = 원시인 말)
나는 네 생각이 매우 위험하다는 것을 안다.(한국식 표현 = 기억력 필요!)

일본어와 한국어는 거의 어순이 같다. 그런데 영어와 한국어는 어순이 아주 많이 다르다. 일본어 경우는 문법 해석이 엉터리라도 바로 번역이 가능하다. 문법 해석을 할 필요도 거의 없다. 그런데 영어의 경우는 위와 같은 이상한 문법으로는 한국어와 영어 기계 번역이 불가능하다. 제대로 문법 구조를 분석하고 거기에 따라 재배치를 해야 한다. 다음 예를 보자!

I like the book you sent me yesterday!
나는 어제 네가 내게 보낸 그 책을 좋아한다!

이것을 문법 해석하면 이렇다.

I+(like+((the+book)+(you+sent+me+yesterday)))!
나는+(((어제+네가+내게+보낸)+(그+책을))+좋아한다)!

주어까지는 일치한다. 술어 부분의 어순이 완전히 정반대이다. 영어 문형을 잘 분석해서 거기에 맞는 한국어 문형으로 위치 바꾸기를 해야 한다는 말이다. 영어 문형을 정확히 분석하지 못하면 벌써 꽝이다. 거기에 대응하는 한국어 문형이 없다면 그 다음으로 꽝이다. 모든 것이 제대로 되도 꽝이 될 수 있다. 왜냐하면 영어에는 물주구문이란 것이 있는데 한국어에는 그런 표현을 사용하지 않기 때문이다. 언어마다 표현 습관이 다르다.

That machine makes me angry!
그 기계나게 한다! (영어식 표현 직역)
그 기계 때문에 난다! (한국식 표현 의역)

바로 이런 이유 때문에 기계 번역을 하지 않고 문장대 문장으로 사람이 직접 번역을 한 것을 기록했다 재활용하는 방법을 사용한다. 전문 번역 업체에선 이런 방법으로 번역을 하고 있다. 번역 품질은 우수하지만 유연성이 없다. 단어 하나만 바뀌어도 다시 번역을 해야 한다. 메모리 낭비가 심하며 검색 시간이 많이 소모된다. 그럼 어떤 방법이 적당한가? 기계 번역과 인간의 번역을 합치는 방법은 없을까? 세상에 불가능은 없다!

문법 분석을 할 때는 즉석에서 빨리 판단을 내리고 그 다음을 예측 할 수 있도록 변형 문법을 사용한다. 사람 머리도 이렇게 동작하고 있음을 느낄 것이다. 이 변형 문법은 이론적으로 완벽한 깔끔한 문법을 분석해서 예측이 쉽도록 만들어서 사용한다. 변형 문법 분석 결과에서 정상적인 문법으로 문형간 변환을 하는 과정이 있어야 한다. 만약 정상적인 문형이 변경 되었다면 이런 변형 문법도 거기에 따라 모두 변경해야 하는데 쉽지가 않다. 깔끔한 문법을 실용적인 변형 문법으로 바꾸면 문형이 갑자기 많이 늘어난다. 고로 이 방법을 그대로 적용하기 어렵다. 컴퓨터가 스스로 문형이나 문법 규칙을 변경하는 학습 능력이 있어야 한다. 정상적이고 이론적으로 깔끔한 문형을 알려 주면 거기에 필요한 변형된 실용성 있는 문법들을 스스로 만들어야 한다. 이렇게 해야 Bottom-Up 분석이 가능하고 예측 분석이 가능하다. 이렇게 힘들게 문형 분석을 해도 그 문형을 한국어 문형으로 재배치하는 과정이 막연하다.






3. 프로그램으로 구현하기

자 그럼 문법 분석은 잠시 접어 두고 어떻게 컴퓨터에서 구현을 할 것인가? 상태 변화도라는 것이 있다. 지금 어떤 상태인데 어떤 입력(단어, 문자)이 들어오면 다음 상태는 어디로 간다라는 그림이다. 위의 문법 표현에서 이런 상태 변화도를 그린다. 이것을 그대로 조건문을 이용해서 프로그램으로 만든다. 예를 들면 다음과 같다.

초기 상태이다. 첫 입력이 접속사이다. 그럼 중간상태1이다.
중간 상태 1이다. 여기서 입력이 주어이다. 그럼 머리1 상태이다.
머리1 상태인데 다음 입력이 목적어이다. 그럼 머리2 상태이다.
머리2 상태인데 다음 입력이 동사이다. 그럼 머리3 상태이다.
머리3 상태인데 다음 입력이 조동사이다. 그럼 문장 완료 상태이다.

초기 상태이다. 첫 글자가 "학"이다. 그럼 "학~" 계열 단어이다.
중간 상태1이다. 다음 글자가 "교"이다. 그럼 "학교~" 계열 단어이다.
중간 상태2이다. 다음 글자가 "종"이다. 그럼 "학교종~" 계열 단어이다.
만약 다음 글자가 단어를 이루도록 연결될 수 없으면 여기서 종료할 것이다.

다음 상태 = 이동 함수(현재 상태, 다음 입력)
다음 교차로 = 이동 함수(현재 교차로, 주사위)
다음 상태 = DB 검색(현재 상태, 다음 입력)
다음 상태 = 상태 배열(현재 상태, 다음 입력)

상태 변화도는 2차원 배열로 구현된다. 또는 DB에 레코드로 구현할 수 있다. 또는 직접 조건문과 선택문을 이용해서 코딩할 수 있다. 이렇게 상태를 바꾸어 가며 자동으로 일을 처리하는 기계를 오토마타[어타~머터]라고 부른다. 다른 말로 튜링이란 사람이 고안했다고 튜링머신이라고 부른다. 이 기계는 상태를 기억하는 장치와 다음 입력에 따라 상태를 바꾸면서 뭔가 동작을 하는 장치로 구성된다. 쉽게 말해서 자동화 기계이다. 이 기계의 기억력은 현재 상태 하나만 기억하는 수준이다. 또는 짝을 이루는 것을 기억하도록 스택을 가지고 있다. 또는 그 이상의 복잡한 상황을 기억하는 기억장치를 가질 수 있다. 외부 자극이 오면 프로그램 된 내용에 따라 다음 상태로 옮긴다. 다음 상태로 옮긴 후에 필요하다면 어떤 출력을 하든가 데이터 조작을 한다. 상태 변화 도표는 실제로는 이렇게 구현된다. 다른 비유를 들면 현재 상태에 갈림길에 있는데 동전을 던지니 우측이 나왔다. 그럼 우측으로 가면서 다른 상태(교차로)에 들어가게 된다. 거기서 또 다른 갈림길로 가기 위해서 주사위를 던지는 것과 비슷하다. 부루마블 게임을 해 본 적 있다면 쉽게 이해할 것이다. 그 게임판의 그림이 바로 상태 변화도이다. 이런 원리로 컴퓨터의 회로가 설계 되어 있다. 튜링 머신이나 오토마타가 구현된 것이 컴퓨터이다.

아주 간단하지만 기계 번역이 어떻게 어려운지 느꼈을 것이다. 좀 더 자세히 들어가 보자. 영어 단어를 해석할 때는 여러 가지 문제가 있는데 문장 처음에는 첫 글자를 대문자를 사용한다는 것이다. 그리고 약어로 된 단어는 문장 종료 기호인 점(dot)을 중간에 사용하기도 한다. 기계적으로 하나의 문장과 단어를 뽑아내는 것도 쉽지 않다. 그리고 영어나 한국어나 음운 현상을 처리하려면 자음과 모음을 분리할 수 있어야 한다. 한글은 받침 유무에 따라 조사가 다르다. 조사가 2쌍이 존재한다. (을/를, 이/가, 로/으로, 는/은 ...) 영어나 한국어나 접미사나 어미변화가 있다. 같은 단어인데 형태가 변한다. (아름답다, 아름다운, 아름답게 ...) 여하튼 단어까지는 뽑아냈다고 하자! 단어의 나열을 보고 문법 해석과 의미 해석을 해야 한다. 문법 해석이란 주로 외형적인 규칙을 지켰는지를 보는 것이다. 의미 해석이란 적절한 번역에 필요하다. 의미 해석을 하려면 기존의 명사, 동사, 형용사, 부사 어쩌고저쩌고 하는 구분으로는 부족하다. 의미에 따라 더 세분할 필요가 있다. 예를 들어 물질 명사, 고유 명사, 추상 명사, 구체 명사 등이다. 그런데 이 분류 방법을 찾아내기 어렵다. 그렇다고 불가능한 것은 아니다. 언젠가는 꼭 이룰 수 있다.

번역 프로그램은 문형집과 단어 사전을 가지고 번역을 한다. 문형집은 앞에서 설명한 것처럼 프로그램 속에 코딩되어 들어 있다. 그래서 외부에서 사용자가 고치기 어렵다. 이 문제를 해결하려면 문형 수정이 가능하도록 공개해야 한다. 문형 그 자체가 프로그램에게 어떻게 동작하라는 지시문이 될 수 있어서 오동작을 일으킬 수도 있다. 그리고 꼬인 문형을 만들면 무한 반복에 빠질 수도 있다. 애매모호한 문형(같은 문장인데 문법이 적용된 순서에 따라 2가지로 해석이 되는 것)을 만들면 엉뚱한 결과가 나온다. 틀린 문형을 대체하려면 문형을 공개 해야 한다. 단어 검색은 시간이 많이 소모된다. 사전을 찾을 때 첫 글자를 보고 해당 위치로 가서 찾기 때문에 약간의 시간 절약을 할 수 있다. 이처럼 표를 통으로 검색하는 것이 아니라 작게 분리하여 검색하는 것을 이용한다. 한 문장에 10개의 단어가 있다면 10번의 사전 검색이 필요하다. 또한 문형을 검색해서 문장과 비교하는 과정이 들어가기 때문에 자동 번역 과정은 거의 검색 과정의 반복이라고 할 수 있다. 빠른 검색 시스템이 필요하다.

좋다. 여기까지 영어 문법을 잘 분석하고 거기에 맞는 한국어 번역 문형을 찾아서 어순을 잘 바꾸어도 결국은 직역이 된다는 것을 알았을 것이다. 의미에 따라서 의역을 해야 하기 때문에 의미에 따라 세분화 된 다른 문형을 선택해서 번역해야 한다는 것을 알았다. 그런데 문제가 하나 더 있다. 단어의 뜻이 여러 가지가 있다는 것이다. 어떤 번역어를 선택해야 하는가? 주변의 인접한 단어와 조합을 해 보면 뜻이 결정된다. 심한 경우는 문장을 다 보아야 뜻이 결정되기도 한다. 문장의 모든 단어의 뜻이 하나로 명확하게 선택되도록 하는 조건을 한 덩어리로 하여 번역을 한다. 예를 들어 a cup of coffee 가 있다고 하자! 여기서 각 단어를 따로 번역하는 것은 무의미하다. cup은 단위로 사용되었지 컵을 나타내는 것이 아니다. 이 단어 나열은 어디에 사용되어도 명확히 하나의 뜻으로 통한다. 이것을 한국어로 “커피 한 잔”이라고 번역하는 것도 직역에 가깝다. 이 경우 컵이 잔으로 번역 된다. 한국에서는 그냥 커피라고 한다. 단어가 뭉쳐서 덩어리가 커지면 단어들의 뜻이 명확해진다. 이 점을 이용할 수 있다. 숙어 사전이 필요하다. 숙어 사전은 단어 사전과 다르다. 문형 사전에 가깝다.

번역이 아닌 단어 뜻 찾아주기 프로그램을 만든다고 하자! 즉, 영어 어순을 한국어 어순으로 바꾸지 않는다. 그냥 영어 문법 분석을 하고 영어 의미 분석을 해서 적절한 단어 뜻을 찾아 바로 단어 밑에 표시한다고 하자! 여기까지만 되어도 대성공이다. 이것만 되어도 영어 문장을 이해할 수 있다. 누구라도 여기까지만 되면 스스로 번역문을 작성할 수 있다. 내가 하고 싶은 일이 이것이다. 이것을 하는 것도 어렵다. 다음 문장을 보라.

I like the book you sent me yesterday!
나 좋다 그 책 너 보냈다 내게 어제!

기계 번역 프로그램이 이렇게 번역을 했다고 했을 때 이것을 이해 못하는 한국사람 없을 것이다. 여기까지만 해도 대성공이라고 말하는 이유는 의미가 명확히 통하기 때문이다. 그런데 현재 기계 번역 프로그램은 단어의 의미도 잘 못 선택하고 거기에 더해서 어순을 꼬아 놓기 때문에 도대체 무슨 소리인지 못 알아듣는다. 위와 같은 수준의 번역만 해도 사람들 스스로 의역을 할 수 있다. 내가 하고 싶은 일이 이것이다. 1차 목표라고 할 수 있다. 그냥 영어 어순 그대로 적절한 단위 뭉치로 번역을 나열하는 것이다. 문법 분석이 엉망이라서 어순 재배치는 무의미하다. 그러니 어순을 그대로 따라가며 단어만 번역하여 나열한다. 예를 들어 다음과 같이 번역이 되었다고 하자!

I+(like the book)+(you sent me)+yesterday!
나+(그 책 좋다)+(너 내게 보냈다)+어제!

누군가 이런 단위로 번역을 했다고 하자! 기계가 부분별로 번역된 것을 단순 조립했다. 그 결과를 나타냈는데 이것을 보고 무슨 뜻인지 이해 못하는 한국인은 없을 것이다. 한 단어의 뜻은 주변 단어들과 합치면서 결정된다. 적절히 영어 문법 단위로 잘라서 번역했다 조립하면 그 의미를 정확히 이해할 수 있는 수준이 된다. 인간의 번역과 기계 번역의 중간 정도 수준인데 현재의 기계 번역보다 더 의미를 잘 전달한다. 이런 절충이 필요하다. 이 정도의 정보를 주고 의역을 하라고 하면 대부분의 한국인들이 정확히 번역할 것이다. 문제는 구현하기 좀 어렵다. 엄청 많은 검색과 비교를 해야 한다. 문형 사전(숙어 사전 포함)이 거의 단어 사전 수준으로 커진다. 그렇지만 이렇게 가는 것이 맞다고 본다.

또 다른 중요한 문제가 있다. 언어에 따라 단어 구분이 어렵다. 중국어와 일본어인데 이것들은 띄어쓰기를 하지 않는다. 단어를 기계적으로 구분하기 매우 어렵다. 일본어는 한자와 히라가나, 가타카나 구분이 있어서 어느 정도 단어를 구분할 수 있다. 그런데 중국어는 단어를 기계적으로 구분할 수가 없다. 종이가 아까운 시절에 있었던 관습으로 공백을 넣지 않았다. 초창기 컴퓨터 언어인 포트란도 이런 이유로 복잡한 문법을 가지게 되었다. 종이가 아까워서 단어들을 붙여 써야 했고, 그래서 단어를 구분해 내는 기술이 필요했다. 이런 황당한 문제가 여전히 존재한다. 일본어는 어간에는 한자를 사용하고 어미에는 가나 문자를 사용한다. 고로 단어 구분 방법이 있다. 중국어는 한 글자 단어인 경우 문법과 밀접한 관계가 있다. 그리고 대부분 2글자 단어이다. 고로 첫 글자를 읽으면 그 다음 글자를 붙여 해석할지 힌트가 나온다. 이런 힌트가 있기 때문에 사람도 중국어 단어를 골라서 읽을 수 있다. 역시 이때도 엄청 많은 검색이 필요하다. 단어를 뽑아서 단어집에서 검색하는 것이 아니라 글자 하나씩 읽을 때 이미 분석이 함께 진행되고 있음을 알 것이다. 글자 하나를 읽으면서 동시에 단어 분석이 되고, 단어 하나를 읽으면서 동시에 문형 분석이 된다. 우리 두뇌는 무한 반복 검색 시스템이다. 오토마타, 튜링 기계와 별로 다를 것이 없다.

다음은 품사 구분에 대한 것이다. 품사란 대체로 외형을 보고 결정한다. 명사, 형용사, 부사, 동사 등이 있다. 한국어는 거의 의미에 따라 품사를 구분한다. 왜냐하면 한국어 단어는 명사형, 부사형, 수식형, 서술형 변형이 가능하기 때문이다. (아름다움, 아름답게, 아름다운, 아름답다.) 영어는 약간의 단어 변형이 있다. 그리고 단어 변형 없이 사용된 위치에 의해서 품사를 결정하기도 한다. 중국어는 단어 변형이 없다. 오직 위치만을 보고 품사를 결정해야 한다. 생각보다 품사를 결정하는 것도 어렵다. 즉, 단어의 외형을 보고 우리가 품사 구분을 하지 않는다는 것이다. 문형과 의미에 의존해서 모든 것을 해결하는 것이다. 그러나 의미에 따른 구분이나 분류 기준이 없다. 의미 분류법이 사람마다 다르기 때문이다. 번역을 정확히 하려면 의미 해석이 필요하고, 의미 해석을 정확히 하려면 의미에 따른 품사 세분화가 필요하다. 물건을 던지는 것과 사랑을 던지는 것은 형태로 보면 “명사+던지다”이지만 의미로 보면 다르다. 여하튼 이런 표현의 문제 때문에 어렵다. 영어에선 “책을 열다”라고 말을 하지만 한국에선 “책을 펴다”라고 말을 한다. 목적어는 같은데 동사의 표현이 다르다. 단순히 문법과 사전만을 가지고 번역을 할 수 없다는 것이다. 의미를 알아야 하고 표현의 차이를 반영해야 한다. 품사 나열로는 문형을 정의하기 어렵다.

그래서 절충안을 사용한다. 즉, 문형 분석과 단어 검색을 이용하는 기계 번역과 사람이 직접 번역하는 의역을 50% 섞어야 한다. 이렇게 하면 거의 100% 자연스러운 자동 번역이 완성될 것으로 본다. 다시 말해서 이 세상 모든 문장을 섬세하게 문형 분석을 해서 넣는 작업이 필요하다. 이 작업 자체가 사람이 직접 번역하는 작업과 거의 비슷할 것이다. 단지 약간의 자동화 처리를 가미하여 단어 하나 바뀐 것으로 인해 사람이 재번역을 해야 하는 상황은 막는 것이다. 고로 번역자들을 고용해서 일을 하지만 번역을 하는 것이 아니라 문형 분석을 해서 번역의 틀을 만드는 작업을 하는 것이다. 이렇게 하면 모든 문장을 통으로 번역 하는 것보다는 번역의 양이 적고 그러면서도 기계적인 번역의 도움을 받을 수 있으며 번역의 품질은 높아진다. 이것이 최종 목표이다. 어학에서 응용이라고 하는 것은 80% 문형 틀에 20% 중요한 단어 교체만으로 이루어진다. 문형에는 당연히 어순이 포함되고 골격을 결정하는 기능성 단어들이 중간에 박혀 있다. 문형의 처음 부분은 문형을 예측할 수 있는 단어들이 나온다. 사람도 이렇게 어학을 공부하는데 머리 나쁜 기계가 다른 방법을 사용할 수 없다. 수준 높은 번역자들의 번역 방법과 절차를 그대로 컴퓨터 프로그램으로 구현할 수 있다. 멀지 않은 시점에 이룰 수 있을 것이다.





4. 비슷한 문장 검색

복잡한 문형 분석을 하지 않고 아주 간단하게 비슷한 문장을 검색해서 차이 나는 부분의 단어만 뜻을 찾아 주는 기능도 매우 유용하다. 이 방법은 이미 번역 전문가들이 소프트웨어를 이용해서 사용하고 있다. 복잡한 문형 분석이라는 것도 길고 긴 검색을 통해서 달성하는 것이다. 만약 일치하는 문형이 없으면 그걸로 끝인가? 컴퓨터에서는 비슷한 것을 찾아 주는 기능이 어렵다. 정확한 것을 찾는 것은 쉽다. 약간만 달라도 무시하고 건너가면 된다. 검색 시간이 절약된다. 그런데 비슷한 것을 찾는 것은 모든 것을 빠짐 없이 비교해야 하는 문제가 있다. 너무 심하게 다르다고 판단 되면 거기서 비교를 종료하고 다른 것을 비교해야 한다. 즉, 비교 중에 기준 이하로 다른 것은 무시한다. 이렇게 검색한 결과는 비슷한 정도가 몇 퍼센트 이상인 것들로 나타난다. 이런 비슷한 것을 검색하는 방법은 어떻게 만들까?

비슷한 문장이란 이런 것이다. 

1. 몇 단어가 빠진 것(삭제)
2. 몇 단어가 추가된 것(삽입)
3. 몇 단어가 위치를 바꾼 것(도치)
4. 몇 단어가 다른 것(대치)

이런 분석에 앞서 비슷한 정도를 빨리 판단하는 방법이 필요하다. 예를 들어 80% 비슷한 문장이라면 일단 단어의 개수나 글자의 개수가 20% 이상 차이가 나면 안 된다. 이런 간단한 비교로 일단 아주 많이 다른 것을 대량으로 제외할 수 있다. 길이가 비슷한 것들 중에서 단어별로(글자별로) 비교를 해야 하는데 비슷한 것을 찾아야 한다. 어떻게 할 수 있을까? 통계학에서 말하는 상관성 분석을 하는 방법을 이용할 수도 있다. 이런 것을 사용하려면 양쪽의 길이가 일치해야 한다. 이 방법은 신경망 회로의 동작과 비슷한 면이 있다. 그런데 삽입/삭제 부분이 있다면 위치가 맞지 않는다. 그래서 그대로 적용하기 어렵다. 분석 후에는 2개의 문장에서 어디가 삽입이 있고, 어디가 삭제 되었으며, 어디가 위치를 바꾸었고, 어디가 다른 것으로 대체 되었는지 표시를 해야 한다. 일본어나 중국어 경우는 단어별로 비교하기 어렵다. 각 문장에서 단어 분석을 미리 해 놓은 경우라면 몰라도 그냥 비교하면 글자 단위로 비교해야 한다. 글자 단위로 비교하면 유사하지 않은 것이 유사한 것으로 나올 가능성도 있다. 역시 단어 분석이 필요하다는 말이 된다. 각 문장은 글자의 개수와 단어의 개수에 대한 정보를 가지고 있는 것이 좋겠다. 그리고 단어 구분 기호도 함께 삽입해 놓는 것이 좋겠다. 이런 작업을 하려면 단어집이 있어야 한다.

나는 내일 학교에 간다.(삽입)
나는 학교에 간다.(삭제)

나는 학교에 간다.(대치)
나는 학교에 갔다.(대치)

나는 학교에 가고 싶다.(대치)
나는 학교에 갔다.(대치)


내일 나는 학교로.(삽입)
나는 학교로 간다.(삽입)

나는 내일 학교에 간다.(도치)
내일 나는 학교에 간다.(도치)

위의 것들이 섞여서 나타나면 어떻게 판단을 할 것인가? 어떤 기준에 따라 DB에서 가능성 있는 문장을 가지고 온 후에 복잡한 비교 과정을 거쳐야 한다. 그 비교 과정은 억지로 만들 수 있지만 속도가 문제다. 인간의 두뇌는 병렬 회로로 되어 있다. 지능적인 비교라고 해도 실제로는 단순한 비교 결과를 종합적으로 다시 비교하여 판단하는 것이다. 아날로그 회로에서 기초 원리는 사칙연산이다. 논리회로에선 And, Or, Xor, Not이다. 이것을 조합하는 것이다. 속도를 위해 병렬 처리로 구현하는 것 뿐이다. 컴퓨터에선 직렬 처리이기 때문에 속도를 빠르게 하기 위해서 어떤 힌트에 의지해서 더 비교할 필요가 없으면 다음 단계로 넘어가는 것이다. 예를 들어 첫 단어를 다른 문장의 단어들과 순서에 따라 비교하면서 진행을 하는데 30% 정도 위치를 넘었는데도 같은 단어가 나오지 않으면 나머지 단어들이 이후부터 일치해도 70% 미만의 유사성을 가진다. 이럴 경우는 70% 유사성 기준에 맞지 않으니 빨리 포기하는 것이다. 가능한 빨리 판단할 수 있는 것부터 처리한다. 이러한 시험을 통과한 것에 대해서 좀 더 상세한 비교를 하는 것이다.

전문 번역가들이 TRADOS라는 소프트웨어로 작업을 하는데 이와 비슷한 기능을 구글 번역에서 제공하고 있다. 번역가들이 번역한 모든 문장들을 모아서 패턴을 분석한다고 한다. 실제로 사용해 본 결과 아직 등록된 번역문은 거의 없고 대부분이 기계 번역을 하고 있다. 일본어는 어순이 같아서 기계 번역도 상당히 정확한 편이다. 영어는 엉망이다. 트라도스의 경우는 위와 같은 비슷한 문장 찾아 주기가 가능하다.


2010년 11월 27일 토요일

12. Information Systems

SQL (Structured Query Language)

안녕하세요. 12단원을 맡게된 김선영이라고합니다.

그럼 이제 블로깅을 시작해 보도록 하겠습니다.




SQL(Structured Query Language)은
                           '구조화된 질의 언어'의 약자이다.

SQL은 Structured Query Language약자로 구조적 질의 언어를 뜻한다. 데이터베이스에서 정보를 얻거나 갱신하기 위해 '질의'를 통해 결과를 얻어낼 수 있는 언어인 것이다.
가령 우리가 데이터베이스 내에 있는 정보 중에서 나이가 24살 이상이며 성별이 여자인 데이터만을 골라내고 싶다면 'SELECT ALL WHERE age > 24 AND sex = "F" '라고 치면 된다.
 
곧 SQL은 데이터베이스와 통신하는데 사용되며, ANSI(미 국립표준연구소)에서 제정한 관계형 데이터베이스(Relational DB)를 위한 표준 언어이다. SQL문장은 데이터베이스에 있는 데이터를 갱신하거나, 데이터베이스의 데이터를 조회하는 작업을 수행하는데 이용한다.
 
SQL을 사용하는 몇가지 범용 관계형 데이터베이스 시스템으로는 Oracle, Sybase, Microsoft SQL Server, Access 등이 있다. 대부분의 데이터베이스 시스템은 표준 SQL, 즉 ANSI SQL을 사용한다.
 
하지만 표준 SQL 외에 자신의 시스템만에서만 사용할 수 있는 고유한 특성의 확장된 SQL 기능을 가지고 있다. 이런 기능은 Oracle, SQL Server 등 각 데이터베이스 벤더들 마다 다르게 가지고 있으므로 각 데이터베이스의 매뉴얼을 참조해야 알 수 있다.
 
그러나 'Select', 'Insert', 'Update','Delete', 'Create',그리고 'Drop' 과 같은 표준 명령 만으로도 데이터베이스에서 원하는 거의 모든 작업을 할 수있다.
 
한마디로 말하자면 SQL은  data base를 작성하기 위한 것으로 원하는 정보를 얻기 위한 '물음 방법'을 주조화 하여 묶어 놓은 언어이다. 따라서 SQL을 이용하여 새로운 데이터를 입력하고(INSERT), 찾고(SELECT), 수정(UPDATE)하고,지울(DELETE) 수 있다.


  
SQL의 종류

SQL은 크게 데이터와 그 구조를 정의하는 DDL과 데이터의 검색과 수정을 위한 DML 그리고 데이터 베이스 사용자의 권한을 정의하는 DCL의 세가지로 분류할 수 있다.

DDL - 데이터 정의 언어

CREATE
데이터베이스 개체를 생성한다.
DROP
데이터베이스 개체를 삭제한다.
ALTER
기존에 존재하는 데이터베이스 개체를 새로 다시 정의한다.
GRANT
데이터베이스 개체에 권한을 부여한다.
REVOKE
이미 부여된 데이터베이스 개체의 권한을 귀소,철회 한다.



DML - 데이터 처리 언어

INSERT
데이터베이스 개체에 데이터를 입력한다.
DELETE
데이터베이스 개체에서 데이터를 삭제한다.
UPDATE
기존에 존재하는 데이터베이스 개체 안의 데이터를 고친다.
SELECT
데이터 베이스 개체로부터 데이터를 검색한다.
COMMIT
커밋(COMMIT)구문 전에 일어난 데이터베이스 액션들을 영구히 저장한다
ROLLBACK
마지막으로 일어난 커밋 후의 데이터베이스 액션들을 원상으로 복구한다



SQL 구문에서는 대소문자를 구별하지 않는다.
모든 SQL문은 세미콜론으로 끝난다.
문법에 맞지 않거나 존재하지 않는 데이터를 검색할 때에는 다음과 같이 Error 코드를 나타낸다.



CREATE TABLE 구문
데이터를 저장하고 검색하기 전에 선행되어야 할 일이 바로 데이터베이스 개체의 구축이다. 데이터베이스 개체의 구축은 CREATE TABLE 구문으로 할 수 있으며 일반적으로 데이터 베이스 개체의 구축을 테이블 생성이라고 한다.

CREATE TABLE 데이터 이름(컬럼 이름 컬럼의 데이터 타입,
컬럼 이름 컬럼의 데이터 타입 NULL or NOT NULL); 


학번
이름
나이
04
홍길동
26
05
김유신
25




student 라는 테이블 명으로 테이블을 생성하였고 stu_Num = 학번 , stu_Name = 이름 , stu_Age = 나이로 3개의 컬럼을 정의 하였다.
  • 테이블 이름을 지정한 후에 각 컬럼 들은 괄호"()"안에서 지정한다.
  • 컬럼 이름 뒤에는 컬럼의 데이터 타입이 항상 정의되어야 한다.
  • 컬럼이 항상 특정 값(NOT NULL)을 가져야 하는지를 지정한다.
  • 각각의 컬럼들은 콤마","로 구분한다.
  • 끝맺음은 항상 세미콜론 ";"으로 한다.
데이터 형

NUMBER(l,d)
일반적인 수사 데이터를 저장한다. l는 저장할 수 있는 최대 자릿수이고, d는 소수점 이하 자리 수를 가리킨다.
CHAR(size)
size에서 지정하는 만큼,2000byte까지 고정 길이 문자열 데이터를 저장한다.
VARCHAR2(size)
size에서 지정하는 만큼, 4000byte까지 가변 문자열 데이터를 지정한다.
DATE
BC 4712 11일부터 AD 4712 12 31일까지의 날짜를 저장한다.
LONG
2GB의 문자까지 문자열 데이터를 저장할 수 있다.
BLOB
이진(Binary)LOB데이터 타입으로서 이진 데이터를 4GB까지 저장한다.
CLOB
문자 LOB 데이터 타입으로 4GB의 문자열을 저장한다.
BFILE
Read_Only 이진(Binary)파일 타입으로, 데이터베이스 외부에 저장된다.




INSERT 구문
생성한 테이블에 데이터를 넣어보자.
INSERT INTO 데이터 이름 VALUES (데이터, 데이터,' '  ,데이터 ); 

테이블에 데이터를 입력하기 전에 어떤 데이터들이 입력될 수 있는지를 알아 보기 위하여 DESCRIBE문을 이용한다.
DESC 테이블 이름;


테이블에 데이터 입력


  • DESCRIBE문에서 보여주듯이 NOT NULL 값이 아닌 컬럼은 생략할 수 있으며 입력하려는 컬럼들만 표시 하여 실행할 수 있다.

SELECT 구문
SELECT문은 기존에 생성한 테이블의 데이터를 검색하는 SQL문이다.

SELECT문의 두 가지 필수 구분과 두 가지 선택 부분
필수 부분
선택 부분
SELECT
무엇을 보고 싶은지를 (테이블의 컬럼이름) 명시한다.
WHERE
검색할 데이터의 검색 조건을 지정한다.
FROM
보고 싶은 데이터를 어디로부터 얻을 것인지를(하나 또는 둘 이상의 테이블 이름) 명시한다.
ORDER BY
검색결과 반환되는 행의 정렬을 위해 사용된다.




필수 부분만 사용한 검색
  

검색할 컬럼을 명시한 SELECT문



WHERE절을 이용한 검색
검색하려 하는 특정 데이터의 조건을 명시하여 특정 열(Row)을 검색할 수 있게 해준다.



student 테이블의 04학번인 학생을 검색한 예제이다.

WHERE절과 AND/OR
두 가지 이상의 조건을 결합하여 검색한 결과값은 AND의 경우는 명시된 조건을 모두 만족하는 데이터가, OR의 경우는 명시된 조건중 한가지라도 만족하는 모든 데이터가 표시된다.




두 가지 조건이 만족되는 데이터가 없으므로 선택된 레코드가 없다는 메시지가 나온다.


ORDER BY절을 이용한 검색
검색 결과 반환될 행을 특정 컬럼 값에 ORDER BY절을 사용하여 정렬할 수 있다.




학번순으로 정렬 하여 주었다.

WHERE 절과 ORDER BY 절을 모두 사용한 검색



WHERE 조건이 맞는 데이터를 stu_Num 순으로 정렬하였다.


UPDATE 구문
테이블 안의 데이터를 수정하려면 UPDATE문을 사용한다.
UPDATE문은 고칠 데이터가 속한 테이블을 지정할 UPDATE, 어떤 컬럼을 어떻게 고칠지를 지정하는 SET 그리고 어떤 행을 고칠지를 지정하는 WHERE의 세 가지 Keyword로 구성된다.

홍길동임꺽정을 바꾸겠다.




DELETE 구문
DELETE문은 더 이상 사용하지 않는 데이터를 삭제 할때 쓰인다.
03학번의 학생을 지우도록 하겠다.





ALTER TABLE 구문
데이터베이스를 구축하다 보면 기존의 테이블의 정의와 구조를 수정해야 할 때 도있다. ALTER TABLE문이 이러한 일을 해준다.
  • ALTER하려는 구조가 테이블 안의 기존의 데이터와 일치하지 않을 경우 ALTER TABLE문을 사용할 수 없다. 즉, 기존에 존재하는 데이터는 보호된다.
기존의 데이터가 수정하려는 구조에 어긋나지 않는다면 그 구조를 바꿀 수 있다는 말과 같다.



DROP TABLE 구문
기존에 사용하던 데이터베이스 테이블이 더 이상 불필요하게 되었거나 처음부터 다시 데이터베이스를 디자인하려 한다면, 기존에 테이블을 삭제할 필요가 있다.DROP TABLE이 이러한 일을 해준다.
한번 삭제한 테이블은 다시 복구할 수 없다.




 
 
 
 
 
 
 
 
 
 
 
 
아이고 어렵다.