본문 바로가기
[Naver Cloud Camp 7] 교육 정리

네이버 클라우드 캠프 14일차 230512

by 우기37 2023. 5. 12.

#1 교육정리

오늘은 아래와 같이 학습한 내용을 정리해보겠습니다.

 

자연어처리(NLP) 기초

워드 임베딩(Word Embedding)

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

케라스 Embedding

문장의 긍, 부정 감성분류 모델

실습 : Tokenizer / Embedding / Rueters / Imbd / Pandas

 

 

 

#2 자연어처리(NLP)의 기초

의미)

자연어 처리는 자연어 텍스트 또는 음성으로 데이터를 상호 연결하는 것으로 '언어 입력(language in)'이라고도 합니다.

예를 들어, NLP는 Oracle Digital Assistant(ODA)나 Siri, Cortana, Alexa와 같은 가상 도우미의 핵심 기술입니다.

이러한 가상 도우미에게 질문을 하면 NLP를 통해 사용자의 요청을 이해할 수 있을 뿐만 아니라 자연어로 응답할 수 있습니다. 

 

컴퓨터가 모든 인간 언어의 구조와 의미를 이해하여 개발자와 사용자가 자연스러운 문장을 사용하여 컴퓨터와 상호 작용하고 소통할 수 있도록 합니다.

 

 딥 러닝은 대규모 데이터 세트에서 매우 복잡한 패턴을 학습할 수 있는 일종의 머신러닝으로 웹에서 가져온 데이터 세트에서 자연어의 복잡성을 학습하는데 매우 적합니다.

 

 

활용)

반복 업무 자동화: NLP로 구동되는 챗봇은 오늘날 사람이 하는 수많은 반복 작업을 처리할 수 있으며, 이를 통해 직원들이 보다 도전적이고 흥미로운 작업을 수행할 수 있도록 해줍니다. 

 

검색 효율 향상: NLP는 문맥에 기반하여 단어 의미를 명확히 하고(예: '캐리어'는 생체의학과 산업 분야의 문맥에서 다른 의미를 가짐), 동의어를 매칭시키고(예: 'automobile' 검색 시 'car'가 언급된 문서 검색), 형태학적 변형을 고려(영어가 아닌 언어 질의와 관련하여 중요함)하여 문서에 대한 키워드 일치 검색 및 FAQ 검색 효율을 개선할 수 있습니다. 

 

검색 엔진 최적화: NLP는 검색을 분석하여 콘텐츠를 최적화함으로써 기업의 온라인 검색 순위를 높이는데 유용한 도구입니다. 

 

대규모 문서 컬렉션 분석 및 정리: 문서 클러스터링 및 주제 모델링과 같은 NLP 기술은 기업 보고서나 뉴스 기사 또는 과학 문서와 같은 대규모 문서 컬렉션의 콘텐츠 다양성 파악 작업을 단순화시켜 줍니다. 

 

소셜 미디어 분석: NLP는 고객의 리뷰와 소셜 미디어 댓글을 분석하여 방대한 양의 정보를 더 잘 파악할 수 있도록 해줍니다.

 

시장 통찰력: NLP를 통해 비즈니스 고객의 언어를 분석하면 고객이 원하는 것을 보다 잘 파악하고 고객과의 소통 방법에 대한 더 나은 아이디어를 얻을 수 있습니다. 

 

콘텐츠 조정t: 사용자 또는 고객 의견이 대량으로 접수되는 비즈니스의 경우 NLP를 사용하여 단어뿐만 아니라 어조와 의도까지 분석함으로써 기업이 전하는 메시지의 품질과 정중함이 유지될 수 있도록 내용을 조정할 수 있습니다.

 

 

분야)

의료서비스 : 전 세계의 의료 시스템이 전자의무기록으로 전환됨에 따라 방대한 양의 비정형 데이터에 직면하게 되었습니다. 이러한 상황에서 NLP를 사용하여 의료 기록을 분석하고 새로운 통찰력을 얻을 수 있습니다.

 

법률 : 변호사들은 사건 준비를 위해 많은 양의 문서를 검토하고 특정 사건 관련 자료를 찾는데 몇 시간을 소비해야 하는 경우가 많습니다. NLP 기술은 법적 증거 수집 프로세스를 자동화하여 대량의 문서를 검색함으로써 시간을 단축하고 인적 오류를 줄일 수 있습니다.

 

