Notice
Recent Posts
Recent Comments
Link
«   2026/02   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

Silver bullet

데이터 탐색과 기술 통계 분석 본문

AI/AI

데이터 탐색과 기술 통계 분석

밀크쌀과자 2024. 7. 4. 12:39

1. 데이터 탐색과 빈도 분석 (Pie chart & Bar chart)

# EDA
# Exploratory Data Analysis
# 탐색적 데이터 분석

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

import warnings
warnings.filterwarnings("ignore") # 불필요한 Warning 메시지를 꺼줍니다.

%matplotlib inline

df = pd.read_csv('cosmetics_.csv')
df.head()
df['gender'] = df['gender'].replace([1, 2], ['male', 'female']) # 교체하다
df.head()

df['gender'].value_counts().plot(kind = 'pie') # plotting a "pie" graph

df['gender'].value_counts().plot(kind = 'bar') # plotting a "bar" graph

df['marriage'] = df['marriage'].replace([1, 2, 3], ['single', 'married', 'other'])
df['marriage'].value_counts() / len(df) * 100 # 결혼한 고객 백분율로 확인

 

2. 데이터 탐색과 기술통계분석

DataFrame의 기본적인 기술통계량 함수 ('1회 평균 구매 비용'을 기준으로)

df = pd.read_csv('cosmetics_.csv')

df.mean()

df['amount'].max() # 가장 높은 [ 1회 평균 구매 비용 ]

df['amount'].min()

total_amount = df['count'] * df['amount']
total_amount.sum()

df['amount'].sum()

df['amount'].mean()

df['amount'].var() # 분산 variance

df['amount'].std() # 표준편차 standard deviation

df['amount'].describe() 

df.info()

 

