Chap 1) Intro. to Data Analysis

Introduction

• Why Data Analysis?

- Data(visible) → ‘Information/Insight(invisible)’ 추출 for problem solving

• What is Information?

- 지식(knowledge)/정보(information)

⇒ 음악-악보, 감정-그림, 언어-문자, 규칙-수

- 유기체/조직체가 ‘환경에 적응하여/문제를 해결하여’ 살기 위한 필수조건

e.g.	곤충/인간 등: 감각기관, 뇌, 유전자(DNA)

기업/국가 등: 정보수집 및 저장, 전산조직

- Data(Media): 인간이 ‘정보’를 표현/저장/전달하기 위한 수단(tool)

⇒ 음성, 그림, 문자, 숫자, 영상 등

• 문제해결(problem solving) 과정

1) 문제와 관련된 data의 수집/탐색/표현

- 비구조적(비정형-텍스트/이미지/오디오)/구조적(정형-Table)

- 특징 파악: 독립변수 – x1, x2, ..., xn, 종속변수 – y1, y2

분포도, 평균, 분산, 상관관계(correlation) 등

- 시각화(visualization)

→ ‘탐색적’ 데이터 분석 (exploratory data analysis)

2) 분석 모델(model)

- 적합한 모델을 사용하여 원하는 information을 추출

- 회귀(regression)/분류(classification)/군집(clustering) 등

3) 성능(performance) 평가

- 평가 지표: 정확도(accuracy)/정밀도(precision)/재현도(recall)

/특이도(specificity) 등

Data Analysis Environments

• Python

- Basic libraries: Numpy/Pandas/Matplotlib

- Modeling libraries: regression/classification/clustering 등

- Programming: Pycharm/Jupyter Notebook/Colab

• R

- Libraries:

• 시각화 도구/block 프로그래밍

- Tuva/Orange3

- Entry

Data의 수집/탐색/표현: Raw Data

• Data의 분류: 구조화된 정도에 따른 분류

① Structured Data: Table - (Relational) DBMS, XML 문서

② Semi-Structured Data: HTML 문서 - Web Search Engine

문서(document) - 문서관리 System/Digital Library, IR

③ Unstructured Data: Multimedia - Multimedia Contents Management

Raw Text - Word Processor

• Data의 수집

Database Mgmt System

Information

Retrieval

(IR)

Search Engine

(Semantic

Web)

Data Communication

(C/S, WWW, Mobile)

for Business

Data Mgmt.

for Digital

Library

for Web

Documents

User1

PC

User2

Tab

Usern

Phone

Big Data (Unstructured/Structured)

• Database의 종류: Data는 어떠한 형식으로 저장되어 있는가?

종류	저장형식	검색	예	비고
서지/문헌 Database	레코드/파일	검색식 (AND, OR 등)	IR(학술 DB)
자료(문자/숫자) Database	Table	SQL	RDBMS (정부/기업 DB)
멀티미디어 Database	Object	Object Query Languages	GIS
Web	HTML/XML	Search Engines	WWW

e.g., RDBMS(MySQL): CSV 파일 download

Copyright (c) 2019 [윤기태 – 이것이 데이터분석이다]

https://github.com/yoonkt200/python-data-analysis

• Example #1: 국가별 음주 데이터 분석

<Step1. 탐색> 데이터의 기초 정보 살펴보기

<Step2. 인사이트의 발견> : 탐색과 시각화

<Step3. 탐색적 분석> : 스무고개로 분석하는 개념적 탐색

<Step4. 통계적 분석> : 분석 대상간의 통계적 차이 검정하기

<Step1. 탐색> 데이터의 기초 정보 살펴보기

[drinks 데이터셋의 기본 정보]

# Google Colab 로그인, Google Drive 연결(mount)

# yun067.ipynb

# 한글폰트 사용 in Colab

%matplotlib inline

import matplotlib as mpl

import matplotlib.pyplot as plt

import matplotlib.font_manager as fm

!apt-get update -qq

!apt-get install fonts-nanum* -qq

path = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'

font_name = fm.FontProperties(fname=path, size=10).get_name()

print(font_name)

plt.rc('font', family=font_name)

fm._rebuild()

mpl.rcParams['axes.unicode_minus'] = False

# ‘런타임>런타임 다시 시작’ 실행 후 다시 한번 위의 코드를 실행하여 폰트 적용!!! <중요>

# 폰트 확인

import matplotlib.font_manager as fm

sys_font=fm.findSystemFonts()

print(f"sys_font number: {len(sys_font)}")

print(sys_font)

nanum_font = [f for f in sys_font if 'Nanum' in f]

