59doit

[ python ] R과 python을 활용한 데이터 분석 시각화 #2 (2) 본문

portfolio

[ python ] R과 python을 활용한 데이터 분석 시각화 #2 (2)

yul_S2 2022. 12. 29. 15:16
반응형

 

 [ 분류분석 / 시각화 ]

wdbc_data.csv
0.12MB

 

 

 

위스콘신 유방암 데이터셋을 대상으로 분류기법 2개를 적용하여 기법별 결과를 비교하고 시각화하시오. (R과 python 버전으로 모두 실행)

* 종속변수는diagnosis: Benign(양성), Malignancy(악성)

 

 

  • 해당 데이터는 유방암으로 의심되는 종양의 모양에 따라 양성과 악성을 구분하는 데이터
  • 종속변수 diagnosis 에 해당되는 값을 범주형 변수로 바꿔주기 위해서 B(Benign) 양성을 0 으로, M(Malignancy) 음성을 1 로 변경
  • 분석하기에 앞서 먼저 데이터를 R 과 python 에서 발생 난수의 순서까지 동일하지 않기 때문에 동일하게 가질 수 있도록 패키지 SyncRNG 를 사용하여 동일한 난수를 통해 분류
  • R 에서는 데이터프레임이 1 부터 시작하기 때문에 python 에서 0 행과 R 에서 1 행이 같게 되므로 같은 인덱스 번호를 가진다면 -1 을 해주어 train 과 test 에 같은 데이터를 담았다.

 

< Python >

데이터의 비어있는 값과 중복값이 있는지, diagnosis 에 담긴 benign 과 malignancy 의 빈도수가 얼마인지 확인

 

#1 필요한 모듈 임포트

import sklearn.datasets as d
import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn import metrics
from sklearn.model_selection import cross_val_score
from SyncRNG import SyncRNG
from sklearn.tree import DecisionTreeClassifier     # 분류모델 구축-결정트리
from sklearn.tree import DecisionTreeRegressor,plot_tree
from sklearn.tree import export_graphviz

 

 

#2 데이터 로드

wdbccancer = pd.read_csv("wdbc_data.csv")
wdbccancer
            id diagnosis  ...  symmetry_worst  dimension_worst
0     87139402         B  ...          0.2827          0.06771
1      8910251         B  ...          0.2940          0.07587
2       905520         B  ...          0.2998          0.07881
3       868871         B  ...          0.2102          0.06784
4      9012568         B  ...          0.2487          0.06766
..         ...       ...  ...             ...              ...
564  911320502         B  ...          0.2235          0.06925
565     898677         B  ...          0.2434          0.08488
566     873885         M  ...          0.3175          0.09772
567     911201         B  ...          0.2606          0.07810
568    9012795         M  ...          0.2730          0.08666
[569 rows x 32 columns]

 

#3 만들어진 wdbccancer의 결측값 확인

wdbccancer.isnull().sum()

 

 

#4 문자형태인 타기 값을 숫자 형태로 변환

wdbccancer['diagnosis'].unique()
# array(['B', 'M'], dtype=object)


def func1(row):
        if 'M' in row :
                return  1
        else :
                return 0
  • M = 1 (악성종양,암), B = 0 으로 변환

 

 

#5 변환된 결과를 데이터프레임에 새로운 컬럼을 만들기

wdbccancer['diagnosis'] = wdbccancer['diagnosis'].apply(func1)
wdbccancer.head()
  • 'diagnosis' 이라는 새로운 컬럼

 

 

 

#6 필요없는 컬럼 삭제

wdbc = wdbccancer.drop(columns=['id'])
wdbc.head()

 

 

 

#7 데이터 셋  7:3 으로 분할

v=list(range(1,len(wdbccancer)+1))
s=SyncRNG(seed=42)
# s.shuffle(v)[:5]

ord=s.shuffle(v)
idx=ord[:round(len(wdbccancer)*0.7)]
# idx[:5]

 

 

 

#8 인덱스 수정-R이랑 같은 데이터 가져오기

for i in range(0,len(idx)):
    idx[i]=idx[i]-1
  • R에서는 데이터프레임이 1부터 시작하기 때문에 python에서 0행과 R에서 1행이 같은 원리로 같은 인덱스 번호를 가진다면 -1을 해주어 같은 데이터를 가지고 오게 한다.

 

 

