ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python 데이터분석 기초 55 - Logistic Regression : 다항분류 (얘는 활성화 함수로 softmax - 결과값을 확률로 반환), 표준
    Python 데이터 분석 2022. 11. 18. 12:41

     

    # Logistic Regression : 다항분류 (얘는 활성화 함수로 softmax - 결과값을 확률로 반환)
    # Logistic Regression은 다중 클래스를 지원하도록 일반화 되어 있다. softmax 함수를 사용하기 때문이다.
    # iris dataset을 사용 - 꽃의 종류를 세가지로 분류한다.
    
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import model_selection
    from sklearn.linear_model import LinearRegression
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score
    from sklearn.preprocessing import StandardScaler # 표준화
    from sklearn import datasets
    from daal4py.sklearn.linear_model.logistic_path import LogisticRegression
    from sklearn.metrics import accuracy_score
    
    iris = datasets.load_iris()
    # print(iris.DESCR)
    print(iris.keys())
    x = iris.data
    # print(x)
    print(np.corrcoef(iris.data[:, 2], iris.data[:, 3])) # 0.96286543
    
    x = iris.data[:, [2, 3]] # petal.length, petal.width만 참여
    y = iris.target
    print(x[:3])
    print(y[:3], ' ', set(y)) # 종류가 3가지 {0, 1, 2}
    
    # train / test split (7 : 3)
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 0)
    print(x_train.shape, x_test.shape, y_train.shape, y_test.shape) # (105, 2) (45, 2) (105,) (45,)
    
    '''
    # data scaling : 표준화 - 최적화 과정에서 안정성, 수렴 속도 향상, 오버/언더 플로우 방지 ... 가능
    print(x_train[:3])
    sc = StandardScaler() # 대상이 독립변수이다.
    sc.fit(x_train); sc.fit(x_test)
    x_train = sc.transform(x_train)
    x_test = sc.transform(x_test)
    print(x_train[:3]) # 표준화
    # 스케일링 자료 원복
    inver_x_train = sc.inverse_transform(x_train)
    print(inver_x_train[:3])
    '''
    
    model = LogisticRegression(C = 1.0, random_state = 0, verbose = 0) # C = 1.0 L2규제(패널티 적용) - 값이 작을수록 규제는 강화된다. vrtbodr는 진행과정을 보여준다.
    print(model)
    model.fit(x_train, y_train)
    
    # 분류 예측
    y_pred = model.predict(x_test)
    print('예측값 :',y_pred)
    print('실제값 :',y_test)
    print('총갯수 : %d, 오류수 : %d'%(len(y_test), (y_test != y_pred).sum()))
    
    # 분류 정확도(accuracy) 1
    print('%.5f'%accuracy_score(y_test, y_pred))
    
    # 분류 정확도(accuracy) 2
    con_mat = pd.crosstab(y_test, y_pred, rownames = ['예측치'], colnames = ['관측치'])
    print(con_mat)
    print((con_mat[0][0] + con_mat[1][1] + con_mat[2][2]) / len(y_test))
    
    # 분류 정확도(accuracy) 3
    print('test :', model.score(x_test, y_test))
    print('train :', model.score(x_train, y_train)) # 두 수치의 차이가 크면 과적합일 수 있다.
    
    # 모델 저장
    import pickle
    pickle.dump(model, open('cla_model.sav', mode = 'wb'))
    del model
    
    mymodel = pickle.load(open('cla_model.sav', mode = 'rb'))
    
    print('새로운 값으로 분류 예측 - petal.length, petal.width만 참여')
    print(x_test[:1])
    new_data = np.array([[5.1, 2.4], [0.3, 0.3], [3.4, 0.2]])
    # 참고 : 만약 표준화로 학습했다면 new_data도 표준화 해 줘야 된다.
    new_pred = mymodel.predict(new_data)   # softmax가 반환한 결과 중 가장 큰 인덱스를 취한 결과
    print('예측 결과 :', new_pred)
    print(mymodel.predict_proba(new_data)) # softmax가 반환한 결과
    
    # 시각화
    from matplotlib.colors import ListedColormap
    plt.rc('font', family='malgun gothic')      
    plt.rcParams['axes.unicode_minus']= False
    
    def plot_decision_region(X, y, classifier, test_idx=None, resolution=0.02, title=''):
        markers = ('s', 'x', 'o', '^', 'v')        # 점 표시 모양 5개 정의
        colors = ('r', 'b', 'lightgreen', 'gray', 'cyan')
        cmap = ListedColormap(colors[:len(np.unique(y))])
        # print('cmap : ', cmap.colors[0], cmap.colors[1], cmap.colors[2])
    
        # decision surface 그리기
        x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
        x2_min, x2_max = X[:, 0].min() - 1, X[:, 0].max() + 1
        xx, yy = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
    
        # xx, yy를 ravel()를 이용해 1차원 배열로 만든 후 전치행렬로 변환하여 퍼셉트론 분류기의 
        # predict()의 인자로 입력하여 계산된 예측값을 Z로 둔다.
        Z = classifier.predict(np.array([xx.ravel(), yy.ravel()]).T)
        Z = Z.reshape(xx.shape)       # Z를 reshape()을 이용해 원래 배열 모양으로 복원한다.
    
        # X를 xx, yy가 축인 그래프 상에 cmap을 이용해 등고선을 그림
        plt.contourf(xx, yy, Z, alpha=0.5, cmap=cmap)
        plt.xlim(xx.min(), xx.max())
        plt.ylim(yy.min(), yy.max())
    
        X_test = X[test_idx, :]
        for idx, cl in enumerate(np.unique(y)):
            plt.scatter(x=X[y==cl, 0], y=X[y==cl, 1], c=cmap(idx), marker=markers[idx], label=cl)
    
        if test_idx:
            X_test = X[test_idx, :]
            plt.scatter(X_test[:, 0], X_test[:, 1], c=[], linewidth=1, marker='o', s=80, label='testset')
    
        plt.xlabel('꽃잎 길이')
        plt.ylabel('꽃잎 너비')
        plt.legend(loc=2)
        plt.title(title)
        plt.show()
    
    x_combined_std = np.vstack((x_train, x_test))
    y_combined = np.hstack((y_train, y_test))
    plot_decision_region(X=x_combined_std, y=y_combined, classifier=mymodel,
                         test_idx=range(105, 150), title='scikit-learn제공') 
    
    
    
    <console>
    dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
    [[1.         0.96286543]
     [0.96286543 1.        ]]
    [[1.4 0.2]
     [1.4 0.2]
     [1.3 0.2]]
    [0 0 0]   {0, 1, 2}
    (105, 2) (45, 2) (105,) (45,)
    LogisticRegression(random_state=0)
    예측값 : [2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0
     2 1 1 2 0 2 0 0]
    실제값 : [2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0
     1 1 1 2 0 2 0 0]
    총갯수 : 45, 오류수 : 1
    0.97778
    관측치   0   1   2
    예측치            
    0    16   0   0
    1     0  17   1
    2     0   0  11
    0.9777777777777777
    test : 0.9777777777777777
    train : 0.9714285714285714
    새로운 값으로 분류 예측 - petal.length, petal.width만 참여
    [[5.1 2.4]]
    예측 결과 : [2 0 1]
    [[9.96150927e-05 8.40157448e-02 9.15884640e-01]
     [9.98114816e-01 1.88518161e-03 1.94610157e-09]
     [1.75251477e-01 8.23787881e-01 9.60642066e-04]]

     

    댓글

Designed by Tistory.