혼자 공부하는 머신러닝+딥러닝

Yes24, 교보문고 평점 평균 10점 만점! 감사합니다!

★★★★★ 박해선님 도서는 항상 기대함. 그러나 항상 기대이상. 이번엔 심지어 재미있음. (a******t 님)
★★★★★ 박해선님이 제대로 된 초보자서를 출간하셨네요. 초보 여러분 믿고 사세요. (c******o 님)
★★★★★ 정말 혼자 공부하기 너무 좋은 머신러닝 독학 책 (pc**831 님)
♥♥♥♥ 혼자 공부하기 좋아요! 설명도 잘되어있어요:) (an**s0603 님)

<혼자 공부하는 머신러닝+딥러닝>은 머신러닝, 딥러닝을 입문하려는 전국민을 위한 책입니다! 🙂

수학 때문에 머신러닝, 딥러닝 공부를 차일피일 미루고 있었다면 더 이상 그럴 필요가 없습니다. 이 책으로 누구나 머신러닝과 딥러닝에 입문할 수 있습니다. 수학을 최대한 배제하고 그림과 이야기를 따라 이론을 쉽게 배울 수 있도록 만들었습니다. 많은 삽화를 곁들여서 읽는 내내 지루하지 않게 했고 각 절이 끝날 때마다 간단한 퀴즈로 학습을 돕고 있습니다. 이 책의 모든 코드는 구글 코랩(Colab)엘리스(elice.io) 아카데미에서 실습할 수 있습니다. 별도의 프로그램을 컴퓨터에 설치할 필요가 없고 웹 브라우저만으로 머신러닝과 딥러닝을 배울 수 있습니다!

텐서 ≈ 스터디 페이스북 그룹에 오시면 동영상 강의와 스터디에 대한 정보와 빠르게 받을 수 있습니다. 스타디가 끝난 후 녹화 영상은 한빛미디어 유튜브 채널과 제 개인 유튜브 채널에서 볼 수 있습니다.

이 페이지에서 책의 에러타와 라이브러리 버전 변경에 따른 바뀐 점들을 계속 업데이트 하겠습니다. 구글 그룹스의 머신러닝/딥러닝 도서 메일링 리스트에 가입하시면 책의 에러타나 수정사항을 자동으로 수신할 수 있습니다.

이 책에 대해 궁금한 점이나 오류가 있으면 이 페이지 맨 아래 ‘Your Inputs’에 자유롭게 글을 써 주세요. 또 제 이메일을 통해서 알려 주셔도 되고 구글 그룹스 머신러닝/딥러닝 도서 Q&A에 글을 올려 주셔도 좋습니다.

감사합니다! 🙂


