기초 파이썬 통계 분석하기

기초통계분석은 데이터의 특징을 설명하기 위한 분석으로, 데이터의 심층적인 분석을 위해 필요한 가장 기본적인 통계이다. 기초통계는 기술통계라고도 하며, 여기서 ‘기술’이란 의미는 ‘기술하다(describe)’ 혹은 ‘서술하다(narrate)’의 의미로 해석할 수 있다. 기초통계를 구성하는 기초통계량에는 크게 중심경향성, 산포도, 분포, 백분위수 이렇게 4가지 범주로 분류할 수 있다. 본 포스팅에서는 파이썬을 통해 기초 통계 분석에 대해 살펴보고자 한다.

1. 데이터 준비

통계분석을 진행하기 전에 가장 먼저 선행되어야 할 것은 바로 분석할 데이터를 통계분석 툴로 불러오는 것이다. 프로그램에서 파일을 부르듯이, 파이썬에서도 데이터를 불러들이는 진행을 거친다. 이 작업은 이후 작업에도 지속해서 등장할 것이므로 특별한 언급이 없더라도 각 장마다 공통적으로 포함되는 작업임을 인지해야 한다. 데이터를 분석하기에 앞서 먼저 데이터를 불러와보자

본 교재에서 이용하는 데이터는 스프레드시트 형식의 csv확장자 파일로 작성되어 있다. 때문에 데이터를 불러오기 위해서는 형식을 그대로 가져오기위한 틀이 필요하다. 파이썬에는 데이터를 다루기 위한 다양한 모듈을 제공하며, 여기서는 가장 대표적인 모듈 중 하나인 pandas 이용하여 진행한다.pandas는 파이썬 프로그래밍 언어용으로 제작된 모듈로, 데이터 구조 및 데이터 분석 도구를 제공하는 오픈 소스 모듈이다

pandas
  • 행과 열로 이루어진 데이터 객체를 만들어 다룰 수 있게 도와주는 모듈로, 열이 있는 표 형식의 자료, SQL 테이블이나 스프레드시트 형식의 데이터에 적합하다.
  • 통합된 시계열 기능을 가지고 있으며, 시계열 데이터와 비시계열 데이터를 함께 다룰 수 있는 통합 구조를 제공한다. pandas를 통해 정렬된 형식의 데이터를 작성, 수정, 색인하는 등의 작업이 가능하다.
  • 기본적으로 정의되는 자료구조인 Series(객체를 담을 수 있는 1차원 배열의 자료구조)와 DataFrame(표 같은 스프레드시트 형식의 자료구조)을 사용한다.

In [26]:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

import pandas as pd

data= pd.read_csv('C:\\폴더명\\파일명.csv', engine='python')
data.head(7)

Out[26]:

고객ID이탈여부총 매출액방문빈도1회 평균매출액할인권 사용 횟수총 할인 금액고객등급구매유형클레임접수여부음향 적절성안내 표지판 설명친절성신속성책임성정확성전문성D1D2D3
010400708017235711154451406666666001
121316840014226314223509952406653666001
23026807801814893261860451416677667001
340594660017349800151951416666656001
450137459507318830192463501206556656100
560332361026127831203481451406555665001
67023693406394890303809451104654554000

7 rows × 42 columns

from IPython.core.interactiveshell import InteractiveShell / InteractiveShell.ast_node_interactivity = “all”
한 셀에 여러 결과값을 도출해 내기위한 문장
import (모듈) as (이름)
필요로 하는 모듈을 부르기 위한 명령문으로 import로 모듈을 불러온 후, as로 대체하고자 하는 이름을 넣는다. as의 경우,편하고 빠른 코딩을 위해 선택적으로 사용하며 pandas는 주로 pd로 명명한다.
(이름)= pd.read_csv(‘파일경로’, engine=’python’)
파일을 읽어 이름을 정해주기 위한 과정. pd모듈의 read_csv로 csv파일을 읽는 명령으로 파일경로와 파일명까지 적어준 후 engine='python'으로 설정하여 파일을 읽는다.
head()
데이터의 첫 5행만 보여달라는 명령으로 head(숫자)로 입력하면 원하는 숫자만큼 행을 보여준다.

In [4]:

