자바스크립트가 비활성화 되어있습니다.
자바스크립트가 활성화 되어야 콘텐츠가 깨지지 않고 보이게 됩니다.
자바스크립트를 사용할수 있도록 옵션을 변경해 주세요.
- willbsoon

본문 바로가기
Bigdata, AI/NLP

word2vector를 통한 단어 임베딩과 K-means로 클러스터링, 신규 데이터 예측까지-1

by willbsoon 2020. 5. 8.

뉴스기사를 모으고 뉴스 제목을 word2vec 알고리즘으로 임베딩한후 k-means를 적용하여 클러스터링 해보았다.

그리고 새로 들어오는 기사들은 이미 클러스터링 되어있는 k-means 학습모델에 따라 재분류 되어지도록 하는 방법이다.

여러 블로그나 구글링을 통해서 보게되면 안되는경우도 많이 있고 새롭게 적용해야할 것들이 많다보니 아.. 너무 어렵더라....

 

하지만... 여기 기록되는 내용들 또한 불친절한 내용들이 많을것이다ㅠ 코드만 가지고 따라하긴 어려울것이다

기초적인 내용들을 아시는분들에 한해서만 보시길...

 

여기 기록되는 내용은 3단계에 거쳐서 진행될 것이다. 그안에서도 중복되는 내용이 많으므로 간략하게 설명해보겠다.

 

여기에 적용된 개발 환경을 보자면!

windows 환경
python 3.7
gensim 3.8.2
scikit-learn 0.22.2
cx-Oracle 7.3.0
konlpy 0.5.2

 

코드가 조금 조잡하다. 양해해주시길 바란다....

 

먼저는 디비에 있는 데이터를 불러와야한다.

 

def db_select(query, address):
    os.putenv('NLS_LANG', '.UTF8')  # 한글입력을 위해
    # 연결에 필요한 기본 정보 (유저, 비밀번호, 데이터베이스 서버 주소)
    conn = cx_Oracle.connect(address)
    cur = conn.cursor()
    cur.execute(query)  # 100개를 가져오는 쿼리

    list = []  # 제목과 본문
    list_only_subject = []  # 제목 토큰화
    list_only_contents = []  # 본문 토큰화
    for name in cur:
        list_news = []  # 뉴스

        word_subject = str(name[0])
        word_subject = re.sub(r"[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》“”’·.a-zA-Z0-9]+", " ", word_subject)
        list_only_subject.append(tokenize_sentense(word_subject))
        list_news.append(str(name[0]))

        word_content = str(name[1].read())
        word_content = re.sub(r"[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》“”’·.a-zA-Z0-9]+", " ", word_content)
        list_only_contents.append(tokenize_sentense(word_content))
        list_news.append(str(name[1].read()))

        list.append(list_news)  # 뉴스 기사

    cur.close()
    conn.close()
    return list_only_subject, list_only_contents, list
    
    
def tokenize_sentense(text):
    okt = Okt()
    return okt.phrases(text)

쿼리문과 접속정보를 인자로 받는 함수를 정의한다. 파이썬은 orm이 있는지 모르겠는데.. 일단 이렇게 작성했다. 대학시절에 배운 파이썬이 전부라.. 이렇게 해도 잘 돌아가니 일단 해보자.

이 함수를 통해 토큰화한 제목, 본문, 그리고 원문 그대로의 리스트를 받게된다.

 

중간에 보이는 특수문자 제거는 꼭 해주자. 특히나 word2vec 학습시에 특수문자와 영문, 숫자는 영향을 주기때문에 되도록이면 삭제해주는편이 좋다.

 

 

그 다음으로는 word2vec을 실행해보자.

def make_model(data, size, min_count):
    model = w2v(data, size=size, window=2, min_count=min_count, iter=300, sg=1)  # 모델을 만들기 위한 본문 수집.
    return model

 

word2vec 모델을 만들기 위해 DB에서 가져온 토큰화한 뉴스 제목을 data 자리에 넣고 w2v 함수를 실행하게되면 모델이 생성이 된다.

여기서 word2vec 각각의 파라미터를 보자면 size - 임베딩 사이즈를 의미, window는 학습하게되는 앞뒤 단어의 수를 의미한다. min_count는 학습하게되는 문장속에서 몇번 이상 반복되는 단어를 모델로 잡을지에 대한 설정이다. 반복 수를 너무 적게 잡으면 모델이 되는 단어가 너무 많아져 추후 클러스터링에 어려움이 생긴다., 너무 많게 잡아도 모델이 되는 단어가 줄어드니 정확도가 낮아진다.

 

 

그리고 마지막으로 실행을 해보자.

start_num1 = 1  # 모델 학습 시작 인덱스
end_num1 = 100  # 모델 학습 종료 인덱스

select_list = db_select(sql(start_num1, end_num1), address)
# 미리 정의해둔 sql과 디비의 접속정보를 인자로 넣는다.

size = 100  # 벡터 사이즈
min_count = 5  # 최소 반복값
model1 = make_model(select_list[0], size=size, min_count=min_count)  

pickle.dump(model1, open("{}\\{}".format(os.getcwd(),"w2v.pkl"), 'wb'))  #모델을 저장.

 

시작 번호와 종료번호를 인자로 가지는 함수 sql()를 미리 만들어 놓고, 디비의 접속정보 address와 함께 db_select 함수에 넣어 데이터를 가져오고 데이터를 통해 make_model 함수로 모델을 제작한다.

그리고 이 모델은 현재 파이썬이 실행되고 있는 경로에 w2v.pkl 파일로 저장을 한다. 

 

이렇게 되면 word2vec 모델이 완성이 된다. 

대부분 디비에서 데이터를 불러오는 동시에 토큰화 하므로 시간이 많이 걸리는 것을 볼수 있다.

뉴스 본문같은경우 텍스트가 길어지면 많이 길어지므로.. 그럴수 있다.

아무튼 이렇게 pickle 을 통해서 모델을 저장하고 다시 불러와서 사용할수 있는것이 참 효율적인것 같다. 

'Bigdata, AI > NLP' 카테고리의 다른 글

mecab 설치하기  (0) 2020.07.20
멀티 gpu 사용하기  (0) 2020.07.20
huggingface 버트 공개 모델  (0) 2020.07.01
우분투에 딥러닝 세팅하기....  (0) 2020.06.01
자연어 처리를 위한 도커 실행중.  (0) 2020.05.06

댓글