타이타닉 승객 데이터셋을 이용한 데이터 시각화 / 예측
전처리 단계에서 새로 추가된 컬럼 설명
-
FamilySize -> 배에 탑승한, 나를 포함한 우리 가족의 총 인원수 입니다.
-
Nationality -> 탑승한 항구로부터 유추한 탑승객의 국적 입니다.
-
Nationality_FR / Nationality_UK -> 원-핫-인코딩한 국적 입니다.
-
male / female -> 원-핫-인코딩한 성별 입니다.
-
Fare_Low
-
Fare_Med -> 수치형 자료인 Fare를 3 개의 그룹으로 나누었습니다.
-
Fare_High
-
Class_Low
-
Class_Mid -> Pclass를 원-핫-인코딩 하였습니다.
-
Class_High
Load Dataset
모든 데이터 분석의 시작은 데이터를 읽어오는 것입니다.
파일의 경로를 지정하는 방법에 주의하셔야 합니다.
만일 read_csv를 실행할 때 (FileNotFoundError)라는 이름의 에러가 난다면 경로가 제대로 지정이 되지 않은 것입니다.
다음의 링크에서 경로를 지정하는 법을 다루고 있습니다.
# 판다스의 read_csv로 titanic_modified.csv 파일을 읽어옵니다.
# 읽어온 데이터를 data 라는 이름의 변수에 할당합니다.
# index_col="PassengerId" => PassengerId 항목을 인덱스로 사용하겠다는 의미입니다.
import pandas as pd
data = pd.read_csv("data/titanic_modified.csv", index_col="PassengerId")
# 새로 불러온 변수 data 의
# 가로, 세로 크기와
# 첫 5 개 행을 확인합니다.
print(data.shape)
data.head()
(891, 24)
Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | ... | Nationality_FR | Nationality_UK | male | female | Class_High | Class_Mid | Class_Low | Fare_Low | Fare_Med | Fare_High | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
PassengerId | |||||||||||||||||||||
1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | ... | False | True | True | False | False | False | True | True | False | False |
2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | ... | True | False | False | True | True | False | False | False | False | True |
3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | ... | False | True | False | True | False | False | True | True | False | False |
4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | ... | False | True | False | True | True | False | False | False | True | False |
5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | ... | False | True | True | False | False | False | True | True | False | False |
5 rows × 24 columns
탐색적 데이터 분석
# 데이터 시각화 도구인 matplotlib를 불러와 이를 줄여 plt라고 사용합니다.
import matplotlib.pyplot as plt
# data 의 Age 컬럼만 뽑아, 승객들의 나이 분포를 히스토그램으로 보려고 합니다.
# plt.hist() 로 히스토그램을 그리고, 승객들의 나이 정보를 data['Age'] 로 지정해 넣어줍니다.
# y 축은 인원 수를 의미하고, x 축은 우리가 지정한 'Age' 입니다.
plt.hist(data['Age'])
히스토그램을 겹쳐 그리는 방법
# 생존한 경우와 그렇지 않은 경우 두 가지를 한 눈에 들어오게 만들어보죠.
# .loc을 이용하여 survived 와 perished 두 가지 경우를 따로 분류해 저장합니다.
# 분포를 볼 기준이 되는 x 축을 x_axis 라는 변수에 지정해둡니다.
survived = data.loc[data['Survived'] == 1]
perished = data.loc[data['Survived'] == 0]
x_axis = 'Age'
# 겹쳐 그리는 것이므로 생존인 경우의 나이와 사망한 경우의 나이를 같이넣어줍니다.
# stacked=True 는 겹쳐 그리는 옵션을 켠 것입니다.
plt.hist([survived[x_axis], perished[x_axis]], stacked=True)
plt.legend(['Survived', 'Perished'])
# 특정 조건을 걸어서, 해당 조건을 만족하는 경우
# 생존 / 사망자의 히스토그램 분포를 보겠습니다.
# data.loc[] 을 이용하여 UK 사람만 뽑아낸 이후 이를 UK 변수에 넣고
UK = data.loc[data['Nationality'] == 'UK']
# 히스토그램에 들어갔던 데이터인 변수 data 대신 UK 를 넣어줍니다.
survived = UK.loc[UK['Survived'] == 1]
perished = UK.loc[UK['Survived'] == 0]
x_axis = 'Age'
# 겹쳐 그리는 것이므로 생존인 경우의 나이와 사망한 경우의 나이를 같이넣어줍니다.
# stacked=True 는 겹쳐 그리는 옵션을 켠 것입니다.
plt.hist([survived[x_axis], perished[x_axis]], stacked=True)
plt.legend(['Survived', 'Perished'])
시각화의 함수화
# 그래프가 들어가는 데이터만 다르고 절차가 동일하기 때문에
# 반복을 줄이기 위해 그래프를 그려주는 함수를 만들어줍니다.
# data_in 과 x_axis 를 함수의 입력값으로 받습니다.
# 보고자 하는 데이터를 data_in 이름으로 함수 안에 넣을 겁니다.
# 히스토그램에서 x 축의 기준이 되는 컬럼이 x_axis 변수 입니다.
def plotter(data_in, x_axis):
# 산 자와 죽은 자를 각각 S, D 변수에 분리해 넣습니다.
S = data_in.loc[data_in['Survived'] == 1]
D = data_in.loc[data_in['Survived'] == 0]
# 겹쳐 그리는 것이므로 생존인 경우와 사망한 경우를 x_axis를 정해 같이넣어줍니다.
# stacked=True 는 겹쳐 그리는 옵션을 켠 것입니다.
plt.hist([S[x_axis], D[x_axis]], stacked=True)
plt.legend(['Survived', 'Perished'])
# 보고자 하는 경우를 data.loc[] 을 이용하여 미리 뽑아둡니다.
# FR과 UK는 국적이 정해졌을 때 생존자의 분포를,
# male과 female은 성별이 정해졌을 때 생존자의 분포를 보기 위함입니다.
FR = data.loc[data['Nationality'] == 'FR']
UK = data.loc[data['Nationality'] == 'UK']
male = data.loc[data['Sex'] == 'male']
female = data.loc[data['Sex'] == 'female']
# UK 국적을 대상으로 Fare 를 x축으로 하여 분포를 확인합니다.
plotter(UK, 'Fare')
# UK 국적을 대상으로 Age 를 x축으로 하여 분포를 확인합니다.
plotter(UK, 'Age')
# FR 국적을 대상으로 Age 를 x축으로 하여 분포를 확인합니다.
# UK 와 FR 의 바로 들어오는 차이점은 y 축의 크기가 다르다는 것입니다.
# -> FR 국적의 사람들이 훨씬 적음을 알 수 있습니다.
# 나이대별 생존인원 / 전체인원의 비율도 어느정도 차이가 있는 것 같아 보입니다.
plotter(FR, 'Age')
# male 성별을 대상으로 Age 를 x축으로 하여 분포를 확인합니다.
plotter(male, 'Age')
# female 성별을 대상으로 Age 를 x축으로 하여 분포를 확인합니다.
# 이번에도 y축의 크기가 다르기 때문에 female 이 인원수가 더 적음을 알 수 있습니다.
# 나이대별 생존인원 / 전체인원의 비율도 차이가 있는 것 같아 보입니다.
plotter(female, 'Age')
생존과 가장 연관있는 특징은 무엇일까? - 상관계수 도출하기
# 행을 사람으로, 컬럼을 해당 사람의 특징으로 하는 데이터프레임인 data 의
# 모든 컬럼들에 대해, .corr()를 이용하여 서로서로 컬럼들 끼리의 상관계수 행렬을 구해줍니다.
# 수치를 해석하는 방법은, 행/열의 이름을 보고 1, -1, 0 어디에 가까운지를 확인합니다.
# 같이 증가하는 경향이라면 1, 하나가 증가할 때 하나가 감소하면 -1, 상관이 없으면 0 에 가깝습니다.
# 흔히 양/음의 상관관계 라고 이야기할 때 이 수치를 기준으로 말합니다.
corr = data.corr()
corr
Survived | Pclass | Age | SibSp | Parch | Fare | FamilySize | Nationality_FR | Nationality_UK | male | female | Class_High | Class_Mid | Class_Low | Fare_Low | Fare_Med | Fare_High | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Survived | 1.000000 | -0.338481 | -0.069809 | -0.035322 | 0.081629 | 0.257307 | 0.016639 | 0.168240 | -0.174718 | -0.543351 | 0.543351 | 0.285904 | 0.093349 | -0.322308 | -0.285349 | 0.131712 | 0.236428 |
Pclass | -0.338481 | 1.000000 | -0.331339 | 0.083081 | 0.018443 | -0.549500 | 0.065997 | -0.243292 | 0.251139 | 0.131900 | -0.131900 | -0.885924 | -0.188432 | 0.916673 | 0.563381 | -0.215576 | -0.530062 |
Age | -0.069809 | -0.331339 | 1.000000 | -0.232625 | -0.179191 | 0.091566 | -0.248512 | 0.032024 | -0.040804 | 0.084153 | -0.084153 | 0.319916 | 0.006589 | -0.281004 | -0.060586 | -0.019972 | 0.118398 |
SibSp | -0.035322 | 0.083081 | -0.232625 | 1.000000 | 0.414838 | 0.159651 | 0.890712 | -0.059528 | 0.061970 | -0.114631 | 0.114631 | -0.054582 | -0.055932 | 0.092548 | -0.390253 | 0.266324 | 0.200727 |
Parch | 0.081629 | 0.018443 | -0.179191 | 0.414838 | 1.000000 | 0.216225 | 0.783111 | -0.011069 | 0.013725 | -0.245489 | 0.245489 | -0.017633 | -0.000734 | 0.015790 | -0.397959 | 0.323111 | 0.131383 |
Fare | 0.257307 | -0.549500 | 0.091566 | 0.159651 | 0.216225 | 1.000000 | 0.217138 | 0.269335 | -0.273614 | -0.182333 | 0.182333 | 0.591711 | -0.118557 | -0.413333 | -0.483538 | -0.021316 | 0.748496 |
FamilySize | 0.016639 | 0.065997 | -0.248512 | 0.890712 | 0.783111 | 0.217138 | 1.000000 | -0.046215 | 0.049211 | -0.200988 | 0.200988 | -0.046114 | -0.038594 | 0.071142 | -0.465538 | 0.343444 | 0.202827 |
Nationality_FR | 0.168240 | -0.243292 | 0.032024 | -0.059528 | -0.011069 | 0.269335 | -0.046215 | 1.000000 | -0.992724 | -0.082853 | 0.082853 | 0.296423 | -0.125416 | -0.153329 | -0.180016 | 0.007366 | 0.256888 |
Nationality_UK | -0.174718 | 0.251139 | -0.040804 | 0.061970 | 0.013725 | -0.273614 | 0.049211 | -0.992724 | 1.000000 | 0.090223 | -0.090223 | -0.305181 | 0.127763 | 0.158965 | 0.185077 | -0.003087 | -0.270492 |
male | -0.543351 | 0.131900 | 0.084153 | -0.114631 | -0.245489 | -0.182333 | -0.200988 | -0.082853 | 0.090223 | 1.000000 | -1.000000 | -0.098013 | -0.064746 | 0.137143 | 0.222830 | -0.089730 | -0.203300 |
female | 0.543351 | -0.131900 | -0.084153 | 0.114631 | 0.245489 | 0.182333 | 0.200988 | 0.082853 | -0.090223 | -1.000000 | 1.000000 | 0.098013 | 0.064746 | -0.137143 | -0.222830 | 0.089730 | 0.203300 |
Class_High | 0.285904 | -0.885924 | 0.319916 | -0.054582 | -0.017633 | 0.591711 | -0.046114 | 0.296423 | -0.305181 | -0.098013 | 0.098013 | 1.000000 | -0.288585 | -0.626738 | -0.550347 | 0.159468 | 0.590527 |
Class_Mid | 0.093349 | -0.188432 | 0.006589 | -0.055932 | -0.000734 | -0.118557 | -0.038594 | -0.125416 | 0.127763 | -0.064746 | 0.064746 | -0.288585 | 1.000000 | -0.565210 | 0.002322 | 0.107350 | -0.156173 |
Class_Low | -0.322308 | 0.916673 | -0.281004 | 0.092548 | 0.015790 | -0.413333 | 0.071142 | -0.153329 | 0.158965 | 0.137143 | -0.137143 | -0.626738 | -0.565210 | 1.000000 | 0.472292 | -0.224766 | -0.381698 |
Fare_Low | -0.285349 | 0.563381 | -0.060586 | -0.390253 | -0.397959 | -0.483538 | -0.465538 | -0.180016 | 0.185077 | 0.222830 | -0.222830 | -0.550347 | 0.002322 | 0.472292 | 1.000000 | -0.764298 | -0.397894 |
Fare_Med | 0.131712 | -0.215576 | -0.019972 | 0.266324 | 0.323111 | -0.021316 | 0.343444 | 0.007366 | -0.003087 | -0.089730 | 0.089730 | 0.159468 | 0.107350 | -0.224766 | -0.764298 | 1.000000 | -0.287509 |
Fare_High | 0.236428 | -0.530062 | 0.118398 | 0.200727 | 0.131383 | 0.748496 | 0.202827 | 0.256888 | -0.270492 | -0.203300 | 0.203300 | 0.590527 | -0.156173 | -0.381698 | -0.397894 | -0.287509 | 1.000000 |
# 생존과 직접적으로 연관이 있는 컬럼들만 알아보기 위해
# 상관계수 행렬을 'Survived' 를 키로 하는 값만 가져와 corr_s 변수에 저장합니다.
corr_s = corr['Survived']
# .sort_values()를 이용해 값들을 보기 편하게 정렬해 표현합니다.
corr_s.sort_values()
# 양수이면 해당 값과 생존 값이 같이 움직인다는 것입니다.(생존 값은 0 또는 1)
# 음수이면 해당 값과 생존 값이 반대로 움직인다는 것입니다.
male -0.543351
Pclass -0.338481
Class_Low -0.322308
Fare_Low -0.285349
Nationality_UK -0.174718
Age -0.069809
SibSp -0.035322
FamilySize 0.016639
Parch 0.081629
Class_Mid 0.093349
Fare_Med 0.131712
Nationality_FR 0.168240
Fare_High 0.236428
Fare 0.257307
Class_High 0.285904
female 0.543351
Survived 1.000000
Name: Survived, dtype: float64
히트맵 방식으로 시각화하기
# heatmap - 2차원의 정보를 열분포 형태의 그림으로 확인합니다.
# 데이터 시각화 도구인 seaborn 을 불러와 이를 줄여 sns라고 사용합니다.
import seaborn as sns
# sns.heatmap()으로 히트맵 시각화를 하고, 여기에 상관계수 행렬인 corr을 넣어줍니다.
sns.heatmap(corr)
# 시각화의 전체 사이즈는 7, 5로 설정합니다.
plt.gcf().set_size_inches(7, 5)
# 밝을수록 양의 상관관계, 어두울수록 음의 상관관계 입니다.
생존자를 예측하기
# Survived 를 제외한 컬럼들은, 전부 Survived를 설명하는 변수들 입니다.
# 맞추고자 하는 대상을 label 이라고 하고, 이를 설명하는 변수들을 feature 라고 합니다.
# all_features 변수에 전처리 단계에서 추가한 컬럼들과 Age 를 리스트로 넣고
all_features = ["Class_High", "Class_Mid", "Class_Low",
"Fare_High", "Fare_Med", "Fare_Low",
"Nationality_UK", "Nationality_FR",
"Age", "FamilySize", "male", "female"]
# label 변수에는 우리가 맞추고자 하는 'Survived' 를 넣습니다.
label = ['Survived']
# 슬라이싱을 적용하여 데이터를 특정 기점으로 잘라줍니다.
# 잘랐을 때, feature(특징) 모음의 경우 컬럼의 개수가 동일해야 합니다.
split = 400
# X_train -> 학습할 데이터의 특징들의 모음
# Y_train -> 학습할 데이터의 레이블
X_train = data[:split][all_features]
y_train = data[:split][label]
# X_test -> 예측할 데이터의 특징 모음
# Y_test -> 예측할 데이터의 레이블
X_test = data[split:][all_features]
y_test = data[split:][label]
# 머신러닝 도구인 sklearn 으로부터 DecisionTreeClassifier 를 불러옵니다.
# DecisionTreeClassifier는 의사결정나무를 이용하는 알고리즘 입니다.
from sklearn.tree import DecisionTreeClassifier
# model 은 어떤 알고리즘으로 학습할 것인지를 나타냅니다.
# max_depth=3 는 의사결정 단계의 깊이를 의미하는데, 직접 바꿔보면서 알아보겠습니다.
model = DecisionTreeClassifier(max_depth=5)
model
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=5,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort=False,
random_state=None, splitter='best')
# model.fit -> 선택한 알고리즘에 학습할 데이터를 넣어서 학습시킨다는 의미입니다.
# model.score -> 예측한 결과인 predict 와 실제 결과를 비교하여 점수를 환산합니다.
# 점수는 mean-average 방식, 맞추면 1 틀리면 0 으로 두고 모든 결과에 대해 평균
model = model.fit(X_train, y_train)
model.score(X_train, y_train)
0.855
# model.predict -> 학습한 알고리즘에 예측할 데이터를 넣어서 결과를 예측하는 것입니다.
# 정답인 Survived 와 비교하기 위해, 예측한 결과를 'Predict' 키에 값으로 넣어줍니다.
y_test['Predict'] = model.predict(X_test)
y_test.head()
Survived | Predict | |
---|---|---|
PassengerId | ||
401 | 1 | 0 |
402 | 0 | 0 |
403 | 0 | 1 |
404 | 0 | 0 |
405 | 0 | 1 |
# 예측결과와 정답이 같으면 True, 다르면 False로 하는 값을
# 'validity' 를 키로 하여 넣어줍니다.
y_test['validity'] = (y_test['Predict'] == y_test['Survived'])
# True 는 1 로 취급하므로, .sum() 으로 True들을 더하면 정답의 개수가 됩니다.
correct = y_test['validity'].sum()
# len() 은 몇 개 들었는지 확인하는 것이었는데요
# 여기에서는 True/False 가리지않고 몇 개 들어있는지 확인하기 위해 사용합니다.
total = len(y_test['validity'])
# 정답의 개수를 전체 인원수로 나누어서, mean-average 로 정확도를 구해줍니다.
pct = correct / total
pct
0.8085539714867617
Feature Importance 추출
# model.fit 으로 학습을 하게 되면, 학습 과정에서 판별을 위해 사용한
# 특징들의 중요도를 의미하는 feature importance를 추출할 수 있습니다.
# model.feature_importances_ 로 추출하여 rank 변수에 넣어줍니다.
rank = model.feature_importances_
print(rank)
# 묶음 형태로 나오게 되는데, 이 순서는 학습시 넣어준 feature 순서대로 입니다.
print(all_features)
# 이를 보기 좋게 정렬하는 방법 두 가지를 소개합니다.
[0.0136221 0. 0.07452883 0.0051696 0.00924445 0.
0. 0. 0.15119727 0.07985843 0. 0.66637932]
['Class_High', 'Class_Mid', 'Class_Low', 'Fare_High', 'Fare_Med', 'Fare_Low', 'Nationality_UK', 'Nationality_FR', 'Age', 'FamilySize', 'male', 'female']
# pd.Dataframe() 으로, 새로운 데이터프레임을 만들 수 있습니다.
# 데이터는 feature 중요도 점수, 인덱스(순서) 는 feature 정보
# 그리고 columns에 넣어준 데이터의 컬럼 이름을 'score' 로 지정합니다.
scoring = pd.DataFrame(
data = rank,
index = all_features,
columns = ['score'])
# 'score' 를 기준으로 정렬하고, 내림차순으로 정렬한다는 의미입니다.
scoring.sort_values(by='score', ascending=False)
score | |
---|---|
female | 0.666379 |
Age | 0.151197 |
FamilySize | 0.079858 |
Class_Low | 0.074529 |
Class_High | 0.013622 |
Fare_Med | 0.009244 |
Fare_High | 0.005170 |
Class_Mid | 0.000000 |
Fare_Low | 0.000000 |
Nationality_UK | 0.000000 |
Nationality_FR | 0.000000 |
male | 0.000000 |
# 두 번째 방법은 순수 파이썬 문법을 사용하는 것입니다.
# sorted() 는 내용물들을 정렬해주는 기능을 수행합니다.
# zip() 은 묶음을 두 개 넣어주면 순서가 같은 것끼리 묶어줍니다.
# zip() 에 점수와 feature를 넣어주면, 같은 순서끼리 묶어주고
# 이를 sorted() 에서 점수의 순서대로 내림차순 정렬해줍니다.
sorted(zip(rank, all_features), reverse=True)
[(0.6663793228128022, 'female'),
(0.15119726660076893, 'Age'),
(0.07985842938788616, 'FamilySize'),
(0.07452882775445713, 'Class_Low'),
(0.013622102842177863, 'Class_High'),
(0.009244454394472421, 'Fare_Med'),
(0.005169596207435185, 'Fare_High'),
(0.0, 'male'),
(0.0, 'Nationality_UK'),
(0.0, 'Nationality_FR'),
(0.0, 'Fare_Low'),
(0.0, 'Class_Mid')]
# 머신러닝 도구인 sklearn 으로부터 export_graphviz 를 불러옵니다.
# export_graphviz 는 의사결정나무를 시각화하는 기능이 있습니다.
# 코드를 실행하면 tree.txt 에 의사결정나무 정보가 저장됩니다.
from sklearn.tree import export_graphviz
dotfile = open("tree.txt", 'w')
export_graphviz(model,
feature_names=all_features,
class_names='Survived',
out_file=dotfile)
dotfile.close()
'''
만든 tree 파일을 메모장으로 열어
안의 내용을 아래 링크에 붙여넣기
http://webgraphviz.com/
'''
'\n만든 tree 파일을 메모장으로 열어\n안의 내용을 아래 링크에 붙여넣기\n\nhttp://webgraphviz.com/\n\n'
'''
그래프 해석법
max_depth 는 의사결정의 단계(깊이) 를 의미합니다.
10 으로 바꿔서 확인하면, 더 깊이있는 그림을 볼 수 있습니다.
의사결정나무는 한번 분기 때마다 두 개의 영역으로 구분합니다.
구분하는 기준은 지니 계수가 감소하는 방향 입니다.
지니 계수는?
균일하게 들어있을수록 1, 한 쪽으로 치우쳐질수록 0 입니다.
어떤 기준을 잡았을 때 Survived 가 한 값만 들어있다면, 값이 0 입니다.
'''
'\n그래프 해석법\n\nmax_depth 는 의사결정의 단계(깊이) 를 의미합니다.\n10 으로 바꿔서 확인하면, 더 깊이있는 그림을 볼 수 있습니다.\n\n의사결정나무는 한번 분기 때마다 두 개의 영역으로 구분합니다.\n구분하는 기준은 지니 계수가 감소하는 방향 입니다.\n\n지니 계수는?\n균일하게 들어있을수록 1, 한 쪽으로 치우쳐질수록 0 입니다.\n어떤 기준을 잡았을 때 Survived 가 한 값만 들어있다면, 값이 0 입니다.\n'
# max_depth 가 3 인 경우
# max_depth 가 5 인 경우
'[입문] 데이터 사이언스? 그게 뭔가요?' 카테고리의 다른 글
파이썬으로 데이터 주무르기 2장 코드에 주석을 달았다는 내용의 제목 (0) | 2019.09.07 |
---|---|
[뉴스 정보] 조금 진지한 크롤링, selenium / beautifulsoup (0) | 2019.08.21 |
[뉴스 정보] 데이터 수집/저장 입문_2 (0) | 2019.08.21 |
[환율 정보] 데이터 수집/저장 입문_1 (0) | 2019.08.21 |
데이터 사이언스 입문자를 위한 [데이터 전처리] (0) | 2019.08.15 |