본문 바로가기
CS/DataAnalysis

데이터 분석

by zieunee 2021. 4. 11.
반응형

데이터분석

raw data

정제되지 않은 데이터

샘플링 이란 ? 어떤 자료로 부터 일부의 값을 추출하는 행위.

피처

데이터를 구성하는 요소

ex> 학급의 신체검사 결과 기록한 데이터 --> 키,몸무게,시력 등등이 피처이다.

피처의 속성, 상관관계 탐색, 시각화

  • 속성탐색 : 학급 데이터에서 학급 평균키 등등 , "표준편차, 중앙값, 데이터등등 통계값"을 구할 수 있다.
  • 상관관계 탐색 : ex> 몸무게, 키 와의 상관관계 / 이를 통계적으로 알아 볼 수 있다.
  • 데이터 시각화 : 수치적 자료만 가지고는 파악하기 힘든 패턴이나 인사이트를 발견하는데 유용하다.

practice

멕시코풍 프렌차이즈 주문 데이터 분석하기

데이터 기초정보

# -*- coding: utf-8 -*-

import pandas as pd

# read_csv 함수로 데이터를 Dataframe 형태로 불러옵니다.
file_path = '../data/chipotle.tsv'
chipo = pd.read_csv(file_path, sep = '\t')

print(chipo.shape)
print("------------------------------------")
print(chipo.info())

result

(4622, 5)
------------------------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4622 entries, 0 to 4621
Data columns (total 5 columns):
 #   Column              Non-Null Count  Dtype 
---  ------              --------------  ----- 
 0   order_id            4622 non-null   int64 
 1   quantity            4622 non-null   int64 
 2   item_name           4622 non-null   object
 3   choice_description  3376 non-null   object
 4   item_price          4622 non-null   object
dtypes: int64(2), object(3)
memory usage: 180.7+ KB
None
  1. 데이터를 불러오기 위해 read_csv() 함수를 사용해야 한다. 데이터 파일경로 입력 (file_path)
  2. shape()와 info()함수를 호출하면 result 와 같은 결과가 나온다.
    1. shpe() 데이터 행과 열 크기를 반환
    2. info() 행의 구성정보와 열의 구성정보를 나타낸다.
    3. item_name 는 object type 으로 알 수 있는데 이는 "문자열 "을 의미
    4. null의 뜻은 데이터가 비어있다 "결측값"이다 라는 의미 / not null 은 데이터가 비어있지 않다.

다양한 함수

# chipo 라는 Dataframe에서 순서대로 10개의 row 데이터를 보여준다.
chipo.head(10)
print(chipo.columns) # 열정보 출력 
print("------------------------------------")
print(chipo.index) # 행정보 출력

연속형 피처

quantity, item_price 두 피처는 연속형 피처(어떤 값도 가질 수 있는 연속적인 숫자 형태)

chipo['order_id'] = chipo['order_id'].astype(str) # order_id는 숫자의 의미를 가지지 않기 때문에 str으로 변환

print(chipo.describe()) # chipo dataframe에서 수치형 피처들의 요약 통계량을 확인.

#result 
          quantity
count  4622.000000
mean      1.075725 # 아이템 평균 주문 수량 
std       0.410186
min       1.000000
25%       1.000000
50%       1.000000
75%       1.000000
max      15.000000

item_price 같은 경우는 object 타입이기 때문에 데이터 전처리 과정을 거쳐야 한다.

print(len(chipo['order_id'].unique())) # order_id의 개수
print(len(chipo['item_name'].unique())) # item_name의 개수
1834
50

unique() 개수 출력

탐색과 시각화

가장 많이 주문한 아이템10

DataFrame['column']의 형태에 value_counts() 함수를 적용한다.

DataFrame['column'] 은 시리즈라는 객체를 반환하는데 value_counts()는 오직 시리즈 객체에서만 적용된다.

# 가장 많이 주문한 item : top 10을 출력
item_count = chipo['item_name'].value_counts()[:10]
for idx, (val, cnt) in enumerate(item_count.iteritems(), 1):

아이템별 주문 개수와 총량

groupby() : 데이터 프레임에서 특정 피처를 기준으로 그룹을 생성하여, 이를 통해 그럽별 연산을 적용할 수 있음

​ ex> "학급" 그룹 만들어서 학급별 키,몸무게를 구할 수 있음

#아이템별 주문개수 출력 
order_count = chipo.groupby('item_name')['order_id'].count()
order_count[:10] ##아이템별 주문 개수 출력

# item당 주문 총량을 출력.
item_quantity = chipo.groupby('item_name')['quantity'].sum()
item_quantity[:10] # item당 주문 총량을 출력.

시각화

그래프로 시각화

tolist() 와 넘파이의 arrange() 함수를 이용해 x_pos를 선언하고 0~50 까지 숫자를 x축 이름으로 사용한다.

