220927 (seaborn의 철학, cylinders는 범주형 데이터에 가깝다, 결측치, include="object", exclude, value_counts, hue, crosstab, 피봇테이블, groupby, boxplot, 사분위수, 산점도 등)
멋쟁이 사자처럼 AI스쿨 7기, 박조은 강사님 강의
어제는 수치형 데이터의 기술통계를 했는데, 오늘은 범주형 데이터의 기술 통계를 해볼 것. displot에서 ecdf는 그려보지 않았지만 누적으로 그려주는 plot. Seaborn의 가장 큰 철학은 통계적 연산을 제공한다는 것.
✅ 0107 실습 파일 - 범주형 기술통계
- 라이브러리 로드
- 데이터셋 불러오기
- df = sns.load_dataset("mpg")
df.shape : shape에 ()를 붙어지 않는 이유. attribute라서 - 데이터셋 일부만 가져오기 : .head(), .tail()
- 요약하기 : .info()
Q.cylinders는 수치형 데이터지만 유일값이 5개 밖에 되지 않기 때문에 범주형 데이터에 가깝다. 그 기준은 df.hist() 시각화해보면 잘 나온다. bins=50 또는 100개를 그려보면 cylinders는 이가 빠져있다. cylinders나 model_year은 범주형에 가깝다. 유니크값의 개수를 확인해보는 방법도 있다. - 결측치 보기
- .isnull().sum() / .isnull().mean() / sns.heatmap(df.isnull(), cmap="gray")
- df.isnotnull()하면 결측치가 아닌 값이 나온다.
- plt.figure(figsize=(12,8)) 해주는 이유는 그냥 하면 6개 결측치가 다 안보이기 때문.
- 기술통계 : .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개 이상 변수에 대한 빈도수
- countplot으로 origin의 빈도를 시각화, cylinders로 다른 색상 표현하기
- seaborn에서 색상을 나타내는 것 : hue
- sns.countplot(data=df, x="origin", hue="cylinders")
- 실린더 갯수에 따라 빈도를 다르게 표현하게 된다.
- countplot으로 cylinders의 빈도수를 시각화하고 origin으로 다른 색상으로 표현하기
- sns.countplot(data=df, x="cylinders", hue="origin")
- 데이터 시각화 전문가들은 hue 색상을 지정할 때 3가지 이상 설정하지 말라고 한다.
- 1번과 같이 색상이 많아지면 구분이 어렵기 때문.
- 실린더 4개가 전세계에서 보편적이다, 이런 식으로 해석을 해낼 수 있다.
실린더가 뭔지 물어보려고 했는데, 이렇게 이해하게 되네
- 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
- pd.pivot_table(data=df, index="origin", values="mpg")
- 피봇테이블 내부는 그룹바이를 포함하고 있다. 그룹바이를 추상화.
- AggFuncType = "mean" 피봇테이블에서 기본값은 평균
- barplot으로 합계 값 구하기
- sns.barplot(data=df, x="origin", y="mpg", estimator=np.sum, ci=None)
- estimator=sum해도 됨.
- np.sum과 sum 중 성능이 더 좋은지 벤치마킹 하는 방법은 %time, %timeit
- barplot에 hue 사용하여 색상 다르게 표현해보기
- sns.barplot(data=df, x="origin", y="mpg", hue="cylinders"
- groupby로 3번 시각화에 대한 값을 구하기
- df.groupby(by=["origin", "cylinders"])["mpg"].mean()
- df.groupby(by=["origin", "cylinders"])["mpg"].mean().unstack()
- 마지막 인덱스값을 끌어올려준다. unstack
- unstack(0)은 가장 앞에 있는 값을 끌어올린다.
- unstack(0) 해서 origin을 끌어올려줘도 된다.
04 판다스 기초 강의 자료 보기
- 피봇테이블로 시각화 값을 구하기
- 크로스탭에서도 밑에 origin 행이 인덱스, 컬럼은 컬럼값들
- 피봇테이블에서도 value는 지정하지 않으면 모든 변수값에 대해서 값을 구하게 된다.
- pd.pivot_table(data=df, index="origin", columns="cylinders", values="mpg")
- Q. 피봇과 피봇테이블이 어떤 차이가 있을까? 연산을 하는지 여부
- 피봇테이블이 연산을 하고, 피봇은 연산을 하지 않는다.
- mpg값에 대해서만 평균을 구하게 된다. values로 지정해줬으니
- AggFuncType = "mean"
Boxplot
- 박스플롯과 사분위수
- 그룹바이로 origin 값에 따른 mpg의 기술통계
- desc = df.groupby("origin")["mpg"].describe()
eu=desc.loc["europe"] - loc는 행 인덱스 기준으로 가져온다.
- origin 값으로 그룹바이, 하나이기 때문에 대괄호로 묶어줄 필요 없다.
- IQR, 이상치를 제외한 최댓값, 최솟값 구하기
- Q3 = eu[75%]
- Q1 = eu[25%]
- IQR = Q3 - Q1
- OUT_MAX = (1.5*IQR) + Q3
- OUT_MIN = Q1 - (1.5*IQR)
- 유럽에 해당하는 값에 대한 박스플롯
df.boxplot(data=df[df["origin"]=="europe"], x="mpg") - boxenplot
- 수염에 있는 값을 조금 더 자세히 알아보고자 그리게 된 플롯
- 바이올린플롯
- boxenplot을 보완한게 violinplot
- 밀도 추정한 kdeplot을 마주보고 그린 것이 violinplot
산점도를 통한 범주형 데이터 표현
- scatterplot
- sns.scatterplot(data=df, x="origin", y="mpg")
- 변수간의 상관성을 파악하기 어렵다.
- 가장 큰 단점은 점이 겹쳐서 빈도수를 알기 어렵다.
- stripplot
- sns.stripplot(data=df, x="origin", y="mpg")
- 점을 옆으로 뿌려서 그리게 된다.
- scatter에 비해 값이 퍼지니까 조금 더 빈도수를 확인하기 적젏다.
- 빈도가 USA가 많아보이는데, scatterplot을 보면 알기 어렵다.
- swarmplot
- warnings.warn(msg, UserWarning) 칸이 좁아서 점이 겹쳐서 그려진다는 워닝메시지 : plt.figure(figsize=(12,4))로 넓혀줌
- sns.swarmplot(data=df, x="origin", y="mpg")
- catplot
- sns.catplot(data=df, x="origin", y="mpg")
- 기본값이 stripplot이다.
- seaborn.pydata.org 구분도 다시 한 번 보기
- pointplot은 안그려봤는데 선그래프를 그려준다.
- 범주형 데이터는 pointplot, 수치형데이터는 lineplot
- 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
해결과제
- 앤스컴스 콰르텟에서 그룹바이 사용했던 것 찾아보기
- eu=desc.loc["europe"]에서 왜 iloc가 아니라 loc를 쓸까
- 앤스컴스 콰르텟에서 values로 카운트 한 부분 설명 다른 사람 필기 찾아보기
- seaborn 사이트의 Example Gallery의 내용을 정리하면서 TIL해도 좋다.
댓글