1. Data Set

Kaggle의 개와 고양이 컬러 이미지를 아래 경로로 다운로드 받는다.

https://www.kaggle.com/tongpython/cat-and-dog

 

2. Data Argumentation

 

데이터 학습량을 늘려서 데이터가 변조되었을 때 모델이 이를 잘 캐치할 수 있도록 모델강화를 위해

데이터를 회전, 좌우반전, 이동, 역전등으로 이미지를 바꿀 것이다.

이때, 케라스에서 제공하는 이미지 제너레이터를 사용한다. 

 

tensorflow.keras.preprocessing.image에 ImageDataGenerator를 우선 로드하고

traning과 test set 폴더를 가지고 있는 cat-and-dog폴더까지 path를 지정해주자. 

 

데이터는 training set과 test set으로 나눠져 있으며 그 안에 고양이와 강아지 이미지가 각각 다른 파일에 존재한다. 

import os
from tensorflow.keras.preprocessing.image import ImageDataGenerator

rootPath = 'C:/Users/USER-PC/Documents/Kaggle_dataanalysis/cat-and-dog'

이제 ImageDataGenerator를 사용해서 이미지를 이리저리 굴려서 만들것이다. 

rescale, shear_range, zoom_range등의 옵션을 설정해줘서 해당 데이터 전처리를 하려고 한다. 

imageGenerator = ImageDataGenerator(rescale=1./255,
                                    rotation_range=20,
                                    width_shift_range=0.1,
                                    height_shift_range=0.1,
                                    brightness_range=[.2,.2],
                                    horizontal_flip=True,
                                    validation_split=.1)

rescale: 원래 이미지에 입력된 값만큼 이미지의 크기에 곱해서 조율함.

rotation_range: 지정된 각도 범위에서 임의로 원본 이미지를 회전.

width_shift_range: 지정된 수평방향 내에서 임의로 원본 이미지를 좌우로 이동.

height_shift_range: 지정된 수직방향 내에서 임의로 원본 이미지를 상하로 이동.

brightness_range: 이미지 밝기를 랜덤하게 주는 것.

horizontal_flip: 수평방향으로 뒤집기

validation_split: 주어진 데이터셋을 test와 training으로 나누는 비율.

 

*MNIST데이터를 사용할때는 손글씨이기 때문에 수평반전이 일어나면 안된다!

 

3. Data spliting

 

flow_from_directory함수를 사용해서 이미지 데이터들이 들어있는 directory 자체를 불러와서 training set과 validation set을 나눠준다. 

 

target_size option으로 읽어올 이미지의 크기를 정해주는데 우리는 64*64 사이즈로 읽어온다. 

subset은 위에서 validation_split으로 선정한 trainig과 validation의 비율만큰 이미지를 가지고 온다.

 

trainGen = imageGenerator.flow_from_directory(os.path.join(rootPath,'training_set'),
                                              target_size=(64,64),
                                              subset='training')

validationGen = imageGenerator.flow_from_directory(os.path.join(rootPath,'training_set'),
                                                  target_size=(64,64),
                                                  subset='validation')

 

4. Model setting

 

우리는 Sequential model을 사용해서 레이어를 선형으로 연결해서 구성할 것이다. 

Sequential은 첫번째레이어의 입력 형태에 대한 정보를 필요로 하지만 그 후에는 자동으로 형태를 추정하여 형태 정보를 갖고올 필요가 없다.

그리고 Add 메소드로 여러개의 레이어 추가가 가능하다.

 

우선 Sequential과 Layers를 불러온다. 

from tensorflow.keras.models import Sequential
from tensorflow.keras import layers

model = Sequential()

우리는 

Layers를 이용해 inputlayer에 우리가 읽어드려온 64*64 image 형태 정보를 준다.

Conv2D를 사용해 16개의 각각 3*3의 Convolution fiter를 적용해 줄 것이고, 

Maxpooling은 2*2사이즈로 수행 할 것이다.

Dropout할 비율을 0.3으로 정해주었다.

model.add(layers.ImputLayer(input_shape=(64,64,3)))
model.add(layers.Conv2D(16,(3,3),(1,1),'same',activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))

