티스토리 뷰

반응형

숫자형 단변량 분석

 

데이터가 그렇게 분포하고 있는데에는 다 이유가 있다.

분포로부터 뭔가 특이한 점이 있다면 그 이유를 찾는 게 데이터 분석이다.

 

20명의 나이 데이터(정보)가 있다.

그러면 데이터를 한눈에 파악하기 위해서는 무엇을 해야 하는가?

 

->내 생각: 기본적인 건 정렬. 그 후에 그룹화

 

수치형 변수를 정리하는 두 가지 방법

1. 숫자로 요약하기 : 정보의 대표값

평균, 중앙값,최빈값, 사분위수 -> 기초 통계량

 

2. 구간을 나누고 빈도수를 계산한다. -> 도수 분포표

 

평균 : 산술평균, 기하 평균, 조화 평균

조화평균은 모델링 할때 다룬다. -> ROC AUC, F1 SCORE

 

np.mean(df['컬럼명']) = 넘파이 함수

df.mean()

 

중위수 : 순서상 가운데

최빈값 = mode : 자료 중에서 가장 빈번

 

 

평균을 대표값으로 사용할 때 주의할 점

정규분포를 이뤄야 한다. + '이상치'

 

&&&

사용자들이 책을 제때 반납할 확률은? 그런 과제

회원 나이 평균을 계산

20몇세

 

히스토그램을 보았을 때, 봉우리가 2개

10대들이 많고, 40대가 많다.

즉, 평균의 함정 

&&&

 

즉, 정규분포화를 만들어야 한다.

 

사분위수

4로 나눌 때 경계의 위치에 해당하는 수가 4분위수

최소,25%,50%,75%,최대

 

Q1 = 25%

Q3 = 75%

IQR = Q3-Q1

최대 = Q3+IQR*1.5

최소 = Q1-IQR*1.5

 

이 분포가 그래도 대략 가늠해주게 해준다.

df.describe()
df.describe(include='all')

describe()는 IQR로 나오지 않는다.

min, max는 실제 min, max로 나온다.

숫자 타입으로 된 것만 계산

include='all'을 넣으면 모든 피처를 기준으로 계산해준다.

 

&&&

일련번호는 분석 대상이 아니다. 즉, 행 구분자는 대부분 분석 대상이 아니다.

타깃값 = 이진 범주

이름 또한 범주형이지만 Mr,miss 등의 특징이 있다.

운임료는 달러

embarked는 

k-means 클러스터링?

&&&

 

구간의 75% 데이터가 왼쪽에 몰려있다. 0~31

나머지 4분의 1은 32~512에 있다.

밀도가 높다 => 왜도가 높다.

그래서 4분위수가 분포를 파악하게 해준다.

 

기초통계량은 일단 수를 보고 데이터의 분포를 대략적으로 파악하게 해준다.

코드는 간단하고 해석이 중요하다.

 

히스토그램(도수분포표)

plt.hist로 쓰면 된다.

plt.hist(df.컬럼명, bins = 5, edgecolor = 'gray') #edgecolor를 넣어야 구분이 된다.
#sns는 전부 해준다.

bins은 얼마나 나눠지는지를 표시하는 것이다.

bins에 리스트를 넣으면, 그 구간별로 쪼개준다.

bins=[8,16,24,32,48]

 

seaborn에서도 그릴 수 있다.

sns.histplot(x= '컬럼명', data = df, bins = 20)
plt.show()

 

아무것도 넣지 않으면, y는 각 구간별 해당 값의 개수를 표시한다.

커널밀도함수인 kdeplot도 똑같은 형태.

 

커널밀도함수

면적으로 구간에 대한 확률을 추정한다.

 

20이라는 값이 있을 때, 전체 구간에서 어느정도의 확률일까? 를 추정

그래서 밀도함수 그래프 아래 면적은 1이다.

sns.kdeplot(x='Fare', data=titanic)
sns.kdeplot(titanic['Fare']) #똑같이 나온다

 

해석 1: 대부분의 탑승객은 30달러 이내.

극 소수의 사람들이 200 달러 이상

 

해석 2: 비즈니스 해석 - 당시 1910년대의 1달러는 현재의 200배 가치.

탑승객 대부분은 중산층. 아메리칸 드림을 꿈꾸었다.

-> 당시 시대상을 알아야 하므로, 도메인 지식을 알아야 한다.

도메인 지식을 기반으로 해석해내야 한다.

 

히스토그램을 그릴 때 주의할 점 : bins를 적절히 조절해야 한다.

구간의 개수에 따라서 파악할 수 있는 내용이 달라진다.

조절하면서 봐야 한다.

 

20대 초반과 30대 초반이 많다.

10세 이하의 어린 자녀들도 많다.

 

seaborn를 쓸 떄는 항상 matplotlib을 같이 불러와야 한다.

 

k

kdeplot으로 그리면, 아동들이 뾰족하게 있는지 아닌지 잘 알 수가 없다.

완전한 시각화를 다루려면 둘 다 봐야 한다. kde=True를 하면 아주 간단하게 해준다.

sns.histplot(df['Age'],kde=True)

 

인사이트 - 그래프 읽기

축의 의미를 일단 파악(x,y축)