Outputs (aka. errata)

  • ~28: 2쇄에 반영되었습니다.
  • ~44: 3쇄에 반영되었습니다.
  1. (p57) 맨 아래 마지막 문장에서 “특징을 알아보습니다”를 “특징을 알아보습니다”로 수정합니다.
  2. (p121) 맨 위 식에서 “(타깃 – 예측)^2 / (타깃 – 평균)^2″을 “(타깃 – 예측)^2의 합 / (타깃 – 평균)^2의 합“으로 정정합니다. 그 아래 첫 번째 문장에서 “타깃과 예측한 값의 차이를 제곱합니다. 그다음 타깃과 타깃 평균의 차이를 제곱한 값으로 나눕니다”를 “각 샘플의 타깃과 예측한 값의 차이를 제곱하여 더합니다. 그다음 타깃과 타깃 평균의 차이를 제곱하여 더한 값으로 나눕니다”로 정정합니다.(임*경 님)
  3. (p78) 두 번째 손코딩 위에 다음과 같은 노트를 추가합니다. “(노트) 2차원 배열은 행과 열 인덱스를 콤마(,)로 나누어 지정합니다. 슬라이싱 연산자로 처음부터 마지막 원소까지 모두 선택하는 경우 시작과 종료 인덱스를 모두 생략할 수 있습니다.”
  4. (p87) “시작하기 전에” 절 아래 7번째 줄에서 “250g”을 “150g”으로 정정합니다.
  5. (p103) 페이지 아래 쪽 풍선말에서 “테스트 세트의 기준으로 훈련 세트를 변환해야”를 “훈련 세트의 기준으로 테스트 세트를 변환해야”로 정정합니다.(서*교 님)
  6. (p100) 마지막 문단 옆에 풍선말을 추가합니다. “브로드캐스팅은 넘파이 배열 사이에서 일어납니다. train_input, mean, std가 모두 넘파이 배열입니다.”
  7. (p115) 여기서 잠깐 섹션에서 “1980년대 통계학자이자”를 “19세기 통계학자이자”로 정정합니다.(서*교 님)
  8. (p121) 위에서 3번째 문장에서 “타깃예측에 아주 가까워지면 (분모가 0에 가까워지기 때문에)”를 “예측타깃에 아주 가까워지면 (분자가 0에 가까워지기 때문에)”로 정정합니다.(서*교 님)
  9. (p274) 첫 번째 손코딩과 그 아래 첫 번째 문단을 다음 내용으로 교체합니다.(서*교 님)

    히스토그램 기반 그레이디언트 부스팅의 특성 중요도를 계산하기 위해 permutation_importace() 함수를 사용하겠습니다. 이 함수는 특성을 하나씩 랜덤하게 섞어 모델의 성능이 변화하는지 관찰하는 식으로 어떤 특성이 중요한지 계산합니다. 또한 훈련 세트 뿐만 아니라 테스트 세트에도 적용할 수 있고 사이킷런에서 제공하는 추정기 모델에 모두 사용할 수 있습니다.

    먼저 히스토그램 기반 그레이디언트 부스팅 모델을 훈련하고 훈련 세트에서 특성 중요도를 계산해 보겠습니다. n_repeats 매개변수는 랜덤하게 섞을 횟수를 지정합니다. 여기서는 10으로 지정하겠습니다. 기본값은 5입니다.

    from sklearn.inspection import permutation_importance

    hgb.fit(train_input, train_target)
    result = permutation_importance(hgb, train_input, train_target, n_repeats=10, random_state=42, n_jobs=-1)
    print(result.importances_mean)

    [0.08876275 0.23438522 0.08027708]

    permutation_importance() 함수가 반환하는 객체는 반복하여 얻은 특성 중요도(importances), 평균(importances_mean), 표준 편차(importances_std)를 담고 있습니다. 평균을 출력해 보면 랜덤 포레스트와 비슷한 비율임을 알 수 있습니다. 이번에는 테스트 세트에서 특성 중요도를 계산해 보겠습니다.

    result = permutation_importance(hgb, test_input, test_target, n_repeats=10, random_state=42, n_jobs=-1)
    print(result.importances_mean)
    [0.05969231 0.20238462 0.049 ]


    테스트 세트의 결과를 보면 그레이디언트 부스팅과 비슷하게 조금 더 당도에 집중하고 있다는 것을 알 수 있습니다. 이런 분석을 통해 모델을 실전에 투입했을 때 어떤 특성에 관심을 둘지 예상할 수 있습니다.
  10. (p182) 페이지 마지막 문장 “ 번째 클래스에 대한 확률은 1/3=0.3333이고 다섯 번째 클래스에 대한 확률은 2/3=0.6667이 됩니다”를 “다섯 번째 클래스에 대한 확률은 1/3=0.3333이고 번째 클래스에 대한 확률은 2/3=0.6667이 됩니다”로 정정합니다.(s*o 님)
  11. (p148) 아래에서 4번째 줄에 “fit_intercept 매개변수를 True로 지정하면 절편을 학습하지 않습니다”를 “fit_intercept 매개변수를 False로 지정하면 절편을 학습하지 않습니다”로 정정합니다.
  12. (p141) 아래쪽 손코딩 중 아래에서 2번째 줄에 plt.scatter([50], [1574], marker='^')plt.scatter(50, 1574, marker='^')로 수정합니다. 실행 결과는 동일하지만 코드를 읽기 쉽도록 바꾸었습니다.(서*교 님)
  13. (p243) <여기서 잠깐> 박스의 첫 번째 줄에 “테스트 세트와 훈련 세트로 떼어 놓습니다”를 “테스트 세트와 검증 세트로 떼어 놓습니다”로 정정합니다.(서*교 님)
  14. (p305) 맨 아래에서 3번째 줄 끝에 “labels_ 길이는 샘플 개수“를 “labels_ 배열의 길이는 샘플 개수와 같습니다. 이 배열은“로 수정합니다.(서*교 님)
  15. (p159) 맨 아래 노트 끝에 다음 문장을 추가합니다. “특성마다 계산하므로 55개의 평균과 표준 편차가 들어 있습니다.
  16. (p355) 맨 아래 2개의 리스트 항목에서 “binary_corssentropy”와 “categorical_corssentropy”를 “binary_crossentropy”와 “categorical_crossentropy”로 정정합니다.(고*진 님)
  17. (p356) 아래쪽 그림에서 오른쪽의 원-핫 인코딩 배열에서 첫 번째 원소를 0에서 1로, 두 번째 원소를 1에서 0으로 수정합니다.(고*진 님)
  18. (p560) 3-1절 1번 문제 답을 (1)번에서 다음과 같이 (2)번으로 정정합니다. “(2) k-최근접 이웃 회귀는 예측할 샘플에서 가장 가까운 k 개의 주변 샘플을 찾고 이 주변 샘플의 타깃값을 평균하여 예측값을 구합니다“(오*경 님)
  19. (p569) 8-1절 확인문제 2번 답에서 두 번째 열의 값이 8, 8, 10이 아니라 8, 12, 14입니다.(고*진 님)
  20. (p471) 맨 아래 코드에서 dense1(hidden)dense2(hidden)으로 수정합니다.(고*진 님)
  21. 코드와 설명을 맞추기 위해 (p472) 위에서 두 번째 줄에 있는 코드에서 Model(inputs, outputs)keras.Model(inputs, outputs)로 바꾸어 주세요. (p473) 두 번째 그림에서 conv_acti = Model(...)conv_acti = keras.Model(...)로 바꾸어 주세요.(고*진 님)
  22. 코드의 일관성을 위해 (p474) 첫 번째 코드에서 keras.models.Model(...)keras.Model(...)로 바꾸어 주세요. 마찬가지로 (p476) 첫 번째 손코딩, (p480) 마지막 줄, (p481) 아래에서 10번째 줄에서 keras.models.Model(...)keras.Model(...)로 바꾸어 주세요.
  23. (p417) 코드 끝에서 3번째 줄에 plt.save('7_3-07', dpi=300)을 삭제합니다.(채*석 님)
  24. (p474) 첫 번째 코드 블록에 <손코딩> 아이콘을 추가해 주세요.
  25. (p137) 아래쪽 손코딩 박스 위 두 번째 문장에서 (50, 15 \times 39 - 709)(50, 50 \times 39 - 709)로 정정합니다.(C*e 님)
  26. (p536) 손코딩 박스의 4번째 줄에서 best-dropout-model.h5를 best-2rnn-model.h5로 정정합니다.(고*진 님)
  27. (p326) 두 번째 손코딩의 plt.plot(pca.explained_variance_ratio_) 아래 plt.show()를 추가합니다. 마찬가지로 (p333) 아래에서 3번째 줄 plt.plot(pca.explained_variance_ratio_) 아래 plt.show()를 추가합니다.(서*교 님)
  28. (p406) 첫 번째 줄에서 “가장 큰 값을 골라”를 “가장 큰 값의 인덱스를 골라”로 수정합니다.(서*교 님)
  29. (p445) 마지막 줄인 “이제 train_scaled의 차원은 (50000, 28, 28)에서 (50000, 28, 28, 1)이 되었습니다”를 “이제 (48000, 28, 28) 크기인 train_input이 (48000, 28, 28, 1) 크기인 train_scaled가 되었습니다”로 정정합니다. 그림에 (두군데) 표시된 50,00048,000으로 바꾸어 주세요. 그림 아래 쓰인 (50000, 28, 28)을 (48000, 28, 28)로 바꾸고 (50000, 28, 28, 1)을 (48000, 28, 28, 1)로 바꾸어 주세요.(서*교 님)
  30. (p472) 첫 번째 문장에서 “그다음 inputs와 output“을 “그다음 inputs와 outputs“로 정정합니다.(서*교 님)
  31. (p501) 마지막 문단 위에서 3번째 줄에 “‘cat’을 13에 매핑하더라도 ‘ca‘이 ‘He’보다”를 “‘cat’을 13에 매핑하더라도 ‘cat‘이 ‘He’보다”로 정정합니다.(서*교 님)
  32. 코드 실행에는 이상이 없지만 표기 일관성을 위해 예제 데이터셋의 경로를 변경합니다. (p221) <여기서 잠깐> 바로 위와 4번째 줄과 첫 번째 손코딩, (p236) 손코딩 4번째 줄, (p243) 첫 번째 손코딩, (p256) 손코딩 4번째 줄, (p267) 첫 번째 손코딩, (1쇄:p277, 2쇄:p278) 손코딩6 번째 줄에서 https://bit.ly/wine-datehttps://bit.ly/wine_csv_data 로 수정합니다.
  33. 코드 실행에는 이상이 없지만 표기 일관성을 위해 예제 데이터셋의 경로를 변경합니다. (p178) 손코딩, (p193) 손코딩 5번째 줄, (p207) 첫 번째 손코딩, (p213) 손코딩 4번째 줄에서 https://bit.ly/fish_csvhttps://bit.ly/fish_csv_data 로 수정합니다.
  34. 코드 실행에는 이상이 없지만 표기 일관성을 위해 예제 데이터셋의 경로를 변경합니다. (p153) 첫 번째 손코딩, (p167) 손코딩 4번째 줄에서 https://bit.ly/perch_csvhttps://bit.ly/perch_csv_data 로 수정합니다.
  35. 코드 실행에는 이상이 없지만 표기 일관성을 위해 예제 데이터셋의 경로를 변경합니다. (p287) 첫 번째 손코딩, (p299) 손코딩 3번째 줄, (p305) 첫 번째 손코딩, (p314) 손코딩 3번째 줄, (p322) 첫 번째 손코딩, (p332) 손코딩 3번째 줄에서 https://bit.ly/fruits_300https://bit.ly/fruits_300_data 로 수정합니다.
  36. (p361) 위에서 4번째 줄에 sc.core(val_scaled, val_target)을 sc.score(val_scaled, val_target)로 정정합니다.(홍*창 님)
  37. (p454) 손코딩 바로 아래 줄에 ‘fit() 메서드 출력 중 여덟 번째 에포크의’를 ‘fit() 메서드 출력 중 아홉 번째 에포크의’로 정정합니다.(홍*창 님)
  38. (p492) 위에서 5번째 줄에 “타임스텝 3의 셀로 주입니다”를 “타임스텝 3의 셀로 주입됩니다”로 정정합니다.(홍*창 님)
  39. (p542) 손코딩 3번째 줄에서 rnn_model.evaluate(val_seq, val_target)rnn_model.evaluate(test_seq, test_target)로 정정합니다.(홍*창 님)
  40. (p233) 위에서 7번째 줄에 “-0.239보다 작고 또 -0.802보다도 작아야 합니다”를 “-0.239보다 작고 -0.802보다 커야 합니다”로 정정합니다. 8번째 줄에 “-0.802와 같거나 작은 와인”을 “-0.802보다 크고 -0.239보다 작은 와인”으로 정정합니다.
  41. (p234) 위에서 2번째 줄에 “1.625와 같거나 작은”을 “1.625보다 크고 4.325보다 작은”으로 정정합니다.
  42. (p246) 손코딩의 출력 결과에 있는 들여쓰기를 삭제해 주세요.
  43. (p128) 2번 문제와 코드 사이에 노트를 추가합니다 “note: 맷플롯립의 plot() 함수는 x 축과 y 축의 값을 받아 선 그래프를 그립니다.”
  44. (p207) SGDClassifier 절 바로 아래 줄에 “판단스 데이터프레임을 만들어”를 “판다스 데이터프레임을 만들어”로 정정합니다.(윤*철 님)
  45. (p320) 위에서 3번째 줄에 “분산이 큰 방향을 데이터로 잘 표현하는 벡터로 생각할 수 있습니다”를 “분산이 큰 방향이란 데이터를 잘 표현하는 어떤 벡터라고 생각할 수 있습니다”로 정정합니다.
  46. (p321) 두 번째 그림에서 “p(4, 5)”를 “p(4.5)”로 정정합니다.
  47. (p561) 3-3절 1번 문제의 답에서 “1, a, b, c, a2, b2, c2, ab, bc, ac, abc, ab2, ac2, bc2, ba2, ca2, cb2, a3, b3, c3“를 “1, a, b, c, a2, b2, c2, ab, bc, ac, abc, ab2, ac2, bc2, ba2, ca2, cb2, a3, b3, c3“로 정정합니다.(박*환 님)
  48. (p355) <여기서 잠깐> 박스 3번째 줄에서 “케라스 API에도“를 “케라스 API에서도“로 수정합니다.
  49. (p357) 위에서 10번째 줄에서 “2장에서 배웠던 넘파이 브로드캐스팅이 여기에도 적용됩니다.“를 “길이가 같은 넘파이 배열의 곱셈은 원소별 곱셈으로 수행됩니다. 즉,“으로 수정합니다.
  50. (p208) 2번째 손코딩 위에 다음과 같은 노트를 추가합니다. “노트 다중 분류일 경우 SGDClassifier에 loss=’log’로 지정하면 클래스마다 이진 분류 모델을 만듭니다. 즉 도미를 양성 클래스로 두고 나머지를 모두 음성 클래스로 두고 모델을 만드는 식입니다. 이런 방식을 OvR(One versus Rest)라고 부릅니다.”
  51. (p179) 마지막 손코딩 위에 다음 노트를 추가합니다. “노트 Species 열을 선택할 때 fish[['Species']]와 같이 두 개의 괄호를 사용하지 않도록 주의하세요. 이렇게 하면 fish_target이 2차원 배열이 됩니다.”
  52. (p436) 밑에서 7번째 줄의 코드에서 stidesstrides로 정정합니다.(신*상 님)
  53. (p450) 손코딩에서 plot_model(model, show_shapes=True, to_file='cnn-architecture.png', dpi=300)plot_model(model, show_shapes=True)로 수정합니다. 또한 출력 결과에서 input과 output 박스에 있는 ? 를 None 으로 모두 수정합니다.
  54. (p468) 손코딩 아래 3번째 줄과 4번째 줄에서 conv_weights[:,:,:0,0]conv_weights[:,:,0,0]으로 정정하고 conv_weights[:,:,:0,31]conv_weights[:,:,0,31]로 정정합니다.
  55. (p538, p540) GRU 셀 그림에서 ‘-1‘ 표시를 ‘1-‘로 정정합니다.
  56. (p408) ModelCheckpoint 콜백 객체를 만들 때 save_best_only=True 매개변수가 누락되었습니다. <콜백> 절 아래 3번째 문장에서 “ModelCheckpoint 콜백은 기본적으로 최상의 검증 점수를 만드는 모델을 저장합니다.“를 “ModelCheckpoint 콜백은 기본적으로 에포크마다 모델을 저장합니다. save_best_only=True 매개변수를 지정하여 가장 낮은 검증 점수를 만드는 모델을 저장할 수 있습니다.”로 정정합니다.
  57. (p419) ModelCheckpoint 항목 맨 아래에 다음 문장을 추가합니다. “save_best_only 매개변수를 True로 지정하면 가장 낮은 검증 점수를 만드는 모델을 저장합니다.”
  58. 다음 손코딩에서 ModelCheckpoint 객체를 생성할 때 save_best_only=True 매개변수를 추가합니다.(몽*이 님)
    • p408 첫 번째 손코딩 4번째 줄
    • p409 손코딩 4번째 줄
    • p416 7번째 줄과 17번째 줄
    • p452 손코딩 3번째 줄
    • p459 15번째 줄
    • p512 손코딩 4번째 줄
    • p516 두 번째 손코딩 4번째 줄
    • p521 7번째 줄
    • p522 3번째 줄
    • p531 손코딩 4번째 줄
    • p533 두 번째 손코딩 4번째 줄
    • p536 손코딩 4번째 줄
    • p540 손코딩 4번째 줄
    • p544 5번째 줄, 마지막 줄
    • p545 아래에서 6번째 줄
    • p546 아래에서 12번째 줄
  59. (p200) 위에서 3번째 줄에 “불평만 늘어 놀 시간이 없습니다”를 “불평할 시간조차 아깝습니다”로 수정합니다.(김*식 님)
  60. (p48) 손코딩 첫 번째 줄에 있는 주석에서 “pylot 함수를 plt로”를 “pyplot 함수를 plt로” 정정합니다.(이*연 님)
  61. (p419) ModelCheckpoint 항목 설명 중에서 “save_weights_only 매개변수의 기본값은 True로 모델의 가중치와 절편만 저장합니다. False로 지정하면 전체 모델을 저장합니다”를 “save_weights_only 매개변수의 기본값은 False로 전체 모델을 저장합니다. True로 지정하면 모델의 가중치와 절편만 저장합니다”로 정정합니다.(조*영 님)
  62. (p54) 첫 번째 손코딩 바로 아래에 ‘알고리즘을 훈련시킨 뒤 훈련합니다‘를 ‘알고리즘을 훈련합니다‘로 정정합니다.
  63. (p102) 아래에서 5번째 줄에 “샘플 [20, 150]을 동일한 비율로”를 “샘플 [25, 150]을 동일한 비율로”로 정정합니다.(이*석 님)
  64. (p554) 위에서 6번째 줄에 “<머신 러닝 교과서 with 파이썬, 사이킷런, 텐서플로>(길벗, 2019)”를 “<머신 러닝 교과서 with 파이썬, 사이킷런, 텐서플로 (개정 3판)>(길벗, 2021)”로 수정합니다.
  65. (p501) 아래쪽 <여기서 잠깐> 바로 윗줄에 “하나의 타임스탬프에 해당합니다”를 “하나의 타임스텝에 해당합니다”로 정정합니다.(박*식 님)
  66. (p276) ‘앙상블 학습 보고서’의 그레이디언트 부스팅 설명에서 ‘이진 트리의 손실을’을 ‘이전 트리의 손실을’로 정정합니다.(박*식 님)
  67. (p445) 손코딩 위의 4번째 줄에서 “7장 1절에서 언급했듯이”를 “8장 1절에서 언급했듯이”로 정정합니다.(박*식 님)

Your Inputs