[세션] Python 이상치 및 결측치

yeji·2024년 10월 28일
0

Python

목록 보기
12/36

결측치

  • 데이터의 누락된 부분
  • 결측치 제거
# 컬럼별 결측치 식별 
df3.isnull().sum()

# 결측치 제거1 - 열 제거하기 
df3 = df3.drop('Unnamed: 4', axis=1)


# 결측치 제거2 - 결측치가 있는 행들은 모두 제거 (가장 많이 씀)
df3.dropna()
# 같은 표현
df3.dropna(axis=0, how='any')

# 결측치 제거3 - 결측치가 있는 열을 모두 제거 
# 열로 제거하면 컬럼이 제거되는 현상이 발생하므로 매우 위험합니다.  
# df3.dropna(axis=1)

# 결측치 제거4 - 전체 행이 결측값인 경우만 삭제하고 싶은 경우
# how='all'을 사용해줍니다. 
df3 = df3.dropna(how='all')

# 결측치 제거5 - 결측치 제거 후 결과를 바로 저장하고 싶을 때
# inplace=True 조건을 넣어줍니다. 
df3.dropna(inplace=True)

# drop 이후 결측치가 잘 제거되었는지 체크가 필요하겠죠? 
df3.isnull().sum()
  • 결측치 대체
# 결측치 대체: 최빈값
# mode 는 최빈값을 의미
# df3 의 Interaction type 컬럼을 fillna함수를 이용하여 채워주되, mode() 함수를 사용하여 최빈값으로 넣어줌
# mode 함수는 시리즈를 output으로 가집니다. 
# 따라서,[0]을 통해 시리즈 중 단일값을 가져와야 합니다. 
df3 = df3['Interaction type'].fillna(df3['Interaction type'].mode()[0])

# 결측치 대체: 평균값
df['sw'] = df['sw'].fillna(df['sw'].mean())
df.isnull().sum()

# 결측치 대체: 중간값
# inplace=True 로 하면 원본 데이터가 바뀌게 됩니다.
df['sw'] = df['sw'].fillna(df['sw'].median())
df.isnull().sum()

# 결측치 대체: 바로 위 값으로 대체
df['sw'] = df['sw'].fillna(method='ffill')
df.isnull().sum()

# 결측치 대체: 바로 아래 값으로 대체
df['sw'] = df['sw'].fillna(method='bfill')
#df.isnull().sum()

# 결측치 대체: group by 값으로 대체
# 사전 데이터 확인
df.groupby('Is Amazon Seller')['sw'].median()

# group by한 데이터를 데이터프레임의 컬럼으로 추가하기 위해 
# transform 함수 사용
df['sw'] = df['sw'].fillna(df.groupby('Is Amazon Seller')['sw'].transform('median'))
df.isnull().sum()

df['sw'].fillna(df.groupby(기준컬럼)[계산할 컬럼].transform(계산방식))

이상치

  • 정확한 기준이 없음

이상치 식별

  • Z-Score (많이 사용)
    평균으로부터 얼마나 떨어져 있는가? 를 통한 이상치 판별
    데이터가 정규분포를 따를 때 사용
    python의 scikit-learn라이브러리가 이를 지원
    표준 점수는 평균으로부터 얼마나 멀리 떨어져 있는지를 보여주며, 일반적으로 -3에서 3 사이의 값을 가지고 있음, ±3 이상이면 이상치로 간주
# df 의 Shipping Weight를 기준으로 다양한 이상치 감지 기법을 적용해 보겠습니다. 
df = pd.read_csv("p.csv")

# string -> float -> int 
df['sw'] = df['Shipping Weight'].str.split().str[0]
df['sw'] = pd.to_numeric(df['sw'] , errors='coerce').fillna(0.0).astype(int)

# z-score 를 적용할 컬럼 선정
df1 = df[['sw']]

# 표준화 진행
# 표준화 :  평균을 0으로, 표준 편차를 1로 
# 데이터를 0을 중심으로 양쪽으로 데이터를 분포시키는 방법
# 표준화를 하게 되면 각 데이터들은 평균을 기준으로 얼마나 떨여져 있는지를 나타내는 값으로 변환
scale_df = StandardScaler().fit_transform(df1)