print(f"nanum_font number: {len(nanum_font)}")

nanum_font

#-------------------------------------------

import pandas as  pd

import numpy as np

import matplotlib.pyplot as plt

# read_csv 함수로 데이터를 Dataframe 형태로 불러옵니다.

import os

os.chdir('/content/drive/MyDrive/Colab Notebooks')

drinks=pd.read_csv('drinks.csv')

# 비수치형 피쳐 – country/continent, continent에는 23개의 결측치, spirit-주정(Whiskey 등)

drinks.info()

drinks.head(10)

drinks.tail()

# 수치형 피쳐의 통계적 정보 살펴보기

drinks.describe()

# 타입 살펴보기

drinks.dtypes

# 대한민국 음주량 찾기(locate) - loc()

print(drinks.loc[drinks['country'] == 'South Korea'])

<Step2. 인사이트의 발견> : 탐색과 시각화

[두 피처간의 상관계수 구하기]

[여러 피처의 상관관계 분석/시각화]

# 'beer_servings', 'wine_servings' 두 피처간의 상관계수(-1 ~ 1)를 계산: corr()

# -1; 음의 상관관계, 1: 양의 상관관계

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

corr = drinks[['beer_servings', 'wine_servings']].corr(method = 'pearson')

# print(corr)과 동일

corr

# 여러 피처간의 상관계수 행렬

cols = ['beer_servings', 'spirit_servings', 'wine_servings', 'total_litres_of_pure_alcohol']

corr = drinks[cols].corr(method = 'pearson')

corr

# heatmap/pairplot을 사용한 시각화 – ‘seaborn’ 라이브러리 사용

!python —version

#!pip install ‘라이브러리’ - !pip install seaborn

!pip list

import seaborn as sns

# corr 행렬 히트맵을 시각화 – heatmap()

cols_view = ['beer', 'spirit', 'wine', 'alcohol'] # 그래프 출력을 위한 cols 이름을 축약

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()

# 시각화 라이브러리를 이용한 피처간의 scatter plot을 출력 – 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()

<Step3. 탐색적 분석> : 스무고개로 분석하는 개념적 탐색

[결측 데이터 전처리]

[그룹 단위의 데이터 분석 : 대륙별 분석]

[그룹 단위의 데이터 분석 : 의미를 가지는 피처 재구성하기]

# 결측 데이터 찾기 – continent 23개

drinks['continent'].isnull()

drinks[‘continent’][drinks[‘continent’].isnull()]

drinks.loc[184]

# 결측데이터 처리: ‘기타’ 대륙으로 채움 -> 'OT' (Others)

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

drinks.head(10)

print(drinks.loc[drinks[‘continent’]==’OT’])

# 파이차트 시각화: ‘OT’가 차지하는 비율  - plt.pie()

# label 찾아서 리스트 만들기 - ['AF', 'EU', 'AS', 'OT', 'OC', 'SA']

labels = drinks['continent'].value_counts().index.tolist()

labels

# 빈도수(frequency) 계산해서 리스트 만들기

fracs1 = drinks['continent'].value_counts().values.tolist()

fracs1

# ‘OT’(4번째)를 뽑아서 Pie Chart  만들기

explode = (0, 0, 0, 0.25, 0, 0)

plt.pie(fracs1, explode=explode, labels=labels, autopct='%.0f%%', shadow=True)

plt.title('대륙별 음주 데이터: null data to \'OT\'')

plt.show()

# agg() 함수를 이용한 대륙별 분석

# apply()와 기능은 동일하지만, 함수 파라미터를 병렬로 설정하여 결과를 동시에 계산

# 대륙별 spirit_servings의 통계적 정보는? – 평균/최소/최대/합계를 계산

result = drinks.groupby('continent').spirit_servings.agg(['mean', 'min', 'max', 'sum'])

result

# 전체 평균보다 많은 ‘알코올’을 섭취하는 대륙은?

total_mean = drinks.[‘total_litres_of_pure_alcohol’].mean()

total_mean

continent_mean = drinks.groupby('continent')['total_litres_of_pure_alcohol'].mean()

continent_mean

continent_over_mean = continent_mean[continent_mean >= total_mean]

continent_over_mean

# ‘맥주(beer_servings)’를 가장 많이 마시는 대륙은?

# idxmax(): 시리즈 객체에서 값이 가장 큰 index를 반환

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

beer_continent

#분석 결과에 대한 시각화

# 대륙별 spirit_servings의 평균, 최소, 최대, 합계를 시각화

n_groups = len(result.index)

n_groups

means = result['mean'].tolist()

means

mins = result['min'].tolist()

mins

maxs = result['max'].tolist()

maxs

