ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 머신러닝 03 - sklearn 알아 보기 (분류 - 2 (몇가지 알고리즘))
    빅데이터/Machine-Learning 2022. 2. 8. 21:39

    패스트캠퍼스 '직장인을 위한 파이썬 데이터분석 올인원 패키치 Online' 참조

     

    • 첫 강의에서 서술했듯이 sklearn은 많은 알고리즘을 제공 한다

     

     

    01 회귀 알고리즘

    • 로지스틱 회귀 (Logistic regression) - 독립 변수의 선형 결합을 이용하여 사건의 발생 가능성을 예측하는 기법
    • 로지스틱 회귀는 서포트 벡터 머신(SVM)과 같은 개념으로 2진 분류만 가능 (2개의 클래스 판별만 가능)
    • 3개이상일 경우 아래와 같이 달라짐
      ONE-VS-REST(OvR) - K개의 클래스가 존재할 때, 1개의 클래스를 제외한 다른 클래스를 K개 만들어, 각각의 이진 분류에 대한 롹률을 구하고 총합을 통해 최종 클래스를 판별
      ONE-VS-ONE(OvO) - 4개의 계절을 구분하는 클래스가 존재한다고 가정했을때, 0vs1-0vs2-0vs3.. 2vs3 까지 NX(N-1)/2개의 분류를 만들어 가장 많이 양성으로 선택된 클래스를 판별
      - 대부분 OvsR 전략을 선호

     

    - 로지스틱 회귀를 해보자! 아래와 같이 로지스틱스회귀를 임포트 한다

    from sklearn.linear_model import LogisticRegression
    # step 1 - 모델 선언 * 너무나도 중요함
    lr = LogisticRegression()
    
    # step 2 - 데이터 준비
    # stratify='' - 데이터 세트 클래스 비율을 유지 한다(즉 훈련용이든 테스트 용이든 고르기 0,1,2 클래스를 다 가지도록 하는것, 쏠림방지)
    x_train, x_valid, y_train, y_valid = train_test_split(df_iris.drop('target',1), df_iris['target'],
                                                         stratify=df_iris['target'])
                                                         
    # step 3 - 모델 학습
    lr.fit(x_train, y_train)
    
    # step 4 - 예측
    prediction = lr.predict(x_valid)
    
    prediction[:5]
    array([1, 1, 2, 0, 2])
    
    # prediction이 y가 예상한값과 맞으면 평균을 구함
    # True = 1 , False = 0
    (prediction == y_valid).mean()
    0.9736842105263158

    - 로직을 반드시 정리하고 넘어 가야 한다.

    1. 모델 선언
    2. 데이터를 훈련용, 검증용으로 준비 (훈련데이터에는 예측데이터가 들어가면 안되므로 .drop()으로 걸러준다)
      훈련 데이터 - x(feature) = df_iris.drop('target',1)
      예측 데이터 - y(label) = df_iris['target']
      여기서 각각의 데이터가 8:2 로 훈련용/검증용으로 들어 간다 
      이값들이 80:20 으로 나뉘어서 훈련용, 검증용으로 나뉜다
    3. 여기서 이해가 안됬던 부분이 '.fit() - 훈련을 시킨다' 인다 훈련보다는 학습을 시킨다고 보면 좋을 듯 하다. 가장 쉽게 말해 x데이터는 문제지, y데이터는 정답인것이다.
      이렇게 x 0,1,2 데이터는 4가지 변수의 데이터를 들고있고 이런 데이터는 0이라고 학습을 시키는것이다. 그렇게 되면 150개가 되는 데이터에서 0,1,2 번의 데이터와 가까운것들 혹은 0,1,2 번의 데이터처럼 특정한 값이 같은것들은 은 0으로 클래스 지정이 되도록 학습이 되는것.

    4. 학습이 끝나면 이제 학습이 잘되었는지 검증이 필요하므로 검증(예측)을 시켜 보는 것. .predict()함수의 역할은 주어진 데이터(x_valid)에 대한 예측 수행을 해 결과값을 리턴함 즉 아래의 사진처럼 학습 이후 검증 데이터를 주면 학습 데이터에서 학습한 것들로 예측을 하게 됨
      89번 변수의 특징은 어느 특정 클래스와 같다라고 예측을 함
    5. 그리고 예측값과 정답지인 y = y_valid랑 비교해서 정확도가 있는지를 판단 함 (True = 1, False = 0 이므로 정확할수록 1값과 가깝게 나옴) 
      일반적으로는 1.0에 가까운 값이 나오지 않는다. 가깝게 나옴
      ▶ 몇 가지 기억해야할 중요 부분 - 1) 'stratify'를 통한 데이터 균등분배 2) 학습 → 예측 → 예측 평가

     

     

    02 SGD Classifier (Stochastic Gradient Descent - 확률적 경사 하강법)

    • 오차가 가장 적은 지점을 찾아 점점점 선이 내려가는 분류법

    - 경사하강법을 임포트 해준다

    from sklearn.linear_model import SGDClassifier
    # 모델 선언
    sgd = SGDClassifier()
    
    # 모델 학습
    sgd.fit(x_train, y_train)
    
    # 예측
    prediction = sgd.predict(x_valid)
    
    # 예측 평가
    (prediction == y_valid).mean()
    
    0.9473684210526315 -> 1과 가까울수록 예측률이 정확함

     

     

     

    03 하이퍼 파라미터 튜닝 (Hyper-Parameter)

    • 각기 다른 알고리즘은 다른 파라미터 튜닝이 들어 간다
      보통 .fit()을 돌리게되면 아래와 같이 각각의 알고리즘에 맞는 하이퍼파라미터 튜닝값들이 나온다.
    • 모두 다 외울 순 없다. 알고리즘에 따라 필요한 하이퍼파라미터들을 넣으면 된다. 문서들을 참고하여 적절한 가설을 세우고 적용하고 검증을 해야 한다
    • 그 중 규제(penalty) 값을 많이 쓰게 된다(규제의 종류는 몇 가지 된다). 오버피팅을 방지하기 위한 키. 연습 해 보자
    # 규제 파라미터 penalty="", default 는 L2 
    sgd = SGDClassifier(penalty='elasticnet', random_state=0, n_jobs=-1)
    
    # 학습
    sgd.fit(x_train, y_train)
    
    # 예측
    prediction = sgd.predict(x_valid)
    
    # 예측 검증
    (prediction == y_valid).mean()
    0.9210526315789473
    1. random_state - 모델 성능을 볼 때 다른 파라미터 값때문에 좋은 성능이 나오는지 아니면 랜덤한 변수들을 통해 좋아졌는지 알기 어렵기 때문에 random_state 값을 고정해야한다. 고정하면 input data들을 나눌때 셔플을 통해 진행되는데 이 셔플 결과를 항상 동일하게 해준다. 즉 결과 재현에 반드시 필요하다. 숫자는 임의로 지정 가능 하다. 
      random_state를 고정하지 않으면 결과는 매번 바뀌게 될 것이다. 
      (참조 링크:https://www.inflearn.com/questions/110501)
    2. n_jobs - 이 파라미터를 지원하는 알고리즘이 따로 있다. CPU코어를 몇개 사용할지 정해줌. -1를 하면 모두 사용하게함

     

     

    04 K-NeighborsClassfier - 최근접 이웃 알고리즘

    • 새 샘플을 넣고 이 새 샘플이 특정 군집중 어느 군집에 가깝게 배치되는지 보는 알고리즘
      샘플에 근접하는 개수를 K로 지정. K=3일때는 B에 가깝고 K=7이면 A에 가깝다. 즉 K의 성능에 따라 갈린다


    • from sklearn.neighbors import KNeighborsClassifier # 모델 선언 knc = KNeighborsClassifier(n_neighbors=9) # 학습 knc.fit(x_train, y_train) # 예측 knc_pred = knc.predict(x_valid) # 예측 검증 (knc_pred == y_valid).mean() 1.0​

     

     

    05 서포트 벡터 머신 (SVC)

    • 딥러닝 이전 가장 성능이 좋았던 모델
    • 새로운 데이터가 어느 카테고리에 속할지 판단하는 비확률적 이진 선형 분류 모델
    • 경계로 표현되는 데이터들 중 가장 큰 폭을 가진 경계를 찾는 알고리즘
    • 로지스틱 회귀와 같이 이진 분류만 가능 (2개의 클래스만 판별 가능)
    • OvsR 전략 사용
    from sklearn.svm import SVC
    
    # 모델 선언
    svc = SVC()
    
    # 학습
    svc.fit(x_train, y_train)
    
    # 예측
    svc_pred = svc.predict(x_valid)
    
    # 예측 검증
    (svc_pred == y_valid).mean()
    1.0
    • SVC는 각 클래스 별 확률값을 리턴해주는 'decision_function()' 함수를 지원 한다
    svc_pred[:5]
    array([1, 1, 0, 0, 0])
    
    svc.decision_function(x_valid)[:5]
    array([[-0.21646074,  2.23781304,  0.87022263], = 0
           [-0.22300519,  2.23590015,  0.90478615], = 1
           [ 2.23204618,  1.15706748, -0.25362773], = 2
           [ 2.23566568,  1.10233201, -0.24688635], = 3
           [ 2.23376359,  1.14901038, -0.25313105]]) = 4
           
    0 번 리스트에는 1번째 값이 높음으로 x_valid 1번 값에 대한 클래스 정의는 1
    2 번 리스트에는 1번째 값이 높음으로 x_valid 2번 값에 대한 클래스 정의는 1
    3 번 리스트에는 0번째 값이 높음으로 x_valid 3번 값에 대한 클래스 정의는 0
    ...

     

     

     

    06 결정 트리 (Decision Tree)

    • 쉽게말해 스무고개를 타는것처럼 생각하면 된다.
    from sklearn.tree import DecisionTreeClassifier
    
    dtc = DecisionTreeClassifier(random_state=0) * max_dept='' 로 가지치기 개수 제한 가능
    dtc.fit(x_train, y_train)
    dtc_pred = dtc.predict(x_valid)
    
    (dtc_pred == y_valid).mean()
    1.0

    알고리즘을 쓸때 어떤 하이퍼파라미터들이 들어가는지 보고 random_state는 꼭 고정 해주자!

     

     

     

    06 - 2 트리 알고리즘 시각화

    #트리 알고리즘 시각화 툴
    from sklearn.tree import export_graphviz
    from subprocess import call
    
    def graph_tree(model):
        # .dot 파일로 export 
        export_graphviz(model, out_file='tree.dot')
        
        # 생성된 .dot 파일을 .png로 변환
        call(['dot', '-Tpng', 'tree.dot', '-o', 'decision-tree.png', '-Gdpi=600'])
        
        # .png출력
        return Image(filename = 'decision-tree.png', width=500)
        
    graph_tree(dtc)

    ▶ 주피터 노트북에선 오류가 걸린다.. 코랩에서는 정상 작동..

    1. value - 나눠진 클래스 개수 (Imbalanced 기준)
    2. X[3] 컬럼을 기준으로 <= 0.8 조건에 맞으면 0번 클래스
    3. 아니면 X[2] 컬럼을 기준으로 <= 4.95 이렇게 계속 가지를 치는 방식
    4. gini계수 - 불순도를 이야기 하며 높을수록 엔트로피가 높다라고 하며 엔트로피가 높다는 말은 클래스가 혼잡하게 섞여있다는 뜻
    5. * max_dept='' 로 가지치기 개수 제한 가능. 

     

Designed by Tistory.