data.info() #info(): 데이터내 컬럼의 이름, 셀의 개수, null값의 유무, 데이터 타입을 설명
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 42 columns):
고객ID                1000 non-null int64
이탈여부                1000 non-null int64
총 매출액               1000 non-null int64
방문빈도                1000 non-null int64
1회 평균매출액            1000 non-null int64
할인권 사용 횟수           1000 non-null int64
총 할인 금액             1000 non-null int64
고객등급                1000 non-null int64
구매유형                1000 non-null int64
클레임접수여부             1000 non-null int64
구매 카테고리 수           1000 non-null int64
거주지역                1000 non-null int64
성별                  1000 non-null int64
고객 나이대              1000 non-null int64
거래기간                1000 non-null int64
할인민감여부              1000 non-null int64
멤버쉽 프로그램 가입전 만족도    1000 non-null int64
멤버쉽 프로그램 가입후 만족도    1000 non-null int64
Recency             1000 non-null int64
Frequency           1000 non-null int64
Monetary            1000 non-null int64
상품 만족도              1000 non-null int64
매장 만족도              1000 non-null int64
서비스 만족도             1000 non-null int64
상품 품질               1000 non-null int64
상품 다양성              1000 non-null int64
가격 적절성              1000 non-null int64
상품 진열 위치            1000 non-null object
상품 설명 표시            1000 non-null object
매장 청결성              1000 non-null int64
공간 편의성              1000 non-null int64
시야 확보성              1000 non-null int64
음향 적절성              1000 non-null int64
안내 표지판 설명           1000 non-null int64
친절성                 1000 non-null int64
신속성                 1000 non-null int64
책임성                 1000 non-null int64
정확성                 1000 non-null int64
전문성                 1000 non-null int64
D1                  1000 non-null int64
D2                  1000 non-null int64
D3                  1000 non-null int64
dtypes: int64(40), object(2)
memory usage: 328.2+ KB




2. 중심경향성


중심경향성이란 데이터의 분포가 중앙에 모이게 되는 경향을 의미하며, 데이터 분포의 중심을 나타내는 값을 의미한다. 중심경향성은 매우 주요한 통계로서 중심을 나타내는 값으로는 (산술적) 평균(mean 또는 average), 중앙값(median), 그리고 최빈값(mode)이 있다. 평균은 데이터 속성의 값을 합한 후 그 합을 데이터 값의 개수만큼 나눈 것으로 속성에 대한 중심적인 경향을 쉽게 파악할 수 있다. 그러나 평균은 속성 값에 특이점(outlier)이 있을 경우 평균값이 크게 변동되기 때문에 특이점 하나로 인해 전체 속성에 대한 설명이 변할 수 있다는 문제점을 지니고 있다. 중앙값은 값을 산술적 가치로 서열화한 후 나열했을 때 가장 가운데 위치한 값을 의미한다. 특이점이 있는 데이터에서 평균은 제 역할을 하지 못하지만 중앙값은 서열화 된 결과로 중앙을 찾기 때문에 특이점에 영향을 받지 않고 중심적인 경향을 찾아낼 수 있다. 최빈값은 속성의 값들 중 그 수가 가장 많은 값을 의미하는데 위의 평균이나 중앙값과는 조금 다른 성향을 지닌다. 평균과 중앙값은 산술적인 가치를 지닌 값에 대해서만 의미를 지니지만 최빈값은 산술적인 가치가 없는 값에 대해서도 유용하게 쓰일 수 있다.

예제 (1)

백화점 고객들의 방문빈도의 평균, 중앙값, 최빈값을 구해보자

In [18]:

mean=data['방문빈도'].mean() #mean(): 평균값을 도출한다
median=data['방문빈도'].median() #median(): 중앙값을 도출한다
mode=data['방문빈도'].mode() #mode(): 최빈값을 도출한다


print("백화점 고객들의 방문빈도 평균: {:.3f}".format(mean))
print("백화점 고객들의 방문빈도 중앙값: {:.3f}".format(median))
mode #mode()는 최빈값, 데이터 타입이 같이 나오므로 위처럼 format(mode)를 사용하면 오류가 발생한다
백화점 고객들의 방문빈도 평균: 26.602
백화점 고객들의 방문빈도 중앙값: 21.000

Out[18]:

0    15
dtype: int64
예제 (1) 해설

백화점 고객들의 방문빈도의 평균은 26.6회, 중앙값은 21회, 최빈값은 15회이다. 평균과 중앙값의 차이가 많이 있는 것으로 보아 높은 값의 특이점이 있다는 것을 예측할 수 있다. 즉, 방문빈도가 매우 높은 고객 층이 있다는 것을 예측해 볼 수 있다.



