서울시 NPO 지원센터

[2016 미트쉐어 컨퍼런스] 데이터 분석 워크샵 '한국 아이돌 워드클라우드'_김혁
작성자 : NPO지원센터, 작성일 : 2016.12.22, 조회수 : 2576
진행개요-

누가 이 컨텐츠를 보면 좋을까요?데이터분석에 관심있는 분

키워드 3가지데이터분석, 아이돌, 워드클라우드

아이돌 노래 가사로 워드 클라우드를 그려보자!

~ 파이썬 자료 분석의 소개 ~

개요

자료: 음원 포털 사이트 '멜론'에서 "댄스" 음악 차트에서 아이돌 '그룹'의 가사를 크롤링(crawling)한 가사 자료

분석 방법: 워드 클라우드

사용 프로그래밍 언어: Python 3.5

 

아이돌 노래에 성차별 요소가 있지 않을까란 문제의식에서 워드 클라우드를 이용해 성별로 나눠 아이돌 가사를 살펴볼까 합니다.

 

분석은 지식만 있다면 할 수 있기 때문에 그 전에 자료를 만드는 것이 어려움. 처음 도구들을 불러와서 그 도구들을 가지고 분석을 하고 그것을 기능적으로 깔끔하게 정리하는 것으로 진행될 것.

 

Step 1. Package Import

 

프로그래밍을 할 때는 모든 기능들을 개발자가 직접 구현하기 어렵기 때문에, 다른 개발자들이 이미 만들어놓은 패키지(또는 라이브러리)를 활용하게 된다. 파이썬도 자료 분석을 위한 여러가지 유용한 패키지들이 구현되어 있다. 이를 활용해보자.

우리가 오늘 불러올 (ipmort) 패키지들은 다음과 같다.

 

NumPy: 파이썬에서 각종 대수적 계산을 가능하게 하는 패키지 (설치 필요)

Pandas: R에서 유용한 DataFrame 자료형과 dplyr 등을 파이썬에서 사용할 수 있도록 하는 패키지 (설치 필요)

os: file input/output을 위한 패키지 (설치 필요 없음)

konlpy: 한국어 자연어 분석(토큰 나누기, 품사 태그하기 등)을 위한 패키지

konlpyJpype(자바 가상 머신을 파이썬이 이용할 수 있도록 하는 것으로 이해할 수 있다.)라는 패키지를 필요로 하므로 꼭 설치해야 한다.

matplotlib: 도표를 그릴 수 있는 패키지

WordCloud (from wordcloud): 워드클라우드를 그릴 수 있는 패키지

Counter (fromo collections): 개수를 셀 때 유용한 패키지

어떤 패키지는 다른 패키지를 필요로 한다 (dependency). 따라서 어떤 패키지를 사용하려면 그것이 의존하는 패키지들을 모두 불러와야 한다.

 

Step 2. Data Load

 

데이터 분석하려면 데이터가 필요하다. 그런데 우리가 평소에 접하는 엑셀 자료나, 워드 문서 등은 프로그래밍 언어가 이해할 수 있는 형태가 아니다. 따라서 프로그래밍을 위해서는 프로그래밍 언어가 이해할 수 있는 형태로 우리가 가지고 있는 자료를 변환해야 한다.

 

그런데 어떻게? 자료는 너무 방대하고, 그것을 하나하나 해결하기란 너무 어려운 일이다. 그래서 프로그래머들은 '표준'을 사용한다. 대표적인 표준들로는 json, xml, csv 등이 있다.

 

json: 웹과 관련해서 요즘 제일 핫한 표준이고, pythonDictionary와 상통한다!

xml: 고전적이지만 파싱(parsing)이 편하다.

csv: 이것도 꽤 고전적인데, 엑셀처럼 시트 형태의 자료는 csv로 많이 교환된다.

 

표준이 있으면 좋은 점은, 표준으로부터 파생된 다른 유용한 도구들을 사용할 수 있다는 것이다. 파이썬의 패키지들을 이용하면 json, xml, csv 파일들은 손쉽게 파이썬이 이해할 수 있는 자료 형태로 바뀐다. 우리가 오늘 사용할 Pandas라는 패키지는 csv 파일을 불러들여 DataFrame 이라는 자료형으로 바꾸어준다.

 