model.add(layers.Conv2D(32, (3, 3), (1, 1), 'same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))

model.add(layers.Conv2D(64, (3, 3), (1, 1), 'same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))

 

컨볼루션이나 맥스풀링을 하면서 주요특징이 추출되고 이런 작업은 이차원에서 진행이 되지만 

fullyconnected layer로 넘겨주기 위해서는 2차원 자료를 1차원자료로 변환하는 작업이 필요한데, 이 때 사용하는 것이 flatten()이다. 

Dense로 512개의 유닛을 가진 fully connected layer를 모델에 추가하고 , 256개의 fully connected layer를 또 하나 추가한다. 2개의 출력 유닛을 가진 sigmoid 층을 연결한다. 

model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(2, activation='sigmoid'))

model.summary()

이미지 데이터 1차원으로 압축

5. Trainig Process

 

model의 compile함수를 사용해서 실제 학습을 시킬 것이다.

optimizeradam을 사용할 것이다.

 

머신러닝 딥러닝에서 흔히 사용하는 optimizer는 SGD, Momentum, NAG, Adagrad, RMSprop, Adam 등 여러가지가 있는데 우리는 Adam을 사용 할 것이다. 

---------------------------------------------------------------------------

Adam?

Adam은 Momentum과 RMSprop를 합친 경사하강법이다.

---------------------------------------------------------------------------

우리는 개와 고양이의 문제인 이분법이기 때문에 loss함수를 binary_crossentropy로 설정해주었다. 

 

Metric은 학습 평가 기준을 말한다. 

우리가 흔하게 아는 'accuracy'로 설정한 경우, 클래스분류 문제에서 categorical_accuracy()함수를 사용해서 정확도를 계산한다. 또한, 사용자 정의 매트릭을 만들어서 사용할 수도 있다. 

사용자 정의 매트릭스를 사용하기 위해서는 아래의 링크를 참고하면 좋을 것이다.

https://tykimos.github.io/2017/09/24/Custom_Metric/

 

클래스별로 학습과정 살펴보기

fit() 함수 로그에는 기본적으로 손실값과 정확도가 표시됩니다. 이진분류 모델에서는 정확도값 하나만 보더라도 학습이 제대로 되고 있는 지 알 수 있지만, 다중클래스분류 문제에서는 클래스별로 학습이 제대로 되고 있는 지 확인하기 위해서는 정확도값 하나로는 부족함이 많습니다. 이진분류 문제에서 클래스간 불균형이 있을 경우에도 정확도값 하나로는 판단할 수가 없습니다. 본 장에서는 학습 중에 클래스별로 정밀도(precision)와 재현율(recall)을 살펴볼

tykimos.github.io

다시 정리해보면 optimizer는 adam, loss는 binary_crossentropy, metrics는 'acc'를 코드에 반영할 것이다. 

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

케라스에서 모델을 학습시킬때는 fit()함수를 사용하는데, 제너레이터로 생성된 배치학습을 시킬 경우, fit_generator()를 사용한다. 

우선 training시킬 데이터를 넣어주고, epoch을 이용해 전체 훈련 데이터셋의 학습 반복 횟수를 지정한다.

steps_per_epoch을 이용해 한 epoch에 사용한 스텝수를 지정한다. 

validation_data에 만들어진 검증데이터셋 제너레이터를 넣어주고,

validation_steps를 이용해 epoch종료 때마다 검증 스텝수를 지정한다. 

epochs = 32
history = model.fit_generator(
    trainGen, 
    epochs=epochs,
    steps_per_epoch=trainGen.samples / epochs, 
    validation_data=validationGen,
    validation_steps=trainGen.samples / epochs,
)

 

6. Visualization and estimation the result

 

Keras에는 모델 학습 시 fit()함수를 많이 사용한다고 언급했습니다. 이 때, 리턴갑으로 학습 이력 정보를 리턴할 수 있다. 

각 epoch마다 loss(훈련 손실값), acc(훈련 정확도), val_loss(검증 손실값), val_acc(검증 정확도)들이 저장되어 있다. 

 

각 loss, acc, val_loss, val_acc를 불러와서 epoch별로 loss와 val_loss의 경향, acc와 val_acc의 경향을 알아보고자한다.

import matplotlib.pyplot as plt

def show_graph(history_dict):
    accuracy = history_dict['acc']
    val_accuracy = history_dict['val_acc']
    loss = history_dict['loss']
    val_loss = history_dict['val_loss']

    epochs = range(1, len(loss) + 1)
    
    plt.figure(figsize=(16, 1))
    
    plt.subplot(121)
    plt.subplots_adjust(top=2)
    plt.plot(epochs, accuracy, 'ro', label='Training accuracy')
    plt.plot(epochs, val_accuracy, 'r', label='Validation accuracy')
    plt.title('Trainging and validation accuracy and loss')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy and Loss')

    plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1),
              fancybox=True, shadow=True, ncol=5)
#     plt.legend(bbox_to_anchor=(1, -0.1))

    plt.subplot(122)
    plt.plot(epochs, loss, 'bo', label='Training loss')
    plt.plot(epochs, val_loss, 'b', label='Validation loss')
    plt.title('Training and validation loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1),
          fancybox=True, shadow=True, ncol=5)
#     plt.legend(bbox_to_anchor=(1, 0))

    plt.show()
show_graph(history.history)

 

 

test set도 generator를 이용해서 gestGenerator를 만든다. 이전에 trainig data를 1/255로 rescale해주었기 때문에, 

test set도 똑같이 rescale해준다. 하지만 다른 이미지 조정은 해주지 않는다. 

testGenerator = ImageDataGenerator(
    rescale=1./255
)

testGen = imageGenerator.flow_from_directory(
    os.path.join(rootPath, 'test_set'),
    target_size=(64, 64),
)

model.evaluate_generator(testGen)

7. Prediction

 

이제 모델로 예측을 해보려고 한다. 

class는 '고양이'와 '개' binary이다. 

from tensorflow.keras.preprocessing.image import array_to_img
import numpy as np

cls_index = ['고양이', '개']

imgs = testGen.next()
arr = imgs[0][0]
img = array_to_img(arr).resize((128, 128))
plt.imshow(img)
result = model.predict_classes(arr.reshape(1, 64, 64, 3))
print('예측: {}'.format(cls_index[result[0]]))
print('정답: {}'.format(cls_index[np.argmax(imgs[1][0])]))

 

요약

1. trainig 과 validation, test data로 분류

2. 새로운 이미지가 들어와도 학습할 수 있도록 image argumentation 수행 (이미지 좌우반전, 회전, 이동, 밝기조절 등 tensorflow.keras.imagegenerator 이용해서)

3. sequential과 layer를 이용해, input layer를 주고 convolutional layer 사이즈 입력, maxpooling 사이즈 입력, drop out 비율 입력

4. fullyconnected layer로 연결하기 전에 2차원으로 나온 특성을 1차원으로 압축

5. 가장 많이 사용되는 adam을 이용해 최적화 진행

6. 테스트

 

옵티마이저에 대한 적절하고 쉬운 설명: 

https://needjarvis.tistory.com/685

'데이터분석 > 딥러닝' 카테고리의 다른 글

LLM(Large Language Model)  (0) 2024.11.13
Knowledge distillation & Calibration  (0) 2024.05.20
GAN 모델이란?  (2) 2021.04.06
MNIST를 이용해 간단한 CNN만들기  (2) 2020.02.12
배치학습 vs 온라인학습  (0) 2020.02.12

------------------------------------------------------------

테이블 정리에 유용한 도구 - Pivot table from Pandas

------------------------------------------------------------

Pivot table이란?

 

pivot table은 엑셀에서 자주 보이던 함수를 인용해서 만든 함수이다. 

data frame에서 column명으로 index를 주면 index안에 어떤 내용물을 기준으로

나머지 (숫자 값만을 가진)열의 데이터를 평균(default)내어준다. 

 

예를 들면,

pd.pivot_table(df,index='Name')

인덱스도 여러개 지정할 수 있다. Name, Rep, Maneger가 각각 하나씩 표현되도록 테이블을 만들고 그것들의 평균을 내서 보여준다.

pd.pivot_table(df,index=['Name','Rep','Manager'])

보고싶은 values를 정할 수도 있다.

pd.pivot_table(df,index=['Name','Rep','Manager'],values='Price')

 

위에서 언급했듯이 기본값은 평균을 내어준다. 하지만 분석메서드를 바꾸고 싶다면

aggfunc이라는 옵션을 추가한다. np.sum은 numpy에 있는 총합계 함수이다.

pd.pivot_table(df,index=['Name','Rep','Manager'],values='Price',aggfunc=np.sum)

위와같이 진행하고 np.sum과 np.mean값을 동시에 얻고 얻은 값들중 margin을 NaN으로 채우지 않고, 값을 주고 싶다면 아래와 같이 수행한다.

pd.pivot_table(df,index=['Name','Rep','Manager'],values='Price',aggfunc=[np.sum,np.mean],fill_value=0,margins=True)

 

2. 서울시 범죄 검거율을 위해 pivot table과 다양한 함수 사용해보기

 

우선 사용할 library를 import하고 데이터도 불러온다. 

import numpy as np
import pandas as pd
crime_anal_police = pd.read_csv('C:/Users/USER-PC/Documents/DataScience_followingbook/data/02. crime_in_Seoul.csv',thousands=',',encoding='euc-kr')
crime_anal_raw = pd.read_csv('C:/Users/USER-PC/Documents/DataScience_followingbook/data/02. crime_in_Seoul_include_gu_name.csv',thousands=',',encoding='utf-8')

구별로 분석할  것이기 때문에 pivot table을 이용해서 경찰서를 구별로 합계내본다.

crime_anal_raw.head()
crime_anal = pd.pivot_table(crime_anal_raw,index='구별',aggfunc=np.sum)
crime_anal.head()

그리고 각 범죄별 검거율을 만들어주고 필요없는 범죄 검거건수는 모두 없애준다.

crime_anal['강간검거율']=crime_anal['강간 검거']/crime_anal['강간 발생']*100
crime_anal['강도검거율']=crime_anal['강도 검거']/crime_anal['강도 발생']*100
crime_anal['살인검거율']=crime_anal['살인 검거']/crime_anal['살인 발생']*100
crime_anal['절도검거율']=crime_anal['절도 검거']/crime_anal['절도 발생']*100
crime_anal['폭력검거율']=crime_anal['폭력 검거']/crime_anal['폭력 발생']*100

del crime_anal['강간 검거']
del crime_anal['강도 검거']
del crime_anal['살인 검거']
del crime_anal['절도 검거']
del crime_anal['폭력 검거']
crime_anal.head()

 결과가 이상한 것들이 보일텐데 이유는 전년도 검거건수가 포함되서 100 이상의 비율을 갖는 것이 본인다.

이를 100으로 모두 대체해준다.

con_list = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']

for column in con_list:
    crime_anal.loc[crime_anal[column]>100,column] = 100
    
crime_anal.head()

그리고 '절도 발생'에서 '발생'이라는 단어를 rename을 이용해서 삭제할 것입니다. 

 

3. 데이터를 정규화 하기 

 

각 범죄당 건수가 너무 다양해서 이를 보기 좋게 만들기 위해 정규화를 수행할 것이다.

이때 데이터 전처리에 아주 잘 사용되는 library가 있는데 scikit learn module이다. 

머신러닝이나 데이터 분석전에 전처리에 아주 유용하게 사용된다.

 

from sklearn import preprocessing

col = ['강간','강도','살인','절도','폭력']

x=crime_anal[col].values
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(x.astype(float))
crime_anal_norm = pd.DataFrame(x_scaled, columns=col, index = crime_anal.index)
col2 = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']
crime_anal_norm[col2]=crime_anal[col2]
crime_anal_norm.head()

그 다음엔 이전에 CCTV데이터를 불러와서 인구수와 CCTV개수를 crime_anal_norm에 붙일 것이다.

또한, 전체 범죄의 합을 '범죄'로 만들고 검거율의 합을 '검거'로 만들어 column을 추가할 것이다.

result_CCTV = pd.read_csv('C:/Users/USER-PC/Documents/DataScience_followingbook/data/01. CCTV_result.csv',encoding='utf-8',index_col='구별')
result_CCTV.head()

crime_anal_norm[['인구수','CCTV']]=result_CCTV[['인구수','소계']]

crime_anal_norm['범죄']=np.sum(crime_anal_norm[col],axis=1)
crime_anal_norm['검거']=np.sum(crime_anal_norm[col2],axis=1)

crime_anal_norm.head()

 

 

-------------------------------------

분석에 유용한 도구 - seaborn

-------------------------------------

 

import matplotlib.pyplot as plt
%matplotlib inline

import seaborn as sns

x = np.linspace(0,14,100)
y1= np.sin(x)
y2 = 2*np.sin(x+0.5)
y3 = 3*np.sin(x+1.0)
y4 = 4*np.sin(x+1.5)

plt.figure(figsize=(10,6))
plt.plot(x,y1,x,y2,x,y3,x,y4)
plt.show()

* 팁: 항사 module을 불러올때 주의해야할 점은 class를 불러와야한다는 것이다. 

module만 불러오면 

'module' object is not callable <= 이와같은 에러가 나타나는데 이유는 class를 불르지 않았기 때문이다.

 

우선 위와같은 데이터로 코드를 만들면 

 

위와같은 예쁜 그래프가 만들어진다.

 

(1). seaborn 기능 - whitegrid

sns.set_style('whitegrid')

plt.figure(figsize=(10,6))
plt.plot(x,y1, x,y2, x,y3, x,y4)
plt.show()

whitegrid를 추가하여 plot할 수 있다.

 

(2). seaborn 기능 

우선 tips데이터를 seaborn에서 예제로 불러온다.

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

sns.set_style('whitegrid')
%matplotlib inline

tips= sns.load_dataset('tips')
tips.head(5)

그리고 x축은 비정형데이터 값 y축은 정형데이터값으로 boxplot을 수행할 것이다.

plt.figure(figsize=(10,6))
sns.boxplot(x='day',y='total_bill', data=tips)
plt.show()

hue 라는 옵션으로 구분자를 줄 수 있다.

plt.figure(figsize=(10,6))
sns.boxplot(x='day',y='total_bill',hue='smoker',data=tips, palette = 'Set3')
plt.show()

lmplot으로 데이터를 scatter해주고 regression한 직선을 그어주며 유효범위 ci도 잡아주는 함수이다.

sns.set_style('darkgrid')
sns.lmplot(x='total_bill',y='tip',data=tips, size=7)
plt.show()

(3). pivot

 

새로운 데이터를 불러와서 

pivot함수를 사용할 것인데

사용 용도는 아래와 같다.

pivot('a','b','c'): a를 인덱스로 b를 컬럼으로 해당되는 c의 데이터를 불러와서 없는 값은 NaN을 준다.

 

flights = sns.load_dataset('flights')
flights.head(5)

flights = flights.pivot('month','year','passengers')
flights.head()

 

 

heatmap함수로 달과 년도에 따라 승객이 얼마나 있는지 heatmap으로 표현한다.

heatmap의 특징은 표현하러는 모든 데이터가 완벽히 갖춰져있고 index와 column이 하나로만 정해져 있다면 그대로 사용할 수 있다. 

만일 원하는 columns에 대해서 정해진 index들이 보고 싶다면,

데이터를 줄 때, dataset[colum]의 형식으로 데이터를 heatmap안에 주는 것이 좋다.

 

plt.figure(figsize=(10,6))
sns.heatmap(flights, annot=True, fmt='d')
plt.show()

마지막으로 유명한 데이터 iris로 종에 따라서 데이터 분포를 보려고 한다.

sns.set(style='ticks')
iris = sns.load_dataset('iris')
iris.head(10)

sns.pairplot(iris, hue = 'species')
plt.show()

hue옵션으로 species에 따른 데이터 분포를 각각 보려고 한다.

결과는 아래와 같다.

 

4. seaborn모듈로 범죄 데이터를 시각화하기

 

일단 한글 폰트 문제를 해결하고 pairplot으로 강도,살인,폭력간의 관계를 알아볼 것입니다.

kind는 'scatter'와 'reg' 두가지가 있는데 reg=regression plot을 수행합니다.

import platform
path = 'C:/Windows/Fonts/malgun.ttf'
from matplotlib import font_manager, rc

if platform.system() == 'Windows':
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font',family=font_name)
    
sns.pairplot(crime_anal_norm, vars=['강도','살인','폭력'],kind='reg',size=3)
plt.show()

vars를 사용해서 특정변수에 대해 pairplot을 수행하면, x,y축 모두 그 변수들을 사용하여 plot하고

x_vars, y_vars를 특정 변수로 준다면 x,y가 그 변수를 이용해 축을 형성한다.

 

그렇다면, x축을 검거율로 하고 y축을 각 구별로 해서 heatmap을 그리면 어떤 결과가 나올까?

검거율을 위해 검거 column의 최댓값을 100으로 놓고 다른 검거값들을 변환해준다.

그리고 검거가 높은 값을 기준으로 값들을 sorting해서

각 구별로 여러 검거율의 현황을 보고자 한다.

tmp_max = crime_anal_norm['검거'].max()
crime_anal_norm['검거']=crime_anal_norm['검거']/tmp_max*100
crime_anal_norm_sort = crime_anal_norm.sort_values(by='검거',ascending=False)
crime_anal_norm_sort.head()

target_col = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']
plt.figure(figsize=(10,10))
sns.heatmap(crime_anal_norm_sort[target_col],annot=True, fmt='f', linewidth=.5)
plt.show()

 

 

---------------------------------------------

지도를 자유자제로 그리는 folium library

---------------------------------------------

 

위도와 경도를 이용해 지도를 그리고, zoom을 얼만큼의 비율로 할것인지도 설정한 뒤에,

지도 위에 원하는 구역을 동그라미치고 색상으로 표시하고

특정로케이션에 마크를 주고 싶다.

import folium

map_2 = folium.Map(location=[45.5236,-122.6750], tiles = 'Stamen Toner', zoom_start = 13)
folium.Marker([45.5244,-122.6699], popup='The Waterfront').add_to(map_2)
folium.CircleMarker([45.5215,-122.6261], radius = 50, popup='Laurelhurst Park',color='#3186cc',fill_color='#3186cc',).add_to(map_2)
map_2

 

json파일에 경로를 담아서 choropleth명령으로 json파일과 데이터를 입력하고 key_on옵션으로 지도에 id를 알려준 다음에 취업률에 따라 color를 fill합니다. 

'데이터분석 > 예제로 데이터분석' 카테고리의 다른 글

서울시 구별 CCTV 현황분석  (0) 2020.02.18

데이터 다운로드를 위한 주소:

github.com/PinkWink/DataScience/blob/master/data

 

PinkWink/DataScience

책) 파이썬으로 데이터 주무르기 - 소스코드 및 데이터 공개. Contribute to PinkWink/DataScience development by creating an account on GitHub.

