문제

위와 같은 STATION 테이블에서, \(P_{1}(a, b), P_{2}(c, d)\)를 정의

- a: LAT_N의 최소값

- b: LONG_W의 최소값

- c: LAT_N의 최대값

- d: LONG_W의 최대값

일 때,

1번 문제: \(P_{1}\)과 \(P_{2}\) 사이의 맨하탄 거리를 구하고, 소숫점 4자리로 반올림

2번 문제:  \(P_{1}\)과 \(P_{2}\) 사이의 유클리디안 거리를 구하고, 소숫점 4자리로 반올림

※ 맨하탄 거리 \(d(P_{1}, P_{2}) = (|a - c|) + (|b - d|)\)

※ 유클리디안 거리 \(d(P_{1}, P_{2}) = \sqrt{(a - c)^{2} + (b - d)^{2}}\)

 

풀이

-- 1번. 맨하탄 거리
-- a: MIN(LAT_N)
-- b: MIN(LONG_W)
-- c: MAX(LAT_N)
-- d: MAX(LONG_W)
-- ABS(): 절댓값(| |)
-- ROUND(a, n): a를 소숫점 n자리로 반올림
SELECT ROUND(ABS(MIN(LAT_N) - MAX(LAT_N)) + ABS(MIN(LONG_W) - MAX(LONG_W)), 4) FROM STATION

-- 출력
259.6859
-- 2번. 유클리디안 거리
-- a: MIN(LAT_N)
-- b: MIN(LONG_W)
-- c: MAX(LAT_N)
-- d: MAX(LONG_W)
-- SQRT(): 제곱근
-- POWER(a, n): a의 n제곱
-- ROUND(a, n): a를 소숫점 n자리로 반올림
SELECT ROUND(SQRT(POWER(MIN(LAT_N) - MAX(LAT_N), 2) + POWER(MIN(LONG_W) - MAX(LONG_W), 2)), 4) FROM STATION

-- 출력
184.1616

 

'SQL' 카테고리의 다른 글

[HackerRank] New Companies(MySQL)  (0) 2024.05.11
[HackerRank] Occupations(MySQL)  (0) 2024.04.08
[HackerRank] Occupations(MySQL)  (0) 2024.04.01
[HackerRank] The PADS(MySQL)  (0) 2024.03.20

문제

테이블로부터
회사 코드 | 설립자 | Lead Manager 총원 |  Senior Manager 총원 |  Manager 총원 | Employee 총원
을 계산한 테이블을 출력하고, 회사 코드 기준으로 오름차순 정렬

 

풀이

1. Employee 테이블에 설립자를 제외한 각 직급별 데이터가 다 나와 있으므로, Employee 테이블과 Company 테이블만 JOIN하여 COUNT

SELECT 
    C.company_code,
    C.founder,
    COUNT(DISTINCT E.lead_manager_code),
    COUNT(DISTINCT E.senior_manager_code),
    COUNT(DISTINCT E.manager_code),
    COUNT(DISTINCT E.employee_code)
FROM Company C
    LEFT JOIN Employee E ON C.company_code = E.company_code
GROUP BY
    C.company_code,
    C.founder
ORDER BY C.company_code