자료형이 뭘까? 자료형(data type)은 말 그대로 자료의 형태이다. 컴퓨터 프로그래밍에서 자료의 형태는 정수, 실수, 문자가 기본이고, 정수의 배열(list; array), 실수의 배열, 문자의 배열(=문자열; string)있고 차원이 올라갈수록 행렬을 만들수도 있다. 그런데 이렇게 단순한 형태로만 자료가 구성되어 있다면 생산적인 프로그램을 만들기가 곤란하다. 그래서 프로그래머들은 자료를 효율적으로 처리할 수 있는 고급 자료형을 이용하기도 하고, 필요에 따라 새롭게 만들기도 한다. 우리는 Pandas가 제공하는 DataFrame이라는 자료형을 이용할 것이다.

 

그러면 이제 자료를 불러와서 DataFrame으로 만들고, 자료가 어떻게 구성되어 있는지 확인해보자.

 

* 1: 불러올 데이터 파일의 경로를 path라는 변수에 저장하였다.

* 2: data라는 변수에 pandas 패키지의 DataFrame 클래스의 from_csv라는 메소드를 이용해 path에 저장된 경로의 데이터 파일을 불러왔다. / 쉽게 이해하려면, csv 파일을 불러와 DataFrame으로 만들어 data 변수에 저장했다, 고 생각하자.

* 3: data 변수를 출력하였다.

 

### 자료의 구성

 

자료는 song_id, artist, title, gender, lyrics 라는 열로 구성되어 있다. 이런 것들을 자료의 레이블이라고도 하고, 인덱스라고도 하고, 변수라고도 한다... 부르는 이름은 다양한데, 오늘은 자료의 레이블이라고 하자.

 

우리가 오늘 불러온 'songs_data'라는 자료는 다음과 같은 레이블로 구성되어 있다.

 

* song_id: 노래의 id (멜론에서 사용하는 id)

* artist: 노래를 부른 가수의 이름(아이돌 그룹)

* title: 노래의 제목

* gender: 노래를 부른 가수의 성별 (f: 여성, m: 남성)

* lyrics: 노래의 가서

 

이들 중에서 오늘 우리가 직접 분석에 사용할 레이블은 genderlyrics이다.

 

Step 3. 자료 처리하기

 

Step 3-1. 가사를 토큰으로 만들기 (tokenization)

 

가사는 텍스트 자료이다. 텍스트 자료를 분석할 때는 개별 분석 단위로 쪼개는 작업, 즉 토큰으로 만드는 작업이 너무 중요하다~! 토큰을 잘못 나누면 왜곡된 분석을 할 수 있다. 토큰을 나눌 때에는 자연어 처리 분석기를 이용하는데, 오늘 우리가 이용할 것은 위에서 언급한 konlpy 패키지이다.

 

konlpy 패키지는 한국어 자연어 처리를 위한 대표적인 분석기들(한나눔, 꼬꼬마, 트위터 분석기 등)을 모두 이용할 수 있다는 장점이 있다. 오늘 우리는 그중에서도 Twitter라는 서브 패키지를 이용할 것이다. 트위터는 한국어 트윗 자료들을 바탕으로 토큰 분석기를 만들어서 제공하고 있다. 트위터 패키지는 사전에 없는 단어를 보거나, 'ㅋㅋ'와 같은 자모 단독 사용에 대한 처리가 유용하다.

 

우선 첫번째 가사만 분석해보자. (참고: 분석기는 바로 사용할 수 없고, instance를 하나 만들어서 사용해야 한다~ 바로 사용하면 오류를 일으킨다.)

 

1: Twitter 분석기를 tagger라는 인스턴스로 불러왔다. 인스턴스로 불러온다는 것은, 예를 들어, '가위'라는 도구를 사용할 때, '가위'라는 총체적인 것을 사용할 수 없고 개별 가위를 사용하는 것이라고 이해하면 된다.

 

2: data에서 lyrics 레이블을 불러와 그 첫번째 요소 (0)를 불러와 토큰으로 만들었다. tagger(우리가 사용할 가위의 이름)pos 라는 메소드를 제공한다. pos라는 메소드는 문장을 형태소 단위로 자르고, 품사를 붙여준다.

 

객체지향 프로그래밍에서, 객체(오브젝트)는 여러 속성과 메소드로 구성된다. 혹시 프로그래밍에 대해 조금이라도 들어본 적이 있다면 메소드는 함수라고 보면 되는데, 함수는 객체에 관련 없이 정의되지만, 메소드는 객체에 종속되는 것으로 정의된다. 프로그래밍에서 이렇게 영역을 제한하는 것은 더 효과적인 (오류를 덜 만들고, 안전하게 프로그래밍 할 수 있도록) 프로그래밍을 가능하게 한다.

 

프로그래밍에서 순서를 말할 때 첫번째는 보통 0이다.

 

그럼 이제 모든 데이터의 가사에 대해 수행해볼까? 이럴 때는 반복문을 쓴다!

 