3. 산포

산포는 용어 그대로 데이터가 퍼져있는 정도를 설명하는 기술통계로, 주요한 통계량으로는 최댓값, 최솟값, 범위, 분산, 표준편차 등이 있다. 최댓값 최솟값은 데이터 중에서 가장 큰 값과 가장 작은 값을 의미하며 범위는 최댓값과 최솟값의 차이이다. 최댓값, 최솟값, 범위는 데이터가 분포하고 있는 전체 범위를 표현해준다. 그리고 분산과 표준편차는 위의 3가지 산포도 통계량이 설명하지 못하는 전반적인 흩어짐과 변화량을 설명해 주는 통계량으로, 분산은 데이터 값들과 평균의 차이인 편차를 제곱한 값들의 평균을 의미한다. 그리고 표준편차는 분산에 루트를 씌운 값이다.

예제 (2)

백화점 고객들의 방문빈도의 최댓값, 최솟값, 범위, 분산, 표준편차를 구해보자

In [24]:

max=data['방문빈도'].max() #max(): 최댓값을 구한다
min=data['방문빈도'].min() #min(): 최솟값을 구한다
var=data['방문빈도'].var() #var(): 분산값을 구한다
std=data['방문빈도'].std() #std(): 표준편차를 구한다

print("백화점 고객들의 방문빈도 최댓값: {:.3f}".format(max))
print("백화점 고객들의 방문빈도 최솟값: {:.3f}".format(min))
print("백화점 고객들의 방문빈도 범위: {:.3f}".format(max-min))
print("백화점 고객들의 방문빈도 분산값: {:.3f}".format(var))
print("백화점 고객들의 방문빈도 표준편차: {:.3f}".format(std))
백화점 고객들의 방문빈도 최댓값: 203.000
백화점 고객들의 방문빈도 최솟값: 2.000
백화점 고객들의 방문빈도 범위: 201.000
백화점 고객들의 방문빈도 분산값: 452.846
백화점 고객들의 방문빈도 표준편차: 21.280
예제 (2) 해설

백화점 고객들의 방문빈도의 최댓값은 203회, 최솟값은 2회, 범위는 201, 분산은 452.8, 표준편차는 21.2회이다. 방문빈도 평균값 26회를 고려하면, 고객들간 방문빈도 차이가 크다는 것을 알 수 있다. 방문빈도만 고려해 보았을 때, 백화점은 방문빈도가 적은 고객들의 방문빈도를 늘릴 수 있는 마케팅을 고려해 볼 수 있다.



4. 분포

분포는 데이터의 형태와 대칭의 정도를 확인할 수 있는 기술통계로 왜도와 첨도 2가지가 있다. 여기서 왜도는 데이터의 분포에 있어서 기울어짐의 정도를 보여주는 척도이며 데이터가 얼마나 대칭적인지 확인할 수 있다. 첨도는 데이터 분포의 뾰족한 정도를 보여주는 척도로 데이터가 얼마나 모여있는지 혹은 분포되어있는지 확인할 수 있다.

왜도

왜도(Skewness)는 데이터의 분포가 왼쪽 또는 오른쪽으로 치우쳐 있는 정도를 나타내는 통계량으로, 그림과 같이 왜도 값이 0보다 큰 값을 가질 경우에는 전체적인 분포가 왼쪽으로 치우친 ‘오른쪽 꼬리 비대칭 분포’를 보이며 반대로 0보다 작은 값을 가질 때에는 분포가 오른쪽으로 치우친 ‘왼쪽 꼬리 비대칭 분포’를 보이게 된다. 왜도 값이 0일 경우 평균과 중앙값이 같으며 치우침이 없는 좌우대칭 분포를 보인다.

첨도

첨도(Kurtosis)는 데이터의 분포가 얼마나 뾰족한지를 나타내는 값으로, 데이터가 얼마나 평균에 집중되어 있는지를 확일할 수 있는 통계량이다. 첨도는 0을 기준으로 0보다 크면 정규분포보다 뾰족판 분포의 형태인 ‘급첨’을 보이고, 0보다 작을 경우에는 정규분포보다 완만한 구룽 모양의 ‘완첨’을 보이게 된다.

예제 (3)

백화점 총 매출액에 대한 왜도와 첨도를 구해보자

In [22]:

skew=data['총 매출액'].skew() #skew(): 왜도값을 구한다
kurtosis=data['총 매출액'].kurtosis() #kurtosis(): 첨도값을 구한다

