자세한 이론 설명과 파이썬 실습을 통해 머신러닝을 완벽하게 배울 수 있습니다!
《파이썬 머신러닝 완벽 가이드》는 이론 위주의 머신러닝 책에서 탈피해 다양한 실전 예제를 직접 구현해 보면서 머신러닝을 체득할 수 있도록 만들었습니다. 캐글과 UCI 머신러닝 리포지토리에서 난이도가 있는 실습 데이터를 기반으로 실전 예제를 구성했고, XGBoost, LightGBM, 스태킹 기법 등 캐글의 많은 데이터 사이언스에서 애용하는 최신 알고리즘과 기법에 대해 매우 상세하게 설명했습니다.
★ 이 책의 특징 ★
- 분류, 회귀, 차원 축소, 클러스터링 등 핵심 머신러닝 알고리즘에 대한 깊이 있는 설명
- 데이터 전처리, 머신러닝 알고리즘 적용, 하이퍼 파라미터 튜닝, 성능 평가 등 최적 머신러닝 모델 구성 방안 제시
- XGBoost, LightGBM, 스태킹 등 머신러닝 최신 기법에 대한 상세한 설명과 활용법
- 난이도 높은 캐글 문제를 직접 따라 해 보면서 실무 머신러닝 애플리케이션 개발 방법 체득(산탄테르 은행 고객 만족 예측, 신용카드 사기 검출, 부동산 가격 예측 고급 회귀 기법, Mercari 쇼핑몰 가격 예측 등)
- 텍스트 분석과 NLP를 위한 기반 이론과 다양한 실습 예제 제공(텍스트 분류, 감성 분석, 토픽 모델링, 문서 유사도, 문서 군집화와 유사도, KoNLPy를 이용한 네이버 영화 감성 분석 등)
- 다양한 추천 시스템을 직접 파이썬 코드로 구축하는 법을 제공
도서 상세 이미지
권철민
엔코아 컨설팅, 한국 오라클을 거쳐 현재 kx systems에서 고성능 인메모리 DB인 kdb+의 Machine Learning 컨설턴트로 근무 중이다. 지난 20년간 50여 개 이상의 주요 고객사에서 데이터컨설팅 분야에 매진해 왔으며, 최근 몇 년간은 AI 기반의 Advanced Analytics 분야에 집중하고 있다. 직접 구현해 보지 않으면 절대 이해하지 못하는 평범한 두뇌의 소유자이며, 절망적인 프로젝트에 참여해 자기학대적인 노력으로 문제를 해결하는 이상한 성격의 소유자이기도 하다.
- ▣ 1장: 파이썬 기반의 머신러닝과 생태계 이해
- 1.1. 머신러닝의 개념
- 머신러닝의 분류
- 데이터 전쟁
- 파이썬과 R 기반의 머신러닝 비교
- 1.2. 파이썬 머신러닝 생태계를 구성하는 주요 패키지
- 파이썬 머신러닝을 위한 S/W 설치
- 1.3. 넘파이
- 넘파이 ndarray 개요
- ndarray의 데이터 타입
- ndarray를 편리하게 생성하기 - arange, zeros, ones
- ndarray의 차원과 크기를 변경하는 reshape( )
- 넘파이의 ndarray의 데이터 세트 선택하기 – 인덱싱(Indexing)
- 행렬의 정렬 – sort( )와 argsort( )
- 선형대수 연산 – 행렬 내적과 전치 행렬 구하기
- 1.4. 데이터 핸들링 - 판다스
- 판다스 시작 - 파일을 DataFrame으로 로딩, 기본 API
- DataFrame과 리스트, 딕셔너리, 넘파이 ndarray 상호 변환
- DataFrame의 컬럼 데이터 세트 생성과 수정
- DataFrame 데이터 삭제
- Index 객체
- 데이터 셀렉션 및 필터링
- 정렬, Aggregation 함수, GroupBy 적용
- 결손 데이터 처리하기
- apply lambda 식으로 데이터 가공
- 1.5. 정리
- 1.1. 머신러닝의 개념
- ▣ 2장: 사이킷런으로 시작하는 머신러닝
- 2.1. 사이킷런 소개와 특징
- 2.2. 첫 번째 머신러닝 만들어 보기 – 붓꽃 품종 예측하기
- 2.3. 사이킷런의 기반 프레임워크 익히기
- Estimator 이해 및 fit( ), predict( ) 메서드
- 사이킷런의 주요 모듈
- 내장된 예제 데이터 세트
- 2.4. Model Selection 모듈 소개
- 학습/테스트 데이터 세트 분리 – train_test_split()
- 교차 검증
- GridSearchCV – 교차 검증과 최적 하이퍼 파라미터 튜닝을 한 번에
- 2.5. 데이터 전처리
- 데이터 인코딩
- 피처 스케일링과 정규화
- StandardScaler
- MinMaxScaler
- 2.6. 사이킷런으로 수행하는 타이타닉 생존자 예측
- 2.7. 정리
- ▣ 3장: 평가
- 3.1. 정확도(Accuracy)
- 3.2. 오차 행렬
- 3.3. 정밀도와 재현율
- 정밀도/재현율 트레이드오프
- 정밀도와 재현율의 맹점
- 3.4. F1 스코어
- 3.5. ROC 곡선과 AUC
- 3.6. 피마 인디언 당뇨병 예측
- 3.7. 정리
- ▣ 4장: 분류
- 4.1. 분류(Classification)의 개요
- 4.2. 결정 트리
- 결정 트리 모델의 특징
- 결정 트리 파라미터
- 결정 트리 모델의 시각화
- 결정 트리 과적합(Overfitting)
- 결정 트리 실습 – 사용자 행동 인식 데이터 세트
- 4.3. 앙상블 학습
- 앙상블 학습 개요
- 보팅 유형 – 하드 보팅(Hard Voting)과 소프트 보팅(Soft Voting)
- 보팅 분류기(Voting Classifier)
- 4.4. 랜덤 포레스트
- 랜덤 포레스트의 개요 및 실습
- 랜덤 포레스트 하이퍼 파라미터 및 튜닝
- 4.5. GBM(Gradient Boosting Machine)
- GBM의 개요 및 실습
- GBM 하이퍼 파라미터 및 튜닝
- 4.6. XGBoost(eXtra Gradient Boost)
- XGBoost 개요
- XGBoost 설치하기
- 파이썬 래퍼 XGBoost 하이퍼 파라미터
- 파이썬 래퍼 XGBoost 적용 – 위스콘신 유방암 예측
- 사이킷런 래퍼 XGBoost의 개요 및 적용
- 4.7. LightGBM
- LightGBM 설치
- LightGBM 하이퍼 파라미터
- 하이퍼 파라미터 튜닝 방안
- 파이썬 래퍼 LightGBM과 사이킷런 래퍼 XGBoost,
- LightGBM 하이퍼 파라미터 비교
- LightGBM 적용 – 위스콘신 유방암 예측
- 4.8. 분류 실습 - 캐글 산탄데르 고객 만족 예측
- 데이터 전처리
- XGBoost 모델 학습과 하이퍼 파라미터 튜닝
- LightGBM 모델 학습과 하이퍼 파라미터 튜닝
- 4.9. 분류 실습 – 캐글 신용카드 사기 검출
- 언더 샘플링과 오버 샘플링의 이해
- 데이터 일차 가공 및 모델 학습/예측/평가
- 데이터 분포도 변환 후 모델 학습/예측/평가
- 이상치 데이터 제거 후 모델 학습/예측/평가
- SMOTE 오버 샘플링 적용 후 모델 학습/예측/평가
- 4.10. 스태킹 앙상블
- 기본 스태킹 모델
- CV 세트 기반의 스태킹
- 4.11. 정리
- ▣ 5장: 회귀
- 5.1. 회귀 소개
- 5.2. 단순 선형 회귀를 통한 회귀 이해
- 5.3. 비용 최소화하기 – 경사 하강법(Gradient Descent) 소개
- 5.4. 사이킷런 LinearRegression을 이용한 보스턴 주택 가격 예측
- LinearRegression 클래스 - Ordinary Least Squares
- 회귀 평가 지표
- LinearRegression을 이용해 보스턴 주택 가격 회귀 구현
- 5.5. 다항 회귀와 과(대)적합/과소적합 이해
- 다항 회귀 이해
- 다항 회귀를 이용한 과소적합 및 과적합 이해
- 편향-분산 트레이드오프(Bias-Variance Trade off)
- 5.6. 규제 선형 모델 – 릿지, 라쏘, 엘라스틱넷
- 규제 선형 모델의 개요
- 릿지 회귀
- 라쏘 회귀
- 엘라스틱넷 회귀
- 선형 회귀 모델을 위한 데이터 변환
- 5.7. 로지스틱 회귀
- 5.8. 회귀 트리
- 5.9. 회귀 실습 – 자전거 대여 수요 예측
- 데이터 클렌징 및 가공
- 로그 변환, 피처 인코딩과 모델 학습/예측/평가
- 5.10. 회귀 실습 – 캐글 주택 가격: 고급 회귀 기법
- 데이터 사전 처리(Preprocessing)
- 선형 회귀 모델 학습/예측/평가
- 회귀 트리 모델 학습/예측/평가
- 회귀 모델의 예측 결과 혼합을 통한 최종 예측
- 스태킹 앙상블 모델을 통한 회귀 예측
- 5.11. 정리
- ▣ 6장: 차원 축소
- 6.1. 차원 축소(Dimension Reduction) 개요
- 6.2. PCA(Principal Component Analysis)
- PCA 개요
- 6.3. LDA(Linear Discriminant Analysis)
- LDA 개요
- 붓꽃 데이터 세트에 LDA 적용하기
- 6.4. SVD(Singular Value Decomposition)
- SVD 개요
- 사이킷런 TruncatedSVD 클래스를 이용한 변환
- 6.5. NMF(Non-Negative Matrix Factorization)
- NMF 개요
- 6.6. 정리
- ▣ 7장: 군집화
- 7.1. K-평균 알고리즘 이해
- 사이킷런 KMeans 클래스 소개
- K-평균을 이용한 붓꽃 데이터 세트 군집화
- 군집화 알고리즘 테스트를 위한 데이터 생성
- 7.2. 군집 평가(Cluster Evaluation)
- 실루엣 분석의 개요
- 붓꽃 데이터 세트를 이용한 군집 평가
- 군집별 평균 실루엣 계수의 시각화를 통한 군집 개수 최적화 방법
- 7.3. 평균 이동
- 평균 이동(Mean Shift)의 개요
- 7.4. GMM(Gaussian Mixture Model)
- GMM(Gaussian Mixture Model) 소개
- GMM을 이용한 붓꽃 데이터 세트 군집화
- GMM과 K-평균의 비교
- 7.5. DBSCAN
- DBSCAN 개요
- DBSCAN 적용하기 – 붓꽃 데이터 세트
- DBSCAN 적용하기 – make_circles( ) 데이터 세트
- 7.6. 군집화 실습 – 고객 세그먼테이션
- 고객 세그먼테이션의 정의와 기법
- 데이터 세트 로딩과 데이터 클렌징
- RFM 기반 데이터 가공
- RFM 기반 고객 세그먼테이션
- 7.7. 정리
- 7.1. K-평균 알고리즘 이해
- ▣ 8장: 텍스트 분석
- NLP이냐 텍스트 분석이냐?
- 8.1. 텍스트 분석 이해
- 텍스트 분석 수행 프로세스
- 파이썬 기반의 NLP, 텍스트 분석 패키지
- 8.2. 텍스트 사전 준비 작업(텍스트 전처리) - 텍스트 정규화
- 클렌징
- 텍스트 토큰화
- 스톱 워드 제거
- Stemming과 Lemmatization
- 8.3. Bag of Words – BOW
- BOW 피처 벡터화
- 사이킷런의 Count 및 TF-IDF 벡터화 구현: CountVectorizer, TfidfVectorizer __BOW 벡터화를 위한 희소 행렬
- 희소 행렬 - COO 형식
- 희소 행렬 – CSR 형식
- 8.4. 텍스트 분류 실습 – 20 뉴스그룹 분류
- 텍스트 정규화
- 피처 벡터화 변환과 머신러닝 모델 학습/예측/평가
- 사이킷런 파이프라인(Pipeline) 사용 및 GridSearchCV와의 결합
- 8.5. 감성 분석
- 감성 분석 소개
- 지도학습 기반 감성 분석 실습 – IMDB 영화평
- 비지도학습 기반 감성 분석 소개
- SentiWordNet을 이용한 감성 분석
- VADER를 이용한 감성 분석
- 8.6. 토픽 모델링(Topic Modeling) - 20 뉴스그룹
- 8.7. 문서 군집화 소개와 실습(Opinion Review 데이터 세트)
- 문서 군집화 개념
- Opinion Review 데이터 세트를 이용한 문서 군집화 수행하기
- 군집별 핵심 단어 추출하기
- 8.8. 문서 유사도
- 문서 유사도 측정 방법 – 코사인 유사도
- 두 벡터 사잇각
- Opinion Review 데이터 세트를 이용한 문서 유사도 측정
- 8.9. 한글 텍스트 처리 – 네이버 영화 평점 감성 분석
- 한글 NLP 처리의 어려움
- KoNLPy 소개
- 데이터 로딩
- 8.10. 텍스트 분석 실습–캐글 Mercari Price Suggestion Challenge
- 데이터 전처리
- 피처 인코딩과 피처 벡터화
- 릿지 회귀 모델 구축 및 평가
- LightGBM 회귀 모델 구축과 앙상블을 이용한 최종 예측 평가
- 8.11. 정리
- ▣ 9장: 추천 시스템
- 9.1. 추천 시스템의 개요와 배경
- 추천 시스템의 개요
- 온라인 스토어의 필수 요소, 추천 시스템
- 추천 시스템의 유형
- 9.2. 콘텐츠 기반 필터링 추천 시스템
- 9.3. 최근접 이웃 협업 필터링
- 9.4. 잠재 요인 협업 필터링
- 잠재 요인 협업 필터링의 이해
- 행렬 분해의 이해
- 확률적 경사 하강법을 이용한 행렬 분해
- 9.5. 콘텐츠 기반 필터링 실습 – TMDB 5000 영화 데이터 세트
- 장르 속성을 이용한 영화 콘텐츠 기반 필터링
- 데이터 로딩 및 가공
- 장르 콘텐츠 유사도 측정
- 장르 콘텐츠 필터링을 이용한 영화 추천
- 9.6. 아이템 기반 최근접 이웃 협업 필터링 실습
- 데이터 가공 및 변환
- 영화 간 유사도 산출
- 아이템 기반 최근접 이웃 협업 필터링으로 개인화된 영화 추천
- 9.7. 행렬 분해를 이용한 잠재 요인 협업 필터링 실습
- 9.8. 파이썬 추천 시스템 패키지 - Surprise
- Surprise 패키지 소개
- Surprise를 이용한 추천 시스템 구축
- Surprise 주요 모듈 소개
- Surprise 추천 알고리즘 클래스
- 베이스라인 평점
- 교차 검증과 하이퍼 파라미터 튜닝
- Surprise를 이용한 개인화 영화 추천 시스템 구축
- 9.9. 정리
- 9.1. 추천 시스템의 개요와 배경
4장 결정트리의 human activity 데이터 세트에 중복된 Feature명으로 인해 신규 버전(0.25버전 이상)의 Pandas에서 Duplicate name 에러가 발생하는 경우에 대해 다음 내용을 수정하고
- 중복 feature명에 대해 원본 feature명에 '_1(또는 2)'를 추가로 부여하는 함수인 get_new_feature_name_df() 생성
- get_human_dataset() 함수는 중복된 feature명을 새롭게 수정하는 get_new_feature_name_df() 함수를 반영해서 수정
수정 사항이 반영된 아래의 2개의 주피터 노트북 파일을 새로 업로드했습니다. 위와 같은 문제가 발생할 경우 아래 파일을 참고하시기 바랍니다.
- 4.2 결정 트리_Ver01.ipynb
- 4.3_앙상블학습4.4랜덤포레스트_4.5_GBM_Ver01
36쪽, 본문 두 번째 예제 코드
org_array = np.array([ 3, 1, 9, 5]) sort_indices = np.argsort(org_array) print(type(sort_indices)) print('행렬 정렬 시 원본 행렬의 인덱스:', sort_indices)
==>
org_array = np.array([ 3, 1, 9, 5]) sort_indices_desc = np.argsort(org_array)[::-1] print('행렬 내림차순 정렬 시 원본 행렬의 인덱스:', sort_indices_desc)
69쪽, 본문 2번째 줄
iloc[0, 0]
을 적용해 보겠습니다.==>
iloc[0, 1]
을 적용해 보겠습니다.70쪽, 5번째 예제 코드
print('명칭 기반 ix slicing\n', data_df.ix['one':'two', 'name'], '\n') print('위치 기반 iloc slicing\n', data_df.iloc[0:1, 0], '\n') print('명칭 기반 loc slicing\n', data_df.loc['one':'two', 'name'])
==>
print('명칭 기반 ix slicing\n', data_df.ix['one': 'two', 'Name'], '\n') print('위치 기반 iloc slicing\n', data_df.iloc[0:1, 0], '\n') print('명칭 기반 loc slicing\n', data_df.loc['one': 'two', 'Name'])
77쪽, 본문 3번째 줄
SQ
, 판다스 모두==>
SQL
, 판다스 모두108쪽, 페이지 상단 예제 코드의 2번째 줄
print('검증 레이블 데이터 분포:\n', label_test.value_counts())iris_df['label'].value_counts()
==>
print('검증 레이블 데이터 분포:\n', label_test.value_counts())
110쪽, 본문 8번째 줄
다음 코드는 KFold를 이용해 데이터를 분리한 것입니다
==>
다음 코드는 StratifiedKFold를 이용해 데이터를 분리한 것입니다.
112쪽, 본문 밑에서 2번째 줄
교차 검증 폴드 수는
5
,==>
교차 검증 폴드 수는
3
,115쪽, 상단 예제 코드의 6번째 줄
iris = load_iris()
==>
iris_data = load_iris()
135쪽, 본문 2번째 줄
그리고 여자 Senior의 경우는
==>
그리고 여자 Elderly의 경우는
157쪽, 본문 밑에서 4번째 줄
predict_prob( )
메서드로 구한==>
predict_proba( )
메서드로 구한167쪽, 페이지 하단 도표
predict_prob( )
의 반환 값 array에서==>
predict_proba( )
의 반환 값 array에서169쪽, 본문 4번째 줄
FRP
이 작은 상태에서==>
FPR
이 작은 상태에서170쪽, 페이지 상단 예제 코드의 3번째 줄
pred = lr_clf.predict(X_test)
==>
pred = lr_clf.predict_proba(X_test)[:, 1]
180쪽, 밑에서 8번째 줄
적용될
수
알고리즘입니다.==>
적용될
수 있는
알고리즘입니다.203쪽, 예제 실행 시 사이킷런 버전이 0.21일 경우('mean_train_score' 키가 삭제되어 오류가 발생) 다음과 같이 예제 코드를 수정
# GridSearchCV 객체의 cv_results_ 속성을 DataFrame으로 생성. cv_results_df = pd.DataFrame(grid_cv.cv_results_) # max_depth 파라미터 값과 그때의 테스트 세트, 학습 데이터 세트의 정확도 수치 추출 cv_results_df[['param_max_depth', 'mean_test_score', 'mean_train_score']]
==>
# GridSearchCV 객체의 cv_results_ 속성을 DataFrame으로 생성. cv_results_df = pd.DataFrame(grid_cv.cv_results_) # max_depth 파라미터 값과 그때의 테스트 세트, 학습 데이터 세트의 정확도 수치 추출 cv_results_df[['param_max_depth', 'mean_test_score']]
223쪽, 본문 9번째 줄
GridSeachCV
, Pipeline 등)와==>
GridSearchCV
, Pipeline 등)와243쪽, 밑에서 12번째 줄
sub_sample
로==>
subsample
로251쪽, 본문 5번째 줄
n_estimators는
200
으로 하되 early_stopping_rounds를50
으로 설정합니다.==>
n_estimators는
500
으로 하되 early_stopping_rounds를100
으로 설정합니다.255쪽, 페이지 하단 예제코드의 4번째 줄
LGBM_clf = LGBMClassifier(n_estimators=200)
==>
lgbm_clf = LGBMClassifier(n_estimators=200)
259쪽, 본문 밑에서 2번째 줄
284,807개의 레코드에서
Not Null
값은 없으며,==>
284,807개의 레코드에서
결측치
값은 없으며,269쪽, 페이지 상단 예제 코드의 10번째 줄
iqr_weight = boundary * weight
==>
iqr_weight = iqr * weight
300쪽, 표 내용 중 MSE 항목의 수식을 다음 수식으로 교체
308쪽, 밑에서 6번째 줄
마찬가지로 두 번째 입력 단항 계수 피처 [x1 = 0, x2 = 1]은 [1, 2, 3, 4, 6, 9]로 변환됩니다.
==>
마찬가지로 두 번째 입력 단항 계수 피처 [x1 = 2, x2 = 3]은 [1, 2, 3, 4, 6, 9]로 변환됩니다.
309쪽, 페이지 상단의 polynomial_func 함수를 다음 코드로 교체
def polynomial_func(X): y = 1 + 2*X[:,0] + 3*X[:,0]**2 + 4*X[:,1]**3 return y
309쪽, 페이지 상단의 [Output]을 다음 내용으로 교체
일차 단항식 계수 feature: [[0 1] [2 3]] 삼차 다항식 결정값: [ 5 125]
309쪽, 페이지 하단의 [Output]을 다음 내용으로 교체
3차 다항식 계수 feature: [[ 1. 0. 1. 0. 0. 1. 0. 0. 0. 1.] [ 1. 2. 3. 4. 6. 9. 8. 12. 18. 27.]] Polynomial 회귀 계수 [0. 0.18 0.18 0.36 0.54 0.72 0.72 1.08 1.62 2.34]
310쪽, 예제 코드의 polynomial_func 함수를 다음 코드로 교체
def polynomial_func(X): y = 1 + 2*X[:,0] + 3*X[:,0]**2 + 4*X[:,1]**3 return y
310쪽, 페이지 하단의 [Output]을 다음 내용으로 교체
Polynomial 회귀 계수 [0. 0.18 0.18 0.36 0.54 0.72 0.72 1.08 1.62 2.34]
312쪽, 예제 코드의 밑에서 16번째 줄
print('\nDegree {0} 회귀 계수는 {1} 입니다.'.format(degrees[i], np.round(coefficients),2))
==>
print('\nDegree {0} 회귀 계수는 {1} 입니다.'.format(degrees[i], np.round(coefficients,2)))
319쪽, 본문 첫 번째 줄
alpha가
10
일 때 평균 RMSE가5.524
로 가장 좋습니다.==>
alpha가
100
일 때 평균 RMSE가5.332
로 가장 좋습니다.342쪽, 페이지 상단 예제 코드의 밑에서 3번째 줄
# MSE는 사이킷런의 mean_absolute_error()로 계산
==>
# MAE는 사이킷런의 mean_absolute_error()로 계산
360쪽, 본문 밑에서 7번째 줄
왜곡 정도가 높다고
판단지만,
상황에 따라==>
왜곡 정도가 높다고
판단하지만,
상황에 따라378쪽, 본문 첫 번째 줄
고유벡터 직교
행렬, 고유값
정방 행렬==>
고유벡터 직교
행렬 * 고유값
정방 행렬381쪽, 페이지 상단 첫 번째 예제 코드
from sklearn.decomposition import PCA pca = PCA(n_components=2) #fit( )과 transform( )을 호출해 PCA 변환 데이터 반환 pca.fit(iris_scaled) iris_pca = pca.transform(iris_scaled) print(iris_pca.shape)
==>
# PCA 변환된 데이터의 컬럼명을 각각 pca_component_1, pca_component_2로 명명 pca_columns=['pca_component_1','pca_component_2'] irisDF_pca = pd.DataFrame(iris_pca,columns=pca_columns) irisDF_pca['target']=iris.target irisDF_pca.head(3)
384쪽, 페이지 하단 예제 코드를 다음 코드로 교체
# header로 의미없는 첫행 제거, iloc로 기존 id 제거 import pandas as pd df = pd.read_excel('default of credit card clients.xls', header=1, sheet_name='Data').iloc[0:,1:] print(df.shape) df.head(3)
392쪽, 밑에서 첫 번째 줄
U의 차원이
m × n
,==>
U의 차원이
m × m
,409쪽, 페이지 상단 예제 코드를 다음 코드로 교체
irisDF['target'] = iris.target irisDF['cluster'] = kmeans.labels_ iris_result = irisDF.groupby(['target', 'cluster'])['sepal_length'].count() print(iris_result)
463쪽, 본문 5번째 줄
NLTK(National Language Toolkit for Python)
==>
NLTK(Natural Language Toolkit for Python)
464쪽, 페이지 하단 예제 코드의 첫 번째 줄
from nltk import sent_tokenize
==>
from nltk import sent_tokenize import nltk nltk.download('punkt')
469쪽, 페이지 하단 예제 코드의 첫 번째 줄
from nltk.stem import WordNetLemmatizer
==>
from nltk.stem import WordNetLemmatizer import nltk nltk.download('wordnet')
560쪽, 페이지 하단 그림을 다음 그림으로 교체(《블레이드 러너 2049》와 《프로메테우스》의 설명이 뒤바뀜)