Python/인공지능

AI (Word Embedding/인공지능에서 벡터 (vector)란/ keras Embedding/ Tokenizer/ Embedding_imdb)

아리빠 2023. 5. 12. 15:17

●워드 임베딩 (Word Embedding)

- 텍스트를 컴퓨터가 이해할 수 있도록 숫자로 변환

- 단어를 표현하는 방법에 따라서 자연어 처리의 성능이 크게 달라짐

- 워드 임베딩은 각 단어를 인공 신경망 학습을 통해 벡터(Vector)화하는 방법

- 케라스에서 제공하는 Embedding() ->단어를 랜덤한 값을 가지는 벡터로 변환한 뒤에, 인공 신경망의 가중치를 학습

 


●인공지능에서 벡터 (vector)란

- 인공지능 분야에서 벡터는 대개 고차원의 숫자 배열(array)을 의미함

- 이미지 데이터의 벡터는 각 픽셀(pixel)의 색상 값을 숫자로 표현하고, 이러한 숫자들을 배열 형태로 나열한 것 (예를 들어, 28 x 28 픽셀의 흑백 이미지는 784차원의 벡터)

- 텍스트 데이터의 벡터는 각 단어(word)를 고유한 정수 인덱스(index)로 매핑하여, 이를 순서대로 배열한 것

 


●케라스 Embedding()

케라스의 Embedding() - 훈련 데이터의 단어들에 대해 워드 임베딩을 수행


● Tokenizer

from keras.preprocessing.text import Tokenizer

text = '나는 진짜 매우 매우 매우 매우 맛있는 밥을 엄청 많이 먹었다'

token = Tokenizer()
token.fit_on_texts([text]) # fit on 하며 index 생성


#index = token.word_index
#print(index)
print(token.word_index)
#({'매우': 1, '나는': 2, '진짜': 3, '맛있는': 4, '밥을': 5, '엄청': 6, '많이': 7, '먹었다': 8}))

x=token.texts_to_sequences([text]) 
print(x)
#[[2, 3, 1, 1, 1, 1, 4, 5, 6, 7, 8]]

-자연어 처리에서 텍스트 분석 할 수 있는 형태

-주로 토큰 단위로 분리하는 작업을 수행하는 도구

-토큰은 문맥에 따라 단어, 문장, 문단 등으로 나뉜다


●문장의 감성 분류 모델

##문장의 긍, 부정을 판단하는 감성 분류 모델

