본문 바로가기

카테고리 없음

데이터 전처리 및 분석, 모델링 연습!

1. 데이터 분석 및 전치리

- 데이터 추출

# 데이터 추출 - 컬럼
df['Age'] # 컬럼 한개
df[['Age','Survived']] # 컬럼 여러개

# 데이터 추출 - 행
df.loc[0,['Survived','Sex','Name']] #Series 추출
df.loc[ [0] ,['Survived','Sex','Name']] #데이터 프레임 추출
df.loc[ [3,9] ,['Survived','Sex','Name']]

# index 베이스로 데이터 추출
df.iloc[0,[1,4,3]]
df.iloc[[0],[1,4,3]]
df.iloc[[3,9],[1,4,3]]

# 데이터 추출 - 조건
cond = df['Sex'] == 'female' # 조건
df[cond]

# 나이(age)가 10세 미만이거나 60이상인 사람들
cond = (df['Age'] < 10) | (df['Age'] >= 60)
df.loc[cond]
df.loc[cond,:]
# df.loc[cond,['Survived','Sex']]

# 나이(age)가 10세 미만이거나 60이상인 사람들 중에서 생존한 사람만 추출(survived=1)
cond_1 = (df['Age'] < 10) | (df['Age'] >= 60)
cond_2 = df['Survived'] == 1
df.loc[cond_1 & cond_2,:]

- value_counts : 컬럼의 수준별 데이터 개수, 다중 분류를 해야하는지 이진 분류로 해야하는지 판단하기 위함

df['Pclass'].value_counts()

'''
3    491
1    216
2    184
Name: Pclass, dtype: int64
'''
# 다중 분류 >> softmax

- sort_values : 컬럼 기준 정렬

# 정렬 - 컬럼 하나 기준
df.sort_values('Age',ascending=True) # 오름차순
df.sort_values('Age',ascending=False) # 내림차순

# 정렬 - 컬럼 여러개 기준
df.sort_values(['Age','Fare'],ascending=False) # 내림차순

- groupby : 

# 항구별 탑승자 수 (데이터 건수, 관측치 갯수)
df.groupby('Embarked').count() # 열을 기준으로 그룹화 → 각 그룹의 모든 열에 대한 데이터 건수
df.groupby('Embarked').size() # 각 그룹의 크기(관측치의 수)를 계산
df.groupby('Embarked').size().to_frame('탑승자수') # 데이터프레임으로 변환하고, 열 이름을 '탑승자수'

# 항구별 탑승자의 평균 연령은?
df.groupby('Embarked')['Age'].mean() # 'Embarked' 열을 기준으로 그룹화 → 'Age' 열의 평균을 계산
df.groupby('Embarked')['Age'].mean().to_frame('평균연령')

- 컬럼 추가, 삭제, 이름 수정

# 컬럼 추가/파생변수 생성
df['familysize'] = df['SibSp'] + df['Parch']

# 컬럼 이름 변경
df.rename(columns={'familysize':'FamilySize'}, inplace=True)

# 컬럼 삭제
df.drop('FamilySize', axis=1, inplace=True)

# 확인
df.head()

- 형 변환, 문자열 수정

# 컬럼 형 변환
# object -> 정수로 변환
# astype()는 inplace=True 옵션 지원하지 않으므로 꼭 해당 컬럼에 재 할당해서 변경완료!! 
# 컬럼안에 특수문자,문자 있으면 에러 발생하니 replace를 적용

df['PassengerId'] = df['PassengerId'].replace('_','-1')
df['PassengerId'] = df['PassengerId'].astype('int64')

- 결측치 : 전과 후를 정확하게 집고 넘어가야 함

# 결측치 갯수(확인)
df.isnull().sum()

# 결측치 포함 데이터 보기 : Age컬럼에서 null인 데이터 추출
df.loc[df['Age'].isnull(),:]

# 결측치 채우기-특정값으로
fdf = df.fillna({'Age':0}) 
fdf.isnull().sum()
fdf['Age'].mean() #결측치 처리 후 평균나이

# 결측치 채우기-평균값으로
fdf = df.fillna({'Age':df['Age'].mean()}) 
fdf['Age'].mean()

# 결측치 모두 삭제하기
fdf = df.dropna()
fdf.isnull().sum()

# 결측치 삭제-특정컬럼 기준
fdf = df.dropna(subset=['Age']) 
fdf.isnull().sum()

- 스케일링 : StandardScaler(), MinMaxScaler(), RobustScaler()

from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
scaler = StandardScaler() # MinMaxScaler() # RobustScaler()
scaled = scaler.fit_transform(df)

- 인코딩 : One-Hot Encoding(→ pd.get_dummies), Label-Encoding(→ replace)

## 원-핫 인코딩
pd.get_dummies(df)

# 타입 지정: object 컬럼만 진행
cal_cols = df.select_dtypes('object').columns.values
pd.get_dummies(df, columns=cal_cols)

# 다중공선성 문제 해결 : ~을 해결하기 위해 원-핫 인코딩을 사용해주세요.
pd.get_dummies(df, drop_first=True)

# True/False -> 1,0 정수로 표현
pd.get_dummies(df, dtype='int', drop_first=True)

## 라벨 인코딩
# 방식1 : replace 사용
df['Survived'].value_counts()
df['Survived'] = df['Survived'].replace(['Dead','Survived'],[0,1])
df['Survived'].value_counts() # 확인

# 방식2 : sklearn 사용
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['Survived'] = le.fit_transform(df['Survived'])
df['Survived'].value_counts()

 

2. 모델링

