for textmining

한국어의 조사

|

이번 글에서는 한국어의 조사에 대해 알아보도록 하겠습니다. 자연언어처리 분야에서 한국어 조사는 분석의 까다로움 때문에 전처리 때 아예 제거되는 불용어(stopwords) 취급을 받고 있는데요. 사실 교착어(첨가어)인 한국어에서 조사는 문법적, 의미적으로 큰 역할을 하고 있는 형태소입니다. 이 글은 기본적으로 한국어 문법론 대가 이익섭 서울대 명예교수께서 쓰신 ‘한국어문법’을 참고했습니다. 조사의 종류와 용법에 대해 간단히 정리한 후 1년치 조간신문 기사에서 조사가 얼마나 많이 쓰였는지 양적인 통계를 한번 내봤습니다.

이 글의 목차는 다음과 같습니다.

격조사

조사(助詞)는 크게 격(格)을 나타내는 격조사와 특수조사로 나뉩니다. 한국어는 조사가 발달한 걸 특징으로 삼을 수 있을 만큼 그 수도 많거니와 그 쓰임도 매우 다양합니다. 우선 격조사를 종류별로 간단히 살펴보겠습니다.

주격조사

주격조사는 한 문장의 주어 자리에 쓰이는 조사입니다.

이/가 : 대표적인 주격조사, 보어 자리에 쓰이기도 합니다

비가 온다. 바람이 분다.

낙엽송은 상록수가 아니다.

께서 : 주어를 존대하기 위해 쓰는 조사

증조할아버지께서 이 비석을 쓰셨답니다.

에서 : 단체나 기관이 주어일 때 쓰는 조사

당국에서 책임을 지겠지요.

대격조사

대격조사(對格助詞) ‘을/를’은 목적어 자리에 쓰이는 조사로 어떤 행위가 미치는 대상을 가리킵니다. 목적격조사라고 불리기도 합니다.

무슨 선물을 받았니?

새해 무슨 좋은 꿈을 꾸셨나요?

어디를 그리 바삐 가니?

인부들이 나무를 밑동을 잘랐다.

처격조사

처격조사(處格助詞)는 처소(處所)를 나타내 주는 것을 주된 임무로 하는 조사입니다.

: 공간적인 범위, 이유 등 꽤 다양한 의미로 쓰이는 처격조사

어제는 종일 집에 있었다. (공간적 범위)

나팔꽃은 아침에 피었다가 저녁에 진다. (시간적 범위)

이 책은 어디에 보낼 거니? (지향점)

올림픽은 4년에 한 번씩 열린다. (단위)

그 글은 내 마음에 들이 않는다. (추상적 공간)

천둥소리에 모두들 깜짝 놀랐다. (이유)

생각난 김에, 순식간에, 에 대하여… (관용구)

에게 : ‘에’와 밀접한 관계에 있는 처격조사, 동물이나 사람처럼 감정이 있는 명사와 결합해 쓰입니다.

그 편지를 어디에 보냈니? // 그 편지를 누구에게 보냈니?

화초에 물 좀 주렴. // 아이들에게 물 좀 주렴.

이번 일의 책임은 전적으로 회사에 있습니다. // 이번 일의 책임은 전적으로 저에게 있습니다.

: ‘에게’의 높임말입니다.

이번 일의 책임은 전적으로 회장님께 있습니다.

한테/더러 : ‘에게’와 거의 같은 성질을 가진 조사이지만 사용에 일부 제약이 있습니다.

이걸 누구에게 물어볼까? // 이걸 누구한테 물어볼까? // 이걸 누구 더러 물어볼까?

너{한테, 에게, *더러} 무슨 책임이 있겠니?

어린 새끼들{한테, ?에게, *더러} 아직 풀은 주지 마라.

에서/에게서/한테서 : ‘에’, ‘에게’, ‘한테’는 이쪽에서 저쪽으로 가는 방향을, ‘에서’, ‘에게서’, ‘한테서’는 반대로 저쪽에서 이리로 오는 방향을 가리킵니다.

선수단이 부산에 왔다. // 선수단이 부산에서 왔다.

누나한테 형한테서 편지가 왔다. // 누나한테서 형한테 편지가 왔다.

에/에서 : 한국어를 배우는 외국인이 어려워 하는 것 중 하나가 ‘에’와 ‘에서’의 구별입니다. 의미 차이가 그리 선명하게 드러나지 않을 때가 종종 있기 때문입니다. 하지만 둘은 분명 구분해서 써야 합니다.

이 화분은 거실에 놓읍시다. // 거실에서 뛰지 마라.

나는 그 때 제주도에 있었다. // 나는 그때 제주도에서 근무하였다.

구격조사

구격조사(具格助詞)는 무엇을 만들 때 쓰이는 도구나 재료 및 어떤 일을 하는 수단을 나타내 주는 조사입니다. 대표적으로 로/으로가 있습니다.

도끼로 장작을 패 본 일이 있니? (도구)

콩으로 메주를 쏜다고 해도 안 믿는구나. (재료)

토끼는 꾀로 그 위기를 벗어났다. (수단)

가뭄으로 농작물의 피해가 여간 크지 않답니다. (이유)

향격조사

‘으로’는 지향점 및 통과지점을 가리키는 데 쓰이는 향격조사(向格助詞)이기도 합니다.

섬진강은 남쪽으로 흘러 남해로 들어간다. (공간적 지향점)

고속도로로 가지 말고 국도로 돌아가자. (공간적 통과지점)

이제부터는 우리에게 협조하기로 약속했습니다. (추상적 지향점)

형은 입사하자 곧 과장으로 승진하였다. (변화)

자격격조사

으로 : 대체로 ‘의 자격으로’로 풀 수 있는 의미로 쓰입니다.

나는 여기서 사병으로 3년을 근무하였다.

새 감독으로 윤 코치가 발탁되었다.

으로서 : 자격을 나타내는 ‘으로’ 뒤에는 ‘서’를 덧붙여 쓰는 일이 많습니다. 수단을 나타내는 ‘으로’에 ‘써’가 결합한 격조사 ‘으로써’와는 구분해서 써야 합니다.

학생으로서의 본분을 잊지 말아야 한다.

‘으로’ 관련 관용구

주로, 대체로, 진실로, 정말로, 참으로…

속격조사

속격조사(屬格助詞) ‘의’는 명사와 명사 사이에서 두 명사를 소유주와 소유물의 관계로 묶어 주는 일, 다시 말하면 소속 관계를 나타내 주는 일을 주된 임무로 하는 조사입니다. 하지만 그 쓰임의 범위는 매우 다양합니다.

누님의 결혼반지

부모님의 꾸중

독서의 계절

이별의 슬픔

하나의 목표

아내와의 약속

자식으로서의 도리

공동격조사

공동격조사(共同格助詞)는 두 명사가 서로 짝이 되어 어떤 일에 관여할 때 그 두 명사를 한 덩어리로 묶어주는 일을 하는 조사입니다.

과/와 : 공동격조사의 대표

개관 10주년 특별전 - 고대와 현대의 조화

하고 : 주로 구어적인 용법에 쓰입니다.

남희와 명호는(/남희하고 명호는) 어렸을 때부터 이웃에서 오누이처럼 지냈다.

공동격조사는 두 문장을 하나로 묶어주는 역할을 하기도 합니다. 하지만 그 쓰임에 일부 제약이 있습니다.

나는 사과를 좋아한다. 나는 포도를 좋아한다. // 나는 사과와 포도를 좋아한다. *나는 사과를 포도와 좋아한다.

비교격조사

두 명사의 상태를 비교할 때 쓰이는 비교격조사(比較格助詞)에는 보다, 처럼, 만큼, 같이가 있습니다.

남한의 인구가 북한의 인구보다 많다.

바위가 꼭 물개처럼 생겼구나.

너도 언니만큼 예쁘구나.

주위는 온통 칠흙같이 어두웠다.

호격조사

호격조사(呼格助詞)는 누구를 부를 때 이름이나 호칭 다음에 쓰는 조사로 아/야가 있습니다.

진숙아, 전화 왔어.

명호야, 너 뭐 잊은 거 없니?

호격조사는 경어법 면에서는 특히 큰 제약을 받습니다. 손윗사람을 부르는 호칭에는 호격조사를 생략하거나 기도문과 같은 상황에서는 이여/여, 이시여/시여를 써서 상대를 최대한으로 높입니다.

아버님, 저희들 왔어요.

주여, 여름은 참으로 찬란하엿습니다.

특수조사

특수조사(特殊助詞)는 격을 나타내 주는 것이 아니라 어떤 의미를 나타내주는 조사들을 말합니다.

‘오직’, ‘오로지’, ‘유일’이라는 뜻을 나타내는 조사입니다. 수량표현과 어울리면 ‘최소’라는 의미가 붙습니다.

이 꽃은 그늘에서만 잘 자란다.

조금만 참으세요.

다른 것에 그것이 포함된다는 뜻을 나타냅니다. ‘아울러’ 정도의 의미입니다. 이외에도 다양한 의미로 쓰입니다.

이 꽃은 그들에서도 잘 자란다. (아울러)

원숭이도 나무에서 떨어지는구나. (특별한 사태)

저 사람 고집은 누구도 못 꺾어요. (남김없이 모두)

옷을 많이도 입었구나. (강조)

은/는

한국어의 특수조사 중 그 의미를 추출해내기가 가장 까다로운 종류입니다. 주격조사 ‘이’와 용법을 가려내는 일은 한국어를 배우는 외국인은 물론 국어학자들도 어려워 하는 대목입니다.

이 꽃은 그늘에서는 잘 자란다. (대조)