#9 학습데이터, 테스트데이터 생성

train=wdbc.loc[idx]                # 70%
train=train.sort_index(ascending=True)
test=wdbc.drop(idx)              # 30%

train_x=train.drop(['diagnosis'],axis=1)
train_y=train['diagnosis']

test_x=test.drop(['diagnosis'],axis=1)
test_y=test['diagnosis']

 

 

 

#### 의사결정 나무 #### 

#1 모델 생성

reg = DecisionTreeRegressor(max_depth=2).fit(train_x,train_y)
  • reg : 
  •  

 

#2 예측

pred=reg.predict(test_x)
p1=pred.round()
p2=np.array(test_y)

 

 

 

#3 정확도

import sklearn.metrics as metrics
metrics.accuracy_score(p2,p1)
# 0.9181286549707602

 

 

 

#4 변수중요도

for i,col in enumerate(train_x.columns):
    print(f'{col} 중요도 : {reg.feature_importances_[i]}')

 

 

#5 시각화

fig = plt.Figure(facecolor="white")
plot_tree(reg,feature_names=train_x.columns,filled=True)

 

 

 

 

#### SVM ####

 

#1 필요한 모듈 임포트

from sklearn.svm import LinearSVC
from sklearn.svm import SVC
import sklearn.svm as svm
import sklearn.metrics as mt
from sklearn.model_selection import cross_val_score, cross_validate

 

 

#2 데이터 로드

wdbccancer_svm = pd.read_csv("wdbc_data.csv")
wdbccancer_svm

 

 

#3 결측값 확인

wdbccancer_svm.isnull().sum()

 

# 아이디는 유방암을 예측하는데 전혀 도움이 되지 않기 때문에 무시
# diagnosis M = 1 (악성종양,암), B = 0

 

 

#4 문자형태인 타기 값을 숫자 형태로 변환

wdbccancer_svm['diagnosis'].unique()
# array(['B', 'M'], dtype=object)


def func1(row):
        if 'M' in row :
                return  1
        else :
                return 0

 

 

#5 변환된 결과를 데이터프레임에 '진단' 이라는 새로운 컬럼을 만들어 넣어준다

wdbccancer_svm['진단'] = wdbccancer_svm['diagnosis'].apply(func1)
wdbccancer_svm.head()

 

#6 필요없는 컬럼 삭제

wdbc = wdbccancer_svm.drop(columns=['id','diagnosis'])
wdbc.head()

 

 

#7 분류보델 구축 - 결정트리 & 훈련 검증용 데이터 분리 임포트

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split

 

#8 데이터 셋 7:3으로 분할

X = wdbc.drop(['진단'], axis = 1)    # 목표변수
y = wdbc['진단']                              # 설정변수

X_train,X_test,y_train,y_test = train_test_split (X,y, test_size = 0.3 , random_state = 1004)
  •  test_size: 테스트 셋 구성의 비율

 

#9 kernel = linear 로 선형분리

svm_model = svm.SVC(kernel='linear', random_state=100)

 

#9-1) 교차검증

scores = cross_val_score(svm_model,X,y,cv=5)
scores

pd.DataFrame(cross_validate(svm_model,X,y,cv=5))
print("교차검증 평균: ", scores.mean())
  • 교차검증 평균 : 0.9508461419034312

 

#10 kernel = 'rbf'로 비선형분리 진행

svm_model2 = svm.SVC(kernel='rbf')

 

#10-2) 교차검증

scores2 = cross_val_score(svm_model2, X, y, cv=5)
scores2

pd.DataFrame(cross_validate(svm_model2, X, y, cv=5))
print('교차검증 평균: ', scores2.mean())
  • 교차검증 평균:  0.9156652693681104

 

 

선형 분리에서 높은 평균 SCORE , 선형분리가 적합한 케이스

 

#11 시각화

import matplotlib.pyplot as plt
plt.figure(figsize=(7,7))
X1=np.array(X)
y1=np.array(y)
plt.scatter(X1[:,0],X1[:,1],c = y1)
plt.xlabel("radius_mean")
plt.ylabel("texture_mean")
plt.show()

 

 

 

반응형
Comments