import numpy as np 
from tensorflow.keras.preprocessing.text import Tokenizer 
from tensorflow.keras.preprocessing.sequence import pad_sequences
sentences = ['nice great best amazing', 'stop lies', 'pitiful nerd’, 
'excellent work', 'supreme quality', 'bad', 'highly respectable’] 
y_train = [1, 0, 0, 1, 1, 0, 1] #긍정인 문장은 1, 부정인 문장은 0

#1. keras의 tokenizer를 사용하여 단어 집합을 만들고 크기 확인
tokenizer = Tokenizer() 
tokenizer.fit_on_texts(sentences) 
vocab_size = len(tokenizer.word_index)

#2. 각 문장에 대해서 정수 인코딩을 수행
X_encoded = tokenizer.texts_to_sequences(sentences)

#3. 가장 길이가 긴 문장의 길이 계산
max_len = max(len(l) for l in X_encoded)

#4. 최대 길이로 모든 샘플에 대해서 패딩 진행
X_train = pad_sequences(X_encoded, maxlen=max_len, padding='post’) 
y_train = np.array(y_train) 
print('패딩 결과 :’) 
print(X_train)

#5. 전형적인 이진 분류 모델을 설계
from tensorflow.keras.models import Sequential 
from tensorflow.keras.layers import Dense, Embedding, Flatten 
embedding_dim = 4
model = Sequential() 
model.add(Embedding(vocab_size, embedding_dim, input_length=max_len))
model.add(Flatten()) 
model.add(Dense(1, activation='sigmoid')) #output에 1개의 뉴런을 배치 활성화 함수는 시그모이드 함수
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc']) 
model.fit(X_train, y_train, epochs=100, verbose=2) #손실 함수로 binary_crossentropy 사용

 


●실습코드

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM, Dropout
from keras.datasets import imdb
from keras.preprocessing.text import Tokenizer
from keras_preprocessing.sequence import pad_sequences
import time

# 1. 데이터
(x_train, y_train), (x_test, y_test) = imdb.load_data(
    num_words=10000) # 가져오려는 데이터의 숫자를 지정함.

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

# 최대길이와 평균길이
print('리뷰의 최대 길이 : ', max(len(i) for i in x_train))
print('리뷰의 평균 길이 : ', sum(map(len, x_train )) / len(x_train))

# 2. 모델구성
model = Sequential()
model.add(Embedding(input_dim = 10000, output_dim=100))  # 데이터를 '10000'으로 설정했음
model.add(LSTM(128, activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(64, activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(64, activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(1, activation = 'sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics='acc')

# 3. 데이터 전처리
# 텍스트 데이터를 숫자로 변환하기 위해 Tokenizer를 사용합니다.
tokenizer = Tokenizer(num_words=10000)
x_train = tokenizer.sequences_to_matrix(x_train, mode='binary')
x_test = tokenizer.sequences_to_matrix(x_test, mode='binary')

# 입력 데이터의 길이를 맞추기 위해 패딩을 적용합니다.
max_length = 500
x_train = pad_sequences(x_train, maxlen=max_length)
x_test = pad_sequences(x_test, maxlen=max_length)

# 4. 모델 훈련


from keras.callbacks import EarlyStopping, ModelCheckpoint
earlyStopping = EarlyStopping(monitor='val_loss', patience=50, mode='min',
                              verbose=1, restore_best_weights=True) 
from keras.callbacks import ModelCheckpoint
# Model Check Point
mcp = ModelCheckpoint(
    filepath='./_mcp/tf18_california.hdf5',
    monitor='val_loss',
    mode='auto',
    verbose=1,
    save_best_only=True,
    save_weights_only=False
)

start_time = time.time()
model.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.2)
end_time = time.time() - start_time

# 5. 모델 평가
loss, accuracy = model.evaluate(x_test, y_test)
print("Test Loss:", loss)
print("Test Accuracy:", accuracy)

●Embedding_imdb

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM, Flatten
from keras.datasets import imdb
from keras.preprocessing.text import Tokenizer
from keras_preprocessing.sequence import pad_sequences
from keras.utils import to_categorical

# 1. 데이터
(x_train, y_train), (x_test, y_test) = imdb.load_data(
    num_words = 10000
)

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

# 최대길이와 평균길이
print('리뷰의 최대 길이 : ', max(len(i) for i in x_train))
print('리뷰의 평균 길이 : ', sum(map(len, x_train)) / len(x_train))

# pad_squences
x_train = pad_sequences(x_train, padding='pre',
                       maxlen=100,  truncating='pre')
x_test = pad_sequences(x_test, padding='pre',
                      maxlen=100,  truncating='pre')

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

# pip install numpy==1.19.5

# 2. 모델구성
model = Sequential()
model.add(Embedding(input_dim=10000, output_dim=100))
model.add(LSTM(128, activation='relu'))
model.add(Dense(64, activation='relu'))          
model.add(Dense(64, activation ='relu'))
model.add(Dense(1, activation='sigmoid'))

model.summary()


●HW

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score

#1. 데이터
path = './'
datasets = pd.read_csv(path + 'train.csv')

print(datasets.columns)
#print(datasets.head(7))

x = datasets[['id', 'date', 'bus_route_id', 'in_out', 'station_code', 'station_name',
       'latitude', 'longitude', '6~7_ride', '7~8_ride', '8~9_ride',
       '9~10_ride', '10~11_ride', '11~12_ride', '6~7_takeoff', '7~8_takeoff',
       '8~9_takeoff', '9~10_takeoff', '10~11_takeoff', '11~12_takeoff',
       '18~20_ride']]
y = datasets[['18~20_ride']]

datasets['NAN'] = np.nan #NAN 값 바꿔주기 
 
print(datasets) #출력 

# NAN 처리하기
x = x.fillna(0) #  0으로 채우기
#x = x.fillna(method='ffill') #해당 컬럼의 바로 앞 데이터의 값으로 채우기 
#x = x.fillna(method='bfill') #해당 컬럼의 바로 뒤 데이터의 값으로 채우기 
#x = x.fillna(x.mean()[0]) # 0열 평균값으로 처리하기

print(x.info()) # info() 컬럼명, null값, 데이터 타입 확인

# 문자를 숫자로 변경

from sklearn.preprocessing import LabelEncoder

ob_col = list(x.dtypes[x.dtypes=='object'].index) # object 컬럼 리스트 추출
for col in ob_col : 
    x[col] = LabelEncoder().fit_transform(x[col].values)

    datasets[col]


#상관계수 히트맵
import matplotlib.pyplot as plt
import seaborn as sns

x_train, x_test, y_train, y_test = train_test_split(
    x, y, test_size = 0.2, shuffle=True, random_state=77
)
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

sns.set(font_scale = 1.2)
sns.set(rc = {'figure.figsize':(20, 15)})
sns.heatmap(data=datasets.corr(),
           square = True,
            annot = True,
            cbar = True,
            cmap = 'coolwarm'
           )
plt.show()