한글은 소리글자요, 한자는 뜻글자다. (대조)

한글은 소리글자다. (대조? 주어?)

‘은/는’과 주격조사 ‘이/가’ 비교

  • 새로 꺼내는 이야기와 이미 알려진 정보

    시장에 무엇이 새로 나왔을까? // *시장에 무엇은 새로 나왔을까?

  • 초점(focus)

    영미가 노래를 더 잘 한다. (영미가 다른 아이보다)

    영미는 노래를 더 잘 한다. (다른 것보다 노래를)

  • 정의 : ‘은’이 더 잘 어울립니다

    지구는 둥글다.

    해는 동쪽에서 떠서 서쪽으로 진다.

  • 복문의 주어

    근심이(*근심은) 없는 사람은 하나도 없었다.

    우리가(*우리는) 출발한 시간은 여섯 시 정각이었다.

  • 화제(topic) : ‘은’의 의미를 화제로 규정하기도 합니다. 화제란 한 단락의 중심생각을 가리키는 말입니다.

    훈민정음은 세종이 친히 창제하였다.

    그늘에서는 곡식이 잘 자라지 않는다.

조차, 마저, 까지, 부터

이제부터 설명드릴 ‘조차’, ‘마저’, ‘까지’, ‘부터’는 ‘도’와 비슷한 의미로 서로 넘나들며 쓰일 수 있습니다.

너{도, 조차, 마저, 까지} 나를 못 믿는구나.

조차 : 그것이 기대하는 최소, 최하, 최후의 것임을 제시하면서 거기에서도 기대가 허물어지는 사태에 쓰입니다. 주로 부정문, 평서문에 사용됩니다.

요즈음은 아이들조차 자기 주장이 강하다.

*너조차 앉아 쉬어라.