금융 : 금융계는 매우 급박하게 움직이며 경쟁 우위를 선점하는 것이 중요합니다. 금융 분야의 거래자는 NLP 기술을 사용하여 기업 문서 및 보도 자료에서 정보를 자동으로 마이닝하여 포트폴리오 및 거래 결정과 관련된 정보를 추출할 수 있습니다.

 

고객 서비스 : 많은 대기업들이 기본적인 고객 문의와 정보 요청에 대한 답변은 가상 도우미와 챗봇의 도움을 받고 필요한 경우 복잡한 질문만 사람에게 전달하도록 하고 있습니다.

 

보험 : 대형 보험사들은 보험 청구 문서 및 보고서 검토에 NLP를 활용하여 업무 수행 방식을 간소화하고 있습니다.

 

더욱 자세한 내용은 아래 웹을 확인해주세요.

https://www.oracle.com/kr/artificial-intelligence/what-is-natural-language-processing/

 

#3 워드 임베딩(Word Embedding)

텍스트를 컴퓨터가 이해하고, 효율적으로 처리하게 하기 위해서는 컴퓨터가 이해할 수 있도록 텍스트를 적절히 숫자로 변환해야 합니다.

단어를 표현하는 방법에 따라서 자연어 처리의 성능이 크게 달라지기 때문에 단어를 수치화 하기 위한 많은 연구가 있었고, 현재에 이르러서는 각 단어를 인공 신경망 학습을 통해 벡터화하는 워드 임베딩이라는 방법이 가장 많이 사용되고 있습니다.

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

 

이미지 출처 : https://www.nsuchaud.fr/2018/03/difference-between-classical-nlp-deep-learning-nlp/

 

 

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

인공지능에서 벡터는 수학적 개념으로, 크기와 방향을 가진 양을 표현하는 도구입니다. 벡터는 다차원 공간에서 점 또는 화살표로 표현할 수 있습니다. 각 차원은 하나의 요소를 나타내며, 벡터의 크기는 차원의 개수에 따라 결정됩니다.

 

벡터 표현은 주로 숫자로 이루어진 배열이며, 컴퓨터가 이해할 수 있는 입력으로 사용될 수 있습니다.

 

딥러닝에서는 벡터를 사용하여 신경망의 가중치, 편향, 입력 데이터, 출력 결과 등을 표현합니다. 벡터 연산을 통해 신경망은 입력 데이터로부터 출력 결과를 예측하고 학습합니다.

 

이미지 데이터의 벡터는 각 픽셀(pixel)의 색상 값을 숫자로 표현하고, 이러한 숫자들을 배열 형태로 나열한 것입니다.

(예를들어, 28 x 28 픽셀의 흑백 이미지는 784차원의 벡터)

 

텍스트 데이터의 벡터는 각 단(word)를 고유한 정수 인덱스(index)로 앱핑하여 이를 순서대로 배열한 것입니다. 단어 간의 유사고 계산, 문서 간의 유사도 비교 등 다양하게 활용 가능합니다.

 

이미지 출처 : [Numpy] 넘파이는? (velog.io)

 

 

Keras Embedding)

Keras는 각 단어를 정의된 크기의 고정 길이 벡터로 변환하는 임베딩 레이어를 제공합니다. 원-핫 인코딩 기술은 단일 단어를 나타내는 큰 희소 행렬을 생성하는 반면 임베딩 레이어에서는 모든 단어가 고정 길이의 실수 값 벡터를 갖습니다. 단어를 표현하는 데 필요한 최소한의 차원이 이 기술의 주요 이점입니다. 차원 축소로 인해 단어 표현은 원-핫 인코딩에 비해 최소한의 공간을 차지합니다.

 

임베딩 레이어는 각 단어를 고유하게 나타내기 위해 정수로 인코딩된 입력 데이터가 필요합니다. 데이터를 준비하기 위해 Keras에서 제공하는 TokenizerAPI를 사용할 수 있습니다.

 

임베딩 레이어는 사전 훈련된 단어 임베딩 모델을 로드하기 위해 전이 학습에 사용되기 때문에 유연합니다. 또한 임베딩 레이어는 모델 자체와 함께 임베딩이 수행되는 딥 러닝 모델의 일부가 될 수 있습니다.

