인공지능으로 자연어 분석을 많이한다. 나도 남 따라 해보기로 했다. 조금씩 배워하므로 코드는 별거 없지만 많은 시간을 쓰고있다. 생각은 이렇다.
- 나는 설비 태그를 가지고 있다. 사람마다 태그 작성을 다르게 한다. 이렇게 되면 일관성없어 분석하기 어렵다. 이를 표준화? – 적어도 형식에 벗어난 태그를 찾기위해 – 하는 무엇인가 있으면 좋겠다.
- 태그를 준비한다. 한글+영어로 구성된다.
- 간단한 분류기를 구성한다. 처음과 끝 단어를 기준으로 OK, NG를 임의로 넣는다.
- 한글을 사용하여 형태소를 기준으로 자른다. konlpy로 태그를 자른다.
- 핫한 word2vec를 활용한다.
- 내 맘대로 네트웍을 구성하여 학습하고 결과를 본다.
일단 word2vec를 만들었다. 인터넷에 이 유명한 word2vec 대한 설명을 쉽게 찾는다. 이론은 그렇다치고, 응용을 어떻게할지 확인했다. https://wikidocs.net/book/2155 를 그대로 참조했다.
태그를 word2vec에서 사용한 vector로 나타내야 한다. 인터넷에 위키피디아 등 방대한 문서로 학습한 word2vec를 구할 수 있고, 쉽게 적용할 수 있다. 그러나 내가 가진 태그는 이쪽 업계 자의적, 단축 단어로 이뤄졌다. 예를 들어 차종, 절환 등 일본어 비슷한 단어를 주로 사용한다. 이 단어는 표준어도 아니고, 심지어 위키피디아에서 사용하지 않는다. 이를 구분하려면 사용자 정의 사전에 입력해야 한다. 인터넷 능력자의 도움으로 명사로 추가했다. 위 링크 핵심은 1. 사용할 형태소 분석기 압축을 푼다. 2. 사전 파일에 단어를 추가한다. 3. 다시 jar로 압축한다. 이다.
다시 konlpy로 단어, 숫자,영어로 분리한다. 아래 코드의 word[0]은 단어이고, word[1]은 품사 정도 된다.
이제 분리한 단어를 word2vec 함수로 vector를 만들어 파일로 저장한다. 아래 코드는 인터넷에서 구했고 나는 정말 조금만 수정했다.
from konlpy.tag import Okt
okt=Okt()
from gensim.models import Word2Vec
targetFile = open("./tagv4태그붙인파일.csv", "r", encoding='UTF-8')
#lines=targetFile.readline()
i=0
result=[]
while True:
lines = targetFile.readline()
firstColumn = lines.split(',')
#print(lines)
#print(lines[0])
#print(firstColumn[1])
#print(firstColumn[4])
#firstColumn[4]가 마지막 OK, NG 플래그
#if not lines:break
#1000라인에서 쉽게 끊기 위해 넣어줌.
if i == 1000:
break
#print(lines)
i=i+1
if i%1000 == 0:
print("%d번째 while문"%i)
tokenlist = okt.pos(firstColumn[1], stem=True, norm=True)
temp=[]
for word in tokenlist:
if word[1] in ["Noun","Alpha","Number"]:
temp.append((word[0]))
if temp:
result.append(temp)
# print(result)
targetFile.close()
#print(result[100:])
print(result)
#print(tokenlist)
model=Word2Vec(sentences=result, size=200, window=4, min_count=2, workers=6, sg=0, iter=100)
model.save('myModel')
a=model.wv.most_similar("센서")
print(a)
"""
sent_text = sent_tokenize(lines)
normalized_text = []
for string in sent_text:
tokens = re.sub(r"[^a-z0-9]+", " ", string.lower())
normalized_text.append(tokens)
result=[]
result=[word_tokenize(sentence) for sentence in normalized_text]
#print(result)
#print(lines)
model=Word2Vec(sentences=result, size=100, window=5, min_count=3, workers=6, sg=0, iter=10000)
print(model)
a=model.wv.most_similar("you")
#print(model['man'])
print(a)
#print(normalized_text)
#print(result[:10])
"""
이제 vector를 불러와 keras로 학습을 시켜야 한다. rnn이나 lstm 이런 모듈을 사용할 예정이다. 학습할 입력을 vector 형식으로 네트웍에 집어 넣어야하는데, embedding으로 쉽게 사용할 수 있는 듯 하다. 입력으로 넣기 위해 크기를 일정하게 맞춰야한다. pad_sequences로 쉽게 가능하다. 다만 dtype=’float32’로 소수점 버림을 막아준다.
pad_sequences를 적용하기 전에는 스트링으로 인식하는데, 이 후에 바로 vector로 바꿔준다. 어디까지 해줄 지 모르겠으나, 이 부분을 직접 입력으로 넣어도 될 듯 하다. vector 크기를 100으로 했는데 너무 크게 잡은 듯 하다. 나중에 줄여야겠다.
중간에 실재 6개(내가 정한 최대값)로 일치되는지와 각 단어를 vector로 print로 뽑았다. 역시 word2vec를 만든 형태소 분석기를 그대로 사용했다.
from konlpy.tag import Okt
okt=Okt()
from gensim.models import Word2Vec
from keras.layers import Dense, LSTM, Dropout
from keras.models import Sequential
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
import numpy as np
model=Word2Vec.load('./myModel')
#b=model.wv.most_similar(positive=["클램프", "잠김"])
print(model)
#tokenizer 설정.
#Okt()사용.
targetFile = open("./tagv4태그붙인파일.csv", "r", encoding='UTF-8')
i=0
result=[]
WORD_MAX=10
WV_SIZE=200
blankArray = np.zeros(WV_SIZE)
while True:
lines = targetFile.readline()
firstColumn = lines.split(',')
if i == 100:
break
i=i+1
#word2vec를 만든 형태소 분석기를 사용..
tokenlist = okt.pos(firstColumn[1], stem=True, norm=True)
temp=[]
for word in tokenlist:
#word[0]은 단어.
#word[1]은 품사.
#print("word[0]은",word[0])
#print("word[1]은",word[1])
if word[1] in ["Noun","Alpha","Number"]:
temp.append(model.wv[word[0]])
if temp:
result.append(temp)
targetFile.close()
#최대 단어를 6으로 설정.
#행 수보다 6까지 뒤쪽으로 0을 채움.
#word2Vec가 실수이므로 float32로 설정
fixed_result = pad_sequences(result, maxlen=6, padding='post', dtype='float32')
#정확하게 입력되어 있는지 테스트하는 부분.
print(len(fixed_result))
j=0
while True:
print("여기가 시작")
print(len(fixed_result[j]))
#print(fixed_result[j][0].shape)
print(result[j])
#print(fixed_result[j])
print(fixed_result[j][0])
print(fixed_result[j][1])
print(fixed_result[j][2])
print(fixed_result[j][3])
print(fixed_result[j][4])
print(fixed_result[j][5])
j=j+1
if j == 100:
break;
#print(result[0][0])
#print(result[0][1])
#b1=model.wv[result[0][0]]
#b2=model.wv[result[0][1]]
#print(b1)
#print(b2)
#keras 모델 설정.
model = Sequential()
Dense(100, input_dim=200, kernel_initializer='uniform', activation='relu')
Dense(2, input_dim=100, activation='softmax')
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
이 후는 나중에 계속 해야된다.