-- 출력
C1 Angela 1 2 5 13 
C10 Earl 1 1 2 3 
C100 Aaron 1 2 4 10 
C11 Robert 1 1 1 1 
C12 Amy 1 2 6 14 
C13 Pamela 1 2 5 14 
C14 Maria 1 1 3 5 
C15 Joe 1 1 2 3 
C16 Linda 1 1 3 5 
C17 Melissa 1 2 3 7 
C18 Carol 1 2 5 6 
C19 Paula 1 2 4 7 
C2 Frank 1 1 1 3 
C20 Marilyn 1 1 2 2 
C21 Jennifer 1 1 3 7 
C22 Harry 1 1 3 6 
C23 David 1 1 1 2 
C24 Julia 1 1 2 6 
C25 Kevin 1 1 2 5 
C26 Paul 1 1 1 3 
C27 James 1 1 1 3 
C28 Kelly 1 2 5 9 
C29 Robin 1 2 4 9 
C3 Patrick 1 2 2 5 
C30 Ralph 1 1 2 5 
C31 Gloria 1 1 1 3 
C32 Victor 1 2 4 8 
C33 David 1 2 5 12 
C34 Joyce 1 2 6 10 
C35 Donna 1 2 6 12 
C36 Michelle 1 2 5 11 
C37 Stephanie 1 1 2 5 
C38 Gerald 1 2 4 6 
C39 Walter 1 1 3 7 
C4 Lisa 1 1 1 1 
C40 Christina 1 1 3 6 
C41 Brandon 1 2 3 7 
C42 Elizabeth 1 2 4 8 
C43 Joseph 1 2 4 6 
C44 Lawrence 1 1 3 4 
C45 Marilyn 1 1 1 3 
C46 Lori 1 2 3 9 
C47 Matthew 1 2 3 4 
C48 Jesse 1 1 3 3 
C49 John 1 1 3 8 
C5 Kimberly 1 2 3 9 
C50 Martha 1 1 2 5 
C51 Timothy 1 2 5 12 
C52 Christine 1 1 2 2 
C53 Anthony 1 1 1 1 
C54 Paula 1 2 4 7 
C55 Kimberly 1 2 2 3 
C56 Louise 1 1 1 3 
C57 Martin 1 1 2 5 
C58 Paul 1 2 4 8 
C59 Antonio 1 1 2 4 
C6 Bonnie 1 1 2 6 
C60 Jacqueline 1 1 1 2 
C61 Diana 1 1 1 1 
C62 John 1 2 5 11 
C63 Dorothy 1 2 5 7 
C64 Evelyn 1 1 1 2 
C65 Phillip 1 2 4 8 
C66 Evelyn 1 2 4 11 
C67 Debra 1 1 1 3 
C68 David 1 2 5 9 
C69 Willie 1 1 1 3 
C7 Michael 1 1 1 2 
C70 Brandon 1 2 4 7 
C71 Ann 1 2 5 10 
C72 Emily 1 2 3 7 
C73 Dorothy 1 1 1 2 
C74 Jonathan 1 2 4 7 
C75 Dorothy 1 1 2 4 
C76 Marilyn 1 2 5 12 
C77 Norma 1 2 5 10 
C78 Nancy 1 2 3 7 
C79 Andrew 1 1 2 2 
C8 Todd 1 1 1 3 
C80 Keith 1 1 1 2 
C81 Benjamin 1 1 3 9 
C82 Charles 1 1 2 3 
C83 Alan 1 2 3 4 
C84 Tammy 1 1 1 3 
C85 Anna 1 2 4 8 
C86 James 1 1 3 5 
C87 Robin 1 2 3 5 
C88 Jean 1 1 2 3 
C89 Andrew 1 2 4 7 
C9 Joe 1 1 3 6 
C90 Roy 1 1 2 3 
C91 Diana 1 2 2 2 
C92 Christina 1 1 1 3 
C93 Jesse 1 1 2 2 
C94 Joyce 1 2 5 13 
C95 Patricia 1 1 3 5 
C96 Gregory 1 1 2 2 
C97 Brian 1 1 1 1 
C98 Christine 1 1 2 5 
C99 Lillian 1 1 2 6

 

 2. Employee 테이블에는 Lead Manager나 Senior Manager, Manager 중 하위 직급이 없는 사람에 대한 정보가 없으므로 완벽한 정보를 가지지 않을 수 있으므로, 상위 직급의 테이블도 연쇄적으로 JOIN하여 누락을 방지할 필요가 있음

SELECT 
    C.company_code,
    C.founder,
    COUNT(DISTINCT L.lead_manager_code),
    COUNT(DISTINCT S.senior_manager_code),
    COUNT(DISTINCT M.manager_code),
    COUNT(DISTINCT E.employee_code)