github.com

read_csv, read_excel, head(), rename()등의 기본기를 익힌후에 접근해본다.

 

1. 데이터 프레임 조작하기

 

일단 데이터 분석을 위한 library들을 불러온다.

항상 import 뒤에 모듈명이 들어간다.

import pandas as pd
import sys
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
pd.__version__
# print(sys.version) #Python 내에서 현재 python version확인용

우리가 사용할 library중 테이블을 잘 정리하고 분석에 용이한 Pandas라는 library에 대해 간략히 정리할 것이다.

우선 pandas의 기본 데이터 유형은 Series인데 어떤 데이터 유형이던 담을 수 있다. 

s = pd.Series([1,3,4,np.nan,6,8]) #pandas 의 기초유형
s

또한, 날짜 관련 데이터 유형이 있다. periods를 이용해서 지정한 2013년01월01일부터 2013년 01월06일까지 dates variable에 지정된다.

dates = pd.date_range('20130101',periods=6)
dates
#pd.date_range 함수를 쓰면 모든 날짜/시간을 일일히 입력할 필요없이 시작일과 종료일 또는 시작일과 기간을 입력하면 범위 내의 인덱스를 생성해 준다.

DataFrame을 만들고 여러가지 테이블 관련 함수를 사용하거나 문자와 숫자로 인덱싱을 할 수 있다.