1: data에서 lyrics라는 레이블의 각 요소(lyric)에 대해

2: lyric을 토큰으로 나누었다.

프로그래밍에서 반복문을 구성하는 방법은 무척무척 다양한데, 여기서 사용한 for 반복문은 명령들을 반복할 배열에서 각 요소를 순차적으로 방문하여 명령을 실행하는 것이다. 여기서 반복 명령을 수행할 배열이 datalyrics 레이블이고, for 반복문 내에서 그 배열의 각 요소를 lyric이라고 부르기로 했다 (1). 그래서 각 요소에 대해 명령(토큰 나누기 + 품사 붙이기)을 수행한 것(2)이다.

 

이 반복문을 한 줄로 쓰면 다음과 같다.

 

1: 반복문을 한 줄에 실행시킨 배열을, tagged라는 변수에 저장했다.

2: 배열 tagged를 출력했다.

Step 3-2. 토큰의 개수를 헤아려보자.

토큰의 개수를 헤아리기 위해 우리는 처음에 Counter라는 패키지를 불러왔다. Counter라는 패키지는 다소 복잡한 것들의 개수를 세어준다. (프로그래밍할 때 무척 유용한 경우들이 많다.) 한 번 개수를 세어보고, 뭐가 얼마나 많은지 확인해보자.

 

그냥 개수를 세어보려 했더니 오류가 났다. 왜일까? Counter는 배열 요소들의 개수를 세어주는데, 우리가 개수를 세려고 하는 (단어, 품사) 쌍은 tuple이라는 것으로 좀 복잡한 자료형이고 2차원의 배열이라서, 단어만 추출한 1차원 배열로 만들어야 한다. ㅠㅠ 안타깝지만 복잡한 반복문을 써야한다.

 

1: 토큳들을 저장할 배열을 선언하였다.

2: lyrics 레이블의 각 요소 lyric에 대해~

3: tagged_list라는 변수는 lyric을 토큰으로 만들고 품사를 붙인 배열이고,

4: 다시 tagged_list의 각 요소인 item에 대해서,

5: word_listitem을 추가한다. (append)

6: 완성된 배열을 출력했다.

(참고) 이 과정은 numpy의 메소드를 활용할 수도 있지만 tuple의 리스트라서, 작동되지 않는다.

그럼 이제 다시 세어보자.

 

1: 개수 세어서, 결과를 cnt라는 변수에 저장하기

2: cnt 출력하기 개수가 세어졌다. {(단어, 품사):개수}의 형태로 저장되었다. 이런 자료형은 파이썬에서 dictionary라고 한다. (파이썬이 유용한 이유 중 하나) 그럼 이제 어떤 토큰들이 많았는지 살펴보자.

 

1: 10개의 가장 흔한 단어 보기

? '하다', 조사 '', '' 같은 것들이 압도적으로 많다!! 이렇게 압도적으로 많이 나타나는 토큰들은 유효한 해석을 방해한다. 그런데 많다고 다 제거할 수는 없다. 이런 패턴을 보이는 요소들을 보면, '하다' 같은 보조 용언, 조사, '', '' 같은 대명사(심지어 영어로도!)들이다. 그러면 이런 요소들을 제거해보자.

 

Step 3-2 (수정). Stop Word 제거하기

 

이렇게 의도하지 않아도 자주 쓰이는 단어들을 stop word 라고 부른다. stop word에는 대체로 문법적인 토큰들 (조사, 어미, 대명사 등)이 포함된다. 우리는 '하다'라는 동사와 '', '', '', '', '우리', '', '그녀' 라는 대명사 그리고 조사, 어미, 선어말 어미를 제거할 것이다.

 

그런데 효율성을 생각해보자. 조건이 많은 변수를 제거하는 것이 편할까? 아니면 해당하는 요소들만 추출하는 것이 편할까? 이건 상황에 따라 다른데, 이 경우에서는 '하다'와 대명사를 제거한 다음, 명사, 동사, 형용사, 관형사, 부사, 감탄사, 외래어, 외국어에 해당하는 것만을 추출하는 것이 편하다!

 

이렇게 조건을 주고 선택적으로 수행할 때에는 if 조건문을 쓴다. 단순한 if 조건문은 어떤 조건에 해당하면 이 명령을 수행해라~ 라고 말하는 것으로 파이썬에서는

if 조건:

명령

과 같이 쓴다.

그럼 stop word를 제거해보자.

 

중간 질문

 

참여자1: 해당하는 한글 단어만 제거해주면 밑에 따로 지정할 필요 없지 않나요?

