[Python] 예제로 익히는 Python 04~5

Data_Student·2024년 10월 28일
0

Python

목록 보기
6/7

[Python] 예제로 익히는 Python 04~5

예제로 익히는 파이썬 - 4~5회차 정리 및 복습

  • 데이터의 이상치와 결측치 개념을 이해
  • python 라이브러리를 사용하여 이상치와 결측치를 처리하는 과정을 학습

01. 이상치, 결측치란?

1. 이상치 : 전체 데이터 범위에서 벗어난 아주 작은 값이나 큰 값
2. 결측치 : 데이터 수집 과정에서 측정되지 않거나 누락된 데이터

  • 이상치와 결측치를 정제해야하는 이유 : 평균의 오류를 줄이기 위해서

02. 결측치

1. 결측치 : 데이터의 누락된 부분
2. 결측치 처리 - 제거

 # 컬럼별 결측치 식별 
 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()

3. 결측치 처리 - 대체
1) 최빈값 : 범주형 변수에 주로 사용, 데이터가 가장 많이 도출된 값으로 대체 가능
2) 중앙값, 평균값 : 수치형 변수에 사용, 결측치에 중앙값이나 평균값으로 대체
3) 그 외 : 행 기준 바로 위나 바로 아래 값 또는 group by 연산의 결과로 대체

  # 결측치 대체: 최빈값
  # 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(계산방식))

03. 이상치

1. 이상치 : 전체 데이터 범위에서 벗어난 아주 작은 값이나 큰 값
but, 정확한 기준에 대한 정답은 없기에 통계적 기법 + 데이터분석가의 주관이 필요
2. 이상치 식별 방법
1) Z-Score(StandardScaler) - ESD

  • '평균으로부터 얼마나 떨어져 있는가?' 를 기준
    데이터의 분포가 정규 분포를 이룰 때, 데이터의 표준 편차를 이용해 이상치를 탐지하는 방법
  • 표준점수 : 일반적으로 -3에서 3 사이의 값, ±3 이상이면 이상치로 간주
  • Python의 scikit-learn 라이브러리 활용
# 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()

2) IQR(Interquartile Range) - 사분위수

  • 데이터의 분포가 정규 분포를 이루지 않을 때 사용
# 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()

3) Isolation Forest (이미지 참고하면 이해하기 쉬움!)

  • 머신러닝의 기법 중 하나로 데이터셋을 결정트리 형태로 표현
  • 질문에 질문이 이어지는만큼 경로가 짧을 경우 이상치
  • 컬럼의 수가 많을 때 유용

4) DBScan (이미지 참고하면 이해하기 쉬움!)

  • 밀도 기반의 클러스터링 알고리즘
  • 어떠한 군집에도 포함되지 않는 데이터를 이상치로 탐지하는 방법
  • 복잡한 구조의 데이터에서 이상치 판별할 때 유용
  • 주로 지리 데이터 분석, 이미지 데이터 분석의 이상치 기법으로 사용

0개의 댓글