*주의 할 점은 인덱싱을 할 때, 숫자나 문자로 인덱싱이 된다. 하지만 loc함수에서도 문자로만 indexing이 되고 iloc은 숫자로 인덱싱이 된다.

#data frame의 index를 dates로 설정, column명은 ABCD로 설정
df = pd.DataFrame(np.random.randn(6,4),index=dates, columns=['A','B','C','D'])
#data frame을 위에서 6줄만 보여줌
df.head(3)
#index, colums과 values
df.index
df.columns
df.values
df.info()
#column별로 통계량을 계산해준다.
df.describe()
#B컬럼을 기준으로 오름차순으로 정렬
df.sort_values(by='B',ascending=True)
#index을 문자로만 인덱싱
df['20130102':'20130104']
# loc함수는 문자로만 indexing
df.loc[dates[0]]
df.loc[:,['A','B']]
df.loc['20130102':'20130104',['A','B']]
# iloc는 index(숫자) 자체로만 indexing
df.iloc[3:5,1:3]
df.iloc[[1,2,4],[0,2]]

 조건을 걸어서 데이터 프레임을 조작할 수 있다.

copy()함수를 쓰는 이유는 그냥 다른 변수에 원래 변수를 할당해주면 동일한 주소를 갖게되므로 

copy()함수를 써서 다른 주소로 변수를 할당해주어야한다.

