카테고리 없음

9주차 TIL - 결측치와 이상치와의 싸움

게임취업하고싶은 사람 2025. 3. 4. 21:12

 

데이터 분석 및 정리 방안

1. 칼럼 정리

  • Unnamed: 0: 인덱스로 보이며 삭제 가능.
  • Grading Date: 날짜 데이터이므로 datetime 형식으로 변환.
  • Harvest Year: 일부 결측치 존재, 예측 또는 삭제 여부 결정 필요.
  • altitude_mean_meters: 결측치 존재, 평균 또는 중위수로 대체 가능.
  • Processing Method, Region, Color: 범주형 데이터, 결측치 처리 필요.

2. 이상치 처리

  • Moisture Percentage: 0.0의 값이 존재하는데, 일반적인 수분 함량은 10~12%이므로 이상치 가능성 있음.
  • Total Cup Points, Aroma, Flavor 등 점수 관련 칼럼: 값의 분포를 확인 후 극단값 처리 필요.

3. 결측치 처리

  • 수치형 데이터 (altitude_mean_meters, Harvest Year): 평균 또는 중앙값 대체.
  • 범주형 데이터 (Processing Method, Region, Color): 최빈값 대체 또는 "Unknown" 처리.

우선 이상치 및 결측치 비율을 더 자세히 확인한 후 정리 방향을 결정하겠습니다. ​​

결과 분석 및 정리 방안

1. 결측치 처리

  • 범주형 데이터 (Processing Method, Region, Color)
    • Processing Method(8.33% 결측): 최빈값 또는 "Unknown"으로 대체.
    • Region(3.10% 결측): 최빈값으로 대체 가능, 또는 "Unknown".
    • Color(20.02% 결측): 결측 비율이 높아 "Unknown"으로 대체하는 것이 적절.
  • 수치형 데이터 (altitude_mean_meters, Harvest Year)
    • altitude_mean_meters(3.74% 결측): 중앙값으로 대체.
    • Harvest Year(2.99% 결측): 평균값 대체 가능하나, 최신 연도(2022년)와의 차이 분석 후 판단.

2. 이상치 처리

  • Moisture Percentage: 최소값이 0.0, 최대값이 28.0으로 범위를 벗어나는 값 존재. 정상 범위(10~12%) 밖의 값은 중앙값으로 대체.
  • Category One Defects, Category Two Defects: 최대값이 31, 55로 상당히 크므로 이상치 필터링 필요.
  • Bag Weight: 최소값이 0.0, 최대값이 21,600.0. 일반적인 커피 가방 무게(1~70kg) 이상은 제거 또는 조정 필요.




# 결측치 비율 확인
missing_values = df.isnull().sum() / len(df) * 100
missing_values = missing_values[missing_values > 0].sort_values(ascending=False)

# 이상치 확인 (수치형 데이터의 기본 통계)
numeric_summary = df.describe()

# 결과 출력
missing_values, numeric_summary

 

 

 

# 1. 불필요한 칼럼 제거
df_cleaned = df.drop(columns=["Unnamed: 0"])

# 2. 결측치 처리
df_cleaned["Processing Method"].fillna("Unknown", inplace=True)
df_cleaned["Region"].fillna("Unknown", inplace=True)
df_cleaned["Color"].fillna("Unknown", inplace=True)
df_cleaned["altitude_mean_meters"].fillna(df_cleaned["altitude_mean_meters"].median(), inplace=True)
df_cleaned["Harvest Year"].fillna(round(df_cleaned["Harvest Year"].mean()), inplace=True)

# 3. 이상치 처리
# Moisture Percentage: 10~12% 이내로 조정
df_cleaned.loc[df_cleaned["Moisture Percentage"] < 10, "Moisture Percentage"] = df_cleaned["Moisture Percentage"].median()
df_cleaned.loc[df_cleaned["Moisture Percentage"] > 12, "Moisture Percentage"] = df_cleaned["Moisture Percentage"].median()

# Bag Weight: 일반적인 범위(1~70kg)로 제한
df_cleaned = df_cleaned[(df_cleaned["Bag Weight"] > 1) & (df_cleaned["Bag Weight"] < 70)]

# Category One Defects, Category Two Defects: 99th 퍼센타일 초과 값 제거
q1_defect_threshold = df_cleaned["Category One Defects"].quantile(0.99)
q2_defect_threshold = df_cleaned["Category Two Defects"].quantile(0.99)
df_cleaned = df_cleaned[(df_cleaned["Category One Defects"] <= q1_defect_threshold) & 
                        (df_cleaned["Category Two Defects"] <= q2_defect_threshold)]

df_cleaned.to_csv("cleaned_quakers_data.csv", index=False)
from google.colab import files
files.download("cleaned_quakers_data.csv")

import missingno as msno
import matplotlib.pyplot as plt

msno.bar(df_cleaned)
plt.show()

 

 

sns.scatterplot(x=df_cleaned["altitude_mean_meters"], y=df_cleaned["Total Cup Points"])
plt.xlabel("Altitude (m)")
plt.ylabel("Total Cup Points")
plt.show()