지난해 겨울 텐 서 플로우 OpenCV 출간 이후 7 개월 만 에 2 권 에 해당 하 는 “ Scikit PyTorch 머신 러닝 ” 을 출간 하 게 되 었 다 . 각권 이 450 페이지 이 므로 합 900 페이지 에 달하 는 내용 이 라 무슨 머신 러닝 을 공부 하 는 데 분량 이 왜 이렇게 많 은가 ? 하 고 의문 을 가질 수 도 있 겠 으나 그 내용 이 튜토리얼 성 에 가까워 사실 그렇게 큰 부담 은 없 는 책 이 다 . 물론 책 내부 에 파이 선 코드 를 끼워 넣 는 먹통 짓 은 지금 세상 에서 는 할 필요 가 없 을 것 이 다 . 해당 책 의 머리말 에 써둔 하이퍼링크 목차 를 다운 받 으면 블로그 를 직접 열 어 볼 수 있 으며 거기 서 예제 코드 를 다운 받 을 수 있 다 . 1 권 에 해당 하 는 텐 서 플로우 OpenCV 머신 러닝 에서 는 2017 년 9 월 경 부터 2018 년 12 월 사이 에 머신 러닝 을 이해 하 고자 하 는 필자 의 열공 ( ? ) 내용 을 담 아 보 았 다면 2 권 에서 는 1 권 에서 제기 되 었 던 여러 내용 들 에 대해서 해답 을 찾아가 는 내용 들 을 꽤 많이 포함 하 였 다 . 2 권 이 라고 해서 내용 적 으로 완전히 정리 된 것 은 아니 기 때문 에 다시 3 권 의 출발점 이 될 수 도 있 을 것 이 다 . 다소 아쉬운 점 은 흥미 위주 로 시작 했 던 1 , 2 권 의 Softmax 관련 내용 을 완전히 정리 하 지 는 못했 는데 이 그 이유 는 R & D 영역 으로 넘어갔 기 때문 이 다 . 2020 년 에 는 그 내용 까지 도 포함 하 여 출간 할 계획 이 다 . 본 서 의 출간 목적 은 작가 들 과 출판사 가 염원 하 는 베스트셀러 화 가 목표 가 아니 다 . 사회 적 으로 인공지능 ( 머신 러닝 ) 에 대한 이해 필요 성 이 점증 하 는 시기 이 며 , 인공지능 분야 의 발전 속도 가 상당히 빠르 기 때문 에 그 에 맞춰서 비 전공 자라 할지라도 머신 러닝 에 입문 해 볼 수 있 도록 경험 과 생각 을 공유 해 보 고자 하 는 것 이 다 . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +++++++++++++++++++++++++ 랜덤 포레스트 ( Random Forrests ) 머신 러닝 기법 은 Classification 성능 이라든지 또는 확장 성 ( Scalability ) 과 쉬운 사용법 으로 인해 지난 10 년 간 에 걸쳐 각광 을 받 았 다 . 랜덤 포레스트 기법 은 직관 적 으로 Decision Tree 들 로 이루어진 앙상블 이 라고 볼 수 있 다 . 즉 랜덤 포레스트 는 높 은 변동성 을 가지 는 여러 Decision Tree 들 의 결과 를 대상 으로 평균 을 냄 으로 인해 보다 로버 스틱 하 면서 Overfitting 에 덜 민감 한 머신 러닝 모델 을 구축 할 수 있 게 된다 . 랜덤 포레스트 알고리듬 은 다음 과 같이 4 단계 로 구성 이 될 수 있 다 . 사이즈 가 n 인 랜덤 한 시작 용 샘플 을 뽑 는다 . 시작 용 샘플 들 로부터 Decision Tree 를 키워 나간다 . - 각 Tree 마디 ( node ) 에서 시작 용 샘플 들 의 replacement 없이 랜덤 하 게 d 개 의 특징 들 을 선택 한다 . - 이 특징 을 사용 하 면서 IG ( Information Gain ) 를 최대 화 할 수 있 도록 Tree 를 마디 ( node ) 에서 분리 시킨다 . gini impurity 나 entropy 둘 중 에 하나 를 택하 면 된다 3 . 1 , 2 단계 를 k 번 ( estimator 의 수 ) 반복 하 여 앙상블 을 구성 해야 한다 . 4 . 다수결 원칙 에 의해 class 라벨 을 할당 한 각 Tree 의 예측 값 을 합하 도록 한다 . DecisionTree Classifier 결과 와 RandomForestClassifier 결과 를 비교 해 보 자 . 경계 에서 Classification 결과 는 Decision Tree 가 보다 민감 해 보인다 . # Random _ forest _ 01 from sklearn import __ version __ as sklearn _ versionfrom sklearn import datasetsimport numpy as npfrom sklearn . model _ selection import train _ test _ splitfrom sklearn . metrics import accuracy _ scorefrom matplotlib . colors import ListedColormapimport matplotlib . pyplot as pltfrom sklearn . tree import D ecisionTreeClassifierfrom sklearn . ensemble import RandomForestClassifier # Loading the Iris dataset from scikit - learn . iris = datasets . load _ iris ( ) X = iris . data [ : , [ 2 , 3 ] ] y = iris . targetprint ( ' Class labels : ', np . unique ( y ) ) # Splitting data into 70 % training and 30 % test data : X _ train , X _ test , y _ train , y _ test = train _ test _ split ( X , y , test _ size = 0 . 3 , random _ state = 1 , stratify = y ) print ( ' Labels counts in y : ', np . bincount ( y ) ) print ( ' Labels counts in y _ train : ', np . bincount ( y _ train ) ) print ( ' Labels counts in y _ test : ', np . bincount ( y _ test ) ) def plot _ decision _ regions ( X , y , classifier , test _ idx = None , resolution = 0 . 02 ) : # setup marker generator and color map markers = ( ' s ', ' x ', ' o ', '^', ' v ') colors = ( ' red ', ' blue ', ' lightgreen ', ' gray ', ' cyan ') cmap = ListedColormap ( colors [ : len ( np . unique ( y ) ) ] ) # plot the decision surface x 1 _ min , x 1 _ max = X [ : , 0 ] . min ( ) - 1 , X [ : , 0 ] . max ( ) + 1 x 2 _ min , x 2 _ max = X [ : , 1 ] . min ( ) - 1 , X [ : , 1 ] . max ( ) + 1 xx 1 , xx 2 = np . meshgrid ( np . arange ( x 1 _ min , x 1 _ max , resolution ) , np . arange ( x 2 _ min , x 2 _ max , resolution ) ) Z = classifier . predict ( np . array ( [ xx 1 . ravel ( ) , xx 2 . ravel ( ) ] ) . T ) Z = Z . reshape ( xx 1 . shape ) plt . contourf ( xx 1 , xx 2 , Z , alpha = 0 . 3 , cmap = cmap ) plt . xlim ( xx 1 . min ( ) , xx 1 . max ( ) ) plt . ylim ( xx 2 . min ( ) , xx 2 . max ( ) ) 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 ') # highlight test samples if test _ idx : # plot all samples X _ test , y _ test = X [ test _ idx , : ] , y [ test _ idx ] plt . scatter ( X _ test [ : , 0 ] , X _ test [ : , 1 ] , c ='', edgecolor =' black ', alpha = 1 . 0 , linewidth = 1 , marker =' o ', s = 100 , label =' test set ')# Decision tree learningtree = DecisionTreeClassifier ( criterion =' gini ', max _ depth = 4 , random _ state = 1 ) tree . fit ( X _ train , y _ train ) y _ pred = tree . predict ( X _ test ) print ( '\ nDecision Tree ') print ( ' Misclassified samples : % d ' % ( y _ test ! = y _ pred ) . sum ( ) ) print ( ' Accuracy : %. 2 f ' % accuracy _ score ( y _ test , y _ pred ) ) print ( ' Accuracy : %. 2 f ' % tree . score ( X _ test , y _ test ) ) X _ combined = np . vstack ( ( X _ train , X _ test ) ) y _ combined = np . hstack ( ( y _ train , y _ test ) ) plot _ decision _ regions ( X _ combined , y _ combined , classifier = tree , test _ idx = range ( 105 , 150 ) ) plt . xlabel ( ' petal length [ cm ] ') plt . ylabel ( ' petal width [ cm ] ') plt . legend ( loc =' upper left ') plt . tight _ layout ( ) plt . show ( ) # Combining weak to strong learners via random forestsforest = RandomForestClassifier ( criterion =' entropy ', n _ estimators = 25 , max _ depth = None , random _ state = 1 , n _ jobs = 2 ) forest . fit ( X _ train , y _ train ) y _ pred = tree . predict ( X _ test ) print ( '\ nRandom Forests ') print ( ' Misclassified samples : % d ' % ( y _ test ! = y _ pred ) . sum ( ) ) print ( ' Accuracy : %. 2 f ' % accuracy _ score ( y _ test , y _ pred ) ) print ( ' Accuracy : %. 2 f ' % tree . score ( X _ test , y _ test ) ) plot _ decision _ regions ( X _ combined , y _ combined , classifier = forest , test _ idx = range ( 105 , 150 ) ) plt . xlabel ( ' petal length [ cm ] ') plt . ylabel ( ' petal width [ cm ] ') plt . legend ( loc =' upper left ') plt . tight _ layout ( ) plt . show ( )