#조건에 맞는 테이블 찾기
df[df>0]
#변수 복사
df2 = df.copy()
#column하나 추가
df2['E']=['one','one','two','three','four','three']
#E컬럼에서 two와 four를 갖고있는 조건의 df2 데이터프레임 반환
df2[df2['E'].isin(['two','four'])]
#apply는 apply함수로 어떤 함수를 전체 데이터프레임에 적용함
df.apply(np.cumsum)
#간단하게 함수를 만들때 lambda를 사용
df.apply(lambda x: x.max()-x.min())
dist = lambda x: x.max()-x.min()

이제 실제로 데이터 분석을 위해 저장된 엑셀파일을 불러와보자. 

CCTV_seoul = pd.read_csv('C:/Users/USER-PC/Documents/DataScience_followingbook/data/01. CCTV_in_Seoul.csv',encoding='utf-8')
pop_seoul_ori= pd.read_excel('C:/Users/USER-PC/Documents/DataScience_followingbook/data/01. population_in_Seoul.xls')
pop_seoul = pd.read_excel('C:/Users/USER-PC/Documents/DataScience_followingbook/data/01. population_in_Seoul.xls',
                            encoding='utf-8',usecols='B,D,G,J,N',header=2,)
pop_seoul_test = pd.read_excel('C:/Users/USER-PC/Documents/DataScience_followingbook/data/01. population_in_Seoul.xls',
                            encoding='utf-8',header=2)

CCTV_seoul.head()
pop_seoul.head()
pop_seoul_test.head()

맘에 들지 않는 컬럼명을 바꿔보자.

CCTV_seoul.rename(columns={CCTV_seoul.columns[0]:'구별'},inplace=True)
CCTV_seoul.head()
pop_seoul.rename(columns={pop_seoul.columns[0]:'구별',
                         pop_seoul.columns[1]:'인구수',
                         pop_seoul.columns[2]:'한국인',
                         pop_seoul.columns[3]:'외국인',
                         pop_seoul.columns[4]:'고령자'},inplace=True)

데이터를 특정 column기준으로 정렬해보자.

CCTV_seoul.head()
CCTV_seoul.sort_values(by='소계',ascending=True).head(5)
CCTV_seoul.sort_values(by='소계',ascending=False).head(5)
CCTV_seoul['최근증가율']=(CCTV_seoul['2014년']+CCTV_seoul['2015년']+CCTV_seoul['2016년'])/CCTV_seoul['2013년도 이전']*100
CCTV_seoul.sort_values(by='최근증가율',ascending=False).head()

맘에 들지 않는 행이나 열을 지워보자.

pop_seoul.head()
pop_seoul.drop([0],axis=0) #drop함수는 행이나 열을 제거 axis =0 행, 1열
pop_seoul['구별'].unique()
pop_seoul[pop_seoul['구별'].isnull()]
pop_seoul.drop([26],axis=0)
pop_seoul.head()

 

2. 데이터 프레임끼리 JOIN

 

간단하게 데이터 프레임끼리 어떤 기준키로 데이터프레임을 조작하는 방법을 알아보자.

우선 사용할 df를 만들어주자.

df1 = pd.DataFrame({'A':['A0','A1','A2','A3'],
                   'B':['B0','B1','B2','B3'],
                   'C':['C0','C1','C2','C3'],
                   'D':['D0','D1','D2','D3']},index=[0,1,2,3])
df2 = pd.DataFrame({'A':['A4','A5','A6','A7'],
                   'B':['B4','B5','B6','B7'],
                   'C':['C4','C5','C6','C7'],
                   'D':['D4','D5','D6','D7']},index=[4,5,6,7])
df3 = pd.DataFrame({'A':['A8','A9','A10','A11'],
                   'B':['B8','B9','B10','B11'],
                   'C':['C8','C9','C10','C11'],
                   'D':['D8','D9','D10','D11']},index=[8,9,10,11])
df4 = pd.DataFrame({'B':['B2','B3','B6','B7'],
                   'D':['D2','D3','D6','D7'],
                   'F':['F2','F3','F6','F7']},index=[2,3,6,7])

concat은 행기준으로 데이터를 병합하는 것이고 열 기준으로 묶기 위해서는 axis를 1로 변경해준다. 그런데 자주 사용 안 할 것 같다.

result = pd.concat([df1,df2,df3],keys=['x','y','z']) #keys를 설정하면 다중 인덱스가 됨
result.index
result.index.get_level_values(0)
result = pd.concat([df1,df4],axis=1) #concat은 index를 기준으로 date를 합침
result = pd.concat([df1,df4],axis=1,join='inner') #concat은 index를 기준으로 date를 합침
result = pd.concat([df1,df4],axis=1,join_axes=[df1.index]) #concat은 index를 기준으로 date를 합침
result = pd.concat([df1,df4],ignore_index=True) #concat은 index를 기준으로 date를 합침
result

대신 merge라는 것을 사용할 것이다. 

left=pd.DataFrame({'key':['k0','k4','k2','k3'],
                  'A':['a0','a1','a2','a3'],
                  'B':['b0','b1','b2','b3']})
right=pd.DataFrame({'key':['k0','k1','k2','k3'],
                  'C':['c0','c1','c2','c3'],
                  'D':['d0','d1','d2','d3']})
left
right
pd.merge(left,right,on='key')
pd.merge(left,right,how='left',on='key')
pd.merge(left,right,how='right',on='key')
pd.merge(left,right,how='outer',on='key')
pd.merge(left,right,how='inner',on='key')
data_result = pd.merge(CCTV_seoul,pop_seoul,on='구별')
data_result.head()
del data_result['2013년도 이전']
del data_result['2014년']
del data_result['2015년']
del data_result['2016년']
data_result.head()
data_result.set_index('구별',inplace=True)
data_result.head()

이제 정렬이 어느 정도 되었으니 각 column별로 얼마나 관계를 띄는지 확인해보려 한다.

이때, corrcoef함수로 correlation coefficient를 볼 수 있다.

np.corrcoef(data_result['고령자비율'],data_result['소계'])
np.corrcoef(data_result['외국인비율'],data_result['소계'])
np.corrcoef(data_result['인구수'],data_result['소계'])

 

'데이터분석 > 예제로 데이터분석' 카테고리의 다른 글

서울시 범죄 현황 분석  (0) 2020.02.19

tensorflow의 examples들 중 mnist를 이용해서 간단한 CNN을 구축해 볼 것이다.

우리는 0~9까지 이미지를 구별해 내는 CNN 모델을 구축할 것이다.