merge_df = pd.concat([df1, pd.DataFrame(StandardScaler().fit_transform(df1))],axis=1)
merge_df.columns = ['Shipping Weight', 'zscore']

# 이상치 감지 
# Z-SCORE 기반, -3 보다 작거나 3보다 큰 경우를 이상치로 판별 
mask = ((merge_df['zscore']<-3) | (merge_df['zscore']>3))

# mask 메소드 사용
strange_df = merge_df[mask]

# 총 55 건 탐지 
strange_df.count()
  • IQR (많이 사용)
    데이터의 분포가 정규 분포를 이루지 않을 때 사용
    데이터의 25% 지점()과 75% 지점() 사이의 범위()를 사용
# df 의 Shipping Weight를 기준으로 다양한 이상치 감지 기법을 적용해 보겠습니다. 
df = pd.read_csv("p.csv")

# string -> float -> int 
df['sw'] = df['Shipping Weight'].str.split().str[0]
df['sw'] = pd.to_numeric(df['sw'] , errors='coerce').fillna(0.0).astype(int)

# 이상치를 감지할 컬럼 선정
df1 = df[['sw']]

# Q3, Q1, IQR 값 구하기
# 백분위수를 구해주는 quantile 함수를 적용하여 쉽게 구할 수 있음
# 데이터프레임 전체 혹은 특정 열에 대하여 모두 적용이 가능

q3 = df1['sw'].quantile(0.75) 
q1 = df1['sw'].quantile(0.25)

iqr = q3 - q1
q3, q1, iqr

# 이상치 판별 및 dataframe 저장 
# Q3 : 100개의 데이터로 가정 시, 25번째로 높은 값에 해당합니다.
# Q1 : 100개의 데이터로 가정 시, 75번째로 높은 값에 해당합니다.
# IQR : Q3 - Q1의 차이를 의미합니다.
# 이상치 : Q3 + 1.5 * IQR보다 높거나 Q1 - 1.5 * IQR보다 낮은 값을 의미

def is_outlier(df1):
    score = df1['sw']
    if score > 7 + (1.5 * 6) or score < 1 - (1.5 * 6):
        return '이상치'
    else:
        return '이상치아님'

# apply 함수를 통하여 각 값의 이상치 여부를 찾고 새로운 열에 결과 저장
df1['이상치여부'] = df1.apply(is_outlier, axis = 1) # axis = 1 지정 필수

# IQR 방식으로 구한 이상치 개수는 349 개 
df1.groupby('이상치여부').count()
  • Isolation Forest
    머신러닝 기법 중 하나로, 컬럼 갯수가 많을 때 이상치를 판별하기 용이
    데이터셋을 결정트리 형태로 표현
    한 번 분리될 때 마다 경로 길이가 부여되며 이상치는 다른 관측치에 비해 짧은 경로 길이를 가짐

  • DBScan
    밀도 기반의 클러스터링 알고리즘으로 어떠한 클러스터에도 포함되지 않는 데이터를 이상치로 탐지하는 방법
    주로 지리 데이터 분석, 이미지 데이터 분석의 이상치 기법으로 사용
    심 포인트들이 서로 연결되어 군집을 형성하며, 이와 연결되지 않은 포인트는 이상치로 분류

이상치 처리

  • 제거 : 이상치가 데이터 오류나 적절하지 않은 값일 경우 제거, 데이터의 표본 크기를 줄일 수 있음
  • 대체
    로그 변환 : 데이터에 로그 변환을 적용하여 극단적인 값 완화
    상한값과 하한값 : 하한값과 상한값을 결정한 후 하한값보다 적으면 하한값으로 대체, 상한값보다 크면 상한값으로 대체
    평균 절대 편차 : 중위수로부터 n편차 큰 값 대체(자주 사용하지 않음)
  • 분리 : 새로운 데이터프레임을 생성하여 이상치를 저장
profile
👋🏻

0개의 댓글