본문 바로가기
부트캠프(LIKELION AIS7)/수업

[AI스쿨 7기, 2주차] 범주형 기술통계

by aimaimee 2023. 4. 9.

220927 (seaborn의 철학, cylinders는 범주형 데이터에 가깝다, 결측치, include="object", exclude, value_counts, hue, crosstab, 피봇테이블, groupby, boxplot, 사분위수, 산점도 등)

 

멋쟁이 사자처럼 AI스쿨 7기, 박조은 강사님 강의

 

어제는 수치형 데이터의 기술통계를 했는데, 오늘은 범주형 데이터의 기술 통계를 해볼 것. displot에서 ecdf는 그려보지 않았지만 누적으로 그려주는 plot. Seaborn의 가장 큰 철학은 통계적 연산을 제공한다는 것.

✅ 0107 실습 파일 - 범주형 기술통계

  1. 라이브러리 로드
  2. 데이터셋 불러오기
  3. df = sns.load_dataset("mpg")
    df.shape : shape에 ()를 붙어지 않는 이유. attribute라서
  4. 데이터셋 일부만 가져오기 : .head(), .tail()
  5. 요약하기 : .info()
    Q.cylinders는 수치형 데이터지만 유일값이 5개 밖에 되지 않기 때문에 범주형 데이터에 가깝다. 그 기준은 df.hist() 시각화해보면 잘 나온다. bins=50 또는 100개를 그려보면 cylinders는 이가 빠져있다. cylinders나 model_year은 범주형에 가깝다. 유니크값의 개수를 확인해보는 방법도 있다.
  6. 결측치 보기
    • .isnull().sum() / .isnull().mean() / sns.heatmap(df.isnull(), cmap="gray")
    • df.isnotnull()하면 결측치가 아닌 값이 나온다.
    • plt.figure(figsize=(12,8)) 해주는 이유는 그냥 하면 6개 결측치가 다 안보이기 때문.
  7. 기술통계 : .describe()
    • 범주형 변수에 대한 기술통계 보기 : .describe(include="object")
    • exclude : 특정 데이터타입만 제외, .describe(exclude=np.int64)
    • df.describe(include="all") 전체 형식의 데이터를 볼 수 있다.

범주형 변수

범주형 데이터 유일값이 빈도수

  • .unique() / .nunique()
  • unique()는 series 타입만 가능하고, nunique()는 dataframe 타입만 가능한가? 맞다. 하지만 nuique는 시리즈에도 가능하긴 함
  • countplot은 x축, y축 하나만 지정해주면 된다. 그러면 나머지 축의 빈도수를 표시해준다.
  • countplot으로 origin 빈도수 시각화하기 : sns.countplot(data=df, x="origin") / y="origin"으로 하면 그래프 x,y 축이 바뀜

1개 변수의 빈도수

  • origin의 빈도수 구하기 : df["origin"].value_counts()
  • 앤스컴스 콰르텟 할 때는 values로 카운트를 했다?
  • Q. 1개 변수 빈도수 구하는 Pandas API는 뭘까? value_counts