이미 만들어진 코드를 참고하여 수행과정에서 나올 수 있는 에러와 추가 설명을 부가하여 설명한다.

 

우선 첫번째로 데이터 셋을 불러온다.

 

1. MNIST 데이터 셋 불러오기

import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data 

가끔 tensorflow의 example module을 불러올 때, tf를 정상적으로 다운로드 받음에도 불구하고

대표적인 'no moduled'에러 같은것이 발생한다.

이유는 tf 버전이 2.0이상이면 tutorial module을 자동으로 다운받지 않기 때문이다.  

그래서 1.14.0버전을 사용할 것을 권장한다.

 

mnist = input_data.read_data_sets('MNIST_data',one_hot=True, reshape=False)

MNIST_data인 data set을 읽어올때는 이미지 그대로 불러오기 위해 reshape=False(numpy에 있는 함수)로 지정해주고 

one_hot coding 형태로 읽어온다.

읽어온 이미지의 사이즈는 28*28*1 이다. 

 

 

One hot incoding은 특정 상수값으로 표현된 Y를 Matrix 형태로 바꿔주는 방법이다.

One hot incoding

 

2. CNN 모델 설정하기

CNN 모델 설정

좋은 모델을 만드는 것은 여러 방법이 있지만 가장 간단히 표현하기 위해

Convultion layer를 2번 거치고 Fully connected Layer로 0~9사이의 값을 판별할 것 이다.

 

CNN의 특징은 일반 뉴럴네트워크를 수행하기 이전에 이미지로부터 Feature를 먼저 뽑아내어서 이를 전달해

NN를 수행하는 것 이다.

Convolution을 수행하는 계층은 크게 두가지로 구성되어져 있다.

(1) Convolution layer는 이미지로부터 특징을 추출하는 Filter 기능을 한다. 

(2) 필터값을 비선형값으로 바꿔주는 Activation 함수로 이루어진다.

 

일단 이미지를 4부분으로 쪼개어서 28*28*1의 이미지를 14*14*4의 형태로만들어 주고 

이를 한번 더 수행해 7*7*8의 형태로 바꾸어 줄 것 이다.

 

 

X= tf.placeholder(tf.float32, shape=[None,28,28,1])
Y_Label = tf.placeholder(tf.float32, shape=[None,10])

입력 데이터는 학습을 위해 계속해서 업데이트 해줘야 하고 

Y_Label 또한 미리 정한 결과를 계속 직접 넣어줄 것이다. 

 

tensorflow에서 데이터 입력 받는 방법중에서 상수와 변수를 입력받는 방법도 있지만

데이터의 형태만 지정하고 실제 데이터는 실행단계에서 입력받을 수 있도록 해주는 방법이 있다.

그것이 placeholder()함수인데

사용법은 아래와 같다.

 

 

placeholder 사용법

데이터의 타입을 무조건 지정해주고 입력데이터의 형태를 주어야한다.

 

우리의 예제에서는 shape이 [None, 28,28,1]의 형태를 띄고 있는데

맨 앞의 None은 앞으로 우리가 배치수행을 할 것이기 때문에 None으로 배치수행할만큼의 데이터 공간을 미리 확보해 주는 것이다.

----------------------------------------------------------------------------------------------------------------------------

* 배치수행이란? 우리가 일반적으로 작업을 수행할때 모두 데이터를 불러놓고 수행하는 방식을 말한다.

온라인 수행은 필요한 데이터를 매번 불러오는 것인데 실제 데이터분석필드에서는 데이터를 불러오기만 해도 

메모리를 모두 할당하고 있는 경우가 많기 떄문에 온라인 수행이 당연해졌다.

----------------------------------------------------------------------------------------------------------------------------

 

3. Convolution layer 생성

 

Convolution + Relu + Maxpooling을 거쳐 28*28*1을 14*14*4의 형태로 변형할 것이다.

 

convolution 후 relu activation 수행, maxpooling을 마지막으로 수행

 

우선 kernel과 bias값을 생성하고 convolution lyaer, activation function, pooling을 수행하는 코드를 작성해 볼 것이다.

Kernel1 = tf.Variable(tf.truncated_normal(shape=[4,4,1,4],stddev=0.1))

kernel은 filter와 같은데 filter는 이미지 특징을 찾아내기 위한 공용 파라메터이다.

일반적으로 4*4나 3*3과 같은 정사각 행렬로 정의하고 

지정된 간격대로 순회하며 채널별로 합성곱을 하는 과정을 convolution이라고 한다.

그리고 convolution을 적용한 input image의 결과물을 Feature Map 또는 activation map이라고 부른다. 

filter를 이용한 convolution과정

filter가 되어줄 variable을 위와같이 설정한 뒤,  kernel을 사용해 convolution한 뒤 같은 사이즈만큼 더해주기 위한 변수를 만들어야한다.

4장을 만들어 주었기 때문에 사이즈는 4로 설정해주어야 한다.

Bias1 = tf.Variable(tf.truncated_normal(shape=[4],stddev=0.1))

 이제 실제 Convolution과정을 수행해보아야 하는데 

아래의 코드를 수행해준다.

Conv1 = tf.nn.conv2d(X, Kernel1, strides = [1,1,1,1],padding='SAME')+ Bias1

입력된 이미지 X에 만들어준 필터 Kernel1을 Convolution 곱해주는데 

filter가 이동하는 간격을 의미한는 stride를 설정하고, 데이터 손실이 얼마나 있을지 고려해 padding을 'SAME'으로 한다. stride는 주로 중앙에 2값을 이용한다. 예를 들어, 2칸씩 이동하는게 목적이라면

stride =[1,2,2,1]의 형태로 준다.

특히 padding을 하는 이유는, 실제 원본의 사이즈 (예를 들면, 5*5)보다 filter를 적용하고 나서 이미지가 

3*3으로 줄어들 수가 있는데 이떄 데이터 손실이 나기 때문에 이부분을 보정해주기 위해서 사용된다.

원래 이미지 주변의 0 값을 넣어주어 입력값의 크기를 인위적으로 키워서 결과값이 작아지는 것을 막는다. 

또한 오버피팅도 방지하는데 원본 데이터에 0값을 넣어 원래의 특성을 희석시켜서 

머신러닝이 트레이닝값에만 정확히 맞아들어가는 것을 방지한다.

Activation1 = tf.nn.relu(Conv1)

convolution을 하고나면 feature맵은 정량적인 값을 갖게 되는데 이를 특징이 '있다 없다'로 표현하기 위해 비선형화를 시키려고 한다. 그것이 activation 함수이다. 