A: 동음이의어가 생길 수 있기 때문이다. 하다가 동사일 가능성이 높겠지만 낮은 확률로 명사로 쓰일 수도 있다. 그렇기 때문에 품사를 지정해주는 것이다.

참여자2: 토큰 처리 할 때 형용사로 처리한다면 동음이의어를 다르게 인식할 수 있나?

A: 예를 들어 ’. 나는이라는 말을 들으면 어떻게 쪼갤 수 있을까요? 이것을 쪼개는 방법만 2-3개다. 하늘이 붙으면 하늘을 나는 그때 느는 연결어미. 다른 예로 은 조사로 분리할 수도 있다. 관심대상이라고 친다면 그 두 개가 구분이 안 된 상태로 돼 있으면 심각한 오류가 생길 수 있다.

 

(다시 수업으로)

 

1~2: 제거할 단어들을 stop_token이라는 배열에 저장했다.

3: 제거하지 않을 품사들을 non_stop_pos라는 배열에 저장했다

5: word_list에 앞으로 단어들을 저장할 것이다.

6: lyris 레이블의 lyric 요소들에 대해

7: 토큰화하고 품사를 붙여서 만든 배열을 tagged_list라는 변수에 저장하고,

8: tagged_list의 각 요소 item에 대해

9: itemstop_token의 목록 중에 있으면?

10: 이 반복문은 넘어간다

11: item의 두번째 요소(1, 품사)non_stop_pos에 있으면

12: word_listitem을 추가한다.

13: word_list를 출력한다.

그런데 우리가 목표로 하는 워드클라우드에 품사도 덕지덕지 나오면 조금 안 예쁠 것이다. 그래서, 품사를 제거하고 목록에 추가하는 것으로 바꾸어보자.

 

Step 3-3. 토큰의 개수를 세어보자

다시 개수를 세어보자.

In [97]:

 

cnt = Counter(word_list)

cnt.most_common(20)

Out[97]:

