sangmandu / Optimus

LG Aimers
0 stars 2 forks source link

IQR을 이용하여 탐색한 이상치 검출 데이터셋 생성 #8

Open UGeunJi opened 2 years ago

UGeunJi commented 2 years ago

IQR을 이용한 이상치 탐색

이상치 검출 코드

import random
import os
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.stats as stats
%matplotlib inline
import seaborn as sns
import warnings
import plotly.express as px
warnings.filterwarnings('ignore')
train_df = pd.read_csv(file_path + './train.csv')

train_x = train_df.filter(regex='X') # Input : X Featrue
train_y = train_df.filter(regex='Y') # Output : Y Feature

test_x = pd.read_csv(file_path + './test.csv').drop(columns=['ID'])
def outlier_iqr(data, column): 

    # lower, upper 글로벌 변수 선언하기     
    global lower, upper    

    # 4분위수 기준 지정하기     
    q25, q75 = np.quantile(data[column], 0.25), np.quantile(data[column], 0.75)          

    # IQR 계산하기     
    iqr = q75 - q25    

    # outlier cutoff 계산하기     
    cut_off = iqr * 1.5          

    # lower와 upper bound 값 구하기     
    lower, upper = q25 - cut_off, q75 + cut_off     

    print('IQR은',iqr, '이다.')     
    print('lower bound 값은', lower, '이다.')     
    print('upper bound 값은', upper, '이다.')    

    # 1사 분위와 4사 분위에 속해있는 데이터 각각 저장하기     
    data1 = data[data[column] > upper]     
    data2 = data[data[column] < lower]    

    # 이상치 총 개수 구하기
    return print('총 이상치 개수는', data1.shape[0] + data2.shape[0], '이다.')

image

outlier_iqr(train_x,'X_01')

data_X1 = train_x[(train_x['X_01'] < upper) & (train_x['X_01'] > lower)]
len(data_X1)

image

plt.figure(figsize=(10,5))

sns.distplot(train_x.X_01, kde=False)

# 이상치 영역 박스 그리기
plt.axvspan(xmin=lower, xmax=train_x.X_01.min(), alpha=0.2, color='red')
plt.axvspan(xmin=upper, xmax=train_x.X_01.max(), alpha=0.2, color='red')

image

X_01 = data_X1['X_01']

print(type(X_01))
X_01.head()

image

image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image image

계산이 제대로 되지 않는다.

이상치 검출 마친 데이터 병합

new_train_x = pd.concat([X_01, X_03, X_06, X_07, X_08, X_09, X_12, X_13, X_14, X_15, X_16, X_17, X_18, X_19, X_20, X_21, X_22, X_24, X_25, X_26, X_27, X_28, X_29, X_30, X_31, X_32, X_33, X_34, X_35, X_36, X_37, X_38, X_39, X_40, X_41, X_42, X_43, X_44, X_45, X_49, X_50, X_51, X_52, X_53, X_54, X_55, X_56], axis = 1)

하면서 생각해본 것들

내일은 만든 데이터셋 성능 시험 해보고 다른 전처리 방식 조금 사용해볼 예정

위에 써놓은 거 끝내면 다른 논문 더 찾아보고 효과적인 전처리 방식 찾아볼 듯

# 새로운 x 데이터랑 기존 y 데이터 합병
IQR_train = pd.concat([new_train_x, train_y], axis = 1)
# csv 파일로 저장
IQR_train.to_csv('IQR_train.csv', header = True, index = True)
df = pd.read_csv(file_path + './IQR_train.csv')

# NaN 값 0으로 변환
df1 = pd.DataFrame(df)
df1 = df.fillna(0)
print(df1)
train_df, valid_df = train_test_split(df1, train_size=0.8)

train_x = train_df.filter(regex='X') # Input : X Featrue
train_y = train_df.filter(regex='Y') # Output : Y Feature

valid_x = valid_df.filter(regex='X') # Input : X Featrue
valid_y = valid_df.filter(regex='Y') # Output : Y Feature

test_x = pd.read_csv(file_path + './test.csv').drop(columns=['ID'])
LR = MultiOutputRegressor(LinearRegression()).fit(train_x, train_y)

valid_preds = LR.predict(valid_x)
lg_nrmse(valid_y.values, valid_preds)

결과

image

허허 일부 데이터셋 다른 방식으로 전처리 해보고 돌려본 다음 다른 사례들 보면서 새로운 가설과 함께 새로운 방식으로 시도해보겠다.


다른 방법 1. x feature 7, 8, 30, 31, 32, 33, 38, 39의 이상치 제거 범위 넓혀서 만든 데이터 셋

결과

image

다른 방법 2. 방법 (1)에 X_46을 전처리하지 않고 그대로 합병한 데이터 셋

결과

image

다른 방법 3. 방법 (2)에 공분산 제거를 하지 않은 데이터 셋

결과

image

딱히 달라진 거 없다.

qwqw82000 commented 2 years ago

그래프가 가시성이 좋네요! 저는 (https://dacon.io/competitions/official/235927/codeshare/5945?page=1&dtype=recent)여기 lastdefiance20 님 말씀처럼 "우리가 이상치라고 생각했던 X의 범주에서 벗어난 값들이, 사실 제품이 불량인 Y_value값(정상 범주를 벗어난 Y_value)를 판단하는데 도움을 준다면." 이라는 가설을 검증하기 위해 X 데이터의 이상치가 결과에 미치는 영향을 분석하고자 합니다. 혹시 분석하는데 겹치는 부분이 있을까요? 아직 어떻게 검증을 할지는 생각중입니다

UGeunJi commented 2 years ago

감사합니다! 분석하는 데에 겹치는 부분이 있을 수 있다고 생각됩니다. 현재 제 생각은 X feature는 각 공정 과정의 수치만 나와있고, 수치 자체가 양품인지 아닌지의 여부를 알려주는 정보는 없기 때문에 이상치는 제거되어야 한다고 생각하고 있습니다. 하지만 lastdefiance20 님의 말씀도 맞을 수 있기에 수율 예측에 관한 여러 사례들을 좀 더 살펴보고 이상치를 어떻게 처리해야 할지 좀 더 자세히 알아볼 필요성을 느끼게 되었습니다. 저는 여러 실험과 연구 사례들을 살펴보며 이상치를 어떻게 다루는지 자세히 살펴보고 현재 우리 데이터에 가장 적합한 방법을 선택할 것 같아서 저 또한 어떻게 할지는 정해지지 않은 상태입니다!

sangmandu commented 2 years ago

이상치를 제거했는데 크게 성능이 달라지지 않았네요..

우근님이 생각하시기에는 앞으로의 방향이 무엇이라고 보시나요 1) 이상치 제거 방법이 solution이 아닌 듯 하다. 다른 방법 고민. 2) 좀 더 smart한 이상치 제거 방법이 필요하다. 좀 더 이상치 제거 고민.

무엇이라고 생각하시나요?

UGeunJi commented 2 years ago

지금까지 결과로써는 1번으로 나아가는 것이 더 나을 것 같습니다.

하지만 데이터 전처리를 아예 하지 않으면 안된다고 생각하고 있기도 합니다. 전처리 작업을 한다면 데이터의 Domain 지식을 활용해서 상관관계 분석의 결과와 함께 처리가 필요한 부분의 이상치만 처리해야 성능이 나아질 것으로 생각하고 있습니다.

내일 회의를 통해 서로의 의견을 들어보고 더 나은 방향을 위해 생각하는 시간이 필요할 것 같습니다.