sums = result['sum'].tolist()

sums

index = np.arange(n_groups)

index

plt.xticks(index, result.index.tolist())

# legend 그리기

bar_width = 0.1

rects1 = plt.bar(index, means, bar_width, color='r', label='Mean')

rects2 = plt.bar(index + bar_width, mins, bar_width, color='g', label='Min')

rects3 = plt.bar(index + bar_width * 2, maxs, bar_width, color='b',               label='Max')

rects4 = plt.bar(index + bar_width * 3, sums, bar_width, color='y',                  label='Sum')

plt.legend()

plt.title('대륙별 음주 데이터: 평균, 최소, 최대, 합계')

plt.show()

# 대륙별 알코올 섭취량(total_litres_of_pure_alcohol)을 시각화

continents = continent_mean.index.tolist()

continents.append('평균')

continents

x_pos = np.arange(len(continents))

x_pos

alcohol = continent_mean.tolist()

alcohol.append(total_mean)

alcohol

bar_list = plt.bar(x_pos, alcohol, align='center', alpha=0.5)

bar_list[len(continents) - 1].set_color('r')

plt.plot([0., 6], [total_mean, total_mean], "k--")

plt.xticks(x_pos, continents)

plt.ylabel('알코올 섭취량')

plt.title('대륙별 알코올 섭취량')

plt.show()

<Step4. 통계적 분석> : 분석 대상간의 통계적 차이 검정하기

[아프리카와 유럽간의 술 소비량 차이 검정]

# t-test로 대륙 간에 통계적 차이를 검정

# 두 집단의 n이 비슷하며 정규 분포인 경우, 평균의 차이를 검정

# !pip list

# !pip install scipy

from scipy import stats

# 아프리카와 유럽간의 맥주 소비량 차이를 검정 – stats.ttest_ind()

africa = drinks.loc[drinks['continent']=='AF']

africa

europe = drinks.loc[drinks['continent']=='EU']

europe

# p-value<.01(99% 신뢰도) or p-value<.05(95% 신뢰도): 통계적으로 유의미

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)

# 대한민국(‘South Korea’)은 얼마나 술을 독하게(‘alcohol_rate’) 마시는 나라일까?

# total_servings 피처를 생성

drinks['total_servings'] = drinks['beer_servings'] + drinks['wine_servings'] + drinks['spirit_servings']

drinks.head(10)

# 술 소비량 대비 알콜 비율(‘alcohol_rate’) 피처를 생성

drinks['alcohol_rate'] = drinks['total_litres_of_pure_alcohol'] / drinks['total_servings']

drinks.tail(10)

# 결측치를 찾아서 0으로 입력

drinks['alcohol_rate'][drinks['alcohol_rate'].isnull()]

drinks['alcohol_rate'] = drinks['alcohol_rate'].fillna(0)

print(drinks.loc[drinks['alcohol_rate']==0])

# 알콜 비율(‘alcohol_rate’)로 정렬 - sort_values()

country_with_rank = drinks[['country', 'alcohol_rate']]

country_with_rank = country_with_rank.sort_values(by=['alcohol_rate'], ascending=0)

country_with_rank.head(5)

# 대한민국 알콜 비율(‘alcohol_rate’) - loc()

print(country_with_rank.loc[country_with_rank['country'] == 'South Korea'])

# 순위 정보(실수)를 생성 - rank()

country_with_rank[‘순위’]=country_with_rank['alcohol_rate'].rank(ascending=False)

country_with_rank.head(10)

# 대한민국 음주 순위(정수 변경) – astype(), loc()

country_with_rank[‘순위’]=country_with_rank[‘순위’].astype(int)

print(country_with_rank.loc[country_with_rank['country'] == 'South Korea'])

# 국가별 순위 정보를 그래프로 시각화

country_list = country_with_rank.country.tolist()

country_list

x_pos = np.arange(len(country_list))

x_pos

rank = country_with_rank.alcohol_rate.tolist()

rank[:20]

bar_list = plt.bar(x_pos, rank)

bar_list[country_list.index("South Korea")].set_color('r')

plt.ylabel('alcohol rate')

plt.title('liquor drink rank by contry')

plt.axis([0, 200, 0, 0.3])

korea_rank = country_list.index("South Korea")

korea_alc_rate = country_with_rank[country_with_rank['country'] == 'South Korea']['alcohol_rate'].values[0]

plt.annotate('South Korea : ' + str(korea_rank + 1),

xy=(korea_rank, korea_alc_rate),

xytext=(korea_rank + 10, korea_alc_rate + 0.05),

arrowprops=dict(facecolor='red', shrink=0.05))

plt.show()