머신러닝, 딥러닝 각 3가지 종류 : 회귀(linear), 이진분류(sigmoid), 다중분류(softmax)

- 머신러닝

from sklearn.model_selection import train_test_split

# 회귀 알고리즘
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squard_error, mean_absolute_error, r2_score

# 분류 알고리즘
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score , recall_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report

# =====================================================================================
# 피쳐와 레이블 분리
y_data = df['mpg'] # label
x_data = df.drop(['mpg'],axis=1) # feature
print(y_data.shape,x_data.shape)

# 훈련용과 테스트용 분리
# 학습:테스트=7:3
# random_state=777
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.3, random_state=777)

# ====================================================================================
# 모델 생성(회귀)
model = LinearRegression() #피쳐와 타깃과의 선형관계 학습
model = DecisionTreeRegressor(max_depth=5, min_samples_split=4,random_state=42) #의사결정 
model = RandomForestRegressor(n_estimators=10, max_depth=10,random_state=42) #앙상블 알고리즘

# 모델 생성(분류)
model = LogisticRegression()
model = KNeighborsClassifier(n_neighbors=5)
model = DecisionTreeClassifier(max_depth=3,min_samples_split=2,random_state=42)
model = RandomForestClassifier(n_estimators=3, max_depth=3,random_state=42)

# ====================================================================================
# 모델 학습
model.fit(x_train, y_train)
# 모델 예측
y_predict = model.predict(x_test)

# ====================================================================================
# 모델 성능 평가(회귀)
R2 = r2_score(y_test,y_predict)
MSE = mean_squared_error(y_test,y_predict,squared=True)
RMSE = mean_squared_error(y_test,y_predict,squared=False)
MAE = mean_absolute_error(y_test,y_predict)

# 모델 성능 형가(분류) : 다중 분류일 경우 param에 average='macro' 추가
confusion = confusion_matrix( y_test, y_predict)
accuracy = accuracy_score(y_test , y_predict) #정확도
precision = precision_score(y_test , y_predict) #정밀도
recall = recall_score(y_test , y_predict)  #재현율
f1score = f1_score(y_test , y_predict)   #정밀도,재현율 균형

- 딥러닝

# 데이터 분할
from sklearn.model_selection import train_test_split   

# 딥러닝용 라이브러리(뒤에 다 s 붙이기!)
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStoping, ModelCheckpoint

# 시드 고정
tf.random.set_seed(100)

# =======================================================================================
# 데이터 분리 : 피쳐와 레이블 분리
y_data = df['mpg'] # 타깃
x_data = df.drop(['mpg'],axis=1) # 피쳐
print(y_data.shape,x_data.shape)

# =======================================================================================
# 훈련용과 테스트용 분리
# 학습:테스트=7:3
# random_state=777
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.3, random_state=777)

# =======================================================================================
# 모델 (model) 구축
model = Sequential()
model.add(Dense(units=16, activation='relu',input_shape=(x_train.shape[1],)))  
model.add(Dropout(0.3)) 
model.add(Dense(units=8, activation='relu'))
model.add(Dropout(0.3)) 
model.add(Dense(units=1, activation='linear')) #------->회귀 
model.add(Dense(units=1,activation='sigmoid')) #------->이진 분류 
model.add(Dense(units=3,activation='softmax')) #------->다중 분류(3개로 출력을 해야하는 경우 >> 문제에 따라 변경해야 함)

# 모델 (model) 컴파일 및 summary
model.compile(loss='mse', optimizer=Adam(), metrics=['mae']) #------->회귀 
model.compile(loss='binary_crossentropy',optimizer=Adam(),metrics=['accuracy']) #------------>이진분류
model.compile(loss='sparse_categorical_crossentropy',optimizer=Adam(),metrics=['accuracy']) #---->다중분류:레이블에 라벨 인코딩 적용시 사용
model.compile(loss='categorical_crossentropy',optimizer=Adam(),metrics=['accuracy']) #--->다중분류:레이블에 원핫인코딩 적용시 사용
model.summary()

# 모델 학습
hist = model.fit(x_train, y_train, epochs=50 ,batch_size=15, validation_data=(x_test, y_test))

######################   조기종료, 모델 저장, 과적합 방지 언급시 사용 ####################
######################   아래의 코드를 실행할 시, fit() 코드는 주석처리 필요 #############
# early_stop = EarlyStopping(monitor='val_loss', patience=5)
# check_point = ModelCheckpoint('best_model.h5', monitor='val_loss',save_best_only=True)

# hist = model.fit(x_train, y_train, epochs=50, batch_size=15, 
#                     validation_data=(x_test, y_test),
#                     callbacks=[early_stop,check_point])

# =======================================================================================
# 모델 평가(회귀)
loss, mae = model.evaluate(x_test, y_test, verbose=0)
print(f'MSE:{loss:.3f} MAE:{mae:.3f}')

# 모델 평가(분류)
loss,acc = model.evaluate(x_test, y_test)
print(f'정확도: {acc:.3f}')

 

3. 시각화

import matplotlib.pyplot as plt
plt.figure(figsize=(15,6))
plt.subplot(1,2,1)
plt.plot(hist.history['loss'],label='train loss')
plt.plot(hist.history['val_loss'],label='validation loss')
plt.title('Loss')
plt.xlabel('epochs')
plt.ylabel('loss')
plt.legend()

plt.subplot(1,2,2)
plt.plot(hist.history['accuracy'],label='accuracy')
plt.plot(hist.history['val_accuracy'],label='validation accuracy')
plt.title('Accuracy')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.legend()

plt.show()