print("백화점 고객들의 총 매출액 왜도: {:.3f}".format(skew))
print("백화점 고객들의 총 매출액 첨도: {:.3f}".format(kurtosis))
print("백화점 고객들의 총 매출액 평균: {:.3f}".format(data['총 매출액'].mean()))
백화점 고객들의 총 매출액 왜도: 3.834
백화점 고객들의 총 매출액 첨도: 21.207
백화점 고객들의 총 매출액 평균: 7068689.760
예제 (3) 해설

백화점 고객들의 총 매출액의 왜도는 3.8, 첨도는 21.2 정도로 나타났다. 왜도는 0보다 크므로 오른쪽 꼬리 비대칭 분포이고 첨도역시 0보다 크므로 급첨에 속한다. 즉, 백화점 고객들은 총 매출액 평균인 700만원보다 매출액이 적은 고객들이 많이 몰려있고, 그만큼 매출액이 높은 소수의 고객층이 존재한다는 것을 예측해 볼 수 있다. 매출액만을 기준으로 보았을 때, 백화점은 비교적 매출액이 적은 고객들과 높은 고객들간의 차이가 극명하게 날 것이다.



5. 백분위수

백분위수는 데이터를 순서대로 나열했을 때 백분율로 나타낸 특정 위치의 값을 의미하며, 가장 작은 것을 0으로, 가장 큰 것을 100으로 하여 데이터의 특정 위치에 어떤 값이 있는지를 나타내기 위해 주로 사용한다. 백분위수에서 일정하게 4등분하여 위치한 값을 사분위수라고 하며, 제 1사분위수는 누적백분율 25%, 제 2사분위수는 50%, 제 3사분위수는 75% 그리고 제 4사분위수는 100%에 해당하는 값이다.

예제 (4)

백화점 고객들의 거래기간에 대한 백분율 0인 분위수 그리고 사분위수를 모두 구해보자

In [27]:

quan_0=data['거래기간'].quantile(0) #quantile(): 특정 백분위수에 해당하는 값을 구한다(0~1 사이)
quan_25=data['거래기간'].quantile(0.25)
quan_50=data['거래기간'].quantile(0.50)
quan_75=data['거래기간'].quantile(0.75)
quan_100=data['거래기간'].quantile(1)

print("백화점 고객들의 거래기간 최솟값: {:.3f}".format(quan_0))
print("백화점 고객들의 거래기간 제 1사분위수: {:.3f}".format(quan_25))
print("백화점 고객들의 거래기간 제 2사분위수: {:.3f}".format(quan_50))
print("백화점 고객들의 거래기간 제 3사분위수: {:.3f}".format(quan_75))
print("백화점 고객들의 거래기간 제 4사분위수: {:.3f}".format(quan_100))
백화점 고객들의 거래기간 최솟값: 289.000
백화점 고객들의 거래기간 제 1사분위수: 1003.750
백화점 고객들의 거래기간 제 2사분위수: 1055.000
백화점 고객들의 거래기간 제 3사분위수: 1078.000
백화점 고객들의 거래기간 제 4사분위수: 1095.000
예제 (4) 해설

백화점 고객들의 거래기간의 최솟값, 즉 백분율 0의 분위수는 289, 제 1사분위수는 1003.75, 2사분위수는 1055, 3사분위수는 1078, 4사분위수는 1095이다. 결과를 통해 25% 이상의 거래기간끼리는 큰 차이가 없으나 25% 이하의 거래기간과 25% 이상의 거래기간은 큰 차이를 보이고 있음을 알 수 있다. 백화점은 고객들의 70%이상이 거래기간이 오래 된 기존 고객들로 구성되어 있다. 그만큼 신규고객의 유입이 적다는 것을 유추해볼 수 있는데, 때문에 백화점은 신규고객 유입을 위한 마케팅이나 혹은 기존고객과의 관계를 강화시키는 전략을 구상해 볼 수 있다.



6. 기초통계 전체분석

위에서는 각각의 컬럼을 따로 정한 후 값을 도출하였으나,컬럼을 정하지 않거나, 다른 명령문으로 데이터 전체의 기초통계 분석을 한눈에 정리할 수 있다. 먼저 컬럼을 정하지 않는 방법은 통계명령문 앞에 컬럼이 아닌 데이터 전체를 매칭하는 것이다. 그리고 다른 방법은 describe()를 사용하여 간단한 기초통계량을 한번에 뽑는 것이다 이러한 방법들은 데이터의 전체적인 부분을 확인하거나 컬럼간의 통계값을 비교해 볼 때 유용하게 사용할 수 있다.