네트워크의 첫 번째 숨겨진 계층은 임베딩 계층입니다. 세 가지 인수가 필요합니다.

 

  • input_dim: 입력 데이터의 어휘 크기입니다. 데이터가 0에서 500까지의 정수를 사용하여 인코딩되었다고 가정하면 어휘 크기는 501단어가 됩니다.
  • output_dim : 각 단어에 대한 결과 벡터의 길이를 정의합니다. 벡터의 크기는 1에서 큰 정수까지 다양할 수 있습니다.
  • input_length: input_length는 입력 시퀀스의 총 단어 수입니다. 데이터 세트의 모든 문장에 50개의 단어가 포함된 경우 해당 임베딩 레이어의 input_length는 50이 됩니다.

 

 

 

#4 실습

문장의 감성 분류  긍정 부정 - Tokenizer, Embedding)

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

 

Tokenizer)

토크나이저는 NLP 파이프라인의 핵심 구성 요소 중 하나입니다. 토크나이저는 단지 1가지 목적을 가지고 있습니다. 즉, 입력된 텍스트를 모델에서 처리할 수 있는 데이터로 변환하는 것입니다. 모델은 숫자만 처리할 수 있으므로, 토크나이저는 텍스트 입력을 숫자 데이터로 변환해야 합니다. 

 

Embedding)

 "언어의 벡터화"이다.

이런 벡터화의 과정을 Word Embedding이라고 한다.

 

CountVectorizer는 단순히 각 텍스트에서 횟수를 기준으로 특징을 추출하는 방법이다.

예를 들어 '나는 매일매일 일기를 쓴다'를 벡터화할 때 단어 사전을 먼저 정의해야 하는데 단어 사전이 [나는, 매일 , 혼자, 일기를, 쓴다] 일 때, [1, 2, 0, 1, 1]로 되는 것이다.

 

이 방법은 단순히 횟수만을 특징으로 잡기 때문에 큰 의미가 없고 자주 쓰이는 조사가 높은 특징 값을 가진다는 단점이 있다.

 

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

#1. 데이터
docs = ['재밌어요', '재미없다', '돈 아깝다', '숙면했어요',
        '최고에요', '꼭 봐라', '세 번 봐라', '또 보고싶다',
        'n회차 관람', '배우가 잘 생기긴 했어요', '발연기에요', '최악이에요',
        '후회된다', '돈 버렸다', '글쎄요', '보다 나왔다',
        '망작이다', '연기가 어색해요', '차라리 기부할걸', '후속편이 기대되요', 
        '감동적이에요', '다른 거 볼걸 그랬어요', '같이 보면 더 재밌어요']
#1-1.
# 긍정 1, 부정 0
labels = np.array([1, 0, 0, 0,
                   1, 1, 1, 1,
                   1, 1, 0, 0,
                   0, 0, 0, 0,
                   0, 0, 0, 0,
                   1, 0, 1])

### Tokenizer ###
token = Tokenizer()
token.fit_on_texts(docs)
print(token.word_docs)

x = token.texts_to_sequences(docs)
print(x)
# [[1], [4], [2, 5], [6], [7], [8, 3], [9, 10, 3], [11, 12], [13, 14],
# [15, 16, 17, 18], [19], [20], [21], [2, 22], [23], [24, 25], [26],
# [27, 28], [29, 30], [31, 32], [33], [34, 35, 36, 37], [38, 39, 40, 1]]

### pad_sequences ###
pad_x = pad_sequences(x, padding='pre', maxlen=4)
print(pad_x)
print(pad_x.shape)  # (23, 4) => 4는 maxlen

word_size = len(token.word_index)
print('word_size = ' , word_size)   # word_size =  40

#2. 모델구성
model = Sequential()
model.add(Embedding(input_dim = 41, output_dim = 10, input_length = 4))    #input_dim은 워드사이즈 + 1 / out_dim은 node 수 / input_length는 문장의 길이
model.add(LSTM(32))
model.add(Dense(16, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))   # 이진 분류
#model.summary()

#3. 컴파일, 훈련
model.compile(loss='binary_crossentropy',	# 이진 분류 이기 때문에 binary_crossentropy 를 사용
              optimizer='adam',
              metrics='accuracy')
model.fit(pad_x, labels, epochs=10, batch_size=1)

#4. 평가, 예측
loss, acc = model.evaluate(pad_x, labels)
print('loss : ', loss)
print('accuracy : ', acc)
# loss :  0.06543272733688354
# accuracy :  1.0

##### Predict #####

#x_predict = '영화가 정말정말 너무 재미있네'	# 긍정
x_predict = '진짜 최악 후회된다 재미없네'	# 부정

