brunch

매거진 Spark+Python

You can make anything
by writing

C.S.Lewis

by 보나벤투라 Nov 20. 2017

기술통계 & EDA '직접 구현하기'


  기술통계량은 Numpy 또는 Pandas library들을 통해 간단히 확인할 수 있습니다. 실제로, 이전 포스트들 또한 라이브러리를 활용하였습니다. 그러나, 함수들을 직접 구현해보고 그 원리를 이해할 때 데이터과학을 더 자유롭게 할 수 있으리라 생각되어 직접 알고리즘을 구현해 보았습니다.

  고급 통계 또는 머신러닝 알고리즘과는 달리, 어렵지 않은 기초통계의 부분이므로 본 포스트를 통해 알고리즘을 직접 이해하고 실습해보는 시간을 가져보시길 바랍니다. 



기술통계량 직접 구하기

list=[63,65,75,75,76,84,85,87,90,76,77,65,42,45,47,51,52,69,75,58,66,67,68,69,69,70,34,38,42,58,59,60,61,71,71,72,93,93,97,73,73,74,79,81,81,82,83,83,84,91]


def max(x): #최대값

      sorted_v=sorted(x)

      return sorted_v[-1]


def min(x): #최소값

      sorted_v=sorted(x)

      return sorted_v[0]

def mean(x):

     return sum(x)/len(x)


def sample_var(x): #표본분산

     x_bar=mean(x)

     n=len(x)

     deviation=[(x_i - x_bar)**2 for x_i in x]

     sum_of_square=sum(deviation)

     return sum_of_square/(n-1) 


def sample_standard_deviation(x): #표본 표준편차

     import math

     return math.sqrt(sample_var(x)) 


def mode(x): #최빈값

     from collections import Counter

     dic=Counter(x)

     max_v=max(dic.values())

     return [(key,value) for key,value in dic.items() if value==max_v] 

def quartile(x,p): #분위수 구하기

     n=len(x)+1

     sorted_v=sorted(x)                        

     diff=n*p-int(n*p)

     if diff==0: #np가 자연수일 때

#np번째 순서통계량이 100p 표본백분위수

         return sorted_v[int(n*p-1)]

     else: #np가 r+a(r은 자연수, 0<a<1)의 형태인 경우

#r번째와 (r+1)번째 순서통계량의 가중평균

         return sorted_v[int(n*p-1)]*(1-diff)+sorted_v[int(n*p)]*diff


>> quartile(list,0.25) #제1사분위수(first quartile)

>> quartile(list,0.5) #중위수(median)

>> quartile(list,0.75) #제3사분위수(third quartile)


def summary(x):

     print ("Mean:%d, Sample_Var:%d, Sample_std:%d, Max:%d, 1Q:%d, Median:%d, 3Q:%d, Max:%d" %(mean(x), sample_var(x), sample_standard_deviation(x),min(x),quartile(x,0.25),quartile(x,0.5),quartile(x,0.75),max(x)))

이상치 직접 찾아보기

other_list=[3,5,10,15,95,84,100,150,130,120,25,34,33,63,65,75,75,76,84,85,87,90,76,77,65,42,45,47,51,52,69,75,58,66,67,68,69,69,70,34,38,42,58,59,60,61,71,71,72,93,93,97,73,73,74,79,81,81,82,83,83,84,91]

>> IQR=quartile(other_list,0.75)-quartile(other_list,0.25);IQR

>> inner_left_fence=quartile(other_list,0.25)-1.5*IQR;inner_left_fence

>> inner_right_fence=quartile(other_list,0.75)+1.5*IQR;inner_right_fence

>> [x for x in other_list if x<inner_left_fence] #suspected outliers

>> [x for x in other_list if x>inner_right_fence] #suspected outliers

>> import seaborn as sns

>> import matplotlib.pyplot as plt

>> ax=sns.boxplot(other_list,palette="Set2")

>> plt.setp(ax.artists,alpha=0.6)

>> sns.stripplot(other_list,jitter=True,palette="Set2",alpha=0.7)

>> plt.show()

[3,5,10,15]와 [130,150]의 이상치를 boxplot을 통해서도 동일하게 확인할 수 있습니다.
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari