최근에 실기 문제 유형의 개편이 있었는데, 그 부분을 확실히 담은 최신판이었고, 가장 많이 쓰는 언어는 Python으로 시험을 준비하는 사람들은 위한 버전이었습니다.
이기적 수험서의 장점은 다양한 학습자교의 제공입니다. 계획 없는 P라도 이기적에서 제공해주는 학습 플랜만 따라간다면 누구나 합격할 수 있을 것 같습니다. 위의 캘린더, 스터디 플래너, 오답노트 뿐만 아니라, <이기적 스터디 카페>에 가입하면 Q&A 서비스, 교재 구매 인증 시 추가 학습 자료, 동영상 강의(필기/실기) 까지 무료로 제공하고 있습니다. 이 정도의 학습자로라면 누구나 독학으로 합격할 수 있을 것 같습니다.
실기시험을 준비할 때 가장 걱정되는 것이 실제 시험환경은 어떨지에 관한 것일 건데요. 이 책에는 그 부분도 정확하게 설명해두어서, 실제 시험장에 들어가기 전 걱정을 덜 수 있을 것 같습니다.
파이썬을 베이스로 한 수험서로, 데이터 분석에 필요한 파이썬 코드 뿐만아니라, 파이썬의 기본 코드도 설명해주고 있어서, 파이썬이 완전 처음이신 분이라도 누구나 학습을 시작하기에 어려움이 없을 것 같습니다.
마지막으로 실기시험 준비에 가장 중요한 모의고사를 직접 풀어볼 수 있는 과정이 포함되어 있습니다.해설도 자세히 나와있어서 문제를 어떻게 풀어야할 지 이해하기에 너무나도 쉬웠습니다.
다들 <이기적 빅데이터분석기사 실기 기본서>로 이번 빅데이터 분석기사 실기 시험에 붙어봐요.
새로 생긴 경영정보시각화능력 자격증을 준비하기 위해 이기적을 찾았습니다. IT 관련 자격증을 준비할 때 언제나 찾아보던 이기적 출판사에서 나온 책이라 믿고 보기로 하였습니다.
경영정보시각화능력 자격증은 회계, 재무, 마케팅 등 경영과 관련된 정보와 데이터 관련 내용, 그리고 이런 정보들을 효과적으로 시각화하여 경영을 도울 수 있는 능력을 시험하는 자격증입니다. 데이터 분석을 진행하며 시각화는 정말 중요한 한 부분이라고 생각하여 자격증을 준비하며 시각화 능력을 기르는 것은 좋은 기회라고 생각하였습니다.
책의 두께는 별로 두껍지 않습니다. 자격증 시험은 딥하게 들어갈 필요없이 합격을 위해 필요한 부분만 있으면 된다고 생각하기 때문에 이런 두께는 환영입니다.
책의 목차는 다음과 같이 구성되어 있습니다.
이번에 처음 시행되는 시험이라 다소 생소할 수도 있는 경영정보시각화 능력 자격증에 대한 정보도 상세하게 설명해주어 더 검색할 필요없이 공부에만 집중할 수 있었습니다.
책에는 기본 이론은 물론 '기적의 Tip'을 페이지마다 설명해주어 놓치는 부분없이 공부할 수 있었습니다.
각 장의 마무리는 배운 개념을 체크할 수 있는 문제들로 구성되어 한 번 더 확인하고 복습할 수 있었습니다.
예상문제 또한 시험에 대한 정보가 없는 상황에서 큰 도움이 되는 파트였습니다. 이미 다른 IT 관련 자격증의 문제집을 담당해온 이기적 출판사에서 내준 예상문제라면 더 신뢰성 있어보입니다.
책의 마지막 장에는 기출 예상문제로 구성되어있습니다. 실제 시험과 비슷한 형식으로, 공부를 다 하고, 시험 친다고 생각하고 실전 연습을 해볼 수도 있고, 시험에 대한 정보가 없는 상황에서 가장 비슷하게 시험을 경험해볼 수 있을 것 같습니다.
이기적 경영정보시각화능력 자격증 필기 문제집과 함께 다같이 한 번에 합격할 수 있었으면 좋겠습니다~!
Jenny Ashley Meera Jane
Samantha Christeen Priya Julia
NULL Ketty NULL Maria
풀이
1. 직업 별 이름들을 서브쿼리로 추출해서 JOIN
- row_number() over(ORDER BY Name) 열 추가: 이름 오름차순 정렬 + JOIN 기준으로 하여, 빈 셀에 Null 삽입
- JOIN 방향은 이름 개수가 가장 많은 Professor 열 기준: 다른 열 기준 시 Professor의 이름이 잘리기 때문
SELECT d.Name, p.Name, s.Name, a.Name
FROM
(SELECT Name, row_number() over(ORDER BY Name) as r
FROM OCCUPATIONS
WHERE Occupation = 'Doctor') AS d
RIGHT JOIN
(SELECT Name, row_number() over(ORDER BY Name) as r
FROM OCCUPATIONS
WHERE Occupation = 'Professor') AS p
ON d.r = p.r
LEFT JOIN
(SELECT Name, row_number() over(ORDER BY Name) as r
FROM OCCUPATIONS
WHERE Occupation = 'Singer') AS s
ON p.r = s.r
LEFT JOIN
(SELECT Name, row_number() over(ORDER BY Name) as r
FROM OCCUPATIONS
WHERE Occupation = 'Actor') AS a
ON s.r = a.r
-- 출력
Aamina Ashley Christeen Eve
Julia Belvet Jane Jennifer
Priya Britney Jenny Ketty
NULL Maria Kristeen Samantha
NULL Meera NULL NULL
NULL Naomi NULL NULL
NULL Priyanka NULL NULL
2. 각 직업의 수를 세서 "There are a total of 3 doctors"와 같이 출력(직업 count 오름차순, 직업명 오름차순)
Sample Output
Ashely(P)
Christeen(P)
Jane(A)
Jenny(D)
Julia(A)
Ketty(P)
Maria(A)
Meera(S)
Priya(S)
Samantha(D)
There are a total of 2 doctors.
There are a total of 2 singers.
There are a total of 3 actors.
There are a total of 3 professors.
풀이
1. "이름 (직업의 첫 글자)"를 이름 기준 오름차순으로 출력
SELECT CONCAT(Name, '(', SUBSTR(Occupation,1,1),')')
FROM OCCUPATIONS
ORDER BY Name;
-- 출력
Aamina(D)
Ashley(P)
Belvet(P)
Britney(P)
Christeen(S)
Eve(A)
Jane(S)
Jennifer(A)
Jenny(S)
Julia(D)
Ketty(A)
Kristeen(S)
Maria(P)
Meera(P)
Naomi(P)
Priya(D)
Priyanka(P)
Samantha(A)
2. 각 직업의 수를 세서 "There are a total of 3 doctors"를 직업 수 오름차순, 직업명 오름차순으로 출력
SELECT CONCAT('There are a total of ', COUNT(Occupation), ' ', LOWER(Occupation), 's.')
FROM OCCUPATIONS
GROUP BY Occupation
ORDER BY COUNT(Occupation), Occupation;
-- 출력
There are a total of 3 doctors.
There are a total of 4 actors.
There are a total of 4 singers.
There are a total of 7 professors.
3. 두 쿼리를 UNION으로 결합하여 한 줄로 출력하려고 했지만 MySQL에서 UNION을 사용할 때 ORDER BY가 적용되지 않아 오류 발생
SELECT CONCAT(Name, '(', SUBSTR(Occupation,1,1),')')
FROM OCCUPATIONS
ORDER BY Name
UNION
SELECT CONCAT('There are a total of ', COUNT(Occupation), ' ', LOWER(Occupation), 's.')
FROM OCCUPATIONS
GROUP BY Occupation
ORDER BY COUNT(Occupation), Occupation
-- 출력
-- ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual
-- that corresponds to your MySQL server version for the right syntax to use near 'UNION
-- SELECT CONCAT('There are a total of ', COUNT(Occupation), ' ', LOWER(Occup' at line 4
4. 각 쿼리를 서브쿼리에 넣어 UNION 시도했지만 MySQL에서 UNION하면 ORDER BY로 한 정렬이 풀려버림
SELECT a.*
FROM (SELECT CONCAT(Name, '(', SUBSTR(Occupation,1,1),')')
FROM OCCUPATIONS
ORDER BY Name) AS a
UNION
SELECT b.*
FROM (SELECT CONCAT('There are a total of ', COUNT(Occupation), ' ', LOWER(Occupation), 's.')
FROM OCCUPATIONS
GROUP BY Occupation
ORDER BY COUNT(Occupation), Occupation) AS b
-- 출력
Ashley(P)
Samantha(A)
Julia(D)
Britney(P)
Maria(P)
Meera(P)
Priya(D)
Priyanka(P)
Jennifer(A)
Ketty(A)
Belvet(P)
Naomi(P)
Jane(S)
Jenny(S)
Kristeen(S)
Christeen(S)
Eve(A)
Aamina(D)
There are a total of 3 doctors.
There are a total of 4 actors.
There are a total of 4 singers.
There are a total of 7 professors.
정답
5. 두 쿼리를 UNION으로 묶지않고 ";"로 각 쿼리를 끝내 두 번 출력하는 방법으로 변경
SELECT CONCAT(Name, '(', SUBSTR(Occupation,1,1),')')
FROM OCCUPATIONS
ORDER BY Name;
SELECT CONCAT('There are a total of ', COUNT(Occupation), ' ', LOWER(Occupation), 's.')
FROM OCCUPATIONS
GROUP BY Occupation
ORDER BY COUNT(Occupation), Occupation;
-- 출력
Aamina(D)
Ashley(P)
Belvet(P)
Britney(P)
Christeen(S)
Eve(A)
Jane(S)
Jennifer(A)
Jenny(S)
Julia(D)
Ketty(A)
Kristeen(S)
Maria(P)
Meera(P)
Naomi(P)
Priya(D)
Priyanka(P)
Samantha(A)
There are a total of 3 doctors.
There are a total of 4 actors.
There are a total of 4 singers.
There are a total of 7 professors.
$$\phi(z) = \begin{cases} 1 & z \geq 0 \\ -1 & 그외 \end{cases}$$
- \(w_{0} = -\theta\)를 절편이라고 함
퍼셉트론의 결정함수와 결정 경계
3. 퍼셉트론 학습 규칙
- 뇌의 뉴런 하나가 작동하는 방식을 흉내내는 환원주의 접근 방식 사용
가중치를 0 또는 랜덤한 작은 값으로 초기화
각 훈련 샘플 \(x^{(i)}\)에서 다음 작업 수행
출력 값 \(\hat{y}\) 계산 → 출력값은 계단 함수로 예측한 클래스 레이블
가중치 업데이트 →\(w_{j}:=w_{j}+\Delta w_{j}\) →가중치 업데이트 값인 \(\Delta w_{j}=\eta (y^{(i)}-\hat{y}^{(i)})x_{j}^{(i)}\) → \(\eta\)는 학습률로 0.0~0.1 사이의 값 → \(y^{(i)}\)와 \(\hat{y}^{(i)}\)는 각각 \(i\)번째 훈련 샘플의 정답 레이블, 예측 레이블
- 가중치 벡터의 모든 가중치는 동시에 업데이트
- 모든 가중치가 각자의 업데이트 값 \(\Delta w_{j}\)에 의해 업데이트되기 전에 예측 레이블 \(\hat{y}^{(i)}\)를 다시 계산하지 않음 → \(\Delta w_{0}=\eta(y^{(i)}-output^{(i)})\) → \(\Delta w_{1}=\eta(y^{(i)}-output^{(i)})x_{1}^{(i)}\) → \(\Delta w_{2}=\eta(y^{(i)}-output^{(i)})x_{2}^{(i)}\)
- 퍼셉트론이 클래스 레이블을 정확히 예측하면 가중치 유지(업데이트 값은 0) → \(y^{(i)}=-1, \hat{y}^{(i)}=-1, \Delta w_{j}=\eta(-1-(-1))x_{j}^{(i)}=0\) → \(y^{(i)}=1, \hat{y}^{(i)}=1,\Delta w_{j}=\eta(1-1)x_{j}^{(i)}=0\) - 퍼셉트론이 클래스 레이블을 잘못 예측하면 가중치를 양성 또는 음성 타겟 클래스 방향으로 이동시킴 → \(y^{(i)}=1, \hat{y}^{(i)}=-1, \Delta w_{j}=\eta(1-(-1))x_{j}^{(i)}=\eta(2)x_{j}^{(i)}\) → \(y^{(i)}=-1, \hat{y}^{(i)}=1, \Delta w_{j}=\eta(-1-1)x_{j}^{(i)}=\eta(-2)x_{j}^{(i)}\)
- 가중치 업데이트는 \(x_{j}^{(i)}\)값에 비례하여, 이 값을 조절해 결정경계를 더 크게 움직이거나 더 작게 움직일 수 있음
- 퍼셉트론은 두 클래스가 선형적으로 구분되고 학습률이 충분히 작을 때만 수렴이 보장됨
- 선형 결정 경계로 나눌 수 없다면 훈련 데이터셋을 반복할 최대 횟수(epoch)를 지정해 분류 허용 오차 지정, 그렇지 않으면 퍼셉트론은 가중치 업데이트를 멈추지 않음
퍼셉트론 알고리즘
4. 파이썬으로 퍼셉트론 학습 알고리즘 구현
- 퍼셉트론 클래스 정의
import numpy as np
class Perceptron(object):
def __init__(self, eta = 0.01, n_iter = 50, random_state = 1):
self.eta = eta
self.n_iter = n_iter
self.random_state = random_state
def fit(self, X, y):
rgen = np.random.RandomState(self.random_state) # 난수 생성기 객체 생성(격리된 시드 부여 가능, 이전과 동일한 랜덤 시드 재현 가능)
self.w_ = rgen.normal(loc = 0.0, scale = 0.01,
size = 1 + X.shape[1]) # 평균 0, 표준편차 0.01의 정규분포에서 훈련 데이터 개수(X.shape[1]) + 절편(1)만큼의 난수 생성
self.errors_ = [] # 훈련 중 error의 감소 확인을 위한 객체
for _ in range(self.n_iter):
errors = 0
for xi, target in zip(X, y):
update = self.eta * (target - self.predict(xi)) # 가중치 w_j의 변화량
self.w_[1:] += update * xi # 각 훈련 데이터에 가중치값 곱하기
self.w_[0] += update # 가중치값 업데이트
errors += int(update != 0.0) # 업데이트 된 값이 0이 아니면(실제값과 예측값이 다르면) errors에 1 더함
self.errors_.append(errors) # 전체 훈련 데이터에서 예측값이 실제값과 다르게 나온 횟수 추가
return self
# 최종입력인 Z 계산
def net_input(self, X):
return np.dot(X, self.w_[1:]) + self.w_[0]
# 결정함수를 임계값인 0과 비교, 크거나 같으면 1, 작으면 -1로 반환
def predict(self, X):
return np.where(self.net_input(X) >= 0, 1, -1)
- fit 메서드 내의 w_객체에 가중치를 초기화하여 선언 - 가중치가 0이 아니어야 학습률(eta)가 분류 결과에 영향을 줄 수 있어 0이 아닌 랜덤 값으로 초기화 - 가중치가 0이면 eta는 가중치 벡터의 방향이 아니라 크기에만 영향을 미침
- 붓꽃 데이터셋에서 퍼셉트론 훈련 - Perceptron은 이진분류이므로 setosa와 versicolor에 대해서만 분류 진행 - 또한, 특성은 첫번째 특성(꽃받침 길이)와 세번째 특성(꽃잎 길이)을 사용
import pandas as pd
import matplotlib.pyplot as plt
s = 'https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
df = pd.read_csv(s, header = None, encoding = 'utf-8')
# 처음 100개의 데이터(setosa 50개와 versicolor 50개)의 다섯번째 열인 예측 대상을 y로 선언
y = df.iloc[0:100, 4].values
# setosa이면 -1, versicolor이면 1로 변경
y = np.where(y == 'Iris-setosa', -1, 1)
# 처음 100개의 데이터에서 예측에 사용하고자 하는 특성인 첫번재 열과 세번째 열만 추출
X = df.iloc[0:100, [0, 2]].values
# 산점도로 시각화
plt.scatter(X[:50, 0], X[:50, 1], color = 'red', marker = 'o', label = 'setose')
plt.scatter(X[50:100, 0], X[50:100, 1], color = 'blue', marker = 'x', label = 'versicolor')
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc = 'upper left')
plt.show()
# Perceptron 알고리즘 훈련
ppn = Perceptron(eta = 0.1, n_iter = 10)
ppn.fit(X, y)
# 훈련 과정에서 각 반복에서 나온 오차의 개수 시각화
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker = 'o')
plt.xlabel('Epochs')
plt.ylabel('Number of updates')
plt.show()
from matplotlib.colors import ListedColormap
# 결정경계 시각화 함수
def plot_decision_regions(X, y, classifier, resolution = 0.02):
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
# 두 특성의 최소값과 최대값에 각각 -1, +1을 한 값을 정의
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
# 위에서 구한 최소값과 최대값을 시작으로 하는 meshgrid 생성(최소값과 최대값 사이에 0.02의 간격으로 데이터 생성)
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
# ravel 함수로 meshgrid를 1차원으로 평평하게 펴고, xx1, xx2를 각각 X, y로 Perceptron에 넣어 예측
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
# 예측된 값을 다시 meshgrid 형태로 변경
Z = Z.reshape(xx1.shape)
# contourf 함수로 등고선 그래프 그리기(등고선이 두 집단의 경계로 그려짐)
# 분류된 값이 -1인 것과 1인 것을 각각 빨간색과 파란색으로 구분
plt.contourf(xx1, xx2, Z, alpha = 0.3, cmap = cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
# 훈련 데이터를 빨간색 네모 모양와 파란색 x모양으로 구분
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x = X[y == cl, 0], y = X[y == cl, 1],
alpha = 0.8, c = colors[idx], marker = markers[idx], label = cl, edgecolor = 'black')
plot_decision_regions(X, y, classifier = ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc = 'upper left')
plt.show()
- OvR(One-versus-Resr)기법을 사용하면 이진 분류기로 다중 클래스 문제 해결 가능 →클래스마다 하나의 분류기를 훈련(각 클래스를 양성으로 분류하고 나머지는 음성으로 분류) →레이블이 없는 새로운 데이터 샘플 분류 시에는 클래스 레이블의 개수와 같은 n개의 분류기 사용 → 신뢰도가 가장 높은 클래스 레이블(최종 입력의 절댓값이 가장 큰 클래스)을 분류하려는 샘플의 레이블로 선택
- 퍼셉트론의 가장 큰 문제는 수렴 → 구 클래스가 선형적인 초평면으로 구분될 수 있을 때 수렴하지만, 선형 결정 경계로 완벽하게 구분되지 않으면 최대 epoch를 지정하지 않는한 가중치 업데이트가 멈추지 않음