예제 (5)

백화점 데이터 전체의 평균값을 구해보자

In [14]:

data.mean()

Out[14]:

고객ID                    500.500
이탈여부                      0.067
총 매출액               7068689.760
방문빈도                     26.602
1회 평균매출액             317361.141
할인권 사용 횟수                16.027
총 할인 금액              292371.670
고객등급                      1.266
구매유형                      3.093
클레임접수여부                   0.459
구매 카테고리 수                 5.147
거주지역                      5.147
성별                        0.851
고객 나이대                    4.851
거래기간                   1005.471
할인민감여부                    0.076
멤버쉽 프로그램 가입전 만족도          4.296
멤버쉽 프로그램 가입후 만족도          5.524
Recency                   6.489
Frequency                 3.783
Monetary                  4.141
상품 만족도                    4.634
매장 만족도                    4.877
서비스 만족도                   5.544
상품 품질                     5.926
상품 다양성                    5.713
가격 적절성                    5.736
매장 청결성                    5.762
공간 편의성                    5.877
시야 확보성                    5.707
음향 적절성                    5.810
안내 표지판 설명                 5.700
친절성                       5.383
신속성                       5.427
책임성                       5.672
정확성                       5.546
전문성                       5.526
D1                        0.317
D2                        0.144
D3                        0.496
dtype: float64
예제 (5) 해설

컬럼설정없이 데이터 전체를 매칭하여 전체적인 평균값을 한눈에 확인 할 수 있다.

예제 (6)

백화점 데이터 전체에 describe()를 이용하여 기본적인 통계량을 구해보자

In [25]:

data.describe() 
#describe(): 기초통계 몇가지를 모아서 보여준다. 위에서 부터 셀의 개수, 평균, 분산, 최솟값, 1분위수, 2분위수, 3분위수, 최댓값

Out[25]:

고객ID이탈여부총 매출액방문빈도1회 평균매출액할인권 사용 횟수총 할인 금액고객등급구매유형클레임접수여부음향 적절성안내 표지판 설명친절성신속성책임성정확성전문성D1D2D3
count1000.0000001000.0000001.000000e+031000.0000001.000000e+031000.0000001000.0000001000.0000001000.0000001000.0000001000.000001000.0000001000.0000001000.0000001000.0000001000.0000001000.0000001000.000001000.0000001000.000000
mean500.5000000.0670007.068690e+0626.6020003.173611e+0516.027000292371.6700001.2660003.0930000.4590005.810005.7000005.3830005.4270005.6720005.5460005.5260000.317000.1440000.496000
std288.8194360.2501476.966355e+0621.2801892.310413e+058.341334111937.5010420.4420850.9885990.4985660.783910.7877950.9236690.9928020.7943850.7813410.7361150.465540.3512650.500234
min1.0000000.0000002.271880e+062.0000002.246100e+041.0000003750.0000001.0000001.0000000.0000004.000004.0000003.0000002.0000003.0000003.0000003.0000000.000000.0000000.000000
25%250.7500000.0000003.303285e+0613.0000001.781558e+059.000000261686.2500001.0000002.0000000.0000005.000005.0000005.0000005.0000005.0000005.0000005.0000000.000000.0000000.000000
50%500.5000000.0000004.714785e+0621.0000002.626210e+0517.000000347500.0000001.0000003.0000000.0000006.000006.0000005.0000006.0000006.0000006.0000006.0000000.000000.0000000.000000
75%750.2500000.0000007.900290e+0632.0000003.936732e+0523.000000365400.0000002.0000004.0000001.0000006.000006.0000006.0000006.0000006.0000006.0000006.0000001.000000.0000001.000000
max1000.0000001.0000007.707087e+07203.0000002.680100e+0630.000000400600.0000002.0000004.0000001.0000007.000007.0000007.0000007.0000007.0000007.0000007.0000001.000001.0000001.000000

8 rows × 40 columns

예제 (6) 해설

data.describe()를 이용하여 백화점 전체 데이터에 대한 기초통계량을 확인할 수 있다. 총 매출액과 1회 평균매출액의 경우 단위수가 커서 정확한 값이 표기되지 않는다.

error: Content is protected !!
Scroll to Top