FROM Company C
    LEFT JOIN Lead_Manager L ON C.company_code = L.company_code
    LEFT JOIN Senior_Manager S ON L.company_code = S.company_code
    LEFT JOIN Manager M ON L.company_code = M.company_code
    LEFT JOIN Employee E ON L.company_code = E.company_code
GROUP BY
    C.company_code,
    C.founder
ORDER BY C.company_code

-- 출력
C1 Angela 1 2 5 13 
C10 Earl 1 1 2 3 
C100 Aaron 1 2 4 10 
C11 Robert 1 1 1 1 
C12 Amy 1 2 6 14 
C13 Pamela 1 2 5 14 
C14 Maria 1 1 3 5 
C15 Joe 1 1 2 3 
C16 Linda 1 1 3 5 
C17 Melissa 1 2 3 7 
C18 Carol 1 2 5 6 
C19 Paula 1 2 4 7 
C2 Frank 1 1 1 3 
C20 Marilyn 1 1 2 2 
C21 Jennifer 1 1 3 7 
C22 Harry 1 1 3 6 
C23 David 1 1 1 2 
C24 Julia 1 1 2 6 
C25 Kevin 1 1 2 5 
C26 Paul 1 1 1 3 
C27 James 1 1 1 3 
C28 Kelly 1 2 5 9 
C29 Robin 1 2 4 9 
C3 Patrick 1 2 2 5 
C30 Ralph 1 1 2 5 
C31 Gloria 1 1 1 3 
C32 Victor 1 2 4 8 
C33 David 1 2 5 12 
C34 Joyce 1 2 6 10 
C35 Donna 1 2 6 12 
C36 Michelle 1 2 5 11 
C37 Stephanie 1 1 2 5 
C38 Gerald 1 2 4 6 
C39 Walter 1 1 3 7 
C4 Lisa 1 1 1 1 
C40 Christina 1 1 3 6 
C41 Brandon 1 2 3 7 
C42 Elizabeth 1 2 4 8 
C43 Joseph 1 2 4 6 
C44 Lawrence 1 1 3 4 
C45 Marilyn 1 1 1 3 
C46 Lori 1 2 3 9 
C47 Matthew 1 2 3 4 
C48 Jesse 1 1 3 3 
C49 John 1 1 3 8 
C5 Kimberly 1 2 3 9 
C50 Martha 1 1 2 5 
C51 Timothy 1 2 5 12 
C52 Christine 1 1 2 2 
C53 Anthony 1 1 1 1 
C54 Paula 1 2 4 7 
C55 Kimberly 1 2 2 3 
C56 Louise 1 1 1 3 
C57 Martin 1 1 2 5 
C58 Paul 1 2 4 8 
C59 Antonio 1 1 2 4 
C6 Bonnie 1 1 2 6 
C60 Jacqueline 1 1 1 2 
C61 Diana 1 1 1 1 
C62 John 1 2 5 11 
C63 Dorothy 1 2 5 7 
C64 Evelyn 1 1 1 2 
C65 Phillip 1 2 4 8 
C66 Evelyn 1 2 4 11 
C67 Debra 1 1 1 3 
C68 David 1 2 5 9 
C69 Willie 1 1 1 3 
C7 Michael 1 1 1 2 
C70 Brandon 1 2 4 7 
C71 Ann 1 2 5 10 
C72 Emily 1 2 3 7 
C73 Dorothy 1 1 1 2 
C74 Jonathan 1 2 4 7 
C75 Dorothy 1 1 2 4 
C76 Marilyn 1 2 5 12 
C77 Norma 1 2 5 10 
C78 Nancy 1 2 3 7 
C79 Andrew 1 1 2 2 
C8 Todd 1 1 1 3 
C80 Keith 1 1 1 2 
C81 Benjamin 1 1 3 9 
C82 Charles 1 1 2 3 
C83 Alan 1 2 3 4 
C84 Tammy 1 1 1 3 
C85 Anna 1 2 4 8 
C86 James 1 1 3 5 
C87 Robin 1 2 3 5 
C88 Jean 1 1 2 3 
C89 Andrew 1 2 4 7 
C9 Joe 1 1 3 6 
C90 Roy 1 1 2 3 
C91 Diana 1 2 2 2 
C92 Christina 1 1 1 3 
C93 Jesse 1 1 2 2 
C94 Joyce 1 2 5 13 
C95 Patricia 1 1 3 5 
C96 Gregory 1 1 2 2 
C97 Brian 1 1 1 1 
C98 Christine 1 1 2 5 
C99 Lillian 1 1 2 6