값의 분포로부터 파악할 내용 - 희박한 구간과 밀집구간을 찾는다.

왜 그 구간은 희박한가? 왜 그 구간을 밀집되어 있는가? 그에 대한 비즈니스 의미를 파악한다.

왜 그런지를 궁금해해야 한다.

 

import seaborn as sns
import matplotlib.pyplot as plt

# train_df의 차원이 (936, 9)이므로 9개의 특성이 있습니다.
fig, axes = plt.subplots(3, 3, figsize=(15, 15))

# 9개의 특성에 대한 subplot을 순차적으로 채웁니다.
for i, ax in enumerate(axes.flat):
    if i < len(data.columns):
        column_data = data[data.columns[i]]
        sns.histplot(column_data, ax=ax, color='skyblue', bins=30, kde=True)
        ax.set_title(data.columns[i])  # subplot의 타이틀 설정

plt.tight_layout()
plt.show()

 

박스플롯

주의 : plt에서 박스플롯은 NaN이 있으면 그려지지 않는다.

null을 제외하기 위해서 notnull을 사용한다.

tmp = df.loc[df['Age'].notnull()]

 

boxplot()도 kde 처럼 df['컬럼명']을 넣어주면 된다.

plt.boxplot(df['컬럼명'],vert = False)
sns.boxplot(x = df['컬럼명']) #옆으로 그린다. 
sns.boxplot(y = df['컬럼명']) #위로 그린다.

 

vert를 설정해주면 옆으로 그린다.

sns는 그런거 없이 그냥 그려준다.

 

박스플롯 해석

박스플롯은 어디가 밀집해있는지에 대한 의미다.

 

실제 수염 길이 : 1.5*IQR 범위 이내의 최소, 최대값으로 결정(그래프에서 표현해주는 선까지=Fence)

Whisker(수염) - 1.5*IQR 외의 범위밖의 값들을 이상치라고 생각하지 않는 부분의 최대값과 최솟값을 분류

 

잠재적인 수염 길이 : 1.5*IQR 범위, 잠재적 수염의 길이 범위(Fence까지)

잠재적인 수염 길이의 바깥으로 간 점들은 '이상치'라고 정의할 수 있다.

 

예전에는 이상치를 신경썻으나 현재는 모델이 다 걸러내 주므로 잘 안쓴다.

그러나 이상치를 찾아내는 영역이 있다. 이상탐지

그럴 떄 쓴다.

 

시계열 데이터의 시각화

date를 일단 datetime으로 바꾸고, 그 후에 값들을 라인차트로 표현한다.

df['알자']=pd.to_datetime(df['일자'])

plt.plot('일자','O')
plt.plot('일자','T'

 

인사이트 - 단변량 분석 코드를 함수로 만들어서 효율화한다.

 

def eda_1_n(df, val, bins = 30) :
    # 기초 통계량
    display(df[[val]].describe().T)

    # 시각화
    plt.figure(figsize = (12,8))
    plt.subplot(2,1,1)
    sns.histplot(df[val], bins = bins, kde = True)
    plt.grid()

    plt.subplot(2,1,2)
    sns.boxplot(x = df[val])
    plt.grid()
    plt.show()

 

범주형 변수

 

성별을 분석하려면 어떻게 해야 하는가?

 

범주별 개수를 세면 된다.(빈도수)

 

범주별 빈도수와 범주별 비율을 계산한다.

pie chart 같은 것도 쓴다.

#범주별 빈도수
시리즈.value_counts()

#범주별 비율
시리즈.value_counts(normalize=True)

 

Bar plot

sns.countplot(x='컬럼명1', data=df)

알아서 범주 별로 개수를 보여준다.

 

탭으로 자동완성 기능 활용하기

 

순서를 바꾸고 싶을 때는 order=['컬럼명1','컬럼명2','컬럼명3'] 을 추가

orident = 방향.

v,h,x,y로 방향 결정

 

Pie Chart

파이차트에서 차트 위에 표시해주는 파라미터 = autopct

포매팅도 가능

tmp = df['P'].value_counts()

plt.pie(tmp.values, labels = tmp.index, autopct = '%.2f%%')
plt.show()

 

각도와 방향 조정도 가능하다.

 

startangle = 90 : 90도 부터 시작
counterclock = False : 시계 방향으로

 

간격 띄우고, 그림자 넣기도 가능
explode = [a,b,c] : 중심으로 부터 1,2,3 범주를 을 얼마만큼 띄울지

shadow = True : 그림자 추가

plt.pie(tmp.values, labels = tmp.index, autopct = '%.2f%%',
        startangle=90, counterclock=False)
#각도와 방향 조절

plt.pie(tmp.values, labels = tmp.index, autopct = '%.2f%%',
        startangle=90, counterclock=False,
        explode = [0.05, 0.05, 0.05], shadow=True)
plt.show()
#나누기

 

 

범주형과 수치형 그래프 비교

수치형 그래프는 연속된 숫자 순서대로 붙어있어야 한다. 즉, 순서를 바꿀 수 없다.

범주형 그래프는 순서를 바꿔도 상관이 없다. 그룹화되어있기 때문이다.(x축 차이) 

반응형