activation함수로 여러가지를 쓰는데 주로 relu함수를 사용한다. 이유는 backpropagation이 제대로 작동하지 않아 에러가 희석되는 현상 ( gradient vanishing)이 일어나기 때문이다. 

Pool1 =tf.nn.max_pool(Activation1, ksize =[1,2,2,1],strides = [1,2,2,1], padding='SAME')

 

4. Fully connected layer 만들기

 

이제 Convolution + Activation Function + Pooling을 모두 수행하여 하나의 layer를 만들고 

우리가 목표했던 2 convolution layer를 거치기 위해 동일한 layer하나를 더 만들어 준다. 

Kernel2 = tf.Variable(tf.truncated_normal(shape=[4,4,4,8],stddev=0.1))
Bias2 = tf.Variable(tf.truncated_normal(shape=[8],stddev=0.1))
Conv2 = tf.nn.conv2d(Pool1, Kernel2, strides = [1,1,1,1],padding='SAME')+ Bias2
Activation2 = tf.nn.relu(Conv2)
Pool2 =tf.nn.max_pool(Activation2, ksize =[1,2,2,1],strides = [1,2,2,1], padding='SAME')

 

마지막으로 convoultion과정을 거친 layer를 기존의 뉴럴네트워크에 넣어 분류한다. 실제로 어떤 이미지인지 판별해주는 구간을 만드는 것이다.

W1 = tf.Variable(tf.truncated_normal(shape=[8*7*7,10]))
B1 = tf.Variable(tf.truncated_normal(shape=[10]))
Pool2_flat = tf.reshape(Pool2,[-1,8*7*7])
OutputLayer = tf.matmul(Pool2_flat,W1)+B1

*matmul 함수: 삼차원 텐서 사이의 행렬곱을 수행해주는 함수 

 

W1과 B1은 일반적인 머신러닝에서 볼 수 있는 단순선형관계를 위한 변수들이다. 

W1d은 8*8*7을 10개 받는 variable이며, B1은 output을 10개로 받기 위해 10개의 Bias를 생성한다.

우선 OuputLayer를 보면 선형관계식으로 나타내는 것을 볼 수있다. 이는 일반적인 머신러닝과 같이 

가장 단순한 선형관계로 설명하려는 목적을 갖고 있기 때문에 '입력값 * W1 + B1'의 형태를 띄는 것이다.

 

 

CNN의 최종모델

위 그림은 우리가 수행한 전체적인 모델 구축과정인데 CNN의 가장 큰 특징인 Dropout Layer를 짚고 넘어가도록 하겠다.

* Dropout Layer란 Fully-connected Layer와 Softmax Function사이의 계층으로 오버피팅을 막기위해

뉴럴 네트워크가 학습중일때 랜덤하게 뉴런을 꺼서 학습을 방해함으로써 학습이 학습용 데이터에 치우치는 현상을 막는다.

 

5. Loss function과 Optimizer설정

 

모델을 학습시킨 후 결과값이 실제값과 얼마나 차이가 나는지 확인하기 위하여 Loss값을 계산해 줍니다.

Loss = tf.reduce_mean(tf.nn.sortmax_cross_entropy_with_logits(labels=Y_label, logits=OupputLayer))

reduce_mean: 열의 평균을 구해주는 함수

softmax_cross_entropy_with_logits: multiclassification에서 사용되는 softmax와 cross_entropy가 내장된 함수, labels= 실제값, logits은 모델의 output값을 주면 된다.

 

*softmax는 multiclassification를 할때 입력받은 값을 0~1사이의 값으로 바꿔주고 총합이 1이 되도록 만드는 함수이다.

분류하고 싶은 class개수만큼 만들어지고 가장 큰 출력값을 받은 것이 확률이 가장 크다.

*cross_entropy는 분류모델에서 사용되는 loss function의 한 종류이다.

 

train_step = tf.train.AdamOptimizer(0.005).minimize(Loss)

Loss함수를 정의하고 Optimization 과정을 거쳐 Loss를 최소화 시켜주어 우리 모델을 최적화할 것이다.