'SQL' 카테고리의 다른 글

[HackerRank] Weather Observation Station 18(MySQL)  (0) 2024.05.18
[HackerRank] Occupations(MySQL)  (0) 2024.04.08
[HackerRank] Occupations(MySQL)  (0) 2024.04.01
[HackerRank] The PADS(MySQL)  (0) 2024.03.20

새로 생긴 경영정보시각화능력 자격증을 준비하기 위해 이기적을 찾았습니다. IT 관련 자격증을 준비할 때 언제나 찾아보던 이기적 출판사에서 나온 책이라 믿고 보기로 하였습니다.

 경영정보시각화능력 자격증은 회계, 재무, 마케팅 등 경영과 관련된 정보와 데이터 관련 내용, 그리고 이런 정보들을 효과적으로 시각화하여 경영을 도울 수 있는 능력을 시험하는 자격증입니다. 데이터 분석을 진행하며 시각화는 정말 중요한 한 부분이라고 생각하여 자격증을 준비하며 시각화 능력을 기르는 것은 좋은 기회라고 생각하였습니다.

책의 두께는 별로 두껍지 않습니다. 자격증 시험은 딥하게 들어갈 필요없이 합격을 위해 필요한 부분만 있으면 된다고 생각하기 때문에 이런 두께는 환영입니다.

 

 책의 목차는 다음과 같이 구성되어 있습니다.

 

 이번에 처음 시행되는 시험이라 다소 생소할 수도 있는 경영정보시각화 능력 자격증에 대한 정보도 상세하게 설명해주어 더 검색할 필요없이 공부에만 집중할 수 있었습니다.

 

책에는 기본 이론은 물론 '기적의 Tip'을 페이지마다 설명해주어 놓치는 부분없이 공부할 수 있었습니다.

 

각 장의 마무리는 배운 개념을 체크할 수 있는 문제들로 구성되어 한 번 더 확인하고 복습할 수 있었습니다.

 

 예상문제 또한 시험에 대한 정보가 없는 상황에서 큰 도움이 되는 파트였습니다. 이미 다른 IT 관련 자격증의 문제집을 담당해온 이기적 출판사에서 내준 예상문제라면 더 신뢰성 있어보입니다.

 

 책의 마지막 장에는 기출 예상문제로 구성되어있습니다. 실제 시험과 비슷한 형식으로, 공부를 다 하고, 시험 친다고 생각하고 실전 연습을 해볼 수도 있고, 시험에 대한 정보가 없는 상황에서 가장 비슷하게 시험을 경험해볼 수 있을 것 같습니다.

 이기적 경영정보시각화능력 자격증 필기 문제집과 함께 다같이 한 번에 합격할 수 있었으면 좋겠습니다~!

문제

"노드" || "노드의 부모"로 구성된 테이블에서

- Root: root node

- Leaf: leaf node

- inner: neither root node nor leaf node

구분하여 node 오름차순으로 정렬

 

Sample Output

1 Leaf
2 Inner
3 Leaf
5 Root
6 Leaf
8 Inner
9 Leaf

 

풀이

1. P가 null이면 root node 이다.

CASE WHEN P IS NULL THEN 'Root'

2. N 중에 P에도 값이 있는 node는 누군가의 부모이므로 leaf node가 될 수 없다. root node도 아니기에 inner node이다.

CASE WHEN N IN (SELECT DISTINCT P FROM BST) THEN 'Inner'

3. 그 외에는 전부 leaf node이다.

CASE ELSE 'Leaf'

4. 종합하여 N과 함께 출력하고 N을 기준으로 오름차순으로 정렬한다.