2개 이상 변수에 대한 빈도수

  1. countplot으로 origin의 빈도를 시각화, cylinders로 다른 색상 표현하기
    • seaborn에서 색상을 나타내는 것 : hue
    • sns.countplot(data=df, x="origin", hue="cylinders")
    • 실린더 갯수에 따라 빈도를 다르게 표현하게 된다.
  2. countplot으로 cylinders의 빈도수를 시각화하고 origin으로 다른 색상으로 표현하기
    • sns.countplot(data=df, x="cylinders", hue="origin")
    • 데이터 시각화 전문가들은 hue 색상을 지정할 때 3가지 이상 설정하지 말라고 한다.
    • 1번과 같이 색상이 많아지면 구분이 어렵기 때문.
    • 실린더 4개가 전세계에서 보편적이다, 이런 식으로 해석을 해낼 수 있다. 실린더가 뭔지 물어보려고 했는데, 이렇게 이해하게 되네
  3. crosstab으로 시각화한 값 직접 구하기
    • pd.crosstab(index=df["origin"], columns=["cylinders"]
    • 인덱스와 컬럼스는 빼도 무방하다.
    • 크로스탭 내부의 소스코드 보면 피봇테이블이 있다.
    • 피봇테이블이 추상화되어 있다. 피봇테이블을 구하기 쉽게 만들어 둔 것.

범주형 vs 수치형 변수

barplot으로 origin 별 mpg 값 구하기

  • sns.barplot(data=df, x="origin", y="mpg", ci=None)
  • Q. y축이 의미하는 파라미터는 무엇일까? mpg의 어떤 값? 평균값을 의미한다. extimator="mean"
  • ci=None은 deprecate 되었다. 신뢰구간을 표시하지 않겠다는 뜻. deprecate 용어도 검색해보고 알았다

groupby

origin별로 그룹화, mpg의 평균 구하기
df.groupby("origin")["mpg"].mean()

  • 앤스컴스 콰르텟에서도 그룹바이 사용했다.
  • 두 개로 색인하면 데이터프레임형태 [["mpg"]]
  • 그룹바이는 함수, 메서드라서 소괄호(). mpg는 인덱싱을 해주는 것이기 때문에 대괄호[] - 특정 컬럼값을 인덱싱
  • mean도 함수, 메서드라서 소괄호

pivot table

  1. pd.pivot_table(data=df, index="origin", values="mpg")
    • 피봇테이블 내부는 그룹바이를 포함하고 있다. 그룹바이를 추상화.
    • AggFuncType = "mean" 피봇테이블에서 기본값은 평균
  2. barplot으로 합계 값 구하기
    • sns.barplot(data=df, x="origin", y="mpg", estimator=np.sum, ci=None)
    • estimator=sum해도 됨.
    • np.sum과 sum 중 성능이 더 좋은지 벤치마킹 하는 방법은 %time, %timeit
  3. barplot에 hue 사용하여 색상 다르게 표현해보기
    • sns.barplot(data=df, x="origin", y="mpg", hue="cylinders"
  4. groupby로 3번 시각화에 대한 값을 구하기
    • df.groupby(by=["origin", "cylinders"])["mpg"].mean()
    • df.groupby(by=["origin", "cylinders"])["mpg"].mean().unstack()
    • 마지막 인덱스값을 끌어올려준다. unstack
    • unstack(0)은 가장 앞에 있는 값을 끌어올린다.
    • unstack(0) 해서 origin을 끌어올려줘도 된다.
    • 04 판다스 기초 강의 자료 보기
  5. 피봇테이블로 시각화 값을 구하기
    • 크로스탭에서도 밑에 origin 행이 인덱스, 컬럼은 컬럼값들
    • 피봇테이블에서도 value는 지정하지 않으면 모든 변수값에 대해서 값을 구하게 된다.
    • pd.pivot_table(data=df, index="origin", columns="cylinders", values="mpg")
    • Q. 피봇과 피봇테이블이 어떤 차이가 있을까? 연산을 하는지 여부
    • 피봇테이블이 연산을 하고, 피봇은 연산을 하지 않는다.
    • mpg값에 대해서만 평균을 구하게 된다. values로 지정해줬으니
    • AggFuncType = "mean"

Boxplot

  1. 박스플롯과 사분위수
    • 그룹바이로 origin 값에 따른 mpg의 기술통계
    • desc = df.groupby("origin")["mpg"].describe()
      eu=desc.loc["europe"]
    • loc는 행 인덱스 기준으로 가져온다.
    • origin 값으로 그룹바이, 하나이기 때문에 대괄호로 묶어줄 필요 없다.
  2. IQR, 이상치를 제외한 최댓값, 최솟값 구하기
    • Q3 = eu[75%]
    • Q1 = eu[25%]
    • IQR = Q3 - Q1
    • OUT_MAX = (1.5*IQR) + Q3
    • OUT_MIN = Q1 - (1.5*IQR)
  3. 유럽에 해당하는 값에 대한 박스플롯
    df.boxplot(data=df[df["origin"]=="europe"], x="mpg")
  4. boxenplot
    • 수염에 있는 값을 조금 더 자세히 알아보고자 그리게 된 플롯
  5. 바이올린플롯
    • boxenplot을 보완한게 violinplot
    • 밀도 추정한 kdeplot을 마주보고 그린 것이 violinplot

산점도를 통한 범주형 데이터 표현

  1. scatterplot
    • sns.scatterplot(data=df, x="origin", y="mpg")
    • 변수간의 상관성을 파악하기 어렵다.
    • 가장 큰 단점은 점이 겹쳐서 빈도수를 알기 어렵다.
  2. stripplot
    • sns.stripplot(data=df, x="origin", y="mpg")
    • 점을 옆으로 뿌려서 그리게 된다.
    • scatter에 비해 값이 퍼지니까 조금 더 빈도수를 확인하기 적젏다.
    • 빈도가 USA가 많아보이는데, scatterplot을 보면 알기 어렵다.
  3. swarmplot
    • warnings.warn(msg, UserWarning) 칸이 좁아서 점이 겹쳐서 그려진다는 워닝메시지 : plt.figure(figsize=(12,4))로 넓혀줌
    • sns.swarmplot(data=df, x="origin", y="mpg")
  4. catplot
    • sns.catplot(data=df, x="origin", y="mpg")
    • 기본값이 stripplot이다.
    • seaborn.pydata.org 구분도 다시 한 번 보기
    • pointplot은 안그려봤는데 선그래프를 그려준다.
    • 범주형 데이터는 pointplot, 수치형데이터는 lineplot
  5. catplot을 통한 범주형 데이터의 서브플롯 시각화
    • 박스플롯 sns.catplot(data=df, x="origin", y="mpg", kind="box", col="cylinders", col_wrap=3)
    • col_wrap=3은 한 줄에 3개씩 데이터를 출력해달라는 뜻
    • 바이올린 플롯 : FacetGrid기능. 변수별 서브플롯 제공
    • countplot 그리기 : sns.catplot(data=df, x="origin", kind="count", col="cylinders", col_wrap=3)
    • 변수를 하나로 설정해주어야 한다. 나머지 축에 빈도수를 표시해주기 때문이다.
    • x가 수치형 데이터여야 한다.
    • countplot은 안나와있지만 catplot 안에 포함
    • 서브플롯 그릴 때 FacetGrid / PairGrid로 그릴 수도 있다. ex) pairplot

해결과제

  1. 앤스컴스 콰르텟에서 그룹바이 사용했던 것 찾아보기
  2. eu=desc.loc["europe"]에서 왜 iloc가 아니라 loc를 쓸까
  3. 앤스컴스 콰르텟에서 values로 카운트 한 부분 설명 다른 사람 필기 찾아보기
  4. seaborn 사이트의 Example Gallery의 내용을 정리하면서 TIL해도 좋다.

댓글