# 1) tokenizer
token = Tokenizer()
x_predict = np.array([x_predict])
print(x_predict)
token.fit_on_texts(x_predict)
x_pred = token.texts_to_sequences(x_predict)
print(token.word_index)
print(len(token.word_index))
print(x_pred)
# {'진짜': 1, '최악': 2, '후회된다': 3, '재미없네': 4}
# [[1, 2, 3, 4]]
# [[1 2 3 4]]

# 2) pad_sequences
x_pred = pad_sequences(x_pred, padding='pre')
print(x_pred)   # 4

# 3) model.predict
y_pred = model.predict(x_pred)
print(y_pred)   # [[0.46268842]]

score = float(model.predict(x_pred))

if y_pred < 0.5:
    print("{:.2f}% 확률로 부정\n".format((1 - score) * 100))
else :
    print("{:.2f}% 확률로 긍정\n".format(score * 100))

## result ##
# 53.73% 확률로 부정
# loss :  0.5025939345359802
# accuracy :  0.739130437374115

 

Embedding - Imdb 영화 리뷰)

 

keras에서 imdb data를 가져와서 

import numpy as np
import time
from keras.models import Sequential
from keras.layers import Dense, Embedding, LSTM, Dropout
from keras.datasets import imdb	# keras에서 imdb load 해서 dataset 설정!
from keras.preprocessing.text import Tokenizer
from keras_preprocessing.sequence import pad_sequences
from keras.callbacks import EarlyStopping   # keras 에서 EarlyStopping 가져오기
from sklearn.metrics import r2_score


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

print(x_train.shape, y_train.shape)	# (25000,) (25000,)
print(x_test.shape, y_test.shape)	# (25000,) (25000,)
print(np.unique(y_train, return_counts=True))	# (array([0, 1], dtype=int64), array([12500, 12500], dtype=int64))
print(len(np.unique(y_train)))  # 2

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

# pad_sequences
x_train = pad_sequences(x_train, padding='pre',
                       maxlen=100)
x_test = pad_sequences(x_test, padding='pre',
                      maxlen=100)
print(x_train.shape, y_train.shape)	# (25000, 100) (25000,) => 이진분류로 배열 맞춰주기
print(x_test.shape, y_test.shape)	# (25000, 100) (25000,)	=> 이진분류로 배열 맞춰주기

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

# model.summary()

# Total params: 2,419,906
# Trainable params: 2,419,906
# Non-trainable params: 0

#3. 컴파일, 훈련
model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics='accuracy')
earlystopping = EarlyStopping(monitor='val_loss', patience=100,
                              mode='min', restore_best_weights=True)
start_time = time.time()
model.fit(x_train, y_train, epochs=5, batch_size=32, validation_split=0.2)
# epochs는 data가 많아 시간이 많이 소요되어 우선 5로만 실행하였습니다.
# 더욱 정확한 결과값을 위해서는 최소 100이상은 해야 됩니다.

end_time = time.time() - start_time

#4. 평가, 예측
loss, acc = model.evaluate(x_test, y_test)
y_predict = model.predict(x_test)
r2_score = r2_score(y_test, y_predict)
print('loss : ', loss)
print('acc : ', acc)
print('r2 스코어 : ', r2_score)
print('걸린 시간 : ', end_time)

## result ##
#loss :  355637.53125
#acc :  0.6779199838638306
#r2 스코어 :  0.13733480157369804
#걸린 시간 :  1020.4000318050385

 

로이터 뉴스 분류하기 - Reuter)

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

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

print(x_train.shape, y_train.shape)	# (8982,) (8982,)
print(x_test.shape, y_test.shape)	# (2246,) (2246,)
print(len(np.unique(y_train)))	# 46

print('뉴스기사의 최대길이 : ', max(len(i) for i in x_train))	# 뉴스기사의 최대길이 :  2376
print('뉴스기사의 평균길이 : ', sum(map(len, x_train)) / len(x_train))	# 뉴스기사의 평균길이 :  145.5398574927633

# pad_sequences
x_train = pad_sequences(x_train, padding='pre',
                       maxlen=100)
x_test = pad_sequences(x_test, padding='pre',
                      maxlen=100)
print(x_train.shape, y_train.shape)	# (8982, 100) (8982,)
print(x_test.shape, y_test.shape)	# (2246, 100) (2246,)