분포의 왜도와 첨도

  • 왜도(분포가 좌우로 치우쳐진 정도)0 & 첨도(분포가 뾰족한 정도)1일 때 완전한 정규 분표로 가정할 수 있다. (https://j.mp/367VXKj)
# amount == 1회 평균 구매 비용 

df['amount'].hist() # Histogram

# 왜도 (Skewness) : 0에 가까울수록 정규분포라고 가정할 수 있음 (절대값 기준 3 미초과)
# - 분포에서 긴 꼬리가 왼쪽에 있으면(분포가 우측으로 치우친 경우) 음(negative)의 왜도
# - 분포에서 긴 꼬리가 오른쪽에 있으면(분포가 왼쪽으로 치우친 경우) 양(positive)의 왜도

df['amount'].skew() 

# 첨도 (Kurtosis, 분포의 뾰족한 정도) : 1에 가까울수록 정규분포라고 가정할 수 있음 (절대값 기준 8 또는 10을 미초과)
    
df['amount'].kurtosis()

df['decision'].hist() # 구매 요인 (사회적 요인, 심리적 요인, 외모적 요인)

df['decision'].skew() # 왜도, 분포에서 긴 꼬리가 왼쪽에 있으면 음(negative)의 왜도, 그 반대의 경우 양(positive)의 왜도를 가진다고 한다. 

df['job'].kurtosis() # 첨도, 분포의 뾰족한 정도


Histogram & Distribution plot & Joint plot ('연 구매 횟수'와 '1회 평균 구매 비용'을 기준으로)

df.describe()

df.hist(bins=50, figsize=(20,15))
df_amount = df['amount'] # 1회 평균 구매 비용
df_amount.hist(bins=50, figsize=(20,15))

df_count= df['count'] # 연 구매 횟수
df_count.hist(bins=50, figsize=(20,15))

df[ df['amount'] > 3000000 ] # 이상치 확인
import seaborn as sns

sns.distplot(df_amount, rug=True) 
# "dist"ribution plot 
# rug : Whether to draw a rugplot on the support axis
# rugplot : 그래프 상에서 x축 위의 작은 선분으로 실제 데이터의 위치를 나타내준 것 (False로 지정하여 차이를 확인)
sns.jointplot(x="amount", y="count", data=df) # 산점도와 히스토그램을 한번에 -> Joint-plot 

sns.jointplot(x="amount", y="count", data=df, kind="kde") # Kernel-density (커널이라는 함수를 활용해 추정한 확률밀도함수를 겹쳐 그려주는 방법으로 히스토그램보다 부드러운 형태의 분포 곡선을 보여줌, 상세 설명 @ https://j.mp/35TVL12)

# 꼬리가 너무 긴 형태의 분포 -> 이상치가 분포를 제대로 확인하는 것을 방해하고 있을 수 있음

 

3. Outlier(이상치) 의 탐지 및 제거와 전후 분포 비교 (IQR Score 활용)

- How to Detect Outliers in Machine Learning (4 Methods for Outlier Detection) @ https://bit.ly/3Pdjq1h
- Ways to Detect and Remove the Outliers @ https://j.mp/2JmPKSN
- (추가 학습) Outlier는 모두 제거해야할까?: Outlier detection, IQR @ https://j.mp/35467fq

 

Outlier는 모두 제거해야할까? — Outlier detection, IQR

Outlier는 정말 불필요할까? outlier를 모두 제거해야만 할까? 이 글을 통해 생각해본다.

medium.com

#  수염상자그림
df.boxplot(column='amount') # 위와 아래의 작은 검정색 선이 상/하한선, 그 밖의 경우는 Outlier (동그라미로 표시해 줌)

Interquartile Range(IQR)은 Lower Quartile(25%)와 Upper Quartile(75%) 사이의 값 (만약 Lower Quartile이 30000이고 Upper Quartile이 100000 이면 IQR은 70000이다.)

 

Lower Whisker = Lower Quartile - (IQR * 1.5)

Upper Whisker = Upper Quartile + (IQR * 1.5)

df['amount'].describe()

# count    2.470000e+02
# mean     1.539393e+05
# std      3.980750e+05
# min      3.000000e+03
# 25%      3.000000e+04
# 50%      5.200000e+04
# 75%      1.000000e+05
# max      5.000000e+06
# Name: amount, dtype: float64

df['amount'].quantile() # 사분위수(Quantile), default == 0.5

df['amount'].median() # 중위값 (Median)
30000 - (100000 - 30000) *1.5 #lower Whisker 근데 마이너스 값은 가격에서 나올수 없으므로 최소값(여기선 3000)으로 설정
100000 + (100000 - 30000) *1.5

24.65 * 2+50 # 전체 데이터의 99.3% -> IQR 기법

데이터 분포가 항상 정규 분포를 이루는 것은 아니기 때문에 IQR 값은 항상 적용되는 것은 아니다.

 

# Inter-Quantile Range == 바닥부터 75% 지점의 값 - 바닥부터 25% 지점의 값

Q1 = df['amount'].quantile(q = 0.25)
Q3 = df['amount'].quantile(q = 0.75)

IQR = Q3 - Q1
IQR
# 상한치 : 바닥부터 75% 지점의 값 + IQR의 1.5배 
# 하한치 : 바닥부터 25% 지점의 값 - IQR의 1.5배 
# 그 기준을 넘기면 Outlier로 판단이 가능 

df_IQR = df[ (df['amount'] < Q3 + IQR * 1.5) & (df['amount'] > Q1 - IQR * 1.5) ]
df_IQR.boxplot(column='amount') # 위 아래의 작은 검정색 선이 상/하한선, 그 밖의 경우는 Outlier (동그라미로 표시해 줌)

df.boxplot(column='count') # 위 아래의 작은 검정색 선이 상/하한선, 그 밖의 경우는 Outlier (동그라미로 표시해 줌)
processed_df = df[['amount', 'count']]
processed_df = processed_df[ (processed_df['count'] < 10) & (processed_df['amount'] < 205000) ] # 상한선에 해당하는 값

processed_df.hist(bins=50, figsize=(20,15))

 

 

4. Log 함수를 활용한 Data(Feature) Scaling

- log는 큰 수를 같은 비율의 작은 수로 바꿔주는 역할을 할 수 있음 (큰 수를 작게 만들고 복잡한 계산을 간편하게 만듦, 100 vs 10000(==100^2) -> 10 vs 100(==10^2))
- 데이터 분포의 왜도(좌우로 치우친 정도) 혹은 첨도(뾰족한 정도)가 너무 큰 경우, Log 함수를 적용해 왜도/첨도를 낮춰주는 전처리를 적용할 수 있음
- 결과적으로 이를 통해 데이터(열)의 정규성을 높이고 각종 분석에서 보다 나은(정확한) 값을 얻을 수 있음

 

sns.jointplot(x="amount", y="count", data=processed_df, kind="kde")

# count에 비해 amount의 Scale이 너무 큰 상태
processed_df['logamount'] = np.log(processed_df['amount']) # Log 를 취한다.
processed_df['logamount']

sns.jointplot(x="logamount", y="count", data=processed_df, kind="kde")

 

'AI > AI' 카테고리의 다른 글

그로스 해킹을 위한 파이썬 통계 분석  (0) 2024.07.04
교차 검정 (p-value)  (0) 2024.07.04
기초 Numpy & Pandas  (0) 2024.07.02
한글 텍스트 데이터 전처리  (0) 2024.07.02
TF-IDF & Cosine similarity 이론  (0) 2024.07.02