[SSUDA] 심장병 데이터 분석
from google.colab import drive
drive.mount('/content/drive')
import pandas as pd
data = pd.read_csv("/content/drive/MyDrive/heart.csv")
df = data.copy()
df.head()
디폴트 값은 5입니다.
df.columns
df.columns.values.tolist()
컬럼은 이런 방식으로 확인할 수 있습니다.
밑에 DataFrame.columns.values.tolist() 함수는 컬럼 추출 중 가장 런타임이 빠르다고 합니다.
print('Shape is',df.shape)
303개 데이터, 14개 특성값이 있습니다.
df.isnull().sum()
df.info()
글쓴이는 윗방식으로 null값 유무를 체크했습니다.
그러나 df.info() 방식이 여러가지 정보를 같이 줘 더 효율적입니다.
df.describe()
데이터를 보면 어느정도 스케일링이 필요하다는 것을 알 수 있습니다.
df['age'] = df['age']/max(df['age'])
df['cp'] = df['cp']/max(df['cp'])
df['trtbps'] = df['trtbps']/max(df['trtbps'])
df['chol'] = df['chol']/max(df['chol'])
df['thalachh'] = df['thalachh']/max(df['thalachh'])
df.describe()
이전과 달리 특성 스케일이 확실히 비슷해졌습니다.
from sklearn.model_selection import train_test_split
#splitting data into training data and testing data
X_train, X_test, y_train, y_test = train_test_split(
df.drop(['output'], axis=1),
df.output,
test_size= 0.2, # 20% test data & 80% train data
random_state=0,
stratify=df.output
)
stratify 속성 => y값의 공평한 분배를 위해 사용하는 속성입니다.
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X_train, y_train)
from sklearn.metrics import accuracy_score
Y_pred = clf.predict(X_test)
acc=accuracy_score(y_test, Y_pred)
print('Accuracy is',round(acc,2)*100,'%')
로지스틱 회귀 모형을 별다른 튜닝 없이 사용했습니다.
정확도 측면에서만 보면 캐글에 있는 다른 코드와 별반 다르지 않습니다.
df = data.copy()
df.output.value_counts()
이전 모델에서 생략(?)된 부분인거 같은데 1과 0 값의 비율이 조금 차이가 있습니다.
df.corr().abs()['output'].sort_values(ascending = False)
Y값과의 상관계수가 어느정도 되는지 확인해보았습니다.
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
X = df.drop('output', axis = 1)
y = df['output']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)
X_train.shape
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
여기서는 StandardScaler를 사용해 스케일링을 했습니다.
평균 0, 분산 1로 조정합니다. 이 스케일링은 이상치가 있을때 잘 작용하지 않을 수 있습니다.
from tensorflow import keras
model = keras.Sequential(
[
keras.layers.Dense(
256, activation="relu", input_shape=[13]
),
keras.layers.Dense(515, activation="relu"),
keras.layers.Dropout(0.3),
keras.layers.Dense(50, activation="relu"),
keras.layers.Dropout(0.3),
keras.layers.Dense(1, activation="sigmoid"),
]
)
model.summary()
활성화 함수로 제일 많이 사용하는 relu와 sigmoid함수를 사용했습니다.
relu함수 : 입력이 양수일 경우 그대로 반환, 음수일경우 0으로 만듭니다.
sigmoid함수 : 1 / (1 + e^z) 함수. 값을 0에서 1 사이로 변환합니다.
첫번째 구간에 아웃풋 값을 256개 주었는데, 변수값이 13개임으로 모수가 14개입니다.
그래서 256*14 = 3584개 파라미터가 나오게 된 것입니다.
중간에 있는 드롭아웃은 일정 비율만큼 뉴런을 랜덤하게 꺼서 과대적합을 막는 역할을 합니다.
model.compile(optimizer = 'Adam', loss = 'binary_crossentropy', metrics = ['binary_accuracy'])
early_stopping = keras.callbacks.EarlyStopping( patience = 20, min_delta = 0.001,
restore_best_weights =True )
history = model.fit(
X_train, y_train,
validation_data=(X_test, y_test),
batch_size=15,
epochs=50,
callbacks = [early_stopping],
verbose=1,
)
model.evaluate(X_test, y_test)
predictions =(model.predict(X_test)>0.5).astype("int32")
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
accuracy_score(y_test, predictions)
아까 결과와 비슷한 수치를 보입니다.
print(classification_report(y_test, predictions))
classification_report 함수가 상당히 유용한 걸 알 수있습니다.
한번에 정밀도, 재현율, f1-score 값 까지 보여줍니다.
분류에 기본적인 로지스틱 회귀모형과 단순한 딥러닝 코드를 따라해봤습니다.
특히 딥러닝 부분에 경우 정말 기본적인 것밖에 몰라 코드 해석에 시간이 많이 걸렸네요.
여러가지로 코드를 만져가며 느낀점은 이번 데이터에 경우 스케일링이 많이 중요한 것 같습니다.
스케일링 종류에 따라서 정확도 값이 크게 변하는 것을 관찰했습니다.
특히 트리기반 부스팅 모델이 아니라 더 그런 것 같습니다.
너무 복잡한 모델을 급하게 이해하기 보다, 이해할 수 있는 모델을 관찰하며 데이터 분석은 어떤 과정으로 하는가를 살펴봤습니다.