y값에는 주문 총량인 item_quantity.value.tolist()를 넣어줌

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

item_name_list = item_quantity.index.tolist() # x축에 넣을 값들 리스트 
x_pos = np.arange(len(item_name_list)) # x축에 넣을 값리스트 총 개수
order_cnt = item_quantity.values.tolist() # item_quantity의 개수 리스트 
plt.bar(x_pos, order_cnt, align='center') 
plt.ylabel('ordered_item_count')
plt.title('Distribution of all orderd item')

plt.show()
value_counts()와 unique()의 차이점 ***
print((chipo['item_name'].unique())) # order_id의 개수를 출력합니다.
print("------------------------")
print((chipo['item_name'].value_counts())) # order_id의 개수를 출력합니다.
['Chips and Fresh Tomato Salsa' 'Izze' 'Nantucket Nectar'
 'Chips and Tomatillo-Green Chili Salsa' 'Chicken Bowl' 'Side of Chips'
 'Steak Burrito' 'Steak Soft Tacos' 'Chips and Guacamole'
 'Chicken Crispy Tacos' 'Chicken Soft Tacos' 'Chicken Burrito'
 'Canned Soda' 'Barbacoa Burrito' 'Carnitas Burrito' 'Carnitas Bowl'
.......
-------------------------------
Chicken Bowl                             726
Chicken Burrito                          553
Chips and Guacamole                      479
Steak Burrito                            368
Canned Soft Drink                        301
Chips                                    211
Steak Bowl                               211
Bottled Water                            162
Chicken Soft Tacos                       115
Chips and Fresh Tomato Salsa             110
Chicken Salad Bowl                       110
Canned Soda                              104
Side of Chips                            101
Veggie Burrito                            95
.......

unique() : 배열 형태로 출력되며, 개수를 출력안되고 순서없이 유일한 값으로 1개씩 출력됨

<class 'numpy.ndarray'> #데이터 형태

value_counts() : 테이블 형태로 출력, count된 개수대로 내림차순으로 출력된다.

<class 'pandas.core.series.Series'> #데이터 형태

데이터 전처리 함수 사용

item_price 는 object 이기 때문에 피처의 요약 통계를 구할 수 없었다.

데이터 전처리 방법

item_price 는 앞에 $표시가 있었기 때문에 기호 삭제해주는 전처리 작업이 필요함

chipo['item_price']에 apply()함수를 적용함으로써 가능하다.

apply()는 lambda라는 함수 명령어를 추가해준다.

# column 단위 데이터에 apply 함수로 전처리를 적용합니다.
chipo['item_price'] = chipo['item_price'].apply(lambda x: float(x[1:]))
chipo.describe()

#result
         quantity    item_price
count    4622.000000    4622.000000
mean    1.075725    7.464336
std        0.410186    4.245557
min        1.000000    1.090000
25%        1.000000    3.390000
50%        1.000000    8.750000
75%        1.000000    9.250000
max        15.000000    44.250000

apply()함수는 시리즈 단위의 연산을 처리하는 기능을 수행 , sum()이나 mean()같이 연산이 정의된 함수를 파라미터로 받는다. 우리가 정의할 새로운함수 문자열 데이터에서 첫번째 문자열을 제거하고 나머지 문자열을 수치로 바꿔주는 함수를 파라미터로 입력할 수 있다.

탐색적 분석

  • sum() : 합계

  • info() : 기초적인 정보

  • mean() : 평균값 구하기

  • sort_values() : 데이터 정렬함수

  • drop_duplicates() : 해당 컬럼 중복제거

활용해보기

chipo_one_item = chipo[chipo.quantity == 1] // quantity 가 1인 데이터를 골라서
price_per_item = chipo_one_item.groupby('item_name').min() // item_name이 최솟값인 애들을 골라서
price_per_item.sort_values(by = "item_price", ascending = False)[:10] // item_price기준으로 내림차순 10개를 보여줘라

practice2

국가별 음주데이터 분석

탐색과 시각화

피처관 상관관계 탐색하는 방법

  1. 피처가 2개일때 상관계수를 계산하는 단순 상관 분석방법
  2. 피처가 여러개일때 상호간의 연관성을 분석하는 다중 상관 분석

실습

맥주와 와인 소비량의 상관관계

corr = drinks[['beer_servings', 'wine_servings']].corr(method = 'pearson')
print(corr)
# result
               beer_servings  wine_servings
beer_servings       1.000000       0.527172
wine_servings       0.527172       1.000000

pearson : 상관계수를 구하는 계산 방법 중 하나를 의미하며, 가장 널리 쓰이는 방법

두 피처를 선택 후 corr()함수에 적용. 이를통해 matrix 형태로 출력할 수 있음

heatmap, pairplot

파이썬의 seaborn이라는 시각화 라이브러리를이용해 2의 기법을 사용할 수 있음

!pip install seaborn

아나콘다 프롬포트에서 가상환경을 실행한 상태로 아래 명령어를 입력

heatmap의 경우 corr.values를

pairplot의 경우 데이터 프레임을 파라미터로 넣어줌

#heatmap이용 
import seaborn as sns
cols_view = ['beer', 'spirit', 'wine', 'alcohol'] 
sns.set(font_scale=1.5)
hm = sns.heatmap(corr.values,
            cbar=True,
            annot=True, 
            square=True,
            fmt='.2f',
            annot_kws={'size': 15},
            yticklabels=cols_view,
            xticklabels=cols_view)

plt.tight_layout()
plt.show()

img

#pairplot이용 
sns.set(style='whitegrid', context='notebook')
sns.pairplot(drinks[['beer_servings', 'spirit_servings', 
                     'wine_servings', 'total_litres_of_pure_alcohol']], height=2.5)
plt.show()

기존의 corr를 이용해서 상관관계를 한눈에 확인 가능함

탐색적 분석

fillna()

결측 값을 해당하는 데이터로 처리하는 함수

continent 피처에 존재하는 결측데이터 처리

drinks['continent'] = drinks['continent'].fillna('OT')

plt.pie()

파이차트로 시각화

OT 차지하는 비중 찾기

labels = drinks['continent'].value_counts().index.tolist() #continent에 해당하는 list 다 따옴 ['AF', 'EU', 'AS', 'OT', 'OC', 'SA']
fracs1 = drinks['continent'].value_counts().values.tolist() # continent에 해당하는 각각 군집의 개수  53, 45, 44, 23, 16, 12]
explode = (0, 0, 0, 0.25, 0, 0) ## 파이차트중 어떤것에 해당하는걸 조금더 뒤로 뺄지 .. OT 3번째 배열을 조금 더 뒤로 뺀다 

plt.pie(fracs1, explode=explode, labels=labels, autopct='%.0f%%', shadow=True)
plt.title('null data to \'OT\'')
plt.show()

img

explode 를 0.25 대신 0.9를 줬을때

img

agg()

apply, agg 함수를 이용한 대륙별 분석

agg()는 apply()와 거의 동일한 기능이지만 apply에 들어가는 함수 파라미터를 병렬로 설정하여 그룹에 해단 연산결과를 동시에 얻을 수 있는 함수

# 대륙별 spirit_servings의 평균, 최소, 최대, 합계를 계산.
result = drinks.groupby('continent').spirit_servings.agg(['mean', 'min', 'max', 'sum'])
result.head()

idxmax()

mean()함수를 이용한 탐색 + idxmax()함수를 적용하면 평균 "beer_serving"이 가장 높은 "대륙"이 어딘지 찾을 수 있음.

beer_continent = drinks.groupby('continent').beer_servings.mean().idxmax()
print(beer_continent)

통계적 분석

분석 결과에 타당성을 부여하기 위해 통계적으로 차이를 검정하는 과정

t-test를 통해 분석 대상 간에 통계적 차이를 검정하는 방법

scipy를 활용하여 두 집단간의 t-test를 검정 할 수 있음

!pip install scipy #설치 
# 아프리카와 유럽간의 맥주 소비량 차이를 검정
africa = drinks.loc[drinks['continent']=='AF']
europe = drinks.loc[drinks['continent']=='EU']

from scipy import stats
tTestResult = stats.ttest_ind(africa['beer_servings'], europe['beer_servings'])
tTestResultDiffVar = stats.ttest_ind(africa['beer_servings'], europe['beer_servings'], equal_var=False)

print("The t-statistic and p-value assuming equal variances is %.3f and %.3f." % tTestResult)
print("The t-statistic and p-value not assuming equal variances is %.3f and %.3f" % tTestResultDiffVar)

# result 
The t-statistic and p-value assuming equal variances is -7.268 and 0.000.
The t-statistic and p-value not assuming equal variances is -7.144 and 0.000

p-value

가설이 얼마나 믿을만 한 것인지 나타내는 지표 (ex: -7.268)

테이터를 새로 샘플링 했을 때 가설이 맞다는 전데하에 현재 나온 통계값 이상이 나올 확률 이라고 정의할 수 있음

p-value가 너무 낮으면 가설이 일어날 확률이 낮기 때문에 가설을 기각하게 된다.

이 p-value를 유의확률 이라고 한다.

반응형

'CS > DataAnalysis' 카테고리의 다른 글

데이터 분석_설치환경구축, 라이브러리  (0) 2021.03.28
정형 데이터의 전처리 / 탐색 /시각화  (0) 2019.02.19
Bigdata analytics  (0) 2019.02.19