티스토리 뷰
숫자형 단변량 분석
데이터가 그렇게 분포하고 있는데에는 다 이유가 있다.
분포로부터 뭔가 특이한 점이 있다면 그 이유를 찾는 게 데이터 분석이다.
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을 같이 불러와야 한다.
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축 차이)