#2. 모델구성
model = Sequential()
model.add(Embedding(input_dim = 10000, output_dim = 100))
model.add(LSTM(128, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(128, activation='relu'))
model.add(Dense(46, activation='softmax'))

model.summary()

# Total params: 1,189,102
# Trainable params: 1,189,102
# Non-trainable params: 0

#3. 컴파일, 훈련
model.compile(loss='sparse_categorical_crossentropy',
             optimizer='adam',
             metrics='accuracy')
earlystopping = EarlyStopping(monitor='var_loss', patience=50,
                             mode='min', restore_best_weights=True)
                             
modelcheckpoint = ModelCheckpoint('best_model.h5', monitor='val_acc',
			mode='max', save_best_only=True)

start_time = time.time()
model.fit(x_train, y_train, epochs=50, batch_size=25,
         validation_split=0.2, callbacks=[earlystopping, modelcheckpoint])
end_time = time.time() - start_time

#4. 평가, 예측
loss, acc = model.evaluate(x_test, y_test)
y_predict = model.predict(x_test)

print('loss : ', loss)
print('Accuracy 스코어 : ', acc)
print('걸린 시간 : ', end_time)

## result ##
#loss :  2.6738545894622803
#Accuracy 스코어 :  0.4581478238105774
#걸린 시간 :  3119.16801905632

 

boston_data -  NaN, Heatmap, Data Drop)

제가 갖고 있는 boston_data를 read 해서 NaN, Heatmap, Drop 을 해보겠습니다!

 

pandas로 실행 할거여서 아래와 같이 기본 구성을 해줍니다.

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

 

첫번째로 데이터를 갖구오고 설정해줍니다.

그리고 7행 도출해보겠습니다.

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

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

 

Index(['AGE', 'B', 'RM', 'CRIM', 'DIS', 'INDUS', 'LSTAT', 'NOX', 'PTRATIO',
       'RAD', 'ZN', 'TAX', 'CHAS', 'Target'],
      dtype='object')
    AGE       B     RM     CRIM     DIS  INDUS  LSTAT    NOX  PTRATIO  RAD  \
0  65.2  396.90  6.575  0.00632  4.0900   2.31   4.98  0.538     15.3    1   
1  78.9  396.90  6.421  0.02731  4.9671   7.07   9.14  0.469     17.8    2   
2  61.1  392.83  7.185  0.02729  4.9671   7.07   4.03  0.469     17.8    2   
3  45.8  394.63  6.998  0.03237  6.0622   2.18   2.94  0.458     18.7    3   
4  54.2  396.90  7.147  0.06905  6.0622   2.18   5.33  0.458     18.7    3   
5  58.7  394.12  6.430  0.02985  6.0622   2.18   5.21  0.458     18.7    3   
6  66.6  395.60  6.012  0.08829  5.5605   7.87  12.43  0.524     15.2    5   

     ZN  TAX  CHAS  Target  
0  18.0  296     0    24.0  
1   0.0  242     0    21.6  
2   0.0  242     0    34.7  
3   0.0  222     0    33.4  
4   0.0  222     0    36.2  
5   0.0  222     0    28.7  
6  12.5  311     0    22.9  

아래와 같이 dataset을 해줍니다.

x = datasets[['AGE', 'B', 'RM', 'CRIM', 'DIS', 'INDUS', 'LSTAT', 'NOX', 'PTRATIO',
       'RAD', 'ZN', 'TAX', 'CHAS']]
y = datasets[['Target']]

print(x.shape, y.shape)	# (506, 13) (506, 1)

 

