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()