correct_prediction = tf.equal(tf.argmax(OutputLayer,1),tf.argmax(Y_Label,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

그리고 실제 값과 모델이 학습한 값이 동일한지 correct_prediction으로 해주고, 

accuracy에서는 맞거나 틀린것들에 대한 평균을 내준다.

 

6. Run

with tf.Session() as sess:
    print('start....')
    sess.run(tf.global_variables_initializer())
    for i in range(10000):
        trainingData, Y = mnist.train.next_batch(64)
        sess.run(train_step, feed_dict={X:trainingData, Y_Label:Y})
        if i%100:
            print(sess.run(accuracy, feed_dict={X:mnist.test.images, Y_Label:mnist.test.labels}))

C에서 이루어지는 연산이므로 Sess를 얻어와서 진행을 하고 변수들을 tf.global_variables_initializer()을 사용해서 꼭 초기화해주어야 합니다. 

 

위의 코드는 10000번의 학습으로 64개의 배치크기만큼 가져오고 100번마다 test데이터셋을 통해 정확도를 확인한 것입니다. 

 

 

 

 

출처페이지는 

https://coderkoo.tistory.com/13

 

간단한 CNN(Convolutional neural network) 만들어보기

텐서플로우로 간단한 CNN(Convolutional neural network) 만들어보기 이번 글에서는 MNIST 데이터 셋을 이용해서 텐서플로우에서 CNN을 구성해봅니다. 즉, MNIST 데이터셋을 읽어와서 필기체숫자가 0~9 중 무엇인..

coderkoo.tistory.com

 

'데이터분석 > 딥러닝' 카테고리의 다른 글

LLM(Large Language Model)  (0) 2024.11.13
Knowledge distillation & Calibration  (0) 2024.05.20
GAN 모델이란?  (2) 2021.04.06
CNN으로 개와 고양이 분류하기  (1) 2020.02.25
배치학습 vs 온라인학습  (0) 2020.02.12

일반적으로 대중화된, 아이리스 데이터 등으로 데스크탑에서 손쉽게 돌려볼 수 있는 머신러닝 자료들은 데이터를 통째로 IDE로 불러들인 다음 메모리상에 올려두고 작업하는 방식이었을 것이다. 모델을 학습함에 있어서도 모든 트레이닝 데이터셋의 결과값을 한번에 구한 뒤, 데이터셋과 쌍이 맞는 레이블과의 차이를 구해서 비용함수를 한번에 개선하는 방식의 학습을 n-iterative 하게 진행하였을 것이다. 하지만 머신러닝을 진행함에 있어서 데이터의 크기는 언제든지 늘어나게 된다. 아마 실전의 대부분은, 한 개의 데스크탑에서 불러올 수 없는 양의 데이터가 대부분일 것이다. 이런 경우 R 혹은 Python등의 툴로는 데이터를 메모리에 올려놓고 한번에 처리하기가 힘들어진다. 그렇게 되면 모델을 학습하는 경우에도 트레이닝 데이터를 쪼개서 여러 번 넣어야 하고, 프로그래머 식으로 말하자면 전자는 for loop를 한번 돌지만 후자는 '트레이닝 데이터들' 이라는 loop가 하나 더 생기는 것이라고 할 수 있다. 전자의 경우를 일괄 처리 방식, 일명 batch 방식이라고 한다. 후자는 online processing 혹은 mini batch라고 한다. 딥러닝의 영역으로 들어가게 된다면, 데이터의 양이 기하급수적으로 증가하기 때문에(딥러닝까지 가지 않더라도) mini batch 시스템을 이용하여 모델을 학습하는 것은 거의 필수적인 일이 되어버렸다.

'데이터분석 > 딥러닝' 카테고리의 다른 글

LLM(Large Language Model)  (0) 2024.11.13
Knowledge distillation & Calibration  (0) 2024.05.20
GAN 모델이란?  (2) 2021.04.06
CNN으로 개와 고양이 분류하기  (1) 2020.02.25
MNIST를 이용해 간단한 CNN만들기  (2) 2020.02.12

1. 스칼라 서브쿼리

메인쿼리 내에서 마치 컬럼이나 표현식처럼 사용되는 쿼리

 

SELECT t1.col1, t1.col2, t1.col3,

 

(SELECT col4

FROM table2 t2

INNER JOIN table2 t2

ON t1.col1 = t2.col2) col4

 

FROM table1 t1

 

* 스칼라 서브쿼리는 무조건 반환된 값이 한개여야 한다.

 

2. 인라인뷰

메인쿼리의 FROM절에서 사용하는 서브쿼리

 

*인라인뷰는 FROM하는 테이블을 만들 수 있는 조건으로 

여러 컬럼이 나와도 된다.

 

3. 중첩 서브쿼리

 

4. EXIST == IN 

4. NOT EXIST == NOT IN

 

 

'Sql > 기초' 카테고리의 다른 글

5. 조인 - 테이블간에 관계맺기  (0) 2020.02.10
4. 집합 연산자  (0) 2020.02.10
3. 데이터집계  (0) 2020.02.09
2. SELECT문  (0) 2020.02.07
1. 테이블 생성/ 자료 입력과 삭제  (0) 2020.02.07

---------------------------------------

1. INNER JOIN

----------------------------------------

1-1. WHERE를 사용한 INNER JOIN

 

SELECT col1, col2, ...

FROM table1 t1

table2 t2

WHERE t1.id = t2.id

 

1-2. ANSI JOIN을 사용한 INNER JOIN

 

SELECT col1, col2,...

FROM table1 t1

INNER JOIN table2 t2

ON t1.id = t2.id

 

1-3. 여기서 WHERE조건을 주고 싶을때

1-1의 경우는 AND를 이용해서 조건을 주고

1-2의 경우는 WHERE를 INNER JOIN & ON 구문 뒤에 사용

 

1-4. 여기서 추가로 다른 INNER JOIN을 하고 싶을때

1-1의 경우는 AND조건을 추가해서 조건을 사용

1-2의 경우는 INNER JOIN & ON구문을 두번 사용하면 됨

 

 

---------------------------------------

2. OUTER JOIN

----------------------------------------

 

2-1. WHERE를 사용한 OUTER JOIN

 

SELECT col1, col2, ...

FROM table1 t1

table2 t2

WHERE t1.id = t2.id (+)

 

2-2. LEFT JOIN을 사용한 OUTER JOIN

SELECT col1, col2, ...

FROM table1 t1

LEFT JOIN table2 t2

ON t1.id = t2.id

 

2-3. WHERE를 사용한 OUTER JOIN

 

SELECT col1, col2, ...

FROM table1 t1

table2 t2

WHERE t1.id (+) = t2.id

 

2-4. RIGHT JOIN을 사용한 OUTER JOIN

SELECT col1, col2, ...

FROM table1 t1

RIGHT JOIN table2 t2

ON t1.id = t2.id

 

2-5. FJULL OUTER JOIN

 

양쪽 테이블의 모든 정보를 갖고 오고 싶을때

 

'Sql > 기초' 카테고리의 다른 글

6. 서브쿼리 + 세미조인/안티조인  (0) 2020.02.10
4. 집합 연산자  (0) 2020.02.10
3. 데이터집계  (0) 2020.02.09
2. SELECT문  (0) 2020.02.07
1. 테이블 생성/ 자료 입력과 삭제  (0) 2020.02.07

1. UNION ALL(합집합)

SELECT col1, col2

FROM ...

WEHRE ...

UNION ALL

SELECT col1, col2

FROM ...

WHERE ...

 

UNION ALL로 묶인 SELECT절은 형태가 같아야한다. 이름이 달라도 상관 없다. 첫번째 SELECT문의 이름을 반환한다.

 

2. UNION (실질적인 합집합: 중복된 원소를 하나만 뱉음)

 

SELECT col1, col2

FROM ...

WEHRE ...

UNION 

SELECT col1, col2

FROM ...

WHERE ...

 

만약 중복은 되는데 다른 컬럼이 중복되는게 아니라면 그냥 그대로 배출.

 

3. INTERSECT (교집합: 오직 중복 데이터만 추출)

 

SELECT col1, col2

FROM ...

WEHRE ...

INTERSECT

SELECT col1, col2

FROM ...

WHERE ...

ORDER BY

 

4. MINUS (첫번째 집합에서 두번째 집합을 빼서 보여줌)

 

SELECT col1, col2

FROM ...

WEHRE ...

MINUS

SELECT col1, col2

FROM ...

WHERE ...

ORDER BY

 

'Sql > 기초' 카테고리의 다른 글

6. 서브쿼리 + 세미조인/안티조인  (0) 2020.02.10
5. 조인 - 테이블간에 관계맺기  (0) 2020.02.10
3. 데이터집계  (0) 2020.02.09
2. SELECT문  (0) 2020.02.07
1. 테이블 생성/ 자료 입력과 삭제  (0) 2020.02.07

+ Recent posts