info로 컬럼명, null 값, dtype(datatype)을 확인합니다.

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

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 506 entries, 0 to 505
Data columns (total 13 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   AGE      506 non-null    float64
 1   B        506 non-null    float64
 2   RM       506 non-null    float64
 3   CRIM     506 non-null    float64
 4   DIS      506 non-null    float64
 5   INDUS    506 non-null    float64
 6   LSTAT    506 non-null    float64
 7   NOX      506 non-null    float64
 8   PTRATIO  506 non-null    float64
 9   RAD      506 non-null    int64  
 10  ZN       506 non-null    float64
 11  TAX      506 non-null    int64  
 12  CHAS     506 non-null    int64  
dtypes: float64(10), int64(3)
memory usage: 51.5 KB
None

 

Dataframe 'x'의 열들에 대한 통계 정보를 출력해서 확인합니다.

print(x.describe())

              AGE           B          RM        CRIM         DIS       INDUS  \
count  506.000000  506.000000  506.000000  506.000000  506.000000  506.000000   
mean    68.574901  356.674032    6.284634    3.613524    3.795043   11.136779   
std     28.148861   91.294864    0.702617    8.601545    2.105710    6.860353   
min      2.900000    0.320000    3.561000    0.006320    1.129600    0.460000   
25%     45.025000  375.377500    5.885500    0.082045    2.100175    5.190000   
50%     77.500000  391.440000    6.208500    0.256510    3.207450    9.690000   
75%     94.075000  396.225000    6.623500    3.677083    5.188425   18.100000   
max    100.000000  396.900000    8.780000   88.976200   12.126500   27.740000   

            LSTAT         NOX     PTRATIO         RAD          ZN         TAX  \
count  506.000000  506.000000  506.000000  506.000000  506.000000  506.000000   
mean    12.653063    0.554695   18.455534    9.549407   11.363636  408.237154   
std      7.141062    0.115878    2.164946    8.707259   23.322453  168.537116   
min      1.730000    0.385000   12.600000    1.000000    0.000000  187.000000   
25%      6.950000    0.449000   17.400000    4.000000    0.000000  279.000000   
50%     11.360000    0.538000   19.050000    5.000000    0.000000  330.000000   
75%     16.955000    0.624000   20.200000   24.000000   12.500000  666.000000   
max     37.970000    0.871000   22.000000   24.000000  100.000000  711.000000   

             CHAS  
count  506.000000  #개수(count)
mean     0.069170  #평균(mean)
std      0.253994  #표준편차(std)
min      0.000000  #최솟값(min)
25%      0.000000  #25% 분위수(25% percentile)
50%      0.000000  #50% 분위수(50% percentile, 중앙값)
75%      0.000000  #75% 분위수(75% percentile)
max      1.000000  #최댓값(max)

 

NaN 값으로 넣어줍니다.

x['NAN'] = np.nan

# x = x.fillna(0) nan값 0으로 채우기
#x = x.fillna(x.mean())  # 해당 컬럼의 mean, mode, min, max 의 값 채우기
#x = x.fillna(method='ffill')  # 해당 컬럼의 바로 앞 데이터의 값으로 채우기
#x = x.fillna(method='bfill')  # 해당 컬럼의 바로 뒤 데이터의 값으로 채우기

print(x)

      AGE       B     RM     CRIM     DIS  INDUS  LSTAT    NOX  PTRATIO  RAD  \
0    65.2  396.90  6.575  0.00632  4.0900   2.31   4.98  0.538     15.3    1   
1    78.9  396.90  6.421  0.02731  4.9671   7.07   9.14  0.469     17.8    2   
2    61.1  392.83  7.185  0.02729  4.9671   7.07   4.03  0.469     17.8    2   
3    45.8  394.63  6.998  0.03237  6.0622   2.18   2.94  0.458     18.7    3   
4    54.2  396.90  7.147  0.06905  6.0622   2.18   5.33  0.458     18.7    3   
..    ...     ...    ...      ...     ...    ...    ...    ...      ...  ...   
501  69.1  391.99  6.593  0.06263  2.4786  11.93   9.67  0.573     21.0    1   
502  76.7  396.90  6.120  0.04527  2.2875  11.93   9.08  0.573     21.0    1   
503  91.0  396.90  6.976  0.06076  2.1675  11.93   5.64  0.573     21.0    1   
504  89.3  393.45  6.794  0.10959  2.3889  11.93   6.48  0.573     21.0    1   
505  80.8  396.90  6.030  0.04741  2.5050  11.93   7.88  0.573     21.0    1   

       ZN  TAX  CHAS  NAN  
0    18.0  296     0  NaN  
1     0.0  242     0  NaN  
2     0.0  242     0  NaN  
3     0.0  222     0  NaN  
4     0.0  222     0  NaN  
..    ...  ...   ...  ...  
501   0.0  273     0  NaN  
502   0.0  273     0  NaN  
503   0.0  273     0  NaN  
504   0.0  273     0  NaN  
505   0.0  273     0  NaN  

[506 rows x 14 columns]

 

x_train, y_train, x_test, 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)

print(x_train.columns)
print(x_test.columns)
(404, 14) (102, 14)
(404, 1) (102, 1)
Index(['AGE', 'B', 'RM', 'CRIM', 'DIS', 'INDUS', 'LSTAT', 'NOX', 'PTRATIO',
       'RAD', 'ZN', 'TAX', 'CHAS', 'NAN'],
      dtype='object')
Index(['Target'], dtype='object')

 

히트맵으로 한번 보겠습니다.

#### 상관계수 히트 맵#####
import matplotlib.pyplot as plt
import seaborn as sns # pip install seaborn ==> 오류시 해당 명령어로 설치