[('', 97),

('', 76),

('보다', 68),

('가다', 60),

 

조금 분포가 안정된 것 같다.

 

Step 4. Word Cloud를 그려보자.

이제 단어 개수를 세었으면 워드 클라우드를 그릴 수 있다. 워드 클라우드는 단어 수가 많으면 크게 그려주고, 적으면 작게 그려준다.

 

사각형입니다.

 

1~3: WordCloud 패키지로부터 WordCloud 인스턴스를 만들어 cloud라는 변수에 저장한다. 인스턴스를 만들 때, 나중에 그릴 그림의 크기(width, height)를 설정하고, 글꼴의 경로(font_path)를 지정하고, 배경색상(background_color)을 지정한다.

4: cloud라는 인스턴스에 우리가 아까 헤어렸던 단어 개수(cnt.items())를 적합(fitting)시켜서 저장한다.

5: 그림을 그릴 준비를 한다. matplotlib.pyplot 패키지(plt라는 이름으로 불러옴)figure 함수를 이용해 그림을 그릴 영역을 설정한다.

6: 축을 그리지 않을 거라는 표시

7: cloud를 그릴 거라고 plt에 적합시킨다.

8: 그림을 보여줘라!

 

Step 5. 이걸 함수로 만들어보자~

 

우리는 너무 복잡한 과정을 거쳐왔다. 그리고 이 과정을 다시 여/남 아이돌에 대해 시행할 것이다. 그러면 복잡한 이 모든 코드들을 두 번 써야 한다고? 말도 안 된다. 프로그래머들은 그래서 복잡한 한 과정을 함수로 만든다. 함수로 만들면 한 번에 불러올 수 있다는 장점이 있다. 프로그래밍 실력이 향상된다면, 아마 클래스와 메소드로 만들어 더 깔끔하게 코드를 짤 수 있을 것이다.

 

7행부터 함수를 정의하기 시작한다.

함수는 변수를 입력받아서(인풋), 아웃풋을 만드는 것이다. (표시하기 위해 변수 명을 다르게 하였으므로, 그 차이를 중심적으로 보자)

 

(쉬는 시간)

 

상근님이 진행자 김혁님을 도와서 다른 분들의 진행사항을 봐주었음.

 

Step 6. 필터링

 

이 코드의 목표는 여성/남성 아이돌 노래의 가사 차이를 보고 싶은 것이다. , 아이돌 가수의 성별로 '필터링'을 해야 한다. 필터링은 어떤 레이블에 조건을 주고, 그 조건에 해당하는 요소들만 추출하는 것이다. 우리가 오늘 사용하는 Pandas 패키지는 이 필터링을 손쉽게 만들어준다.

 

이를 위해 데이터를 다시 일부 살펴보자. PandasDataFrame 메소드인 head는 위에서부터 n개까지의 데이터를 보여준다.

 

자료를 보면, 성별을 나타내는 gender'f'(여성), 'm'(남성)으로 코딩되어 있다. , 이 기준으로 필터링을 해야 한다는 것이다.

 

Pandas에서 필터링 하는 방법은, 우선 조건에 해당하는 ''들을 뽑아내는 것에서부터 출발한다. 이를 위해서는 논리 연산자 "=="를 이용한다.

 

데이터를 볼때, 가장 큰 토큰보다는 중간 크기의 토큰들을 살펴보자. 가사의 특성상 등장 빈도는 한 노래 내에서 반복되는 횟수와 무관하지 않다. 여성 아이돌의 경우 "흔들어", "떨리는", "사랑해", "떨리는" 등이 그러하고, 남성 아이돌의 경우 "불러", "필요해", "가져가" 등이 그러하다.

 

한계

 

워드 클라우드는 시각화하는데 효과적이지만 많은 것을 하기엔 한계가 있다. 이 세션은 샘플 세션으로 자료가 많지 않다. 좋은 결과는 많은 자료로부터 나온다.

가사라는 특성상 텍스트 전처리가 어려운 측면이 있다.

프로그래밍 시작하기

 

프로그래밍을 하는 이유가 아닌 것들

- 쉬운 계산을 할 때

- 편한 처리를 위해

- 왠지 다들 하니까

- , 그냥......

 

프로그래밍을 하는 이유

- 복잡한 계산을 할 때

- 그리고 그것을 반복적으로 할 때

 

프로그래밍으로 할 수 있는 것

 

- 앱 만들기

- 데이터 처리

- 커퓨팅 시스템 만들기

- 기계 학습

- 그 밖의 엄청나게 많은 것들...

 

프로그래머가 쏟는 시간

 

- 구조 짜기 50%

(계속 메모를 하면서 해야 하고 그림을 그리면서 구조를 짠다. 생각이 잘 돼 있으면 코딩을 하는 데는 오래 걸리지 않는다.)

- 코딩하기 20%

- 디버깅 30%

(오류를 일으키지 않는 지 체크 함. 오류가 어디서 났는지 찾아서 수정하는 과정을 반복함.)

 

프로그래밍 언어는 거들 뿐

 

- 프로그래밍은 곧 알고리즘을 만드는 것. 알고리즘은 언어제 의존적이지 않다.

- 프로그래밍 언어마다 추상화 수준, 특화된 목적이 있으므로 그에 맞게 잘 사용하면 된다. 그리고 대체로 비슷한 기능들을 제공하니까 트렌드를 따르는 것도 나쁘지 않은 선택

- 무슨 언어를 배울까 고민하기보다는 하나를 정해서 배우자!

 

프로그래밍과 관련된 키워드

 

프로그래밍 패러다임

- 절차적 프로그래밍 : 변수, 함수

- 객체지향 프로그래밍 : 클래스, 메소드, 상속, 인스턴스

 

프로그래밍 과정

- 디버깅

- file I/O (in/out)

- 위키백과를 보고서라도 익히자!

- 주요 구문:

반복문: for, while, 조건문: if-else, swich-case

- 자료구조

- 문자열, 정수, 실수, 논리값

- 배열, 집합, 딕셔너리

- 스택,

- 링크드 리스트, 트리, 그래프

 

프로그래밍 언어로 점프하기 전에 컴퓨터 과학의 기초 이론을 알면 좋을 듯. 이산수학이나 알고리즘이나 오토마타 이론, 정규식 등 기초이론을 알아야 한다. 그리고 수핚과 통계 예를 들어 선형 대수나 확률론 등을 이해하고 있으면 좋다. 또한 기본적 자연 언어 개념과 친숙해져야 한다. 토큰은 무엇인지 타입은 무엇인지 품사, 빈도 등등도 마찬가지다. 자연언어처리 개념인 피싱과 태깅 등과도 친숙해져야 한다.

 

오프라인이나 온라인 (Codecademy, Jump to Python)으로 배울 수 있다. 온라인은 대체로 정말 지루하지만 끝까지 해야 한다. 그리고 검색, 검색 등 끊없는 검색으로 배워나갈 수 있다.

 

마지막은!

 

프로그래밍 언어에 목매달지 말자!

프로그래밍 개념들과 컴퓨터 과학의 기초 이론을 공부하자!

 ​




첨부파일

작성자 : NPO지원센터, 작성일 : 2016.12.22, 조회수 : 2576

코멘트를 달아주세요!