파이썬으로 배우는 딥러닝 교과서 - 이미지 인식 모델을 만들면서 익히는 딥러닝 파이썬으로 배우는 교과서
이시카와 아키히코 지음, 박광수 옮김 / 한빛미디어 / 2020년 3월
평점 :
절판


파이썬으로 배우는 딥러닝 교과서

결론부터 시작하자. 추천할만한가? 그렇다.

목차에서 볼 수 있듯이 한 권의 책에 많은 내용을 넣으려고 해서 좀 산만하다는 느낌이 있다. 대충 나눠도 머신러닝 기초, 파이썬 기초, numpy/pandas, 데이터 시각화, 딥러닝 등 각각 책으로 나올 영역들을 굉장히 많이 다룬다.

하지만 지은이가 초보자를 대상으로 책을 썼다고 밝히고 있으며(그래서 파이썬 문법을 다룸), 최근 전공자가 아닌 사람들도 딥러닝에 관심을 갖는다는 점을 생각하면 한 권으로 다양한 영역을 함께 다루면서 시작할 수 있다는 걸 장점으로 볼 수 있다. 0장의 설치 부분만 넘어서면 예제 코드를 설명하려는 부분만 쓰지 않고 한 예제마다 완결성있게 필요한 부분을 모두 써 넣었기 때문에(예를 들어 필요한 import를 각 예제마다 모두 넣어두거나 심지어는 연습문제로 import _____ as __와 같이 빈 칸을 채우는 문제도 있다), 이런 사소한 부분도 초보자에게는 좋다고 생각하며, 예제들이 (최소한 내가 직접 해본 부분들은) 다 정상 동작한다는 점도 좋았다(의외로 예제를 그대로 따라해도 안 되는 경우가 있는 책들이 종종 있다).

다만 챕터가 주제별로 나뉘어져 있지 않아 개인적으로는 다음과 같은 순서로 보는 게 이해가 더 쉬울 거 같다.

  1. 파이썬 기초; 4~6장 및 13장. 13장은 초급이라고 보긴 힘들지만 파이썬 문법에 관한 부분이기 때문에 같이 묶었다
  2. libraries(numpy, pandas, opencv); 7~9장, 14장 및 15장
  3. 데이터 시각화; 10~12장
  4. 머신러닝 기초; 1~3장 및 16장. 이론
  5. 딥러닝; 17~22장

대부분의 프로그래밍 책이 그렇지만 특히 이 책은 초보자 대상이기 때문에 다 본다고 해서 어떤 영역에 대해 전문가가 되는 게 아니며, 실무에 바로 적용하기도 어렵다. 하지만 이런 부분을 하나씩 쌓아가는데 도움이 될 책은 분명하다.

0장

책에서는 windows에서 했지만 나는 mac이라서 anaconda update 후 다음 버전에서 예제를 진행했다.

❯ /usr/local/anaconda3/bin/python
Python 3.7.4 (default, Aug 13 2019, 15:17:50)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

anaconda부터 설치가 필요하면 https://repo.anaconda.com/archive에서 받아서 설치 가능하다.

anaconda navigator를 따라 진행하는데, 다만 나의 경우 python version은 3.7이었고 이어서 가상 환경에서 터미널을 열라고 해서 따라서 했지만 다음과 같이 오류가 발생했다.

내가 따로 수정을 하고 다시 클릭을 해봤지만 똑같은 오류가 발생해서 살펴보니 클릭을 할 때 자동으로 a.tool을 생성하는 방식이라 내가 수정을 해도 아무 효과가 없었다.

❯ /usr/local/anaconda3/bin/conda create -n venv python=3.7 anaconda
❯ /usr/local/anaconda3/bin/conda init zsh
# 터미널을 새로 시작
(base) base ❯ conda activate venv
venv ❯

