설문조사를 분석하고 시각화하는데 좋은 자료가 있어서 포스팅을 한다.
자료는 아래서 참조하였다.
ref.
corazzon / KaggleStruggle / kaggle-survey-2017 / Kaggle-ML-DS-survey-2017-EDA-FAQ.ipynb
https://github.com/corazzon/KaggleStruggle/blob/master/kaggle-survey-2017/Kaggle-ML-DS-survey-2017-EDA-FAQ.ipynb
분석에 필요한 자료는 아래링크에서 Data탭에 들어가면 구할 수 있다.
https://www.kaggle.com/kaggle/kaggle-survey-2017
============================ Python ============================
import pprint
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
# 이미지를 그려주는 모듈.
import seaborn as sns
# 데이터 프레임의 컬럼을 최대 12개로 늘린다.
pd.set_option('display.max_columns', 12)
# schema.csv를 question 객체에 담기
question = pd.read_csv('schema.csv')
# multipleChoiceResponses.csv를 mcq에 담기. encoding='ISO-8859-1'은 범용적으로 사용되는 인코딩이다.
mcq = pd.read_csv('multipleChoiceResponses.csv', encoding='ISO-8859-1', low_memory=False)
# 한국 자료를 따로 설정해준다.
korea = mcq.loc[mcq.Country == 'South Korea']
### 어디서 데이터 사이언스를 배워야 하는지를 확인
# print(mcq['LearningPlatformSelect'].head()) # 데이터 확인
'''
'어디서 배워야 하는가?'라는 질문에 대해서 중복 응답이 가능하므로
중복응답들을 다 나눠서 갯수를 세어야 한다.
이를 위해서
1. 한 줄로 되어있는 응답을 각 원소별로 나눠서 리스트에 저장.
2. 리스트의 원소값을 분리해서 한 행에 하나의 데이터만 들어가도록 데이터 처리.
2-1. 리스트로 표현된 자료를 2 level 인덱스를 생성하여 한 행에 하나의 데이터만 들어가도록 바꾼다.
2-2. 2 level 인덱스 중, 하나를 없애서 보기 편하게 바꾼다.
3. 각 원소의 갯수를 세서 하나의 응답이 몇 번 나왔었는지 확인.
이 순서로 데이터 처리가 진행되어야 한다.
'''
# LearningPlatformSelect컬럼을 확인한다.
mcq['LearningPlatformSelect'] = mcq['LearningPlatformSelect'].astype('str').apply(lambda x: x.split(','))
# print(mcq['LearningPlatformSelect']) # 데이터 확인. 각 응답자들의 응답이 리스트로 저정되어있다.
'''
'.apply() 메서드'
DataFrame.apply(func, axis=0, broadcast=None, raw=False, reduce=None, result_type=None, args=(), **kwds)
Apply a function along an axis of the DataFrame.
Objects passed to the function are Series objects
whose index is either the DataFrame’s index (axis=0) or the DataFrame’s columns (axis=1).
DataFrame의 축을 따라 함수를 적용하십시오.
함수에 전달 된 객체는 DataFrame의 인덱스 (축 = 0) 또는 DataFrame의 열 (축 = 1) 인
인덱스가있는 Series 객체입니다. - 구글 번역
.apply()메서드는 데이터 프레임의 행이나 열에 대해서 func을 적용시켜 데이터를 바꿔주는 메서드이다.
'mcq['LearningPlatformSelect'] 해석'
1. 한 줄로 되어있는 응답을 각 원소별로 나눠서 리스트에 저장. 을 한다.
mcq의 컬럼 LearningPlatformSelect에 존재하는 값을 string값으로 바꿔준다. string으로 바꿔주는 이유는
뒤의 apply()에 나오는 lambda가 split(',')을 사용하는데 이는 string에서만 사용 가능하기 때문이다.
그런데 이 항목에 대해 대답을 안 한 사람의 데이터가 NaN이 되고 이는 float로 인식된다.
그래서 astype('str')로 컬럼 내의 데이터를 전부 string으로 바꿔줘야
.apply(lambda x: x.split(','))가 제대로 동작 할 수 있다.
(ex) print(type(mcq['LearningPlatformSelect'][16]))
'''
s = mcq.apply(
lambda x: pd.Series(x['LearningPlatformSelect']), axis=1)\
.stack().reset_index(level=1, drop=True)
# 한 사람의 응답에는 같은 인덱스 번호를 부여하여 어떤 응답을 했는지 리스트 형태가 아닌 개별원소로 보여준다.
# print(s.head(10))
'''
's에 대한 해석'
2. 리스트의 원소값을 분리해서 한 행에 하나의 데이터만 들어가도록 데이터 처리. 를 한다.
.apply(lambda x: pd.Series(x['LearningPlatformSelect']), axis=1)
mcq의 LearningPlatformSelect컬럼 중, axis가 1인 즉, 열의 값을 선택해서 내부의 데이터를
Series 데이터 구조로 바꾼다.
2-1. 리스트로 표현된 자료를 2 level 인덱스를 생성하여 한 행에 하나의 데이터만 들어가도록 바꾼다.
.stack()
그렇게 나온 값을 .stack()을 이용해서 2 level의 데이터 프레임으로 바꿔준다. 여기서 2레벨이라는 것은
인덱스를 2개 사용해서 2차원 배열 구조를 시각화 한 것을 말한다.
s = mcq.apply(
lambda x: pd.Series(x['LearningPlatformSelect']), axis=1)\
.stack()
print(s.head(10))
0 0 College/University
1 Conferences
2 Podcasts
3 Trade book
1 0 Kaggle
2 0 Arxiv
1 College/University
2 Kaggle
3 Online courses
4 YouTube Videos
.stack() 메서드를 사용하면
0번 인덱스에 저장되었던 값이 세부항목을 리스트가 아닌 리스트에 달려있던 인덱스 넘버로 출력되는 것을 알 수 있다.
2-2. 2 level 인덱스 중, 하나를 없애서 보기 편하게 바꾼다.
.reset_index(level=1, drop=True)
.stack()까지 2 레벨의 데이터 프레임의 인덱스 중, level=1의 인덱스를 drop시킨다.
즉, 위에서 봤을 때 0 1 2 3 0 0 1 2 3 4 .... 로 진행되는 인덱스를 drop시킨다는 뜻이다.
참고로 맨 앞의 0 1 2 처럼 표현되는 인덱스는 level=0 이다.
최종적으로 s는 아래와 같이 나온다.
0 College/University
0 Conferences
0 Podcasts
0 Trade book
1 Kaggle
2 Arxiv
2 College/University
2 Kaggle
2 Online courses
2 YouTube Videos
dtype: object
'''
s.name = 'platform' # <class 'pandas.core.series.Series'> 인 s에 컬럼 이름을 platform이라고 명명해준다.
# 출력 될 figure의 크기를 설정한다. figsize=(가로, 세로)이다.
# https://matplotlib.org/api/figure_api.html?highlight=figure#module-matplotlib.figure
plt.figure(figsize=(6, 8))
# s에서 s가 nan인 값을 제외하고 각 원소가 몇 개 있는지 갯수를 센다. 그런 다음, 상위 15개를 선택한다.
data = s[s != 'nan'].value_counts().head(15)
# print(data) # 데이터 확인
'''
'data'
Kaggle 6645
Online courses 6042
Stack Overflow Q&A 5703
YouTube Videos 5291
Personal Projects 4873
Blogs 4828
Textbook 4246
College/University 3397
Arxiv 2418
Official documentation 2354
Conferences 2217
Friends network 1617
Tutoring/mentoring 1458
Podcasts 1238
Non-Kaggle online communities 1169
Name: platform, dtype: int64
'''
# data에서는 s에서 데이터로 사용된 것이 index로 들어가게 되므로 y축에는 data.index, x축에는 data값을 위치시켜
# 가로로 누운 바 그래프를 만든다.
sns.barplot(y=data.index, x=data)
# plt.show()
# 설문내용과 누구에게 물어봤는지를 확인
qc = question.loc[question[
'Column'].str.contains('LearningCategory')]
'''
question은 schema.csv를 담고 있는 데이터 프레임이다.
question의 Column이라는 명칭의 컬럼에서 LearningCategory라는 글자가 들어간 컬럼만 선택해서
컬럼의 명칭과 데이터를 qc에 담는다.
'''
# print(qc.shape) # (7, 3)
# print(qc)
'''
'결과'
Column \
91 LearningCategorySelftTaught
92 LearningCategoryOnlineCourses
93 LearningCategoryWork
94 LearningCategoryUniversity
95 LearningCategoryKaggle
96 LearningCategoryOther
97 LearningCategoryOtherFreeForm
Question Asked
91 What percentage of your current machine learni... All
92 What percentage of your current machine learni... All
93 What percentage of your current machine learni... All
94 What percentage of your current machine learni... All
95 What percentage of your current machine learni... All
96 What percentage of your current machine learni... All
97 What percentage of your current machine learni... All
'''
# mcq의 컬럼 중, LearningPlatformUsefulness가 들어간 것들을 찾아서 use_features 리스트에 넣는다.
use_features = [x for x in mcq.columns if x.find(
'LearningPlatformUsefulness') != -1]
# 학습플랫폼과 유용함에 대한 연관성을 살펴본다.
fdf = {} # 데이터를 담을 사전 타입의 객체를 생성한다.
for feature in use_features:
a = mcq[feature].value_counts() # use_features에서 담긴 각 항목들의 갯수를 센다.
a = a/a.sum() # 퍼센트로 표현한다.
# fdf에 LearningPlatformUsefulnessArxiv의 LearningPlatformUsefulness을 뺀 것을 key로, a를 value로 한다.
fdf[feature[len('LearningPlatformUsefulness'):]] = a
# print(fdf) # 데이터 확인
'''
'fdf 데이터'
행에 '유용하지 않다.', '조금 유용하다.', '많이 유용하다.'가 있고
열에 fdf{} 키의 값이 배치되었다.
'''
fdf = pd.DataFrame(fdf).transpose().sort_values(
'Very useful', ascending=False)
'''
위에서 나온 행과 열의 위치를 바꿔주기 위해서 .transpose()를 하고 Very useful컬럼을 내림차순으로 정렬한다.
Very useful에 대한 내림차순 정렬을 하기 위해서 위와 같은 변형을 한 것이다.
'''
# print(fdf) # 데이터 확인
# 학습플랫폼들이 얼마나 유용한지에 대한 상관관계를 그려본다.
plt.figure(figsize=(10, 10))
sns.heatmap(
fdf.sort_values(
"Very useful", ascending=False), annot=True)
'''
annot=True이면 각 셀에 데이터 값을 씁니다.
annot는 annotation(주석)의 약자이다.
'''
# plt.show()
# 유용함의 정도를 각 플랫폼별로 그룹화 해서 본다.
fdf.plot(kind='bar', figsize=(20,8),
title="Usefullness of Learning Platforms")
# plt.show()
============================ Python ============================
'데이터 분석 > 데이터 분석 프로젝트' 카테고리의 다른 글
[설문조사 분석] Python으로 분석한 Kaggle 2017 Survey -5 (0) | 2018.06.28 |
---|---|
[설문조사 분석] Python으로 분석한 Kaggle 2017 Survey -4 (0) | 2018.06.27 |
[설문조사 분석] Python으로 분석한 Kaggle 2017 Survey -2 (0) | 2018.06.22 |
[설문조사 분석] Python으로 분석한 Kaggle 2017 Survey -1 (0) | 2018.06.21 |
[Python] 네이버 금융 데이터를 크롤링하여 주식 데이터를 얻고 특정 종목에 대한 '종가-날짜' 반응형 그래프 만들기 (0) | 2018.06.18 |