*너조차 {안 만나고/*만나고} 갔다고?

마저 : ‘마지막 하나’라는 어감을 가진 조사입니다. 기대를 어긋나는 일에만 쓴다는 제약을 받지 않는다는 점이 ‘조차’와는 다릅니다.

이러다가는 죽을지 모른다는 생각마저 들더라.

올 가을에는 막내마저 시집 보내려고요.

까지 : ‘조차’와 ‘마저’보다 제약이 덜 합니다.

드디어 자가용까지 샀다.

내친 김에 우승까지 하려무나.

부터 : 여러 후보 중 그것이 처음임을 알리거나 시발점을 나타내주는 조사입니다.

남 얘기 하지 말고 너부터 똑똑히 하려무나.

누구부터 줄까.

이나/나, 이나마/나마, 이라도/라도

이나/나 : 자기가 바라는 최상의 길은 아니나 이 정도면 자족할 수 있다는 걸 나타내는 조사입니다. 희망을 나타내는 문장에서는 ‘더 바랄 것이 없다’는 뜻을 함축합니다. 이외에도 다양한 의미로 쓰입니다.

휴가도 못 가는데 잠이나 실컷 자자. (차선)

나도 달나라에나 한번 가 보았으면. (더 바랄 것이 없음)

나는 어디에서나 잘 잡니다. (모든 곳)

우리 학교가 상을 다섯 개나 탔대. (놀라움)

이나마/나마 : ‘이나’와 그 의미가 꽤 비슷하면서도 미묘하게 다릅니다.

선풍기나마(/선풍기나) 하나 있었으면 좋겠어요.

우리도 벤츠나(??벤츠나마) 하나 삽시다.

이라도/라도 : ‘이나’, ‘이나마’와 비슷한 의미이지만 좀 더 절박한 느낌을 줍니다.

입석이라도 좋으니 태워만 주세요.

이런 때일수록 한 푼이라도 아껴야 한다.

이야/야, 이라야/라야

이야/야 : ‘강조’, ‘당연히’, ‘겨우’ 등 꽤 여러가지 의미로 쓰입니다. 굳이 비교하자면 특수조사 ‘은’에 가깝습니다.

나야 이미 알고 있었지.

물론 이름이야 알지요.

마감일 다 되어서야 겨우 마쳤어.

이라야 : 여러 후보 중 유일하게 어느것 하나가 선택됨을 강조해 나타내는 조사입니다. 비교하자면 ‘만’에 가깝습니다. 대수롭지 않게 여긴다는 뜻도 나타내 줍니다.

당신이라야 회사를 살릴 수 있을 거예요.

그 사람 업적이라야 뭐 그렇고 그렇지요. // *그 사람 업적이라야 실로 대단하지요.

1년치 조간신문의 조사 사용 빈도

조선일보, 한겨레, 매일경제 등 국내 주요 10개 조간신문의 2016년 1년치 기사 25만7973건(총 7484만1451개 어절)을 모았습니다. 조사 사용 빈도를 분석하기 위해 KoNLPy 같은 형태소 분석기를 사용하려고 했으나 분석 결과가 대체로 엄밀하지 않다는 판단 하에 말뭉치를 띄어쓰기 기준으로 단어로 나누고, 여기서 나온 모든 단어를 한글자씩 떼어서 단어의 역순으로 그 빈도를 세었습니다. 아래 표는 지금까지 설명한 조사별 사용 빈도입니다. 형태소를 하나하나 정확히 분석한 결과는 아니니 경향성만 확인하는 용도로 보시면 좋을 것 같습니다.

조사명 빈도수
은/는 6689232
을/를 5837313
이/가 4841467
2585899
2312260
로/으로 2189999
과/와 1381267
1288811
에서 856810
646574
이나/나 408129
까지 210205
부터 185473
에게 168642
보다 103521
85295
처럼 65723
이라도/라도 45397
으로서/로서 17806
조차 11709
만큼 11633
같이 11209
마저 7724
이나마/나마 6061
한테/더러 4898
에게서/한테서 4465
께서 3977
이야 2355
이라야 98

위 표를 보시면 아시겠지만 빈도수 상위 5개 조사(은/는, 을/를, 이/가, 의, 에)가 총 2226만6171번 쓰여 전체의 74.26%를 차지합니다. ‘께’, ‘께서’와 같이 높임을 나타내는 조사는 거의 사용되지 않은 점 또한 확인 가능합니다. 한국어 자연언어처리를 할 때 별도의 복잡한 전처리 과정 없이 어절 맨끝에 등장하는 ‘은/는’, ‘을/를’, ‘이/가’, ‘의’, ‘에’ 다섯개 조사만 제거해도 Text Normalization을 효과적으로 수행할 수 있다는 생각이 듭니다. 의견이나 질문 있으시면 언제든지 댓글, 이메일로 알려주시기 바랍니다. 지금까지 읽어주셔서 감사합니다.

Comment  Read more

기초 행렬연산

|

이번 포스팅에서는 머신러닝, 데이터마이닝 기초인 행렬 연산(Matrix Operations)에 대해 다뤄 보려고 합니다. 연산의 정의 정도를 간단히 다루는 것이니 깊은 내용을 원하시는 분들은 이곳을 참고 바랍니다. 이번 포스팅은 기본적으로 고려대 김성범 교수님 강의를 참고했습니다.

데이터마이닝에서의 행렬 연산

데이터마이닝은 기본적으로 아래와 같은 구조의 데이터를 다룹니다. 계산 편의성을 도모하기 위해 위와 같은 데이터를 행렬로 변환합니다. 그렇게 되면 R, Python 등 각종 언어의 수치해석 라이브러리 도움을 받아 빠르게 연산을 할 수 있게 됩니다.

- X1 X2 Xp
obs1 x11 x12 x1p
obs2 x21 x22 x2p
obsn xn1 xn2 xnp

벡터(Vector)

위 데이터에서 X1(d1)이라는 열(행)을 하나 떼서 만든 것이라고 생각하면 되겠습니다. 이를 식으로 쓰면 다음과 같습니다. 벡터는 다음과 같은 연산이 가능합니다.

[X=\begin{pmatrix} { x }{ 1 } \ { x }{ 2 } \ … \ { x }_{ n } \end{pmatrix}​]

스칼라 곱(Scalar Multiplication)

[{ c }_{ 1 }=5,\quad Y=\begin{pmatrix} { 1 } \ { 2 } \ { 3 } \end{pmatrix}]

[{ c }_{ 1 }Y=\begin{pmatrix} { 1 } \ { 2 } \ { 3 } \end{pmatrix}=5\cdot \begin{pmatrix} { 1 } \ { 2 } \ { 3 } \end{pmatrix}=\begin{pmatrix} { 5 } \ 10 \ 15 \end{pmatrix}]

벡터 덧셈(Vector Addition)

[X=\begin{pmatrix} { 1 } \ 3 \ 5 \end{pmatrix},\quad Y=\begin{pmatrix} 2 \ -1 \ 0 \end{pmatrix}]

[X+Y=\begin{pmatrix} { 1 } \ 3 \ 5 \end{pmatrix}+\begin{pmatrix} 2 \ -1 \ 0 \end{pmatrix}=\begin{pmatrix} 3 \ -2 \ 5 \end{pmatrix}]

벡터의 내적(inner product)

[X=({ x }{ 1 },{ x }{ 2 },…,{ x }{ n }{ ) }^{ T }\ Y=({ y }{ 1 },y_{ 2 },…,{ y }{ n }{ ) }^{ T }\ <X,Y>={ X }^{ T }Y=\sum _{ i=1 }^{ n }{ { x }{ i }{ y }{ i }= } { x }{ 1 }{ y }{ 1 }+{ x }{ 2 }{ y }{ 2 }+…+{ x }{ n }{ y }_{ n }]

벡터의 길이(Length)

X가 다음과 같은 벡터로 정의된다면 X의 길이(Lx)는 아래와 같습니다. 2차원 공간에서 삼각형의 빗변을 구하는 피타고라스의 정리를 떠올리시면 쉽게 이해하실 수 있을 겁니다.

[X=({ x }{ 1 },{ x }{ 2 },…,{ x }_{ n }{ ) }^{ T }]

[Lx=\sqrt { { x }{ 1 }^{ 2 }+{ x }{ 2 }^{ 2 }+…+{ x }_{ n }^{ 2 } } =\sqrt { { X }^{ T }X }]

벡터 간 각도(Angle)

벡터 X와 Y 사이의 각도(θ)는 코사인 법칙으로 유도하여 다음과 같이 표현할 수 있습니다. 다시 말해 두 벡터 내적값을 각각의 벡터 길이로 나눠준 값입니다.

[cos(\theta )=\frac { ({ x }{ 1 }{ y }{ 1 }+{ x }{ 2 }{ y }{ 2 }+…+{ x }{ n }{ y }{ n }) }{ Lx\cdot Ly } =\frac { { x }^{ T }y }{ \sqrt { { x }^{ T }x } \cdot \sqrt { { y }^{ T }y } }]

벡터의 사영(projection)

벡터 x를 y에 사영한 결과는 다음과 같습니다.

[projection\quad of\quad x\quad on\quad y=\frac { { x }^{ T }y }{ { y }^{ T }y } \cdot y]

행렬(Matrix)

머신러닝, 데이터마이닝에서의 행렬은 위 표의 데이터 행과 열이 각각 행렬로 변환된 것이라고 보면 됩니다. 예컨대 3 x 2 차원(dimension)의 행렬 A는 다음과 같이 쓸 수 있습니다.

[A=\begin{pmatrix} -7 & 2 \ 0 & 1 \ 3 & 4 \end{pmatrix}]

행렬 덧셈(Matrix Addition)

[\begin{pmatrix} 1 & 2 & 3 \ 4 & 5 & 6 \end{pmatrix}+\begin{pmatrix} 0 & 1 & 0 \ 2 & -1 & 5 \end{pmatrix}=\begin{pmatrix} 1 & 3 & 3 \ 6 & 4 & 11 \end{pmatrix}]

스칼라 곱(Scalar Multiplication)

[{ c }_{ 1 }=2,\quad A=\begin{pmatrix} 1 & 0 \ 2 & 5 \end{pmatrix}]

[{ c }_{ 1 }\cdot A=\begin{pmatrix} 2 & 0 \ 4 & 10 \end{pmatrix}]

전치(transpose)

[A=\begin{pmatrix} 2 & 1 & 3 \ 0 & 1 & -1 \end{pmatrix},\quad { A }^{ T }=\begin{pmatrix} 2 & 0 \ 1 & 1 \ 3 & -1 \end{pmatrix}]

정방행렬(Square Matrix)과 대칭행렬(Symmetric Matrix)

정방행렬은 행 개수와 열 개수가 같은 행렬이며 대칭행렬은 원래 행렬과 전치가 같은 행렬을 뜻합니다.

행렬 곱셈(Matrix Multiplication)

[A=\begin{pmatrix} 3 & -1 & 2 \ 4 & 0 & 5 \end{pmatrix},\quad B=\begin{pmatrix} 3 & 4 \ 6 & -2 \ 4 & 3 \end{pmatrix}]

[A\cdot B=\begin{pmatrix} 11 & 20 \ 32 & 31 \end{pmatrix}]

직관적으로 이해할 수 있는 예제 하나 더 첨부했습니다. (출처)

역행렬(Inverse)

[AB=BA=I\ B={ A }^{ -1 },\quad A={ B }^{ -1 }\ A{ A }^{ -1 }=I]

행렬식(Determinant)

역행렬 존재여부에 대한 판별식이자 행렬의 부피 역할을 하는 값입니다. 데이터마이닝 분야에선 행렬의 차원수가 아무리 크더라도 행렬식이 스칼라값으로 나오기 때문에 중요하게 취급됩니다. 행렬로 표현된 데이터를 요약한 결과로 해석될 여지가 있기 때문입니다. 자세한 내용은 이곳을 참고하세요.

행렬의 대각합(trace)

대각합(trace) 또한 행렬식과 마찬가지로 행렬 차원수에 관계없이 하나의 값을 지니기 때문에 데이터의 의미를 압축 표현했다는 점에서 중요합니다.

정부호행렬(Definite Matrix)

모든 고유값(eigenvalue)이 양수인 행렬을 양의 정부호행렬(Positive Definite Matrix)이라고 합니다. 모든 고유값이 음수가 아닌 행렬을 양의 준정부호행렬(Postive Semi-Definite Matrix)라고 합니다. 아래 예시에선 임의의 벡터 c에 대해 A가 전자, B가 후자입니다.

[A=\begin{pmatrix} 4 & 0 & 0 \ 0 & 2 & 0 \ 0 & 0 & 1 \end{pmatrix}\quad is\quad Postive\quad Definite\quad Matrix]

[\because \begin{pmatrix} { c }{ 1 } & { c }{ 2 } & { c }{ 3 } \end{pmatrix}\begin{pmatrix} 4 & 0 & 0 \ 0 & 2 & 0 \ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} { c }{ 1 } \ { c }{ 2 } \ { c }{ 3 } \end{pmatrix}=4{ c }{ 1 }^{ 2 }+2{ c }{ 2 }^{ 2 }+{ c }_{ 3 }^{ 2 }\ge 0]

[B=\begin{pmatrix} 1 & 1 \ 1 & 1 \end{pmatrix}\quad is\quad Postive\quad Semi-Definite\quad Matrix]

[\because \begin{pmatrix} { c }{ 1 } & { c }{ 2 } \end{pmatrix}\begin{pmatrix} 1 & 1 \ 1 & 1 \end{pmatrix}\begin{pmatrix} { c }{ 1 } \ { c }{ 2 } \end{pmatrix}=({ c }{ 1 }^{ 2 }+{ c }{ 2 }^{ 2 })\ge 0]

공분산 행렬(Covariance Matrix)

변수가 여러 개인 다변량 데이터에선 변수 간 관련성, 즉 상관성(correlation)이 매우 중요한 문제가 됩니다. 확률변수 X의 값이 X의 평균보다 클 때 Y의 값도 Y의 평균보다 커지고, X의 값이 X의 평균보다 작을 때에는 Y의 값도 Y의 평균보다 작아지는 경향이 있으면 표준화된 X와 Y의 곱인 상관계수(correlation coefficient)는 양의 값을 가질 가능성이 큽니다. 바꿔 말하면 두 확률변수의 직선 관계가 얼마나 강하고 어떤 방향인지를 나타내는 값이라고 볼 수 있습니다.

확률변수 X와 Y의 상관계수와 공분산(Covariance)는 다음과 같이 정의되는데요, 공분산을 X, Y의 표준편차로 나누어 표준화한 값이 X와 Y의 상관관계라고 할 수 있겠습니다. (N=데이터 개수, u1=X의 평균, u2=Y의 평균, s1=X의 표준편차, s2=Y의 표준편차)

[\begin{align} \rho &=\frac { 1 }{ N } \sum _{ i=1 }^{ N }{ \left( \frac { { X }_{ i }-{ \mu }_{ 1 } }{ { \sigma }_{ 1 } } \right) \left( \frac { Y_{ i }-{ \mu }_{ 2 } }{ { \sigma }_{ 2 } } \right) } \ &=E\left[ \left( \frac { { X }-{ \mu }_{ 1 } }{ { \sigma }_{ 1 } } \right) \left( \frac { Y-{ \mu }_{ 2 } }{ { \sigma }_{ 2 } } \right) \right] \ &=\frac { E\left[ (X-{ \mu }_{ 1 })(Y-{ \mu }_{ 2 }) \right] }{ { \sigma }_{ 1 }{ \sigma }_{ 2 } }
&=\frac { Cov(X,Y) }{ { \sigma }_{ 1 }{ \sigma }_{ 2 } } \end{align
}]

[\begin{align} cov(X,Y)&=E\left[ (X-{ \mu }_{ 1 })(Y-{ \mu }_{ 2 }) \right] \ &=E\left[ XY-{ \mu }_{ 2 }X-{ \mu }_{ 1 }Y+{ \mu }_{ 1 }{ \mu }_{ 2 } \right] \ &=E[XY]-{ \mu }_{ 2 }E[X]-{ \mu }_{ 1 }E[Y]+{ \mu }_{ 1 }{ \mu }_{ 2 }\ &=E[XY]-{ \mu }_{ 2 }{ \mu }_{ 1 }-{ \mu }_{ 1 }{ \mu }_{ 2 }+{ \mu }_{ 1 }{ \mu }_{ 2 }\ &=E[XY]-{ \mu }_{ 1 }{ \mu }_{ 2 } \end{align}]

공분산 행렬은 행렬의 각 요소가 공분산인 매트릭스를 의미합니다. 임의의 공분산행렬 A를 예를 들어 보겠습니다.

[A=\begin{pmatrix} 2 & 4 \ 4 & 6 \end{pmatrix}]

첫 행은 확률변수 X, 두번째 행은 확률변수 Y에 해당한다고 치면, 마찬가지로 첫번째 열은 X, 두번째 열은 Y를 가리킵니다. 그렇다면 cov(X, X)=var(X)=2가 되겠네요. 역시 cov(Y, Y)=var(Y)=6입니다. cov(X, Y)=cov(Y, X)=4입니다.

그럼 공분산 행렬은 어떻게 구할까요? 아래와 같은 데이터가 있다고 칩시다.

- X Y Z
obs1 1 4 3
obs2 2 3 5
obs3 3 2 2
obs4 4 1 7

위 데이터는 아래와 같이 행렬과 벡터 형태로 바꿀 수 있습니다.

[D= \begin{pmatrix} 1 & 4 & 3 \ 2 & 3 & 5 \ 3 & 2 & 2 \ 4 & 1 & 7 \end{pmatrix}]

[X=\begin{pmatrix} 1 \ 2 \ 3 \ 4 \end{pmatrix},\quad Y=\begin{pmatrix} 4 \ 3 \ 2 \ 1 \end{pmatrix},\quad Z=\begin{pmatrix} 3 \ 5 \ 2 \ 7 \end{pmatrix}]

위에서 정리한 공분산 공식을 벡터 형태로 바꾸면 다음과 같습니다.

[\begin{align} cov(X,Y)&=E[XY]-{ \mu }_{ 1 }{ \mu }_{ 2 }
&=\frac { 1 }{ n -1 } \sum _{ i=1 }^{ n }{ { X }_{ i }{ Y }_{ i } } -{ \mu }_{ 1 }{ \mu }_{ 2 }
&=\frac { 1 }{ n-1 } <X,Y>-{ \mu }_{ 1 }{ \mu }_{ 2 }
\end{align
}]

위의 식을 뜯어보면 벡터 X와 Y의 평균이 0으로 centering돼 있다면 cov(X,Y)는 X와 Y의 내적에 (데이터 개수 - 1)로 나눠준 값과 같습니다. 즉 아래처럼 되는 것이죠.

[\begin{align} cov(X,Y)&=\frac { 1 }{ 3 } \begin{pmatrix} 1 & 2 & 3 & 4 \end{pmatrix}\begin{pmatrix} 4 \ 3 \ 2 \ 1 \end{pmatrix}-(2.5\times 2.5)\ &=\frac { 1 }{ 3 } \begin{pmatrix} -1.5 & -0.5 & 0.5 & 1.5 \end{pmatrix}\begin{pmatrix} 1.5 \ 0.5 \ -0.5 \ -1.5 \end{pmatrix} \&=-1.667 \end{align}]

그럼 데이터 전체의 공분산을 구해볼까요? 앞서 정리한 행렬 곱셈(Matrix Multiplication)의 정의에 의해 행렬끼리의 곱셈결과는 각 요소에 해당하는 벡터들끼리의 내적값과 같습니다. 이러한 성질을 이용해 D를 각 변수별(열 기준)로 평균을 0으로 맞춰주고($D’$) 이를 제곱해주면 데이터 전체의 공분산 행렬을 한번에 구할 수 있습니다.

[\begin{align} cov(D)&={ \frac { 1 }{ 3 } D’ }^{ T }D’\ &=\frac { 1 }{ 3 } \begin{pmatrix} 1-2.5 & 2-2.5 & 3-2.5 & 4-2.5 \ 4-2.5 & 3-2.5 & 2-2.5 & 1-2.5 \ 3-4.25 & 5-4.25 & 2-4.25 & 7-4.25 \end{pmatrix}\begin{pmatrix} 1-2.5 & 4-2.5 & 3-4.25 \ 2-2.5 & 3-2.5 & 5-4.25 \ 3-2.5 & 2-2.5 & 2-4.25 \ 4-2.5 & 1-2.5 & 7-4.25 \end{pmatrix}\ &=\begin{pmatrix} 1.67 & -1.67 & 1.5 \ -1.67 & 1.67 & -1.5 \ 1.5 & -1.5 & 4.92 \end{pmatrix} \end{align}]

위 공분산 행렬의 해석은 이미 설명드린 바와 같습니다. X, Y, Z의 분산은 각각 1.67, 1.67, 4.92입니다. $cov(X,Y)=cov(Y,X)=-1.67$, $cov(Y,Z)=cov(Z,Y)=-1.5$, $cov(X,Z)=cov(Z,X)=1.5$입니다.

독립(independence)과 직교(orthogonality)

확률변수 X의 값이 확률변수 Y의 값에 아무런 영향을 미치지 않는다면 X와 Y는 서로 독립(independent)이라고 합니다. 두 변수가 독립이라면 아래와 같은 식이 성립합니다.

[E[XY]=E[X]\cdot E[Y]]

두 확률변수 X와 Y가 서로 독립이라면 아래 식에 의해 공분산이 0이 됩니다. 바꿔 말하면 확률변수 X와 Y가 아무런 선형관계가 없다는 뜻입니다.

[cov(X,Y)=E[XY]-E[X]\cdot E[Y]=E[X]\cdot E[Y]-E[X]\cdot E[Y]=0]

직교성(Orthogonality)은 이미 설명드린 벡터 간 각도에서 도출된 개념입니다. 90도 직각에 해당하는 코사인값은 0이므로 두 벡터가 직교할 경우 그 내적은 0이 됩니다.

통계학의 ‘독립’, 선형대수학의 ‘직교성’이라는 개념은 엄밀히 말해 정확히 같지는 않지만 공분산(covariance)을 고리로 연결할 수 있게 됩니다. 확률변수(벡터) X와 Y의 평균을 각각 0으로 맞추고 공분산 공식에서 전체 데이터 개수로 나눠주는 부분(1/n)을 무시하면 공분산과 내적 관계를 아래 식처럼 쓸 수가 있습니다.

[cov(X,Y)=<X,Y>]

위 식을 지금까지 논의한 걸 바탕으로 해석하면 이렇습니다. 두 확률변수 X와 Y가 서로 독립이면 공분산은 0입니다. X와 Y의 내적 또한 0이 됩니다. 이를 다시 벡터 간 각도와 연관지어 생각하면 그 내적이 0인 두 벡터는 직교한다는 결론을 도출할 수 있게 됩니다. 따라서 ‘독립’과 ‘직교성’을 연결지어 생각할 수 있게 된다는 얘기입니다.

그램-슈미트 단위직교화(Gram-Schmidt Orthogonalization)

그램슈미트 단위직교화는 직교하지 않는 k개의 벡터(x)를 직교하는 k개 벡터(u)로 변환하는 방법입니다. 그림으로 이해하려면 이곳을 참고하세요. 데이터마이닝에선 변수들끼리 상관관계를 지니게 되면(즉 서로 독립이지 않으면) 분석의 정확성이 떨어지게 됩니다. 이미 언급했듯이 독립과 직교성은 긴밀한 관계를 지니게 되므로 그램-슈미트 단위직교화를 통해 각 변수를 직교 벡터로 바꿀 경우 변수간 상관관계가 제거됩니다.

[\begin{align} { u }_{ 1 }&={ x }_{ 1 }\ { u }_{ 2 }&={ x }_{ 2 }-\frac { { x }_{ 2 }^{ T }{ u }_{ 1 } }{ { u }_{ 1 }^{ T }{ u }_{ 1 } } { u }_{ 1 } \ …\ { u }_{ k }&={ x }_{ k }-\frac { { x }_{ k }^{ T }{ u }_{ 1 } }{ { u }_{ 1 }^{ T }{ u }_{ 1 } } { u }_{ 1 }-…-\frac { { x }_{ k }^{ T }{ u }_{ k-1 } }{ { u }_{ k-1 }^{ T }{ u }_{ k-1 } } { u }_{ k-1 } \end{align}]

한번 예를 들어보겠습니다. 다음과 같은 두 벡터가 있다고 합시다. 내적해보면 알겠지만 직교하지 않습니다.

[{ X }{ 1 }=\begin{pmatrix} 4 \ 0 \ 0 \ 2 \end{pmatrix},\quad X{ 2 }=\begin{pmatrix} 3 \ 1 \ 0 \ -1 \end{pmatrix}]

위 식을 바탕으로 u를 만들어 봅시다.

[{ u }{ 1 }={ X }{ 1 }=\begin{pmatrix} 4 \ 0 \ 0 \ 2 \end{pmatrix}]

[{ u }{ 1 }^{ T }{ u }{ 1 }={ 4 }^{ 2 }+{ 0 }^{ 2 }+{ 0 }^{ 2 }+{ 2 }^{ 2 }=20]

[x_{ 2 }^{ T }{ u }_{ 1 }=12+0+0-2=10]

[u_{ 2 }=\begin{pmatrix} 3 \ 1 \ 0 \ -1 \end{pmatrix}-\frac { 10 }{ 20 } \begin{pmatrix} 4 \ 0 \ 0 \ 2 \end{pmatrix}=\begin{pmatrix} 1 \ 1 \ 0 \ -2 \end{pmatrix}]

u1, u2를 각각의 벡터 길이로 나누어 정규화한 것이 그램-슈미트 방법의 최종 결과물이 되겠습니다.

[z_{ 1 }=\frac { 1 }{ \sqrt { 20 } } \begin{pmatrix} 4 \ 0 \ 0 \ 2 \end{pmatrix},\quad z_{ 2 }=\frac { 1 }{ \sqrt { 6 } } \begin{pmatrix} 1 \ 1 \ 0 \ -2 \end{pmatrix}]

고유값(eigenvalue)과 고유벡터(eigenvector)

고유값과 고유벡터의 개념에 관해서는 이곳을 참고하세요. 다음 식을 만족하는 람다와 X가 각각 정방행렬 A의 고유값과 고유벡터가 됩니다. 고유값과 고유벡터는 분석대상 데이터 행렬를 잘 표현하는 요약 결과이기 때문에 행렬식, 대각합 등과 더불어 중요한 정보가 되겠습니다.

[AX=\lambda X]

간단하게 고유값과 고유벡터를 구해보겠습니다.

[A=\begin{pmatrix} 1 & 0 \ 0 & 3 \end{pmatrix}]

[\left A-\lambda I \right =\left \begin{matrix} 1-\lambda & 0 \ 1 & 3-\lambda \end{matrix} \right =(1-\lambda )(3-\lambda )=0\ \lambda =1\quad or\quad 3]

람다가 1일 때

[AX=1\cdot X=\begin{pmatrix} 1 & 0 \ 0 & 3 \end{pmatrix}\begin{pmatrix} { X }{ 1 } & { X }{ 2 } \end{pmatrix}=\begin{pmatrix} { X }{ 1 } \ { X }{ 2 } \end{pmatrix}]

[{ X }{ 1 }={ X }{ 1 },\quad { X }{ 1 }+3{ X }{ 2 }={ X }{ 2 }\ \therefore \quad { X }{ 1 }=-2{ X }_{ 2 }]

람다가 3일 때

[AX=3\cdot X=\begin{pmatrix} 1 & 0 \ 0 & 3 \end{pmatrix}\begin{pmatrix} { X }{ 1 } & { X }{ 2 } \end{pmatrix}=\begin{pmatrix} { 3X }{ 1 } \ { 3X }{ 2 } \end{pmatrix}]

[{ X }{ 1 }={ 3X }{ 1 },\quad { X }{ 1 }+3{ X }{ 2 }={ 3X }_{ 2 }\ \therefore \quad X=\begin{pmatrix} 0 \ 1 \end{pmatrix}]

고유값 분해(Spectral Decomposition)

데이터 행렬을 고유값(람다)과 고유벡터(e)로 분해하는 방법입니다. 아래와 같이 정의됩니다.

[A=\sum { i=1 }^{ k }{ { \lambda }{ i }{ e }{ i }{ e }{ i }^{ T } }]

고유값 분해를 간단하게 해보겠습니다. 행렬 A의 고유값과 고유벡터는 다음과 같습니다.

[A=\begin{pmatrix} 2.2 & 0.4 \ 0.4 & 2.8 \end{pmatrix}\ { \lambda }{ 1 }=3,\quad { \lambda }{ 2 }=2\ { e }{ 1 }=\begin{pmatrix} \frac { 1 }{ \sqrt { 5 } } \ \frac { 2 }{ \sqrt { 5 } } \end{pmatrix},\quad { e }{ 2 }=\begin{pmatrix} \frac { 2 }{ \sqrt { 5 } } \ \frac { -1 }{ \sqrt { 5 } } \end{pmatrix}]

그러면 행렬 A는 아래와 같이 다시 쓸 수 있습니다. \(\begin{align*} A&=\begin{pmatrix} 2.2 & 0.4 \\ 0.4 & 2.8 \end{pmatrix}\\ &=3\begin{pmatrix} \frac { 1 }{ \sqrt { 5 } } \\ \frac { 2 }{ \sqrt { 5 } } \end{pmatrix}\begin{pmatrix} \frac { 1 }{ \sqrt { 5 } } & \frac { 2 }{ \sqrt { 5 } } \end{pmatrix}+2\begin{pmatrix} \frac { 2 }{ \sqrt { 5 } } \\ \frac { -1 }{ \sqrt { 5 } } \end{pmatrix}\begin{pmatrix} \frac { 2 }{ \sqrt { 5 } } & \frac { -1 }{ \sqrt { 5 } } \end{pmatrix} \end{align*}\)

Comment  Read more

그래프로 중요 기사 걸러내기

|

이번 포스팅에서는 ‘그래프’로 중요 기사를 걸러내 보도록 하겠습니다. 같은 시간대에 비슷한 제목의 기사가 많으면 중요한 이슈를 다루는 보도일 것이라는 가정이 깔려 있는 분석 방법론인데요, 매우 간단한 방법론이지만 생각보다 퍼포먼스가 좋아서 써먹을 일이 많을 것 같습니다. 자 시작해 볼까요?

Structured Journalism

하루에도 수백 수천건의 기사가 쏟아지는 ‘뉴스의 홍수’ 시대입니다. 소비자 입장에선 어떤 기사가 중요하고 그렇지 않은지 알기 어렵고 생산자 입장에선 공들여 만든 뉴스가 단 하루만 지나도 쓸모 없어지기 때문에 대단히 비효율적입니다. 생산자든 소비자든 뉴스의 맥락을 짚기가 매우 어려운 것이 요즘 현실입니다. 예를 들어볼까요? 대한민국 대표기업 ‘삼성’에 관련된 이슈를 찾아보고 싶다고 칩시다. 네이버에 삼성 키워드를 넣어서 뉴스를 검색해봤습니다.

많이들 검색해보셔서 아시겠지만 지금 당장 벌어지고 있는 이슈는 비교적 쉽게 알 수 있지만 과거 이슈는 시간과 노력을 들이지 않으면 알기 어렵습니다. 또 ‘공채’, ‘최순실 수사’, ‘삼성전자의 하만 인수’ 등은 시간의 흐름에 따라 진화, 발전하는 이슈지요. 저는 뉴스 소비자에게 중요한 기사를 걸러 보여주면서도 뉴스의 맥락(context)을 알 수 있게 하면 좋겠다는 생각을 했습니다. 이와 관련된 개념이 바로 스트럭처 저널리즘(Structured Journalism)입니다.

스트럭처 저널리즘은 언론학계에 최근 제시되고 있는 개념으로 기사 및 기사 속에 내재된 정보를 계속 누적시켜 재맥락화(recontextualize)하려는 노력을 총칭합니다. 위 그림에서처럼 단순 팩트나 기존 기사들을 재조합하여 새로운 가치, 맥락을 만들어보려는 시도입니다.

중요기사의 기준

중요한 기사란 무엇일까요? 야구를 좋아하는 사람은 메이저리그 기사, 정치에 관심있는 독자는 박근혜 전 대통령 탄핵 관련 보도가 중요하겠지요. 이렇듯 각자가 중요하다고 생각하는 기사는 저마다 다를 겁니다. 기사 중요도 판단은 어느 정도는 주관적인 영역이라는 거지요. 그런데 저는 중요 기사의 조건을 아래처럼 양적으로 접근해 보기로 했습니다.

언론은 특종 경쟁에 매몰돼 있다. 같은 사실을 보도하더라도 어제와 ‘다른’ 뉴스, 남들과는 ‘차별화한’ 시각을 추구한다. 그런데 많은 언론사들이 유사한 제목의 비슷한 기사를 보도한다면 해당 사건이나 이슈는 사회에 파급력이 클 가능성이 높다. 바꿔 말해 해당 기사는 차별성을 다소 포기하더라도 보도할 만한 가치가 있는 중요한 아티클이라는 이야기다.

위 가정을 제가 기자 생활을 할 때 경험과 연관지어 이야기해보겠습니다. 대부분의 편집국, 보도국은 24시간 365일 체제로 운영됩니다. 국내외 사건사고들이 9 to 6 근무시간에만 발생하지는 않기 때문입니다. 근무시간에는 모든 기자들이 출근해 사건을 취재해 기사를 쓰고, 심야나 휴일 사건은 당직기자들이 커버하는 구조입니다. 저도 기자일 때 평일 심야, 휴일 당직을 여러번 서 봤는데요. 이때 선배들이 입버릇처럼 강조한 말이 있습니다.

물 먹지 마라.

‘물 먹는다’는 표현은 ‘낙종’을 뜻하는 언론계 은어입니다. 낙종은 특종과 반대되는 개념인데 모든 언론사가 취급하는 중요 이슈를 보도하지 않(못)한 경우 이런 말을 씁니다. ‘박근혜 대통령 탄핵’, ‘북한 핵실험’, ‘삼성그룹 미래전략실 폐지’ 같은 중요 사건이 터졌을 때 담당 기자가 넋 놓고 있다가 이를 보도하지 않았(못했)을 때는 시말서를 쓸 각오를 해야 합니다. 그래서 편집국을 대표해 당직을 설 때에는 상당한 긴장감을 갖고 근무를 해야 했습니다.

Graph-based News Representation

지금까지 논의한 걸 바탕으로 모델을 만들어보기로 했습니다. 대전제는 딱 두 줄로 요약됩니다.

  • 중요한 뉴스라면 모든 언론사가 취급할 것이다
  • 중요 기사는 제목이나 키워드가 비슷할 것이다

저의 경우 위 두 가지 전제를 모델링하기 위해 그래프(graph)를 써보기로 했습니다. 뉴스 제목을 노드(꼭지점)엣지(간선)로 표현하는 것입니다. 무슨 말인지 알쏭달쏭하시죠? 예를 들어보겠습니다.

이날 대부분의 신문은 ‘사드’ 관련 기사를 비중있게 보도했습니다. 그만큼 중요한 사안이라는 이야기죠. 우선 뉴스 제목을 포스태깅하고 조사 등 불필요한 품사를 제거했습니다. 그리고 중복 단어 숫자를 웨이트(가중치)로 하는 무방향 엣지를 연결했습니다.

조선일보 1면 톱기사 ‘사드, 경북 성주에 배치한다’는 제목의 노드는 경향신문의 1면 톱기사 ‘사드 배치 경북 성주 사실상 결정’과 단어 중복수가 4개입니다(사드 경북 성주 배치). 조선일보의 1면 톱기사 제목은 한겨레의 1면 톱기사 ‘외교장관 만류에도 사드 결정 강행했다’는 기사와 2개 단어가 겹칩니다(사드, 하다), 경향신문과 한겨레 기사의 경우엔 1개(사드)가 겹칩니다. 이를 그래프로 그리면 위 그림과 같습니다. 단어 중복수를 웨이트로 한 그래프에선 조선일보 ‘사드, 경북 성주에 배치한다’가 중심 노드가 되겠네요.

그래프 이론에서는 노드의 중요도를 뽑는 데 중심성(cetrality) 개념을 제시합니다. 가장 대표적인 것이 간선중심성(degree centrality)입니다. 비교적 직관적으로 이해할 수 있는데요, 각 노드의 중심성 스코어는 엣지에 해당하는 웨이트들의 합입니다. 위의 그림 예시에서 보면 조선일보 1면 톱기사인 ‘사드, 경북 성주에 배치한다’는 노드의 간선중심성은 6입니다.

또 다른 지표는 고유벡터 중심성(eigenvector centrality)를 꼽을 수 있습니다. 중요한 노드에 연결된 노드가 중요하다는 관점에서 창안된 개념인데요. 그래프의 엣지로 이뤄진 인접행렬(i번째 노드와 j번째 노드가 연결돼 있을 경우 $A_{ij}=1$, 아닐 경우 0)을 고유값 분해(eigenvalue decomposion)를 하여 얻을 수 있습니다. 이렇게 구해진 i번째 노드의 고유벡터 중심성 점수($X_i$)와 그 의미는 다음과 같습니다. (n=전체 노드 개수)

[{ x }{ i }=\frac { 1 }{ \lambda } \sum _{ i=1 }^{ n }{ { A }{ ij }{ x }_{ j } }]

[\begin{pmatrix} { A }{ 11 } & { A }{ 12 } & … & { A }{ 1n } \ { A }{ 21 } & { A }{ 22 } & … & { A }{ 2n } \ … & … & … & … \ { A }{ n1 } & { A }{ n2 } & … & { A }{ nn } \end{pmatrix}\begin{pmatrix} { x }{ 1 } \ { x }{ 2 } \ … \ { x }{ n } \end{pmatrix}=\begin{pmatrix} { A }{ 11 }{ x }{ 1 }+{ A }{ 12 }{ x }{ 2 }+…+{ A }{ 1n }{ x }{ n } \ { A }{ 21 }{ x }{ 1 }+{ A }{ 22 }{ x }{ 2 }+…+{ A }{ 2n }{ x }{ n } \ … \ { A }{ n1 }{ x }{ 1 }+{ A }{ n2 }{ x }{ 2 }+…+{ A }{ nn }{ x }{ n } \end{pmatrix}=\begin{pmatrix} { \lambda x }{ 1 } \ \lambda { x }{ 2 } \ … \ \lambda { x }_{ n } \end{pmatrix}]

위 수식과 행렬을 곱씹어 보면 $i$번째 노드의 고유벡터 중심성 점수($x_i$)는 자기 자신의 중심성 점수($x_i$)와 모든 이웃들의 중심성 스코어 점수의 합으로 표현할 수 있습니다. 바꿔 말하면 중심성 점수가 높은 중요한 이웃과 연결된 $i$번째 노드 또한 중심성 점수가 높아지게 된다는 얘기입니다. 반대로 생각하면 $i$번째 노드가 중요한 노드라면 $i$번째 노드와 연결된 이웃들의 중심성이 커지게 됩니다. 즉 중요한 노드에 연결된 노드가 중요하다는 말이 되는 셈이죠.

실험설계 및 결과

이상 논의한 내용을 바탕으로 뉴스 제목의 중복 단어를 가중치로 하는 그래프를 구축했습니다. 각 노드의 중심성은 간선중심성과 고유벡터중심성 두 가지 지표를 구해 이를 곱하여 모두 고려했습니다. 분석 대상은 조선일보, 한겨레 등 10개 주요 조간 매체 10개월치 기사(2016년 1~10월) 20만7729건입니다. 위에서 예시로 든 2016년 7월 13일치 결과를 한번 보겠습니다.

위 표에서 degree는 간선중심성, eigen은 고유벡터중심성, result는 이 둘을 곱한 스코어를 뜻합니다. result 기준으로 정렬해 상위 7개를 뽑았습니다. 이날은 ‘사드’가 중요한 이슈였던 모양입니다. 상위 기사에 ‘사드’ 관련 기사가 모두 포진해있군요. section을 보시면 1~5면 사이의 기사가 상위에 랭크돼 있어 비교적 중요한 기사들이 뽑혔다는 사실 또한 알 수 있습니다.

위 그림은 같은 날짜 스코어 하위 기사들입니다. 보통 중요하지 않은 기사들이 대부분인데요, 빨간색으로 표시한 기사가 눈에 좀 띕니다. 스코어는 낮은데 1면에 보도된 기사입니다. 아무래도 이건 다른 언론사 기사와 제목이 완전히 다른 ‘차별성 있는 기사’인 것 같습니다. result 스코어를 section 정보와 동시에 고려한다면 중요도 지표가 낮은(제목이 특이한) 기사 가운데 앞쪽면 기사는 해당 언론사의 특종이나 단독기획 기사일 가능성이 높다고 해석해도 나쁘지 않을 것 같다는 생각이 듭니다.

중심성 지표 기준 상위 3%를 중요기사라고 분류했습니다. 분석 대상 전체 기사 20만7729건 가운데 해당 면이 차지하는 비중과 비교한 그림은 다음과 같습니다. 지금까지 설명한 방법론이 앞쪽 면(비교적 중요) 기사를 걸러내는 데 효과적임을 알 수 있습니다.

이제 ‘삼성’을 알아볼까요. 중요도 상위 3%에 뽑힌 기사들 가운데 ‘삼성’이라는 키워드가 들어간 기사의 제목을 쭉 나열해봤습니다. 삼성은 대한민국 대표기업인 만큼 회사 측 공식발표도 많고 매일 기사가 쏟아지는데도 중요한 이슈(지배구조 변화, 분기별 실적 등)가 비교적 잘 걸러짐을 확인할 수 있습니다.

samsung

samsung

마치며

Graph-based News representation이 스트럭처 저널리즘의 완벽한 구현이자 종착역은 아닙니다. 다만 단순 팩트나 기존 기사들을 재조합하여 새로운 가치, 맥락을 만든다는 이상에 다가가기 위한 첫 단추로 역할을 할 수 있다면 더할 나위 없이 좋을 것 같습니다. 이외에도 옛날 기사를 어떻게든 되살려보려는 여러 가지 방법론들을 고민하고 있는데요, 지적하실 내용이나 아이디어, 질문 있으시면 언제든지 메일이나 댓글로 알려주시기 바랍니다. 여기까지 읽어주셔서 진심으로 감사드립니다.

Comment  Read more

드디어 GTX1080 장착!

|

해야지 해야지 하면서도 잡일이 많아서 미루고 미뤘던 GTX 1080을 드디어 연구실 컴에 장착했다!! 포장부터 영롱한 자태..

1

포장 개봉을 하면 이렇듯 웅장한 자태를 내뿜는다, 하악

2

비닐을 살포시 뜯어주고..

3

컴퓨터에 장착!! (사실 크기가 너무 커서 본체 케이스 전체를 공사하다시피했다..뒷부분은 다 뜯어냈다고 보면 됨..ㅠ)

4

텐서플로우에서도 잘 인식된다, 저 메모리 용량을 보라.. 그동안 메모리 땜에 고생한 것만 생각하면 ㅠㅠㅠ

5

조명빨도 좀 있다ㅋㅋㅋㅋ

7

앞으로 열공할 일만 남았다.

GPU를 지원해주신 강필성 교수님, 사용을 배려해준 김해동, 조수현, GPU 설치에 많은 도움을 준 박재선 학우 모두들 감사합니다ㅠㅠ

Comment  Read more

Sequence-to-Sequence 모델로 뉴스 제목 추출하기

|

이번 포스팅에서는 Sequence-to-Sequence 모델로 ‘뉴스 제목 추출하기’를 해보려고 합니다. 결론부터 말씀드리자면 완벽한 실험 결과가 나온 건 아니고요, 제가 삽질했던 점들을 중심으로 S2S 모델의 특징과 한계 등에 대해 이야기해볼까 합니다. 자 그럼 시작하겠습니다!

Sequence-to-Sequence?

Sequence-to-Sequence 모델(S2S)은 Recurrent Neural Network의 가장 발전된 형태의 아키텍처입니다. LSTM, GRU 등 RNN cell을 길고 깊게 쌓아서 복잡하고 방대한 시퀀스 데이터를 처리하는 데 특화된 모델이죠. 실제로 S2S는 영어-한국어, 한국어-일본어 등 기계번역에 쓰이고 있다고 합니다. 이 모델은 2014년 이 논문에서 처음 소개가 됐는데요, 구글 텐서플로우에서도 이를 구현한 코드를 공개해 눈길을 끌고 있습니다. 이번 포스팅은 기본적으로 텐서플로우 예제들을 커스터마이징해서 만들었습니다.

S2S는 크게 인코더(encoder)디코더(decoder) 두 파트로 나뉩니다. 영어를 한국어로 변환하는 기계번역을 예로 들어보겠습니다. 인코더는 소스랭귀지(source language)인 영어 텍스트를 처리합니다. 디코더는 타겟랭귀지(target language)인 한국어 텍스트를 맡게 되죠. 디코더의 입력은 이 모델 정답에 해당하는 한국어 텍스트이며 출력 또한 한국어 텍스트입니다. <go><eos>는 각각 정답 시작과 끝을 알리는 일종의 기호라고 보시면 되겠습니다. 인코더와 디코더의 입출력과 관련해 한번 예를 들어보겠습니다.

인코더 입력 : Good morning!

디코더 입력 : <go> 좋은 아침입니다!

디코더 출력 : 좋은 아침입니다! <eos>

인코더는 소스랭귀지 정보를 압축합니다. 디코더는 인코더가 압축해 보내준 정보를 받아서 타겟랭귀지로 변환해 출력합니다. 다만 학습과정과 예측(테스트)과정이 조금 다릅니다. 학습과정에서 디코더는 인코더가 보내온 정보와 실제 정답(‘<go>좋은 아침입니다!’)를 입력으로 받아 ‘좋은 아침입니다<eos>’를 출력합니다.

예측 과정에서 디코더는 인코더가 보내온 정보와 ‘<go>’만 입력으로 받아 결과물을 차례대로 출력합니다. 띄어쓰기를 기준으로 인풋을 만든다면 예측 과정에서의 디코더가 내놓는 첫 결과물은 ‘좋은’이 되겠지요. 예측 과정에서의 디코더는 직전에 예측한 ‘좋은’이라는 결과를 다시 자신의 다음 단계 입력으로 넣어 ‘아침입니다’를 출력하게 됩니다.

디코더가 예측 과정에서 자신의 직전 출력(좋은)을 다음 입력으로 다시 넣는 이유는 예측 단계에선 학습 때와는 달리 정답이 없기 때문입니다. 그래야 정답이 주어지지 않은 상태(예컨대 구글 번역기에 우리가 번역하고 싶은 문장을 입력할 때)에서도 예측이 가능해 집니다.

문제 정의

자, 그럼 이번 포스팅의 목적인 ‘뉴스 제목 생성’을 위 아키텍처에 적용해 봅시다. 위 그림처럼 인코더에 뉴스 본문을 넣고 디코더에 제목을 넣는 것이죠. 왜 공들여 이런 일을 하냐고요? 제 포부는 원대했습니다. 정답이 있는 데이터만 S2S 학습이 가능합니다. 하지만 자연언어처리 분야에서 정답이 있는 데이터를 얻기는 매우 어렵습니다. 그런데 뉴스 기사는 다르죠. 뉴스는 다른 분야 말뭉치 대비 양질이면서도 하루에도 수백 수천건씩 쏟아집니다. 조간신문이나 방송에 보도된 뉴스는 제목을 다는 데도 수많은 전문인력이 투입되죠. 비교적 수월하게 구할 수 있는 한국어 말뭉치 중에는 이만한 컨텐츠가 없다고 생각했습니다.

게다가 뉴스 제목은 대체로 본문 내용을 전반적으로 포괄하는 경향이 있습니다. 뉴스 본문이라는 문서를 요약하는 학습모델을 만들 때 제목을 정답으로 놓고 모델링을 하면 참 좋겠다는 생각을 했습니다. S2S는 시퀀스 형태의 인풋을 받아 또 다시 시퀀스 형태의 아웃풋을 내놓으므로 요약 결과가 완결된 문장 형태를 지닐 수 있지 않을까 하는 기대를 하기도 했습니다. 뒤에 설명드리겠지만 시작은 아주 창대했답니다.

데이터 전처리

우선 웹에서 2016년 1월초 사흘치 기사 1000건을 모았습니다순Siri 기사를 보고 싶지 않아서는 절대 아닙니다. 원래 기사는 이렇게 생겼습니다.

경기도 준예산 사태…‘보육대란’ 이미 시작됐다

[한겨레] 해법 안보이는 ‘누리예산’

경기도의회 연말 여야 몸싸움

남경필 지사·강득구 도의회 의장

준예산 사태 논의에도 접점 못찾아

당장 이달부터 누리과정 지원중단

교육부는 계속 교육청만 압박

지난 12월31일 경기도의회에서 여야 의원들의 몸싸움이라는 최악의 사태까지 연출한 누리과정(만 3~5살 무상보육) 사태가 새해에도 해법을 찾지 못한 채 정부와 교육청, 시·도의회, 여야 간 타협 없는 대치 국면으로 이어질 전망이다. (하략)

우선 위 기사를 제목과 본문으로 나눴습니다. 본문에는 중간제목으로 보이는 내용들(이탤릭체)도 일부 보입니다만 일일이 손으로 거르기보다는 이대로 넣어도 학습이 가능할 것이라는 근거없는 희망으로 모두 본문에 포함했습니다. 다음은 토크나이징, 노말라이즈 등 전처리를 할 차례인데요. KoNLPy 같은 오픈소스 형태소 분석기를 사용하려고 했습니다. 그러나 형태소 분석 과정에서 잘못된 태깅으로 말뭉치 정보가 왜곡되거나 손실될 염려를 배제하기 위해 다른 방법을 쓰기로 했습니다. 단어를 띄어쓰기 기준으로 나누고 3글자까지만 잘라서 노말라이즈를 하는 겁니다. 이렇게 하면 아래 예시의 토큰들을 한 단어로 취급합니다.

감정가

감정가

감정가격에

감정가격은

감정가격이

텍스트 노말라이즈를 하는 근본 이유는 단어수를 줄여 분석의 효율성을 높이기 위해서입니다. 위 다섯개 단어를 각각 다른 단어로 보고 분석하면 물론 정확성은 높아지겠지만 계산복잡성 또한 증가합니다. 어느 순간엔 정확성 상승 대비 분석 비용이 지나치게 높아지게 될 겁니다. 실제로 단어 단위 S2S 모델은 학습 말뭉치의 단어 수가 분류해야할 클래스의 개수가 되기 때문에 단어수가 지나치게 크면 학습의 질은 물론 속도도 급격하게 감소하는 문제가 있습니다. 이 때문에 단어 수를 적절하게 줄일 필요가 있습니다. 저의 경우 위와 같이 노말라이즈를 했음에도 불구하고 단어 개수가 무려 6만5016개나 됐습니다(ㅠㅠ).

자 그럼 구체적으로 예시를 볼까요? 사흘치 기사에서 영어와 숫자, 문장부호, 줄바꿈문자 등을 제거한 기사는 아래와 같은 형태가 됩니다. (title, contents는 변수명이므로 무시하고 보세요)

title: 경기도 준예산 사태 보육대란 이미 시작됐다

contents: 해법 안보이 누리예산 경기도의회 연말 여야 몸싸움 남경필 지사 강득구 도의회 의장준예산 사태 논의에도 접점 못찾아 당장 이달부터 누리과정 지원중단 교육부는 계속 교육청만 압박 지난 월 일 경기도의회에서 여야 의원들의 몸싸움이라는 최악의 사태까지 연출한 누리과정 만 살 무상보육 사태가 새해에도 해법을 찾지 못한 채 정부와 교육청 시 도의회 여야 간 타협 없는 대치 국면으로 이어질 전망이다 (하략)

이제 S2S에 넣은 인풋을 본격적으로 만들어볼까요? S2S엔 텍스트를 숫자로 바꾸어 넣어야 합니다. ‘경기도’를 0, ‘준예산’을 1, ‘사태’를 2… 이렇게요. 이렇게 단어를 숫자로 바꾸기 위해서는 단어와 숫자가 매칭된 사전(dictionary)이 있어야 합니다. 학습 말뭉치인 사흘치 기사에 한번이라도 나온 모든 단어들을 세어서 이를 숫자로 매핑하는 것이죠. 예측 과정에선 숫자를 단어로 바꿔야 하기 때문에 숫자와 단어가 매핑된 사전도 별도로 만들었습니다.

word_to_ix

{‘학생비자를’: 60946, ‘답답함이’: 13623, (중략) ‘감정가’: 979, ‘감정가의’: 979, ‘감정가격에’: 979, (하략) }

ix_to_word

{0: ‘가’, 1: ‘가가갤’, 2: ‘가감’, 3: ‘가거나’, (중략) 979: ‘감정가’ (하략) }

눈썰미가 있는 분들은 이미 눈치채셨겠지만 저같은 경우엔 학습 말뭉치를 바로 3글자로 줄인게 아니라 단어를 숫자로 바꿔주는 사전인 word_to_ix에 모든 단어를 넣되 앞에서부터 3글자가 겹치는 단어들은 같은 인덱스를 주어서 단어가 숫자로 변환될 때 자연스럽게 3글자로 노말라이즈될 수 있도록 했습니다. 이렇게 하면 원래 데이터가 어떻게 생겼는지 확인하기 쉬워서 이렇게 한건데 그냥 바로 3글자로 줄여도 됩니다. 어쨌든 ‘감정가’, ‘감정가의’, ‘감정가격에’라는 단어는 모두 979라는 숫자로 바뀌게 되고요, 나중에 숫자를 단어로 바꾸고 싶을 땐 979가 ‘감정가’로 변환되게 됩니다. 위 기사 본문의 경우 아래처럼 변환됩니다.

[15087, 42582, 3168, 1162, 3168, 10661, 44455, 47701, (하략) ]

위 데이터를 모델에 넣기 전에 하나 고려해야할 것이 있습니다. 바로 데이터 차원수인데요. RNN의 경우 시퀀스 길이에 유연한 네트워크 구조이긴 합니다만, S2S처럼 복잡하고 방대한 네트워크인 경우에는 시퀀스 길이를 어느 정도 맞춰주는 게 좋은 것 같습니다. 그래서 저는 디코더에 넣을 시퀀스 길이를 뉴스 제목 최대 길이(18개 단어)로 맞췄고요, 인코더에 넣을 시퀀스 길이를 기사 앞부분 100개 단어절대 메모리가 부족해서가 아닙…로 맞췄습니다. 만약 이들 길이보다 데이터 시퀀스 길이가 짧다면 <PAD>를 넣어 길이를 맞춰줬습니다. <PAD> 넣는 법은 쉽습니다. word_to_ix와 ix_to_word에 각각 <PAD>라는 요소를 추가해주고 길이가 부족한 데이터에 끼워 넣었습니다.

모델 구현

제가 사용한 S2S의 디테일한 설정들은 위 그림에 요약돼 있습니다. 아시다시피 녹색으로 표시된 은닉층에 어떤 cell을 쓸지 선택할 수 있지 않습니까? 저의 경우 cell은 두 가지를 실험했고요, 바로 LSTM/GRU입니다. 은닉층을 여러 개 쌓을 수도 있는데요, 저는 1개(single) 혹은 3개(multi)를 실험했습니다. 중요한 부분을 중점적으로 검토하게 해 분석의 정확도를 높이는 attention 기법을 적용/미적용한 것의 차이도 실험했습니다. 데이터 시퀀스의 순방향과 역방향 정보를 모두 고려하는 bidirectional 방법론 가운데 이번 실험에서는 메모리 문제로후자만 차용을 했습니다. 다시 말해 인코더 입력 시퀀스를 모델에 입력으로 넣을 때 역방향으로 넣었다는 이야기입니다(뉴스 본문 첫 단어가 인코더의 맨 마지막 입력이 됨). 아래는 텐서플로우 예제에서 제가 커스터마이징한 코드입니다.

천천히 설명을 드리면 tool.loading_data라는 함수는 아래와 같은 형식의 CSV(utf-8)를 읽어들여 title과 contents로 나누어 줍니다. tool.make_dict_all_cut은 학습 말뭉치를 읽어들여 위 예시처럼 word_to_ix와 ix_to_word를 생성해줍니다.

multi라는 파라메터는 은닉층을 1개만 쌓을건지 여러개 쌓을건지 지정하는 변수입니다. forward_only라는 변수는 학습 때는 false, 추론(테스트) 때는 true로 지정합니다. vocab_size는 말뭉치 사전 단어수, num_layers는 은닉층 개수, learning_rate는 학습률, batch_size는 1회당 학습하는 데이터 수(배치 크기)를 의미합니다.

encoder_size는 인코더에 넣을 입력 시퀀스의 최대 길이, decoder_size는 디코더에 넣을 시퀀스의 최대 길이입니다. tool.check_doclength 함수는 입력 컨텐츠의 최대 길이를 반환합니다. tool.make_inputs는 ‘데이터 전처리’에서 설명드렸듯 단어를 숫자로 바꾸는 과정을 한번에 해주는 함수입니다.

이제 클래스 ‘seq2seq’에 정의한 네트워크 구조를 살펴보겠습니다.

우선 변수 선언 부분입니다. encoder_size만큼의 placeholder를 생성해 encoder_inputs를 만듭니다. 마찬가지로 decoder_inputs, targets, target_weights를 만듭니다. target_weights는 target(제목)에 대응하는 요소가 <PAD>일 경우 0, <PAD>가 아닐 경우 1로 채워넣은 리스트입니다. target_weights는 정답에 끼어있는 <PAD>가 학습에 반영되지 않도록 도와주는 값이라고 이해하시면 될 것 같습니다.

네트워크를 선언한 부분을 보겠습니다. cell은 ‘tf.nn.rnn_cell.GRUCell’이라고 선언했습니다. tf.nn.rnn_cell.LSTMCell’이라고 선언하면 GRU를 간단하게 LSTM cell로 변환 가능합니다. 층을 여러개 쌓고 싶으면 ‘tf.nn.rnn_cell.MultiRNNCell’이라는 함수를 쓰면 됩니다.

이제 학습과 예측 과정을 살펴보겠습니다. 아래는 이해를 돕기 위한 그림입니다.

학습 과정을 살펴보겠습니다. if not forward_only 구문이 실행되는 부분입니다. ‘tf.nn.seq2seq.embedding_attention_seq2seq’ 함수는 outputs를 반환합니다. ‘feed_previous’에 False를 씁니다. attention을 쓰지 않으려면 ‘tf.nn.seq2seq.embedding_seq2seq’ 함수를 사용해 보세요. 이 output에 W를 내적하고 b를 더해 logit을 만들고요, 리를 바탕으로 cross-entropy loss를 구합니다. 여기서 주목할 점은 cross-entropy loss에 target_weight를 곱해준다는 점입니다. target_weight는 <PAD>인 경우 0이기 때문에 <PAD>에 해당하는 cross-entropy loss는 무시됩니다.

추론 과정을 살펴보겠습니다. else: 구문이 실행되는 부분입니다. ‘tf.nn.seq2seq.embedding_attention_seq2seq’ 함수의 ‘feed_previos’에 True를 집어넣습니다. 디코더가 직전 과정에서 내뱉은 결과를 다음 과정의 인풋으로 받아들여 추론하라는 지시입니다. 나머지는 일반적인 딥러닝 네트워크 구조와 크게 다르지 않습니다. 아래는 위 코드가 import해서 사용하는 tool.py입니다. tool.py에 있는 모든 코드들은 제가 직접 만들었습니다.

실험 결과

학습

3-layers, encoder_size(100), decoder_size(20), GRU(300차원), attention, batch_size=16

괄호 안은 정답입니다

§Iter 500 : 신당 신당 신당 신당 신당 <E><E> <E> <E> <E> <E> <E> <E> <E><E> <E> <E> <E> 
(안철수 신당 호남 위 새누리당 수도권 영남 충청서선두)
§Iter 1000 : 윤미옥 김윤정 김윤정 두 두 두 두 향토방 <E><E> <E> <E> <E> <E> <E> <E> <E><E> 
(윤미옥 김윤정 예비역 소령 두 번째 군대 인생 향토방위 수준 높이겠다) 
§Iter 1500 : 삼성베트남 베트남 휴대폰 휴대폰 부품 부품 <E><E> <E> <E> <E> <E> <E> <E> <E><E> <E> 
(삼성 베트남 공장 덕분에 휴대폰 부품 수출 급증)
§Iter 2000 : 롯데 지분지분 취득 <E><E> <E> <E> <E> <E> <E> <E> <E><E> <E> <E> <E> <E> 
(롯데 롯데제과 지분 취득)
§Iter 2500 : 윤병세 윤병세 국민적 국민적 저항자화자찬 자화자찬 자화자찬 삶 삶 삶 높은 높은 높은 질 없는전 전 
(윤병세 장관은 국민적 저항 외면 자화자찬)

예측

1-layer 3-layers 3-layer + attention 정답
대북 도발 김정은 확성기 높이다 대북 방송 국민 단단한 안보 의식이 추가 도발 막는다
최경환 누리 누리 예산 누리 예산 누리과정 예산 일단 늘어나 교부금 활용하라
삼성 삼성 가전 너마저 실적 반도체 불투명 반도체 주춤 삼성전자 영업이익 감소

위 결과 표를 보면 아시겠지만 학습은 비교적 잘 되는 것처럼 보입니다. iter 1000번(배치를 1000번 넣었다는 뜻, 1000개 기사를 학습데이터로 넣었으므로 전체 데이터 기준으로는 16번 학습)만에 어느 정도 제목 윤곽이 나오는 것을 볼 수 있습니다. 학습시 디코더 입력에 실제 정답을 넣어서 이렇게 잘 되는 것 같기도 합니다.

하지만 학습에 쓰이지 않은 데이터를 넣어 예측한 결과를 보면 조금 아쉽습니다. 일단 학습 과정보다는 그 품질이 확실히 떨어집니다. 그 원인은 다양하겠지만 뉴스 자체의 특성 때문 아닐까 생각합니다. 같은 사건을 보도하더라도 완전히 같은 내용의 기사는 없으며, 그 본문이 거의 비슷하더라도 언론사마다 제목은 크게 다른 경우가 많습니다. 다시 말해 ‘Good morning!’의 한국어 표현은 ‘좋은 아침입니다!’, ‘안녕하세요’ 등 몇 가지 안되는 ‘닫힌 정답’이라면 뉴스 제목은 언론사마다 천차만별인 ‘열린 정답’이라는 것입니다. 학습데이터 양이 작아서인지 3개층, attention 모델 등 복잡한 네트워크가 1-layer와 비슷한 성능을 내는 점 또한 확인할 수 있었습니다.

아울러 이번에 실험하면서 S2S에 대해 가장 크게 느낀 점은 S2S는 예측시 비교적 일반적인 단어를 출력하는 경우가 많다는 점입니다. 위 결과에도 알 수 있듯 경제 기사엔 ‘삼성’, 안보 기사엔 ‘대북’, 경제정책 기사엔 ‘예산’ 같은 일반적인 단어를 예측하고 있습니다. 이는 고차원의 입력데이터를 추상화하여 표현하는 S2S만의 특징이 아닌가 생각이 듭니다. 제가 듣기로 챗봇(chatbot) 구현을 위해 대화 데이터를 S2S 입력으로 줄 경우, ‘아…’, ‘네…’, ‘그럼요’ 정도의 답을 내놓게 된다고 하는군요. ‘아…’, ‘네…’, ‘그럼요’ 같은 단어들은 어떤 대화에서도 성립되는, 오답이 아닌 답변이기 때문인 것 같은데요. 앞으로 연구해볼 만한 주제라는 생각이 듭니다.

향후 계획

제 컴퓨터(i5-3690, 32GB RAM, GTX 970) 기준으로 예측해야할 단어수가 6만개가 넘어가면 메모리 부족으로 학습 자체가 불가능했습니다. 단어수를 효과적으로 줄이거나 하드웨어 업그레이드 등을 통해 추가로 실험할 계획입니다. 정치, 경제, 사회 등 도메인별로 학습해볼 생각도 있습니다. 이번 포스팅 관련해서 제언이나 질문 있으시면 언제든지 메일이나 댓글로 알려주시기 바랍니다. 지금까지 읽어주셔서 감사합니다.

Comment  Read more