conda init 명령어로 default로 (base) base >와 같이 prompt가 바뀌는 건 다음 명령으로 해제할 수 있다(https://stackoverflow.com/questions/54429210/how-do-i-prevent-conda-from-activating-the-base-environment-by-default).

conda config --set auto_activate_base false 

현재 사용하는 anaconda python 3.7.7 버전에서, 1장에 나와있는 설치가 필요한 library는 다음과 같이 실행하면 설치할 수 있다(이외에는 이미 설치되어 있음). 나는 일부러 전부 최신으로 설치했지만, 책의 예제를 그대로 따라하고 싶다면 버전까지 일치시켜 설치하는게 더 좋다.

venv ❯ pip install tensorflow
venv ❯ pip install keras
venv ❯ conda install opencv
venv ❯ conda install pydot

이제 anaconda navigator를 시작하고 Environments에 가서 위에서 만든 가상환경을 선택하고 새 jupyter note를 시작해봤으나 설치된 library가 제대로 동작하지 않았다.

그래서 다음과 같이 jupyter lab 시작하고

venv ❯ jupyter lab

0장에 나온 library들을 모두 import 할 수 있는지 확인해본 결과 다음과 같이 문제 없음을 확인하고 책을 읽기 시작했다.

jupyter lab 실행 결과 몇 가지

10장 데이터 시각화

11장 matplotlib

12장 다양한 그래프 그리기

15장 OpenCV 이용 및 이미지 데이터 전처리

18장 하이퍼파라미터와 튜닝(2)

20장 딥러닝 튜닝

22장 CNN을 이용한 이미지 인식 응용



댓글(0) 먼댓글(0) 좋아요(0)
좋아요
공유하기 북마크하기찜하기 thankstoThanksTo
 
 
 
그로킹 딥러닝 - 알기 쉬운 비유와 기초 수학으로 시작하는
앤드루 트라스크 지음, 박상현 옮김 / 한빛미디어 / 2019년 12월
평점 :
절판



서문을 읽으면서 좀 과장된 표현을 한다고 생각을 했다. 다른 딥 러닝 책들도 그렇지만 수학을 몰라도 혹은 기초 수준만 알아도 딥러닝을 이해할 수 있게 한다는 이야기는, 모든 프로그래밍 언어가 배우기 쉽다면서 hello world를 출력하는 데서 시작하는 경우와 마찬가지이다. 예제를 따라하면서 실행을 해볼 때 터미널이나 jupyter notebook에서 숫자가 출력되는 걸 보면 내가 정말로 뭔가를 하는 듯한 느낌을 가지기는 쉽지만, 실제 업무를 하려고 하면 하나부터 열까지 간단한 게 없다.

사실 업무는 둘째치고 책의 예제를 따라하는 거 조차 쉽지 않은 경우도 많다. 머신 러닝, 딥 러닝의 경우 프레임워크가 워낙 많이 발전하고 도커를 비롯한 컨테이너 기술의 발점에 힘입어 예전보다는 확실히 쉬워졌지만, 그래도 종종 커뮤니티에서 따라해보려고 이걸 했는데 오류가 나면서 설치가 안 된다고 문의하는 글을 종종 볼 수 있다.

그런 면에서 이 책은 일단 장점을 갖는다. python과 numpy만 설치하면 예제를 실행할 수 있기 때문에 복잡한 설치 과정으로 시작 전부터 진을 뺄 필요가 없다. 이미 anaconda같은 걸 설치했다면 그냥 시작해도 된다.

1, 2장은 일반적인 설명이고 3장부터 코드와 함께 시작한다. 3~7장까지는 비교적 쉽게 쫓아갈 수 있고 설명도 어느 정도 이해하기 쉽다. 초반부는 정말 지금까지 읽은 책들 중에서 가장 비유를 제대로 사용한 설명이라는 생각이 들었다. 다이얼을 돌리는 그림을 통해 가중치를 변경하는 이야기를 하는데, 간단한 그림을 추가했을 뿐이지만 개인적으로는 꽤 효과가 좋은 방법이었단 생각이 든다. 8장부터는 좀 난이도가 올라간다. 11장부터는 NLP를 통해 여러 가지를 이야기하는데(word embedding, bag of words, LSTM/RNN, …) 아마 저자가 NLP 연구자라서 이렇게 선택을 한 거 같은데 분량에 비해 주제가 커서 후반부는 나 같은 초보자는 사실 그냥 읽는 거도 쉽지 않았다. 15장은 featured learning 소개나 마찬가지이고, 16장은 이 책을 읽은 뒤 할 수 있는 여러가지 학습 방법/자료를 소개한다.

이 책의 장점은 명확하다. 정말로 초보자가 비교적 적은 기반 지식으로도 따라갈 수 있는 설명을 한다는 점이다. 후반부로 가면 어려워지는 건 모든 분야/서적을 막론하고 똑같은 부분이므로 개인적인 노력이 필요하기 때문에 어쩔 수 없다는 생각이다.

Etc.

1장을 보면 저자가 딥 러닝 공부와 함께 이 책을 쓰면서, 옥스퍼드 대학 박사에 진학을 했다고 썼다. 그냥 저자가 똑똑한 놈이라서 그렇다는 편견을 가지고 시작했는데(그런데 이건 편견이 아니라 사실이다. 프로그래밍을 조금 하던 수준에서 18개월 만에 헤지펀드 연구 보조금에 자신의 딥러닝 지식을 적용했다고 썼다) 읽으면서 왠지 저자의 이름이 익숙하단 생각이 들었다. imtrask.github.io와 11줄로 neural network 만들기를 썼던 앤드류 트라스크란 걸 알고 갑자기 믿음이 가고 좀 더 책에 흥미가 가서 더 관심을 갖고 읽었다.

또 하나, amazon.com을 보면 8장의 relu 함수를 잘못 쓰면서 8, 9장의 예제가 모두 문제가 있다는 서평이 있다(https://www.amazon.com/gp/customer-reviews/R16NVHI60Y2F7D/ref=cm_cr_arp_d_rvw_ttl?ie=UTF8&ASIN=1617293709). 8장의 relu나 relu2deriv 함수가 정말 간단하긴 한데, 각 함수의 정의에 비춰볼 때 뭐가 잘못된 건지는 잘 이해가 가지 않는다. tensorflow나 keras source를 봐도 alpha나 max value등의 부가 변수 설정에 관계된 코드를 제외하면 결국 원래 정의대로 따라가는 듯 싶은데, 잘못되었다고 주장하는 부분에 대한 설명이 부족해 어떤 문제가 있다는 건지는 잘 이해할 수 없었다. 하지만 이렇게 평을 하는 사람조차도 7장까지는 매우 좋았다고 쓴 걸 보면 확실히 초반부는 다른 책에 비해 강점이 있다는 생각이 든다.

Ref.

저자가 책이 예제를 jupyter notebook으로 github에 올려뒀다. repository를 clone하면 docker-composer.yml이 있기 때문에 이미 docker를 설치한 경우 다음과 같이 실행해서 jupyter notebook을 시작할 수 있다.

❯ docker-compose up
Creating network "grokking-deep-learning_default" with the default driver
Pulling jupyter (jupyter/tensorflow-notebook:)...
latest: Pulling from jupyter/tensorflow-notebook
423ae2b273f4: Pull complete
...
701d9053a78b: Pull complete
Digest: sha256:59ccc48a299ed7612f89a172268f6ce849d1d5848db7c48412272fc9e311f3d8
Status: Downloaded newer image for jupyter/tensorflow-notebook:latest
Creating jupyter ... done
Attaching to jupyter
jupyter | Executing the command: jupyter lab --NotebookApp.token=''
jupyter | [I 13:43:09.793 LabApp] Writing notebook server cookie secret to /home/jovyan/.local/share/jupyter/runtime/notebook_cookie_secret
jupyter | [W 13:43:10.186 LabApp] All authentication is disabled. Anyone who can connect to this server will be able to run code.
jupyter | [I 13:43:10.680 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
jupyter | [I 13:43:10.680 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
jupyter | [I 13:43:10.683 LabApp] Serving notebooks from local directory: /home/jovyan
jupyter | [I 13:43:10.683 LabApp] The Jupyter Notebook is running at:
jupyter | [I 13:43:10.683 LabApp] http://f7dd26013306:8888/
jupyter | [I 13:43:10.683 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

browser를 열고 localhost:8888에 접속하면 다음과 같이 예제를 실행할 수 있는 jupyter lab을 사용할 수 있다.

다만 예제에서 dataset을 위해 keras 설치가 필요한 경우가 있는데(예를 들어 8장) 어쩐 일인지 docker-compose.yml에서 keras가 설치되지 않은 image를 사용하고 있어서 keras dataset를 사용하는 예제(mnist)를 실행하기 위해서는 결국 keras가 필요하다.


댓글(0) 먼댓글(0) 좋아요(1)
좋아요
공유하기 북마크하기찜하기 thankstoThanksTo
 
 
 
다이내믹 프로그래밍 완전 정복 - 빠르고 우아한 상향식 문제 풀이법
미나크시.카말 라와트 지음, 박상은 옮김 / 한빛미디어 / 2019년 10월
평점 :
장바구니담기


나름대로 꾸준히 알고리즘 문제를 풀기는 하지만, 항상 어려운 부분이 있는데 그 중 하나가 DP, dynamic programming이다. 밀접한 관계에 있는 재귀는 비교적 쉬운데 왜 DP는 항상 어려운지 잘 모르겠는데(아마 노력이 부족해서겠지) 이번에 그걸 보완할만한 책이 있어 읽어보게 되었다. 책을 읽으면서 나름대로 연습을 해서 그런지 읽고 난 후 약간 DP에 대한 자신감이 생기는 느낌이다. 실제 문제를 풀어봐야 확실해지겠지만. 개인적인 연습 코드는 python3로 작성했다.

Chapter 1

완전히 초보자를 위한 재귀에 대한 소개. 재귀 자체에 대한 이해도 필요하지만, 메모리 내부에서 재귀 호출이 어떻게 메모리를 할당하고 해제하는지 컴퓨터 구조의 측면에서 이해하는 부분도 중요하다는 점을 알려준다.

Chapter 2

재귀 호출에 대해 좀 더 설명을 한다. 우선 피보나치 수열과 matrix를 이용해 범위를 줄여 계산하는 종류의 문제가 재귀와 DP에 적합하다는 점을 설명한다. 그 다음으로 메모 전략(memoization)을 설명하는 데 이해하고 사용하기는 쉽지만 이것만으로도 인터뷰에서 꽤 쓸만한 성과를 낼 수 있기 때문에(특히 온라인 문제 풀이의 경우) 혹시라도 몰랐다면 매우 유용한 방법이다.

# p68, 역 사이 최소 비용 구하기
def minCost(cost, s, d):
if d == s:
return 0
if d - s == 1:
return cost[s][d]
minRes = cost[s][d]
for i in range(s + 1, d):
minRes = min(minCost(cost, s, i) + minCost(cost, i, d), minRes)
return minRes

Chapter 3

드디어 DP이다. 앞서 살펴봤던 피보나치 수열과 matrix를 이용해 역간 이동 비용을 계산하는 문제를 DP로 해결하면 시간 복잡도가 줄어든다는 걸 설명한다. 그리고 부분 문자열 문제를 이용해 본격적인 설명을 한다. 재귀와 DP의 차이는 하향식이냐 상향식이냐의 차이인데, 이걸 피보나치 수열을 통해 더 자세히 설명한다. 아마 이 부분이 이 책에서 가장 중요하지 않을까 싶은데(최소한 나에게는 그렇다), 재귀와 비슷하면서도 차이가 있는 부분을 인식해야 각각에 알맞은 방법을 찾을 수 있기 때문이다. 마지막으로 드물지만 상향식 프로그래밍(DP)가 하향식에 비해 덜 효율적인 경우에 대해 설명하고 이번 장을 마친다.

# p89, 부분 문자열 다루기
class Solution:
# recursive
def maxEqualSumLen0(self, s: str) -> int:
if s is None or 0 == len(s):
return 0
def getMaxEqualSumLen(l):
m = len(l) // 2
if sum(l[:m]) == sum(l[m:]):
return 2 * m
return max(getMaxEqualSumLen(l[2:]), getMaxEqualSumLen(l[1:-1]), getMaxEqualSumLen(l[:-2]))
l = list(int(c) for c in s)
if len(l) % 2 == 0:
return getMaxEqualSumLen(l)
return max(getMaxEqualSumLen(l[:-1]), getMaxEqualSumLen(l[1:]))

Chapter 4

DP에 익숙해지기 위해 재귀, 메모, DP의 세 가지 방법을 한 가지 문제(2 * 2 matrix에서 최소 비용으로 이동하기)에 대해 설명하고 예제를 소개한다. 이어서 3가지 예제를 통해 DP에 대해 더 설명하는데, 책에도 나와있듯이 실제 면접에서 사용될만한 난이도의 문제들이라 아주 좋은 연습이 된다.

# p105, 행렬에서 최소 이동 비용 구하기
class Solution:
def minCost(self, grid: List[List[int]]) -> int:
if grid is None or 0 == len(grid) or 0 == len(grid[0]):
return 0
R, C = len(grid), len(grid[0])
cost = [[0] * C for _ in range(R)]
cost[0][0] = grid[0][0]
for r in range(1, R):
cost[r][0] = cost[r - 1][0] + grid[r][0]
for c in range(1, C):
cost[0][c] = cost[0][c - 1] + grid[0][c]
for r in range(1, R):
for c in range(1, C):
cost[r][c] = min(cost[r - 1][c], cost[r][c - 1]) + grid[r][c]
return cost[-1][-1]
# p120, 특정 점수에 도달하는 경우의 수 구하기
class Solution:
def countWaysRecur(self, num):
if num == 0:
return 0
def count(n):
if 0 == n:
return 1
if n < 3:
return 0
cnt = 0
for c in [3, 5, 10]:
if c <= n:
cnt += count(n - c)
return cnt
return count(num)def countWaysDP(self, num):
if num == 0:
return 0
dp = [0] * (num + 1)
dp[0] = 1
for i in range(1, len(dp)):
for c in [3, 5, 10]:
if c <= i:
dp[i] += dp[i - c]
return dp[-1]
# p122, 연속된 부분 배열의 최댓값 구하기
class Solution:
def maxSubSumArray(self, arr: List[int]) -> int:
if arr is None or 0 == len(arr):
return 0
if 1 == len(arr):
return arr[0]
maxSum, subSum = 0, [0] * len(arr)
for i, a in enumerate(arr):
curSum = subSum[i - 1] + a
if curSum <= 0:
continue
subSum[i] = curSum
maxSum = max(maxSum, curSum)
return maxSum

Chapter 5

여러가지 문제를 통해 DP에 익숙해지는 연습이다. 문제 풀이 연습 사이트들에서 볼 수 있는, 면접에 나올 가능성이 있는 문제들이다. 개인적으로는 마지막 문제가 가장 기억에 남는데, 수년 전 가고 싶던 회사에서 저 문제를 못 풀어서 떨어졌던 기억이 나기 때문이다. 당시에는 영어 설명부터가 머리에 들어오지 않아 DP 문제라는 생각조차 못했다. 여러 문제 풀이 연습 사이트에서 세부 주제별 문제 분류를 제공하니(i.e. https://leetcode.com/tag/dynamic-programming/) 추가로 연습을 진행하면 더 좋을 것이다.

# p130, 최소 교정 비용 문제
class Solution:
def minEditNum(self, s1: str, s2: str) -> int:
if (s1 is None or 0 == len(s1)) and (s2 is None or 0 == len(s2)):
return 0
if s1 is None or 0 == len(s1):
return len(s2)
if s2 is None or 0 == len(s2):
return len(s1)
R, C = len(s1), len(s2)
grid = [[0] * (C + 1) for _ in range(R + 1)]
for r in range(1, R + 1):
for c in range(1, C + 1):
if s1[r - 1] == s2[c - 1]:
grid[r][c] = 1 + grid[r - 1][c - 1]
else:
grid[r][c] = max(grid[r - 1][c], grid[r][c - 1])
return max(R, C) - grid[-1][-1]
# p152, 부분집합의 합 구하기
class Solution:
def minEditNum(self, s1: str, s2: str) -> int:
if (s1 is None or 0 == len(s1)) and (s2 is None or 0 == len(s2)):
return 0
if s1 is None or 0 == len(s1):
return len(s2)
if s2 is None or 0 == len(s2):
return len(s1)
R, C = len(s1), len(s2)
grid = [[0] * (C + 1) for _ in range(R + 1)]
for r in range(1, R + 1):
for c in range(1, C + 1):
if s1[r - 1] == s2[c - 1]:
grid[r][c] = 1 + grid[r - 1][c - 1]
else:
grid[r][c] = max(grid[r - 1][c], grid[r][c - 1])
return max(R, C) - grid[-1][-1]
# p171, 거스름돈 최적화
class Solution:
def minCoins(self, coins: List[int], money: int) -> int:
if coins is None or 0 == len(coins):
return 0
dp = [float('inf')] * (money + 1)
dp[0] = 0
for m in range(1, money + 1):
for coin in coins:
if m < coin:
continue
elif m == coin:
dp[m] = 1
else:
if dp[m - coin] > 0:
dp[m] = min(dp[m], 1 + dp[m - coin])
return dp[-1]
# p176, 철근 자르기
class Solution:
def maxProfitRecur(self, costs: List[int], length: int) -> int:
if costs is None or 0 == len(costs):
return 0
def getMaxProfit(acc, _costs, _length):
if _length == 0:
return acc
if _length < 0:
return 0
subProfit = 0
for rodLen, cost in _costs:
if rodLen > _length:
continue
acc += cost
curProfit = getMaxProfit(acc, _costs, _length - rodLen)
subProfit = max(subProfit, curProfit)
acc -= cost
return subProfit
return getMaxProfit(0, [(i + 1, cost) for i, cost in enumerate(costs)], length)def maxProfit(self, costs: List[int], length: int) -> int:
if costs is None or 0 == len(costs):
return 0
dp = [[0, 0]] * (length + 1)
dp[0] = [0, 0]
for d in range(1, length + 1):
for i, cost in enumerate(costs):
rodLen = i + 1
if d < rodLen:
continue
candCost = dp[d - rodLen][1] + cost
if dp[d][1] < candCost:
dp[d] = [dp[d - rodLen][0] + 1, candCost]
return dp[-1][1]
# p187, 최장 회문 부분 수열의 길이
class Solution:
def maxPalindromeLen(self, s: str) -> int:
if s is None or 0 == len(s):
return 0
R = C = len(s)
rStr, grid = s[::-1], [[0] * (C + 1) for _ in range(R + 1)]
for r in range(1, R + 1):
for c in range(1, C + 1):
if s[c - 1] == rStr[r - 1]:
grid[r][c] = 1 + grid[r - 1][c - 1]
else:
grid[r][c] = max(grid[r - 1][c], grid[r][c - 1])
return grid[-1][-1]

한국어판 부록 A

알고리즘 서적에는 항상 빠지지 않는 시간/공간 복잡도에 대해 간단히 소개한다. 간단한 소개에 그치기 때문에 자세한 내용은 자료구조/알고리즘 교과서를 보는 게 좋다

한국어판 부록 B

codility 사용 방법을 소개한다. 많은 회사들이 면접 시 1차로 리크루터와 통화를 한 후 두 번째 단계로 이런 문제 풀이 사이트에서 문제를 풀고 제출하게 하는데, codility나 hackerrank가 가장 유명한 편이다. 우리나라에서도 점점 많은 회사들이 도입하고 있기 때문에 시간 날 때마다 풀어보면서 익숙해지는 게 좋다.

소소한 장점

원서는 c source인데 역자가 python으로 옮겨놓았다 https://github.com/crapas/dp

중간중간 박스를 통해 실제 인터뷰에서 유용할 팁을 알려주는 경우가 있다. 원서 제목 자체가 Dynamic Programming for Coding Interviews이니 적절한 설명이라고 생각한다.

소소한 단점

(리디북스 한정) 역시나 매번 그렇듯 옮긴이의 말에 있는 링크는 정상 동작하지 않는다. 사소한 버그이지만 리디북스의 프로그래밍 책을 읽는다는 특성상 컴퓨터에서 읽는 경우가 많은데 링크가 동작하지 않으면 불편하다.

Site



댓글(0) 먼댓글(0) 좋아요(0)
좋아요
공유하기 북마크하기찜하기 thankstoThanksTo
 
 
 
[전자책] 파이썬 자료구조와 알고리즘 : 기초 튼튼, 핵심 쏙쏙, 실력 쑥쑥
미아 스타인 / 한빛미디어 / 2019년 8월
평점 :
장바구니담기


총평

파이썬이 인기를 얻으면서 최근에는 출간 목록도 다 쫓아가기 힘들 정도로 많은 책이 나오고 있다. 새로운 프레임워크나 언어 자체에 대한 책은 보통 버전이 올라가면 새로운 내용이 추가되므로 기존의 책은 다시 볼 일이 거의 없지만, 기본에 대한 책은 그렇지 않다. “파이썬 자료구조와 알고리즘”도 그런 책이다. 프로그래밍 면접을 볼 때 파이썬은 주로 사용하는 언어 중 하나이며, 자료구조와 알고리즘은 프로그래밍에서 항상 빠지지 않는 기본 중의 기본이다. 게다가, 최근 한국에서도 더 많은 소프트웨어 관련 회사들이 알고리즘 문제를 어떻게 해결하는 지를 주요 평가 기준으로 사용하기 때문에 시의적절한 책이라고 생각한다. Part 1은 파이썬 문법, Part 2, 3는 알고리즘이며, Part 3에서 그래프, 트리를 다루고 있다(각 장별 상세한 리뷰는 아래). 분량에 비해 비교적 많은 예제를 통해 설명하고 있고, 연습문제도 leetcode.com의 easy 난이도 정도의 문제들로 구성되어 이제 막 초급을 벗어나려는 경우 적절하다고 생각한다. 다만 각 chapter별 난이도가 고르지 않은 느낌이 있고, 구성이 일반적인 파이썬/자료구조 & 알고리즘 책과 다른 게 약간 어색하다는 생각이 든다.

Part 1

아무래도 제한된 분량 내에서 파이썬 문법을 설명하려다 보니 자세한 설명은 부족하지만, 하나의 소주제마다 많은 예제를 통해 바로 사용할 수 있는 실용성에 초점을 둔 거 같다.

Chapter1.

파이썬 기초 문법을 주로 설명하는데, 넘파이가 같이 포함되어 있다. 초보자들의 경우 설치부터 어려움을 겪는 경우가 많은데 이 부분을 언급하지 않고 바로 넘파이를 설명하면 python만 설치한 경우에는 분명히 오류를 보고 책에 문제가 있다거나 설명이 부족하다는 생각을 할 거 같다.

Chapter2.

string 처리를 설명하는데, string reverse에서 시작해 단어별 reverse와 같은 방식으로 확장하거나, 순열, palindrome 회문을 설명하는 등 초보자에게는 약간 어려울 수 있는 부분까지 확장한다.

Chapter3.

컬렉션을 설명하고, anagram 애너그램, 주사위, 중복 제거 등의 연습 문제를 보여준다. 이 부분은 워낙 중요하기도 하고 어떤 프로그램을 작성하건 항상 사용하는 부분이라 조금 더 설명이 자세하면 좋겠다는 생각이 들었다.

Chatper4.

4장은 순전히 파이썬 문법에 관계된 부분이며, 문제를 해결하는데 보조적인 역할을 하는 여러 가지 부분을 설명한다(대표적으로 file I/O). 간단한 문제 해결을 위한 프로그램에서는 별로 관계가 없으나 프로젝트를 진행하는 등 약간이라도 규모가 커지는 경우는 역시 매우 중요한 부분이다(예를 들어 프로젝트 구조를 결정하기 위해 import를 하는 등).

Chapter5.

5장은 OOP에 대한 내용인데, 이게 과연 초보자용 책에 필요할지는 잘 모르겠다. 디자인 패턴까지 넣었지만, 또 들어간 내용은 observer와 singleton뿐인데, 이건 심화 주제로 따로 소개만 하는 게 좋았을 거란 생각이 들었다.

Chapter6.

6장 역시 5장과 마찬가지로, 프로세스와 스레드, 가상 환경은 초보자용의 주제는 아니다. 물론 이 책은 초중급용이긴 하지만, 책의 주제를 생각하면 너무 적은 분량에 많은 주제를 넣고 싶어 했던 저자의 욕심이 아닐까 하는 생각이 든다. 디버깅과 테스트 부분은 하나의 파일/모듈로만 이뤄진 프로그램에서도 필요한 부분이므로 넣을 만 하단 생각이 든다.

Part 2

Chapter7.

스택 큐 힙 연결 리스트 해시 테이블같은 기본이 되는 자료구조에 대한 장. 특히 7장에서 나온 스택과 큐 구현은 정석적인 구현으로 확실히 기억해두는 게 좋다. 해시테이블은 보통 프로그래밍 문제를 해결할 때 파이썬 내장을 이용하고, 해시테이블 자체를 구현해야 하는 문제는 없으므로 보고 이해만 할 수 있으면 된다.

Chatper8.

시간 복잡도를 설명하는 장. 보통 자료구조 알고리즘 책을 보면 거의 1장에 나오는 내용이므로 7장보다 앞에 가야 순서가 맞을 거 같다.

Chatper9.

정렬을 설명한다. python에서는 sort()나 sorted()로 간단하게 정렬을 할 수 있지만, 프로그래밍 면접에서는 실제로 구현을 해야 하는 경우가 있고(대개는 quicksort나 mergesort, heapsort), 구현은 안 해도 설명을 해야 하는 경우는 종종 있기 때문에 잘 파악을 해야 한다. 연습문제는 가장 큰 k개를 찾는 건데 보통 heap을 이용하는데 여기서는 quicksort로 설명을 한다.

Chapter10.

순차와 이진 검색을 설명하고 여러 가지 연습문제를 설명한다. 교집합을 구하는데 이진 검색을 사용하는 경우는 처음 본 거 같은데 개인적으로 잘 기억해야겠다는 생각을 했다. 자주 나오는 문제는 자기가 언제나 확실히 해결할 수 있는 방식을 하나 이상 확실히, 외울 정도로 기억하고 이렇게 새로운 방식으로 가능하다는 점도 알아두는 식으로 확장을 하면 좋다.

Chapter11.

dynamic programming. memoization을 아주 간단하게 언급하고 지나간다. 면접에서 만나는 프로그래밍 문제의 경우 간단한 DP 문제가 나오는 경우가 많기 때문에 이에 대한 연습이 필요한 경우 따로 책을 보는 게 좋다. 최근에 출간된 책 — 다이내믹 프로그래밍 완전 정복이 있어서 한 번 보려고 생각 중인데, 목차만 볼 때는 기본적인 부분을 설명하고 여러 가지 대표적인 DP관련 프로그래밍 문제를 다루는 걸로 보인다.

Part 3

Chapter12.

graph 기초를 설명하고 간단히 구현할 수 있는 방법을 설명한다. 설명이 간단한 편이라 잘 읽어보고 그래도 이해가 안 되면 더 자세하게 설명하는 책을 봐야 한다.

Chapter13.

binary tree & binary search tree를 알려준다. 이 부분은 프로그래밍 퀴즈에서 정말 자주 나오는 부분이라 잘 기억해야 한다. 반면에 AVL 트리나 레드 블랙 트리는 물론 알면 좋지만 이 책의 전반적인 수준에서는 굳이 필요할까 하는 생각이 들었다. 개인적으로 봤던 수많은 프로그래밍 면접에서 단 한 번도 겪어본 적이 없는 문제이고, 다른 사람들 후기에서도 거의 본 적이 없다. 물론 그만큼 좀 더 어려운 부분이라 잘 알고 설명할 수 있다면 자신만의 강점이 될 수 있는 부분이기도 하다.

Chapter14.

DFS, BFS. stack과 queue를 이용해 iterative로 잘 설명하고 있다. 여러 가지 프로그래밍 문제에서 아주 유용하게 사용할 수 있는 부분이라 외울 정도로 기억해두는 게 좋은 기본 코드이다. 너비 우선 탐색을 영어로 breadth-first search BFS로 썼지만 예제에서 함수 이름은 BFT로 썼는데, 이게 breadth-first traverse의 약자라는 걸 같이 써주면 더 좋았겠다는 아주 쓸데없는 트집 하나 정도는 잡을 수 있다.

부록

그래프 알고리즘을 참고할 geeksforgeeks 링크와 프로그래밍 면접 준비를 위한 hackerrank, 백준 알고리즘 사이트 추천을 하고 있다. 개인적으로는 hackerrank보다 leetcode를 추천하는데, 그 이유는 hackerrank는 일단 문제 설명이 쓸데없이 길고 아주 가끔이지만 leetcode보다 좀 더 오류(도저히 못 풀겠어서 hackerrank가 제공하는 solution을 그대로 입력했는데도 timeout이 발생하는 등)가 있었기 때문이다.

Etc.

옮긴이 github. 예전에도 겪었던 일인데, 책 시작 부분의 저자 혹은 옮긴이의 말 부분에 있는 link는 리디북스에서는 link가 걸리지 않아서 따로 입력을 해야 한다. 일일이 확인을 하진 않았지만, 어떤 경우는 link를 클릭해서 바로 브라우저에서 볼 수 있고(34p NOTE의 시간 복잡도) 또 그렇지 않은 경우(37p 넘파이 링크는 클릭 불가능)가 있는 걸 보면 리디북스에서 link 부분을 처리할 때 오류가 있는 게 아닌가 싶다.

https://github.com/AstinCHOI/Python-and-Algorithms-and-Data-Structures


댓글(0) 먼댓글(0) 좋아요(1)
좋아요
공유하기 북마크하기찜하기 thankstoThanksTo
 
 
 
[전자책] C++ 최적화
커트 건서로스 / 한빛미디어 / 2019년 8월
평점 :
장바구니담기


1장

2장

3장

4장

5장

6장

7장

8장

9장

10장

11장

12장

13장

예제

❯ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin



댓글(0) 먼댓글(0) 좋아요(0)
좋아요
공유하기 북마크하기찜하기 thankstoThanksTo