본 글에서는 👉이전글에서 전처리된 데이터를 기반으로 선형회귀, 로지스틱 회귀, 의사결정나무 모델에 학습시키고 성능을 평가해볼 것입니다.
데이터 준비
샘플데이터 : boston.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/boston.csv")
데이터 분리 : 모델의 Overfitting(과적합)을 방지하기 위해 학습용, 평가용, 검증용(Option) 데이터를 나누는 과정입니다. Overfitting(과적합) : 학습용(train) 데이터에 과도하게 적합해져서 새로운 데이터에 대한 예측력이 떨어지는 현상
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']
# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split
# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)
지도학습 회귀 - 선형회귀
샘플데이터 : boston.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/boston.csv")
데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']
# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split
# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)
단순선형회귀 (Linear Regression) : 1개의 feature를 기반으로 수치를 예측하는 모델, 👉Linear Regression글 참고
# 라이브러리 호출
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
# 모델 선언
model = LinearRegression()
# 학습하기
model.fit(x_train[['RM']], y_train)
# 예측하기
y_pred = model.predict(x_test)
# 평가하기
print("MSE : ", mean_squared_error(y_test, y_pred))
# MSE(Mean Squared Error) : 평균제곱오차, 예측값과 실제값과의 차이를 제곱한 것의 평균
# 모델의 성능과 MSE는 반비례
# 선형회귀 분석 결과 시각화
# 회귀계수 확인
w = model.coef_
b = model.intercept_
print("기울기 : ", w) # 기울기
print("절편 : ", b) # 절편
# 선형회귀식
x = x_test[['RM']]
y = w * x + b
# 시각화
import matplotlib.pyplot as plt
plt.scatter(x_test[['RM']], y_test)
plt.plot(x, y, color='r')
plt.xlabel('RM')
plt.ylabel('MEDV')
plt.show()
# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_lr = pd.DataFrame()
df_lr['y_test'] = y_test
df_lr['y_pred'] = y_pred
df_lr.reset_index(drop=True, inplace=True)
# 시각화
plt.plot(df_lr['y_test'], label='Actual')
plt.plot(df_lr['y_pred'], label='Predicted')
plt.legend()
plt.show()
MSE (Mean Squared Error)
다중선형회귀 (Linear Regression) : 다수의 feature를 기반으로 수치를 예측하는 모델, 👉Linear Regression글 참고
# 라이브러리 호출
from sklearn.linear_model import LinearRegression
# 모델 선언
model2 = LinearRegression()
# 학습하기
model2.fit(x_train, y_train)
# 예측하기
y_pred = model2.predict(x_test)
# 평가하기
print("MSE : ", mean_squared_error(y_test, y_pred))
# 선형회귀 분석 결과 시각화
# 회귀계수 확인
w = model.coef_
b = model.intercept_
print("기울기 : ", w) # 기울기
print("절편 : ", b) # 절편
# 선형회귀식
formula = "MEDV = {:.2f}".format(b)
for i, feature_name in enumerate(x_test.columns):
formula += " + {:.2f} * {}".format(w[i], feature_name)
print("선형회귀식: " + formula)
# 시각화
import matplotlib.pyplot as plt
plt.plot(y_test.values[:50], label='Actual')
plt.plot(y_pred[:50], label='Predicted')
plt.legend()
plt.show()
지도학습 분류
샘플데이터 : wine.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/wine.csv")
데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']
# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split
# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
로지스틱 회귀 (Logistic Regression) : 다수의 feature를 기반으로 이진분류하는 모델, 👉Logistic Regression글 참고
# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 모델 선언
model = LogisticRegression()
# 이진분류를 위한 테스트데이터 세팅
x_train_b = x_train.loc[y_train[y_train !='class_2'].index]
y_train_b = y_train[y_train !='class_2']
x_test_b = x_test.loc[y_test[y_test !='class_2'].index]
y_test_b = y_test[y_test !='class_2']
# 학습하기
model.fit(x_train_b, y_train_b)
# 예측하기
y_pred = model.predict(x_test_b)
# 평가하기
print("accuracy : ", accuracy_score(y_test_b, y_pred))
# accuracy_score : 정확도를 계산하기 위한 sklearn패키지 함수 (예측결과가 동일한 데이터 건수 / 전체 예측 데이터 건수)
# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_result = pd.DataFrame()
df_result['y_test_b'] = y_test_b
df_result['y_pred'] = y_pred
df_result.reset_index(drop=True, inplace=True)
소프트맥스 회귀 (Softmax Regression) : 다수의 feature를 기반으로 다중분류하는 모델, 👉Softmax Regression글 참고
: 의사결정나무 모델은 아래 그림처럼 여러 target으로 분기하는 과정에서 여러 기준에 의거하여 데이터를 분류하거나 결과값을 예측하는 모델 학습을 통해 기준 수치를 조정하여 모델을 일반화하게 되고, 회귀/분류 모델로서 활용 가능합니다. 아래 그림은 outlook, humidity, windy 기준으로 경기가 열릴지 안열리지를 판단하는 모델을 도식화한 그림입니다.
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/wine.csv"
데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']
# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split
# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
의사결정나무 - 분류
# 라이브러리 호출
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
# 모델 선언
model = DecisionTreeClassifier()
# 학습하기
model.fit(x_train, y_train)
# 예측하기
y_pred = model.predict(x_test)
# 평가하기
print("accuracy : ", accuracy_score(y_test, y_pred))
# 의사결정나무(Decision Tree) 구조 보기
# 시각화 모듈 불러오기
from sklearn.tree import export_graphviz
# 이미지 파일 만들기
export_graphviz(model, # 모델이름
out_file='tree_wine.dot',
feature_names=x.columns, # Feature 이름
class_names=y.unique(), # Target Class 이름
rounded=True,
precision = 3,
filled = True)
!dot -Tpng tree_wine.dot -o tree_wine.png -Gdpi=300
# 이미지 파일 로딩
from IPython.display import Image
Image(filename='tree_wine.png', width=600) # 사이즈 조정
# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_result = pd.DataFrame()
df_result['y_test'] = y_test
df_result['y_pred'] = y_pred
df_result.reset_index(drop=True, inplace=True)
의사결정나무 - 회귀
# 데이터 불러오기
df = pd.read_csv("./data/boston.csv")
# 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']
# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split
# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
# 라이브러리 호출
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error
# 모델 선언
model = DecisionTreeRegressor()
# 학습하기
model.fit(x_train, y_train)
# 예측하기
y_pred = model.predict(x_test)
# 평가하기
print("MSE : ", mean_squared_error(y_test, y_pred))
# 의사결정나무(Decision Tree) 구조 보기
# 시각화 모듈 불러오기
from sklearn.tree import export_graphviz
# 이미지 파일 만들기
export_graphviz(model, # 모델이름
max_depth=5,
out_file='tree_boston.dot',
feature_names=x.columns, # Feature 이름
rounded=True,
precision = 3,
filled = True)
!dot -Tpng tree_boston.dot -o tree_boston.png -Gdpi=300
# 이미지 파일 로딩
from IPython.display import Image
Image(filename='tree_boston.png', width=600) # 사이즈 조정
# 예측값 실제값 비교
# 실제값과 예측값을 비교하기 위해 데이터프레임으로 만들기
df_result = pd.DataFrame()
df_result['y_test'] = y_test
df_result['y_pred'] = y_pred
df_result.reset_index(drop=True, inplace=True)
# 시각화
plt.plot(y_test.values[:50], label='Actual')
plt.plot(y_pred[:50], label='Predicted')
plt.legend()
plt.show()
예측과 성능 평가
샘플데이터 : boston.csv, wine.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("./data/boston.csv")
데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']
# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split
# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
회귀모델 성능 평가
# 라이브러리 호출
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
# 모델 선언
model_lr = LinearRegression()
model_dt = DecisionTreeRegressor()
# 모델 학습
model_lr.fit(x_train, y_train)
model_dt.fit(x_train, y_train)
# 예측하기
y_pred_lr = model_lr.predict(x_test)
y_pred_dt = model_dt.predict(x_test)
# 평가하기
print("LinearRegression 모델")
print("MSE : ", mean_squared_error(y_test, y_pred_lr))
print("RMSE :", mean_squared_error(y_test, y_pred_lr)**(1/2))
print("MAE : ", mean_absolute_error(y_test, y_pred_lr))
print("R2 Score : ", r2_score(y_test, y_pred_lr))
print("")
print("DecisionTreeRegressor 모델")
print("MSE : ", mean_squared_error(y_test, y_pred_dt))
print("RMSE :", mean_squared_error(y_test, y_pred_dt)**(1/2))
print("MAE : ", mean_absolute_error(y_test, y_pred_dt))
print("R2 Score : ", r2_score(y_test, y_pred_dt))
# R2_Score (결정계수) = SSR/SST = 1 - SSE/SST, 해당 수치가 클 수록 회귀 모델의 성능이 높음
# SST (Total Sum of Squares) : 실제값에서 실제값의 평균을 뺀 차이의 제곱을 모두 합한 수치
# SSR (Sum of Squares due to Regression) : 예측값에서 실제값의 평균을 뺀 차이의 제곱을 모두 합한 수치
# SSE (Sum of Squares Residual of Error) : 실제값에서 예측값을 뺀 차이의 제곱을 모두 합한 수치
SST/SSR/SSE
분류모델 성능 평가
# 데이터 불러오기
df = pd.read_csv("./data/wine.csv")
# 데이터 분리
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']
# sklearn 패키키 증 train_test_split 함수 불러오기
from sklearn.model_selection import train_test_split
# Feature와 Target을 train, test 데이터 셋으로 나누기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)
# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import confusion_matrix, precision_score, recall_score, accuracy_score, f1_score, classification_report
# 모델 선언
model_lr = LogisticRegression()
model_dt = DecisionTreeClassifier()
# 모델 학습
model_lr.fit(x_train, y_train)
model_dt.fit(x_train, y_train)
# 예측하기
y_pred_lr = model_lr.predict(x_test)
y_pred_dt = model_dt.predict(x_test)
# 평가하기
print("LogisticRegression 모델")
print("Precision : ", precision_score(y_test, y_pred_lr, average='macro'))
print("Recall :", recall_score(y_test, y_pred_lr, average='macro'))
print("Accuracy : ", accuracy_score(y_test, y_pred_lr))
print("F1 Score : ", f1_score(y_test, y_pred_lr, average='macro'))
print("")
print("DecisionTreeClassifier 모델")
print("Precision : ", precision_score(y_test, y_pred_dt, average='macro'))
print("Recall :", recall_score(y_test, y_pred_dt, average='macro'))
print("Accuracy : ", accuracy_score(y_test, y_pred_dt))
print("F1 Score : ", f1_score(y_test, y_pred_dt, average='macro'))
# precision_score : 정밀도, 모델이 1이라고 예측한 것중에 실제로 1인 것의 정도
# accuracy_score : 정확도, 모델이 예측한 값과 실제 값이 일치하는 정도
# recall_score : 재현율, 실제로 1인 것중에 모델이 1이라고 예측한 비율
# f1_score : 정밀도와 회수율을 고르게 활용하기 위한 조화평균, 1에 가까울수록 성능이 좋음
Precision/Recall
Cross Validation (교차 검증)
: 데이터를 train set과 test set으로 나누는 방식에서 train set을 train set + validation set으로 추가로 나누어 검증하는 방식 데이터를 train set과 test set으로 나누고, test set을 활용하여 모델의 성능을 검증 및 개선 과정을 반복하면 모델이 test set 과적합(overfitting)될 우려가 있음. 이를 방지하기 위해 교차 검증으로 모델의 성능 검증 및 개선을 진행함.
샘플데이터 : boston.csv, wine.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("./data/boston.csv")
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['MEDV'])
y = df['MEDV']
회귀모델 교차검증
# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
# 모델 선언하기
model_lr = LinearRegression()
model_dt = DecisionTreeRegressor()
# 학습, 예측, 평가하기
lr_cv_score = cross_val_score(model_lr, x, y, cv=10, scoring='neg_mean_squared_error')
dt_cv_score = cross_val_score(model_dt, x, y, cv=10, scoring='neg_mean_squared_error') # cv는 위 사진에서 Fold의 갯수를 가리킴
# 결과 확인
# 확인
print("LinearRegression 모델")
print(lr_cv_score)
print("MSE : ", -lr_cv_score.mean())
print("DecisionTreeRegressor 모델")
print(dt_cv_score)
print("MSE : ", -dt_cv_score.mean())
분류모델 교차검증
# 데이터 불러오기
df = pd.read_csv("./data/wine.csv")
# Feature는 x, Target은 y 로 저장합니다.
x = df.drop(columns=['class'])
y = df['class']
# 라이브러리 호출
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
# 모델 선언하기
model_lr = LogisticRegression()
model_dt = DecisionTreeClassifier()
# 학습, 예측, 평가하기
lr_cv_score = cross_val_score(model_lr, x, y, cv=5, scoring='f1_macro')
dt_cv_score = cross_val_score(model_dt, x, y, cv=5, scoring='f1_macro')
# 결과 확인
# 확인
print("LogisticRegression 모델")
print(lr_cv_score)
print("F1 Score : ", lr_cv_score.mean())
print("DecisionTreeClassifier 모델")
print(dt_cv_score)
print("F1 Score : ", dt_cv_score.mean())
👉이전글에서 소개된 것처럼 AI 모델은 많은 데이터를 기반으로 생성됩니다. 그렇기때문에 양질의 데이터는 높은 퀄리티의 AI 모델을 생성하기 위해 반드시 필요한 요소죠.
본 글에서는 일반적인 데이터를 AI 모델에 활용할 양질의 데이터로 가공하기 위한 방법들을 다뤄보겠습니다.
사용 환경은 아래와 같습니다.
IDE : Jupyter Notebook
Language : python
library : pandas
데이터 탐색
샘플데이터 : ratings.csv
데이터 확인
# 라이브러리 불러오기
import pandas as pd
# 샘플데이터 가져오기
df = pd.read_csv("./data/ratings.csv")
# 앞에서부터 데이터확인
df.head() # 앞 10개 (default)
df.head(5) # 앞 5개
# 뒤에서부터 데이터확인
df.tail() # 뒤 10개 (default)
df.tail(5) # 뒤 5개
# 단순 위/아래로 row를 붙임
df_concat_1 = pd.concat([df_movies, df_ratings])
# 옆으로 row를 붙임
df_concat_2 = pd.concat([df_movies, df_ratings], axis=1)
# 합치는 두 데이터프레임에 모두 존재하는 row의 인덱스만 가져옴
df_concat_3 = pd.concat([df_movies, df_ratings], join='inner')
데이터 병합하기 : merge()
# on='key값'이 없을 경우, default 설정대로 같은 이름을 가진 열이 자동으로 key값으로 지정됨
pd.merge(df_movies, df_ratings)
# movieId 기준 병합
pd.merge(df_movies, df_ratings, on='movieId')
# join 방법 설정
pd.merge(df_movies, df_ratings, how='outer' on='movieId') # outer join
pd.merge(df_movies, df_ratings, how='left' on='movieId') # left outer join
pd.merge(df_movies, df_ratings, how='right' on='movieId') # right outer join
정렬하기 : sort_values()
# movieId기준 오름차순 정렬
df.sort_values(by='movieId')
# movieId기준 내림차순 정렬
df.sort_values(by='movieId', ascending=False)
# movieId기준 오름차순 정렬 후 바로 적용
df.sort_values(by='movieId', inplace=True)
# 정렬로 인해 뒤섞인 인덱스를 재배열
df.reset_index()
df.reset_index(drop=True, inplace=True) # 기존 인덱스 삭제 후, 재배열된 인덱스 적용
데이터 필터링과 편집
샘플데이터 : preprocessing_03.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/preprocessing_03.csv")
데이터 필터링
# 성별의 구성을 확인합니다.
df['gender'].value_counts()
# 성별이 남자인지를 확인해 봅니다.
df['gender']=='M'
# 전체 데이터프레임에서 성별이 남자인 사람으로 필터링한 정보를 가져옵니다.
df[df['gender']=='M']
# 전체 데이터프레임에서 'userId'가 5인 고객이 본 영화 목록을 확인합니다.
df[df['userId']==5]
len(df[df['userId']==5])
# 전체 데이터프레임에서 'userId'가 5인 고객이 평점 2점 이하를 준 영화 목록을 확인합니다.
df[(df['userId']==5) & (df['rating']<=2) ]
# 필터링 결과 중 'title'만 출력
df[(df['userId']==5) & (df['rating']<=2)]['title']
컬럼명 변경
# 기존 컬럼명 확인하기
df.columns
# 새로운 컬럼명 List를 작성하여 대체하기
df.columns = ['movieId', 'imdbId', 'tmdbId', '영화제목', 'genres', 'userId', 'rating',
'timestamp', 'gender', 'age', 'occupation', 'zipcode']
# 기존 컬럼명 선택하여 변경 ( df.rename(columns={'기존 컬럼명' : '새 컬럼명'}) )
df = df.rename(columns={'zipcode':'우편번호'})
컬럼 생성
# 컬럼 생성 후 기본값 세팅 ( df['새로운 컬럼명'] = 기본값 )
df['new'] = 0
# df['영화제목']의 정보를 문자열 처리한 후 괄호'(',')'를 제외한 4자리의 숫자만 가져온 후에 새로운 컬럼 'year'에 세팅
df['year'] = df['영화제목'].str[-5:-1]
# 데이터 분리 후 새로운 컬럼 생성
df['genres'].str.split('|') # 배열 형태
df['genres'].str.split('|', expand=True).head() # 'expand=True' 옵션을 통해 새로운 데이터프레임으로 생성
컬럼 삭제
# new 컬럼 삭제
df.drop(columns=['new'])
df.drop(columns=['new'], inplace=True) # 변경내용 적용
# 필요한 컬럼만 선택하여 다시 저장
new_columns = ['movieId', 'imdbId', 'tmdbId', '영화제목', 'year', 'genres', 'userId', 'rating', 'timestamp', 'gender', 'age', 'occupation', '우편번호']
df = df[new_columns]
데이터 결측치 처리
샘플데이터 : preprocessing_04.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/preprocessing_04.csv")
결측치 확인
# 결측치 행 확인 ( 결측치가 있을 경우 True를 반환 )
df.isnull()
# 각 열별 결측치 갯수 확인
df.isnull().sum()
결측치 제거
# 결측치가 있는 행 모두 삭제
df_temp = df.dropna()
# 결측치가 있는 열 모두 삭제
df_temp2 = df.dropna(axis=1)
# 행 전체가 결측치인 행만 모두 삭제
df_temp3 = df.dropna(how ='all')
# 행의 결측치가 n초과인 행만 모두 삭제
df_temp4 = df.dropna(thresh=n)
# 특정 열 중 결측치가 있는 경우의 행만 모두 삭제
df_temp5 = df.dropna(subset=['MovieId'])
df.dropna(subset=['MovieId'], inplace=True) # 데이터프레임에 바로 적용
결측치 채우기
# 결측치를 단일 값(0)으로 대체
df.fillna(0)
# 특정 열의 결측치만 0으로 대체하기
df_na_sample2['UserId'].fillna(0, inplace=True) # 데이터프레임에 바로 적용
# 특정 열의 결측치만 평균값으로 대체하기
df['Age'].fillna(df_na_sample2['Age'].mean(), inplace=True)
# 특정 열의 결측치만 최빈값으로 대체하기
df['Gender'].fillna(df_na_sample2['Gender'].mode()[0], inplace=True)
# 결측치 이전값으로 채우기
df.fillna(method='ffill')
# 결측치 이후값으로 채우기
df.fillna(method='bfill')
데이터 타입 변환/중복데이터 제거
샘플데이터 : preprocessing_05.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/preprocessing_05.csv")
데이터 타입 확인
# 모든 컬럼의 데이터타입을 확인
df.dtypes
# 컬럼별 데이터타입 확인
df['MovieId'].dtype
데이터 타입 변경
# 모든 Columns의 데이터 타입을 'object' 형으로 변경
df_temp = df.astype('object')
# 특정 컬럼의 데이터 타입을 변경
df = df.astype({'Year':'int'})
중복데이터 처리
# 중복 데이터 확인 ( 첫 번째 값은 False, 두 번째 값부터는 True 반환 )
df.duplicated()
# 데이터프레임 df의 'Title'과 'UserId' 컬럼이 중복이 되는 데이터를 확인
df[df.duplicated(['Title','UserId'])]
# 예제 : 영화 제목이 같은 영화를 두번 본 고객이 존재한다고?!
df[(df['Title']=='Iron Man') & (df['UserId']==550)]
df[df.duplicated(['Title','UserId'])]
# 중복데이터 제거
df.drop_duplicates(['Title','UserId', 'Year'], ignore_index=True) # 기존 인덱스를 무시하고 새로 인덱스를 부여
데이터 이상치 처리
샘플데이터 : preprocessing_06.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/preprocessing_06.csv")
이상치 탐지
# 컬럼별 통계적 특성 확인
df.describe()
# 시각화를 통한 이상치 탐지
# 라이브러리 불러오기
import matplotlib.pyplot as plt
# 차트 영역 설정하기 ( box plot 차트 )
plt.figure()
plt.boxplot(df['Age'], labels=['Age'])
plt.show()
이상치 확인
# IQR의 1.5배 이상 크거나 작은 데이터를 이상치로 판별
# IQR 계산
# 중앙값 계산
Q2 = df['Age'].median()
# 하위 25%, 상위 25% 범위 계산
Q1 = df['Age'].quantile(0.25)
Q3 = df['Age'].quantile(0.75)
IQR = Q3 - Q1
# 이상치 판별
df['IsOutlier_Age'] = (df['Age'] < Q1 - 1.5 * IQR) | (df['Age'] > Q3 + 1.5 * IQR)
이상치 처리
# 위에서 생성한 이상치여부 컬럼(IsOutlier_Age) 활용하여 이상치 삭제
df = df[df['IsOutlier_Age'] == False]
# 이상치 대체
df.loc[df['IsOutlier_Age'], 'Age'] = df['Age'].median() # 중앙값 대체
데이터 인코딩
샘플데이터 : preprocessing_07.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/preprocessing_07.csv")
레이블 인코딩 : 범주형 데이터를 숫자로 변환하는 방법으로, 각 범주에 고유한 숫자를 할당하는 방식입니다. 예를 들어, "남성", "여성"과 같은 범주형 데이터를 각각 0과 1로 변환하는 방법이 있습니다.
더미 변수 생성 : 각 카테고리를 이진 형태로 표현하는 방법 각각의 값을 고유한 이진 벡터로 변환하여 해당하는 값의 위치에 1을 표시하고, 나머지 위치에는 0을 표시합니다. (원-핫 인코딩)
# | 구분자 기준으로 데이터를 분할하여 생성된 list type 데이터를 다시 저장
df['Genres'] = df['Genres'].str.split('|')
# list type으로 저장된 데이터를 모두 나누어 새로운 row로 생성
df = df.explode('Genres')
# get_dummies() 함수를 사용 더미변수 생성
pd.get_dummies(df, columns=['Genres'])
pd.get_dummies(df['Genres'])
pd.get_dummies(df['Genres'], prefix='Genre_') # 더미변수 컬럼의 prefix 설정
pd.get_dummies(df['Genres'], drop_first=True) # 더미변수 첫번째 컬럼 삭제
df = pd.get_dummies(df, columns=['Genres'], prefix='Genre', drop_first=True) # 최종
# 더미변수 컬럼 외의 컬럼들을 키값으로 그룹화하여 중복데이터 제거
# 'groupby()'는 특정 컬럼의 값을 기준으로 데이터프레임을 그룹화하여 그룹별로 연산을 수행할 수 있습니다.
# 'agg()'는 그룹화된 데이터프레임에 대해 다양한 집계 함수들을 적용하여 그룹 별로 연산 결과를 집계한 결과를 반환합니다.
df = df.groupby(['MovieId', 'ImdbId', 'TmdbId', 'Title', 'Year', 'UserId', 'Rating', 'Gender', 'Age', 'Occupation']).agg('sum').reset_index()
데이터 스케일링
샘플데이터 : preprocessing_08.csv
데이터 불러오기
# 라이브러리 불러오기
import pandas as pd
df = pd.read_csv("./data/preprocessing_08.csv")
데이터 정규화 : 데이터를 일정 범위로 변환하는 스케일링 방법으로, 데이터를 0과 1 사이의 값으로 변환하는 것을 의미 정규화는 다양한 스케일을 가진 변수들을 동일한 범위로 맞춰줌으로써, 변수 간의 크기 차이를 제거하여 모델이 각 변수를 공평하게 처리할 수 있도록 돕습니다.
# 라이브러리 불러오기
from sklearn.preprocessing import MinMaxScaler
# MinMaxScaler 호출하기
min_max_scaler = MinMaxScaler()
# 'Age', 'Rating' 컬럼의 데이터를 Min Max Scaling 하기
df_normalized = min_max_scaler.fit_transform(df[['Age', 'Rating']])
데이터 표준화 : 데이터를 평균이 0이고 표준편차가 1인 분포로 변환하는 스케일링 방법으로, 데이터를 표준정규분포에 따르는 값으로 변환하는 것을 의미 표준화는 데이터의 분포를 중심으로 조절하여 이상치에 덜 민감하게 만들어줌으로써, 모델의 안정성을 높이고 예측 결과를 개선하는 데 도움을 줍니다.
# 라이브러리 불러오기
from sklearn.preprocessing import StandardScaler
# StandardScaler 호출하기
standard_scaler = StandardScaler()
# 'Age', 'Rating' 컬럼의 데이터를 StandardScaling 하기
df_standardized = standard_scaler.fit_transform(df[['Age', 'Rating']])