ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Support Vector Machine(SVM) 예제 - 심장병 환자 데이터
    Python 데이터 분석 2022. 11. 23. 18:33

     

     

     

     

    <작성자 코드>

    # [SVM 분류 문제] 심장병 환자 데이터를 사용하여 분류 정확도 분석 연습
    # https://www.kaggle.com/zhaoyingzhu/heartcsv
    # https://github.com/pykwon/python/tree/master/testdata_utf8         Heartcsv
    #
    # Heart 데이터는 흉부외과 환자 303명을 관찰한 데이터다. 
    # 각 환자의 나이, 성별, 검진 정보 컬럼 13개와 마지막 AHD 칼럼에 각 환자들이 심장병이 있는지 여부가 기록되어 있다. 
    # dataset에 대해 학습을 위한 train과 test로 구분하고 분류 모델을 만들어, 모델 객체를 호출할 경우 정확한 확률을 확인하시오. 
    # 임의의 값을 넣어 분류 결과를 확인하시오.     
    # 정확도가 예상보다 적게 나올 수 있음에 실망하지 말자. ㅎㅎ
    #
    # feature 칼럼 : 문자 데이터 칼럼은 제외
    # label 칼럼 : AHD(중증 심장질환)
    #
    # 데이터 예)
    # "","Age","Sex","ChestPain","RestBP","Chol","Fbs","RestECG","MaxHR","ExAng","Oldpeak","Slope","Ca","Thal","AHD"
    # "1",63,1,"typical",145,233,1,2,150,0,2.3,3,0,"fixed","No"
    # "2",67,1,"asymptomatic",160,286,0,2,108,1,1.5,2,3,"normal","Yes"
    # ...
    
    import pandas as pd
    import numpy as np
    from sklearn import svm, metrics
    from sklearn.model_selection import train_test_split
    import matplotlib.pyplot as plt
    
    df = pd.read_csv('https://raw.githubusercontent.com/pykwon/python/master/testdata_utf8/Heart.csv', )
    df = df.drop(['Unnamed: 0'], axis=1)
    print(df.head(3), df.shape) # (303, 15)
    print(df.describe())
    print(df.info())
    # print(df.isnull().sum())
    df.fillna({'Ca':float(df['Ca'].mean())}, inplace=True)
    
    df_x = df.drop(columns = ['ChestPain', 'Thal', 'AHD'])
    df_y = df['AHD']
    
    x_train, x_test, y_train, y_test = train_test_split(df_x, df_y, test_size = 0.2, random_state = 1)
    print(x_train.shape, x_test.shape, y_train.shape, y_test.shape) # (242, 12) (61, 12) (242,) (61,)
    
    print()
    # model
    model = svm.SVC(C=1).fit(x_train, y_train)
    
    pred = model.predict(x_test)
    print('예측값 :', pred[:10])
    print('실제값 :', y_test[:10].values)
    
    acc = metrics.accuracy_score(y_test, pred)
    print('acc :', acc) # 0.67213
    
    print()
    # 교차 검증
    from sklearn import model_selection
    cross_vali = model_selection.cross_val_score(model, x_test, y_test, cv = 5)
    print('각각의 검증 정확도 :', cross_vali)
    print('평균 검증 정확도 :', cross_vali.mean())
    
    # 새 값으로 예측
    new_data = pd.DataFrame({'Age':[60, 65], 'Sex':[1, 0], 'RestBP':[145, 160], 'Chol':[250, 245], 'Fbs':[2, 0], 'RestECG':[1, 2], 'MaxHR':[150, 125], 'ExAng':[0, 1], 'Oldpeak':[2.3, 1.7], 'Slope':[3, 2], 'Ca':[3, 2]})
    new_pred = model.predict(new_data)
    print('새로운 예측값 :', new_pred)
    
    
    <console>
       Age  Sex     ChestPain  RestBP  Chol  ...  Oldpeak  Slope   Ca        Thal  AHD
    0   63    1       typical     145   233  ...      2.3      3  0.0       fixed   No
    1   67    1  asymptomatic     160   286  ...      1.5      2  3.0      normal  Yes
    2   67    1  asymptomatic     120   229  ...      2.6      2  2.0  reversable  Yes
    
    [3 rows x 14 columns] (303, 14)
                  Age         Sex      RestBP  ...     Oldpeak       Slope          Ca
    count  303.000000  303.000000  303.000000  ...  303.000000  303.000000  299.000000
    mean    54.438944    0.679868  131.689769  ...    1.039604    1.600660    0.672241
    std      9.038662    0.467299   17.599748  ...    1.161075    0.616226    0.937438
    min     29.000000    0.000000   94.000000  ...    0.000000    1.000000    0.000000
    25%     48.000000    0.000000  120.000000  ...    0.000000    1.000000    0.000000
    50%     56.000000    1.000000  130.000000  ...    0.800000    2.000000    0.000000
    75%     61.000000    1.000000  140.000000  ...    1.600000    2.000000    1.000000
    max     77.000000    1.000000  200.000000  ...    6.200000    3.000000    3.000000
    
    [8 rows x 11 columns]
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 303 entries, 0 to 302
    Data columns (total 14 columns):
     #   Column     Non-Null Count  Dtype  
    ---  ------     --------------  -----  
     0   Age        303 non-null    int64  
     1   Sex        303 non-null    int64  
     2   ChestPain  303 non-null    object 
     3   RestBP     303 non-null    int64  
     4   Chol       303 non-null    int64  
     5   Fbs        303 non-null    int64  
     6   RestECG    303 non-null    int64  
     7   MaxHR      303 non-null    int64  
     8   ExAng      303 non-null    int64  
     9   Oldpeak    303 non-null    float64
     10  Slope      303 non-null    int64  
     11  Ca         299 non-null    float64
     12  Thal       301 non-null    object 
     13  AHD        303 non-null    object 
    dtypes: float64(2), int64(9), object(3)
    memory usage: 33.3+ KB
    None
    (242, 11) (61, 11) (242,) (61,)
    
    예측값 : ['No' 'No' 'No' 'Yes' 'No' 'No' 'No' 'Yes' 'Yes' 'Yes']
    실제값 : ['No' 'No' 'No' 'Yes' 'Yes' 'No' 'No' 'Yes' 'Yes' 'Yes']
    acc : 0.6721311475409836
    
    각각의 검증 정확도 : [0.53846154 0.58333333 0.58333333 0.58333333 0.5       ]
    평균 검증 정확도 : 0.5576923076923077
    새로운 예측값 : ['No' 'Yes']

     

     

    <선생님 코드>

    # [SVM 분류 문제] 심장병 환자 데이터를 사용하여 분류 정확도 분석 연습
    # https://www.kaggle.com/zhaoyingzhu/heartcsv
    # https://github.com/pykwon/python/tree/master/testdata_utf8         Heartcsv
    #
    # Heart 데이터는 흉부외과 환자 303명을 관찰한 데이터다. 
    # 각 환자의 나이, 성별, 검진 정보 컬럼 13개와 마지막 AHD 칼럼에 각 환자들이 심장병이 있는지 여부가 기록되어 있다. 
    # dataset에 대해 학습을 위한 train과 test로 구분하고 분류 모델을 만들어, 모델 객체를 호출할 경우 정확한 확률을 확인하시오. 
    # 임의의 값을 넣어 분류 결과를 확인하시오.     
    # 정확도가 예상보다 적게 나올 수 있음에 실망하지 말자. ㅎㅎ
    #
    # feature 칼럼 : 문자 데이터 칼럼은 제외
    # label 칼럼 : AHD(중증 심장질환)
    
    import pandas as pd 
    import numpy as np
    from sklearn import svm, metrics
    from sklearn.model_selection._split import train_test_split
    
    heartdata = pd.read_csv("../testdata/Heart.csv")
    print(heartdata.info())
    
    data = heartdata.drop(["ChestPain", "Thal"], axis = 1)  # object type은 제외
    data.loc[data.AHD=="Yes", 'AHD'] = 1
    data.loc[data.AHD=="No", 'AHD'] = 0
    print(heartdata.isnull().sum())      # Ca 열에 결측치 4개
    
    Heart = data.fillna(data.mean())   # CA에 결측치는 평균으로 대체
    label = Heart["AHD"]
    features = Heart.drop(["AHD"], axis = 1)
    
    x_train, x_test, y_train, y_test = train_test_split(features, label, test_size = 0.3, random_state = 12)
    print()
    model = svm.SVC(C=0.1).fit(x_train, y_train)
    pred = model.predict(x_test)
    print('예측값 : ', pred)
    print('실제값 : ', np.array(y_test))
    
    # 분류 정확도 
    print(model.score(x_train, y_train))
    print(model.score(x_test, y_test))
    print('분류 정확도 : ', metrics.accuracy_score(y_test, pred))
    
    # 새 값으로 예측
    new_test = x_test[:2].copy()
    print(new_test)
    new_test['Age'] = 10
    new_test['Sex'] = 0
    print(new_test)
    
    new_pred = model.predict(new_test)
    print('예측결과 : ', new_pred)
    
    
    <console>
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 303 entries, 0 to 302
    Data columns (total 15 columns):
     #   Column      Non-Null Count  Dtype  
    ---  ------      --------------  -----  
     0   Unnamed: 0  303 non-null    int64  
     1   Age         303 non-null    int64  
     2   Sex         303 non-null    int64  
     3   ChestPain   303 non-null    object 
     4   RestBP      303 non-null    int64  
     5   Chol        303 non-null    int64  
     6   Fbs         303 non-null    int64  
     7   RestECG     303 non-null    int64  
     8   MaxHR       303 non-null    int64  
     9   ExAng       303 non-null    int64  
     10  Oldpeak     303 non-null    float64
     11  Slope       303 non-null    int64  
     12  Ca          299 non-null    float64
     13  Thal        301 non-null    object 
     14  AHD         303 non-null    object 
    dtypes: float64(2), int64(10), object(3)
    memory usage: 35.6+ KB
    None
    Unnamed: 0    0
    Age           0
    Sex           0
    ChestPain     0
    RestBP        0
    Chol          0
    Fbs           0
    RestECG       0
    MaxHR         0
    ExAng         0
    Oldpeak       0
    Slope         0
    Ca            4
    Thal          2
    AHD           0
    dtype: int64
    
    예측값 :  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
    실제값 :  [0 0 0 0 1 0 1 1 0 1 0 1 1 1 1 0 1 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 0 1 0 0
     0 1 1 0 1 1 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 1 1 0 1 0 1 0 0 1 0 0 0
     1 1 0 0 1 1 1 1 1 0 1 1 0 1 0 0 0]
    0.5330188679245284
    0.5604395604395604
    분류 정확도 :  0.5604395604395604
        Unnamed: 0  Age  Sex  RestBP  Chol  ...  MaxHR  ExAng  Oldpeak  Slope   Ca
    92          93   62    1     130   231  ...    146      0      1.8      2  3.0
    85          86   44    1     140   235  ...    180      0      0.0      1  0.0
    
    [2 rows x 12 columns]
        Unnamed: 0  Age  Sex  RestBP  Chol  ...  MaxHR  ExAng  Oldpeak  Slope   Ca
    92          93   10    0     130   231  ...    146      0      1.8      2  3.0
    85          86   10    0     140   235  ...    180      0      0.0      1  0.0
    
    [2 rows x 12 columns]
    예측결과 :  [0 0]

     

     

     

    댓글

Designed by Tistory.