SELECT
    N,
    (CASE
        WHEN P IS NULL THEN 'Root'
        WHEN N IN (SELECT DISTINCT P FROM BST) THEN 'Inner'
        ELSE 'Leaf'
    END) AS position
FROM BST
ORDER BY N

 

'SQL' 카테고리의 다른 글

[HackerRank] Weather Observation Station 18(MySQL)  (0) 2024.05.18
[HackerRank] New Companies(MySQL)  (0) 2024.05.11
[HackerRank] Occupations(MySQL)  (0) 2024.04.01
[HackerRank] The PADS(MySQL)  (0) 2024.03.20

문제

"이름" || "직업"으로 구성된 테이블에서

1열: 직업이 Doctor인 사람 이름 (오름차순 정렬)

2열: 직업이 Professor인 사람 이름 (오름차순 정렬)

3열: 직업이 Singer인 사람 이름 (오름차순 정렬)

4열: 직업이 Actor인 사람 이름 (오름차순 정렬)

직업 별 이름의 최대 개수 이하인 열에서 빈 셀은 Null로 출력

 

Sample Output

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

 

'SQL' 카테고리의 다른 글

[HackerRank] Weather Observation Station 18(MySQL)  (0) 2024.05.18
[HackerRank] New Companies(MySQL)  (0) 2024.05.11
[HackerRank] Occupations(MySQL)  (0) 2024.04.08
[HackerRank] The PADS(MySQL)  (0) 2024.03.20

문제

 

"이름" || "직업" 으로 구성된 테이블에서

1. "이름 (직업의 첫 글자)" 형태로 추출(이름 오름차순)

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.

'SQL' 카테고리의 다른 글

[HackerRank] Weather Observation Station 18(MySQL)  (0) 2024.05.18
[HackerRank] New Companies(MySQL)  (0) 2024.05.11
[HackerRank] Occupations(MySQL)  (0) 2024.04.08
[HackerRank] Occupations(MySQL)  (0) 2024.04.01

● 퍼셉트론

1. 초기 머신러닝의 역사

 - Warren McCulloch과 Walter Pits가 뇌의 뉴런 개념을 발표

   (MCP 뉴런 - 신경 세포를 이진 출력을 내는 간단한 논리 회로로 표현)

 - Frank Rosenblatt는 MCP 뉴런 모델을 기반으로 퍼셉트론 학습 개념을 발표

 - 퍼셉트론 규칙에서 자동으로 최적의 가중치를 학습하는 알고리즘 제안

 - 가중치는 뉴런의 출력 신호를 낼지 말지 결정하기 위해 입력 특성에 곱하는 계수

 - 지도학습분류 문제에서 퍼셉트론 알고리즘을 사용하여 새로운 데이터가 한 클래스에 속하는지 아닌지 예측 가능

 

2. 인공 뉴런의 수학적 정의

 - 두 클래스를 1과 -1로 나타냄

 - 입력값 \(x\)와 가중치 벡터 \(w\)의 선형 조합으로 결정함수 \(\phi(z)\) 정의

$$z = w_{1}x_{1} + w_{2}x_{2} + \cdots + w_{m}x_{m}$$

$$w = \begin{bmatrix} w_{1} \\ \vdots  \\ w_{m} \end{bmatrix}, x= \begin{bmatrix} x_{1} \\ \vdots  \\ x_{m} \end{bmatrix}$$

 - 특정 샘플 \(x\)의 최종 입력이 사전 정의된 임계값 \(\theta\)보다 크면 클래스 1, 아니면 클래스 -1로 예측

$$\phi(z) = \begin{cases} 1 & z \geq \theta \\ -1 & 그외 \end{cases}$$

 - \(z \geq \theta\) 식에서 \(\theta\)를 왼쪽으로 넘겨 \(w_{0}=-\theta\)이고, \(x_{0}=1\)인 0번째 가중치를 정의하여 식 간소화