sns.set(font_scale = 0.8)
sns.set(rc = {'figure.figsize':(12,8)}) # 중괄호는 딕셔너리 / figsize 는 히트맵 크기
sns.heatmap(data = datasets.corr(), 
           square = True,
           annot = True,
           cbar = True
           ) # corr은 상관관계 co-relation
plt.show() # target과 비슷한 관계가 많은 것을 즉, 밝은 것을 삭제해주면 성능이 훨씬 좋아진다.

'RAD' 와 'TAX' 데이터 drop 하기.

x_train = x_train.drop(['RAD', 'TAX'], axis=1) 
#x_test = x_test.drop(['RAD', 'TAX'], axis=1)  # x_test는 오류가 발생하네요..ㅜ

print(x_train.shape, x_test.shape)

(404, 12) (404, 1)

 

x_test = x_test.drop(['RAD', 'TAX'], axis=1) - 해당 오류는 아래와 같으며 찾는중입니다..ㅜ

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-45-53590b23dd70> in <module>
      1 x_train = x_train.drop(['RAD', 'TAX'], axis=1)
----> 2 x_test = x_test.drop(['RAD', 'TAX'], axis=1)  # 오류 뜸..ㅜ
      3 
      4 print(x_train.shape, x_test.shape)

/opt/conda/lib/python3.8/site-packages/pandas/core/frame.py in drop(self, labels, axis, index, columns, level, inplace, errors)
   4306                 weight  1.0     0.8
   4307         """
-> 4308         return super().drop(
   4309             labels=labels,
   4310             axis=axis,

/opt/conda/lib/python3.8/site-packages/pandas/core/generic.py in drop(self, labels, axis, index, columns, level, inplace, errors)
   4151         for axis, labels in axes.items():
   4152             if labels is not None:
-> 4153                 obj = obj._drop_axis(labels, axis, level=level, errors=errors)
   4154 
   4155         if inplace:

/opt/conda/lib/python3.8/site-packages/pandas/core/generic.py in _drop_axis(self, labels, axis, level, errors)
   4186                 new_axis = axis.drop(labels, level=level, errors=errors)
   4187             else:
-> 4188                 new_axis = axis.drop(labels, errors=errors)
   4189             result = self.reindex(**{axis_name: new_axis})
   4190 

/opt/conda/lib/python3.8/site-packages/pandas/core/indexes/base.py in drop(self, labels, errors)
   5589         if mask.any():
   5590             if errors != "ignore":
-> 5591                 raise KeyError(f"{labels[mask]} not found in axis")
   5592             indexer = indexer[~mask]
   5593         return self.delete(indexer)

KeyError: "['RAD' 'TAX'] not found in axis"

 

Labelling)

기본구성은 위와 같아 데이터 코드부터 작성하겠습니다.

이번에는 medical_noshow data로 labelling 해보겠습니다.

 

아래와 같이 data를 확인해봅니다.

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

print(datasets.columns)
print(datasets.head(7))
Index(['PatientId', 'AppointmentID', 'Gender', 'ScheduledDay',
       'AppointmentDay', 'Age', 'Neighbourhood', 'Scholarship', 'Hipertension',
       'Diabetes', 'Alcoholism', 'Handcap', 'SMS_received', 'No-show'],
      dtype='object')
      PatientId  AppointmentID Gender          ScheduledDay  \
0  2.987250e+13        5642903      F  2016-04-29T18:38:08Z   
1  5.589978e+14        5642503      M  2016-04-29T16:08:27Z   
2  4.262962e+12        5642549      F  2016-04-29T16:19:04Z   
3  8.679512e+11        5642828      F  2016-04-29T17:29:31Z   
4  8.841186e+12        5642494      F  2016-04-29T16:07:23Z   
5  9.598513e+13        5626772      F  2016-04-27T08:36:51Z   
6  7.336882e+14        5630279      F  2016-04-27T15:05:12Z   

         AppointmentDay  Age      Neighbourhood  Scholarship  Hipertension  \
0  2016-04-29T00:00:00Z   62    JARDIM DA PENHA            0             1   
1  2016-04-29T00:00:00Z   56    JARDIM DA PENHA            0             0   
2  2016-04-29T00:00:00Z   62      MATA DA PRAIA            0             0   
3  2016-04-29T00:00:00Z    8  PONTAL DE CAMBURI            0             0   
4  2016-04-29T00:00:00Z   56    JARDIM DA PENHA            0             1   
5  2016-04-29T00:00:00Z   76          REPÚBLICA            0             1   
6  2016-04-29T00:00:00Z   23         GOIABEIRAS            0             0   

   Diabetes  Alcoholism  Handcap  SMS_received No-show  
0         0           0        0             0      No  
1         0           0        0             0      No  
2         0           0        0             0      No  
3         0           0        0             0      No  
4         1           0        0             0      No  
5         0           0        0             0      No  
6         0           0        0             0     Yes  

 

아래와 같이 datasets을 하고 확인해줍니다.

x = datasets[['PatientId', 'AppointmentID', 'Gender', 'ScheduledDay',
       'AppointmentDay', 'Age', 'Neighbourhood', 'Scholarship', 'Hipertension',
       'Diabetes', 'Alcoholism', 'Handcap', 'SMS_received']]
y = datasets[['No-show']]

print(x.shape, y.shape)	# (110527, 13) (110527, 1)

 

info 확인해줍니다.

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

 

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 110527 entries, 0 to 110526
Data columns (total 13 columns):
 #   Column          Non-Null Count   Dtype  
---  ------          --------------   -----  
 0   PatientId       110527 non-null  float64
 1   AppointmentID   110527 non-null  int64  
 2   Gender          110527 non-null  object 
 3   ScheduledDay    110527 non-null  object 
 4   AppointmentDay  110527 non-null  object 
 5   Age             110527 non-null  int64  
 6   Neighbourhood   110527 non-null  object 
 7   Scholarship     110527 non-null  int64  
 8   Hipertension    110527 non-null  int64  
 9   Diabetes        110527 non-null  int64  
 10  Alcoholism      110527 non-null  int64  
 11  Handcap         110527 non-null  int64  
 12  SMS_received    110527 non-null  int64  
dtypes: float64(1), int64(8), object(4)
memory usage: 11.0+ MB
None

 

print(x.describe())
          PatientId  AppointmentID            Age    Scholarship  \
count  1.105270e+05   1.105270e+05  110527.000000  110527.000000   
mean   1.474963e+14   5.675305e+06      37.088874       0.098266   
std    2.560949e+14   7.129575e+04      23.110205       0.297675   
min    3.921784e+04   5.030230e+06      -1.000000       0.000000   
25%    4.172614e+12   5.640286e+06      18.000000       0.000000   
50%    3.173184e+13   5.680573e+06      37.000000       0.000000   
75%    9.439172e+13   5.725524e+06      55.000000       0.000000   
max    9.999816e+14   5.790484e+06     115.000000       1.000000   

        Hipertension       Diabetes     Alcoholism        Handcap  \
count  110527.000000  110527.000000  110527.000000  110527.000000   
mean        0.197246       0.071865       0.030400       0.022248   
std         0.397921       0.258265       0.171686       0.161543   
min         0.000000       0.000000       0.000000       0.000000   
25%         0.000000       0.000000       0.000000       0.000000   
50%         0.000000       0.000000       0.000000       0.000000   
75%         0.000000       0.000000       0.000000       0.000000   
max         1.000000       1.000000       1.000000       4.000000   

        SMS_received  
count  110527.000000  
mean        0.321026  
std         0.466873  
min         0.000000  
25%         0.000000  
50%         0.000000  
75%         1.000000  
max         1.000000  

 

'object' datatype인 column을 숫자로 변경합니다.

Gender, ScheduledDay, AppontmentDay, Neighborhood 가 변환된것을 확인 할 수 있습니다.

## 문자를 숫자로 변경 (Label Encoder) ##
from sklearn.preprocessing import LabelEncoder
ob_col = list(x.dtypes[x.dtypes=='object'].index)  # object 컬럼 리스트 추출
for col in ob_col:
    x.loc[:, col] = LabelEncoder().fit_transform(x[col].values)
    
print(x.head())
      PatientId  AppointmentID  Gender  ScheduledDay  AppointmentDay  Age  \
0  2.987250e+13        5642903       0         27741               0   62   
1  5.589978e+14        5642503       1         27503               0   56   
2  4.262962e+12        5642549       0         27538               0   62   
3  8.679512e+11        5642828       0         27708               0    8   
4  8.841186e+12        5642494       0         27497               0   56   

   Neighbourhood  Scholarship  Hipertension  Diabetes  Alcoholism  Handcap  \
0             39            0             1         0           0        0   
1             39            0             0         0           0        0   
2             45            0             0         0           0        0   
3             54            0             0         0           0        0   
4             39            0             1         1           0        0   

   SMS_received  
0             0  
1             0  
2             0  
3             0  
4             0