$$z = w_{0}x_{0} + w_{1}x_{1} + \cdots + w_{m}x_{m} = w^{T}x$$

 - 결정함수는 다음과 같이 변경

$$\phi(z) = \begin{cases} 1 & z \geq 0 \\ -1 & 그외 \end{cases}$$

 - \(w_{0} = -\theta\)를 절편이라고 함

퍼셉트론의 결정함수와 결정 경계

 

3. 퍼셉트론 학습 규칙

 - 뇌의 뉴런 하나가 작동하는 방식을 흉내내는 환원주의 접근 방식 사용

  1. 가중치를 0 또는 랜덤한 작은 값으로 초기화
  2. 각 훈련 샘플 \(x^{(i)}\)에서 다음 작업 수행
    1. 출력 값 \(\hat{y}\) 계산
      → 출력값은 계단 함수로 예측한 클래스 레이블
    2. 가중치 업데이트
      \(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를 지정하지 않는한 가중치 업데이트가 멈추지 않음

 데이터 분석을 공부하며 네트워크 트래픽을 추출하고 분석해 BI를 창출하는 일에 관심이 있습니다. 네트워크를 모니터링하고 운영하는 일을 배우는데 좋은 기회가 될 것 같아 책을 보게 되었습니다. 데이터 분석 결과를 공유하기 위한 웹사이트 개발을 하고 이후에 보안 위협 탐지를 공부하는데도 프로토콜 지식이 필수 일 것 같아  이 책을 통해 배워볼 수 있을 것 같았습니다.

 

 책의 목차는 다음과 같습니다

1장 네트워크의 개요

01 네트워크의 기본
02 네트워크의 역사
03 네트워크 프로토콜
04 프로토콜과 데이터의 흐름
05 네트워크를 구성하는 장치
06 패킷을 캡처해 보자

2장 통신에 필수적인 프로토콜

07 이더넷의 기본
08 이더넷 패킷을 캡처해 보자
09 IPv4의 기본
10 IPv4의 패킷 형식
11 IPv4 주소
12 IPv4의 주소 분류
13 IPv6의 기본
14 IPv6 주소

3장 통신의 신뢰성을 뒷받침하는 프로토콜

15 TCP의 기본
16 TCP 헤더 형식의 기본
17 TCP 커넥션의 흐름
18 TCP 패킷을 캡처해 보자
19 UDP의 기초

4장 일상에서 사용하는 인터넷을 지원하는 프로토콜

20 HTTP와 HTTPS
21 HTTP와 HTTPS의 패킷을 캡처해 보자
22 DNS의 기본
23 SMTP
24 POP, IMAP
25 PPPoE와 IPoE

5장 네트워크를 지원하는 기술

26 DHCP의 기본
27 NAT, NAPT의 기본
28 NTP의 기본
29 ARP의 기본
30 라우팅 프로토콜
31 TELNET, SSH
32 SNMP
33 FTP
34 ICMP

6장 물리 계층과 관련된 기술

35 프로토콜과 물리 계층의 관계
36 LAN 케이블
37 광섬유 케이블
38 무선 LAN

7장 보안에 관련된 기술

39 정보 보안의 기본
40 SSL/TLS
41 VPN
42 다양한 VPN
43 제로 트러스트

 

 책의 가장 좋은 점은 그림을 통해 이해하기 쉽게 설명해준다는 점이었습니다. 공부하려는 분야가 네트워크인만큼 인터넷과 라우터, 스위치 그리고 데스크톱이나 서버 간의 연결 관계가 중요해보이는데 이러한 점을 그림으로 설명하니 머릿속에 구조가 더 잘 들어왔습니다.

 

 각 장의 마지막에는 연습문제를 통해 배운 것을 복습하고 확인하며 확실히 기억할 수 있도록 도와주었습니다.

 

 앞으로 데이터 분석을 공부하면서도 계속 네트워크와 프로토콜의 구조에 대해서도 공부하며 학문의 분야를 넓히고, 둘을 결합하여 더 방대한 데이터를 분석하는 데이터 분석가가 될 수 있을 것 같습니다.

+ Recent posts