220922 Day20

유예지·2022년 9월 22일

(2) 이상치 제거하기

>>> import pandas as pd
>>> exam = pd.read_excel("excel_exam.xlsx")
>>> exam.rename({'class' : 'nclass'}, axis = 1, inplace = True)
>>> exam.head()

#이상치 만들기
>>> exam.iloc[0,2] = 1
    exam.iloc[1,3] = 1
    exam.iloc[2,4] = 1
    exam[:3]

>>> import seaborn as sns
>>> sns.boxplot(data = exam, y = 'math')

* 이상치 제거하기 - 극단적인 값 (p.190~)

극단치(outlier) : 논리적으로 존재할 수 있지만 극단적으로 크기가 작은 값
몸무게 변수에 200kg 이상의 값이 있다면 존재할 가능성은 있지만 매우 드문 경우이므로 극단치라고 볼 수 있다

극단치를 제거하려면 먼저 어디까지를 정상범위로 볼 것인지 정해야 한다
상자 그림(box plot)은 중심에서 멀리 떨어진 값을 점으로 표현하는데, 이를 이용해 극단치의 기준을 정할 수 있다

  • box plot
    상자 아래 세로선 : 아랫수염, 하위 0~25% 내에 해당하는 값
    상자 밑면 : 1사분위 수, 하위 25% 위치 값
    상자 내 굵은 선 : 2사분위 수, 하위 50% 위치 값(중앙값)
    상자 윗면 : 3사분위 수, 하위 75% 위치 값
    상자 위 세로선 : 윗수염, 하위 75~100% 내에 해당하는 값
    상자 밖 가로선 : 극단치 경계
    상자 밖 점 표시 : 극단치

IQR : Inter Quartile Range 사분위 범위 (1사분위 ~ 3사분위)
수염의 끝 : (1사분위 - 1.5IQR) , (3사분위 + 1.5IQR)
수염의 길이 : (3사분위 + 1.5IQR) - (1사분위 - 1.5IQR)

#3사분위수 구하기 : df.quantile()
>>> exam['math'].quantile(0.75)

#1사분위수 구하기
>>> exam['math'].quantile(0.25)

>>> pct75 = exam['math'].quantile(0.75)
	pct25 = exam['math'].quantile(0.25)
>>> IQR = pct75 - pct25
	IQR
    
#수염의 끝점
>>> pct75 + 1.5*IQR    
>>> pct25 - 1.5*IQR
  • hwy의 극단치 값을 제외하고 평균 구하기
#cty의 수염의 극단치 값은 각각 얼마인가
>>> pip install pydataset
>>> import pydataset
>>> mpg = pd.read_csv("https://raw.githubusercontent.com/
sidsriv/Introduction-to-Data-Science-in-python/master/mpg.csv")
	mpg
>>> mpg = mpg.iloc[:, 1:]
	mpg
    
>>> m_pct25 = mpg['cty'].quantile(.25)
	m_pct75 = mpg['cty'].quantile(.75)
>>> IQR = m_pct75 - m_pct25
	IQR
    
>>> print(m_pct25 - 1.5*IQR)
	m_pct75 + 1.5*IQR

#hwy가 40.5 이상 이거나, 4.5 이하인 것들만 출력
>>> m_pct25 = mpg['hwy'].quantile(.25)
	m_pct75 = mpg['hwy'].quantile(.75)
	IQR = m_pct75 - m_pct25

	print(m_pct25 - 1.5*IQR)
	m_pct75 + 1.5*IQR

>>> mpg[(mpg['hwy'] >= 40.5) | (mpg['hwy'] <= 4.5)]

#이상치를 제외한 hwy의 평균
>>> import numpy as np
>>> mpg[~(mpg['hwy'] >= 40.5) | ~(mpg['hwy'] <= 4.5)].hwy.mean()

6. 그래프 만들기

참고 : https://seaborn.pydata.org/index.html

(1) 산점도 : sns.scatterplot()

>>> mpg.head()

>>> sns.scatterplot(data = mpg, x = 'displ', y = 'hwy', hue = 'drv')

#축 범위 설정하기 : xlim = (), ylim = ()
>>> sns.scatterplot(data = mpg, x = 'displ', y = 'hwy', hue = 'drv')\
.set(xlim = (3,6), ylim = (10,30))
  • 그래프 설정 바꾸기
>>> import matplotlib.pyplot as plt

#이미지 크기 변경
>>> plt.rcParams.update({'figure.figsize' : [4,3]})
>>> sns.scatterplot(data = mpg, x = 'displ', y = 'hwy', hue = 'drv')\
.set(xlim = (3,6), ylim = (10,30))

#일시적으로 이미지 크기 변경
>>> plt.figure(figsize = (숫자, 숫자))
#모든 셀에 크기 적용
>>> plt.rcParams['figure.figsize'] = (숫자, 숫자)

#이미지 저장
>>> sns.scatterplot(data = mpg, x = 'displ', y = 'hwy', hue = 'drv')\
.set(xlim = (3,6), ylim = (10,30))

	plt.savefig("test.png", dpi = 300)

(2) 막대 그래프

* drv별 hwy의 평균

>>> mean_hwy = mpg.groupby('drv')[['hwy']].mean()
	mean_hwy
#집단을 나타낸 변수 drv가 인덱스로 바뀌어있다
#seaborn 그래프를 만들기 위해서는 값이 변수에 담겨 있어야 한다
-> df.groupby()에 as_index = False를 입력한다
    
>>> sns.barplot(data = mpg, x = 'drv', y = 'hwy')

#drv는 x축이 아닌 index 번호 -> column으로 바꾸어주어야 함
>>> sns.barplot(data = mpg, x = mean_hwy.index, y = 'hwy')
ValueError: Grouper and axis must be same length

>>> mean_hwy.reset_index()

>>> sns.barplot(data = mean_hwy.reset_index(), x = 'drv', y = 'hwy')
  • 교재에 나와있는 방법
#groupby로 만들 때 파라미터로 정하기
>>>	mean_hwy = mpg.groupby('drv', as_index = False)[['hwy']].mean()
	mean_hwy
    
>>> sns.barplot(data = mean_hwy, x = 'drv', y = 'hwy')
  • 내림차순으로 정렬하기 : df.sort_values()
>>> mean_hwy = mean_hwy.sort_values(by = 'hwy', ascending = False)
>>> sns.barplot(data = mean_hwy, x = 'drv', y = 'hwy')

(3) 선 그래프

>>> import pydataset
>>> pydatatest.data()

>>> economics = pydataset.data("economics")
	economics.head()
>>> economics.info()    #Dtype 확인    

>>> sns.lineplot(data = economics, x = 'date', y = 'unemploy')
  • 그래프 x축에 두꺼운 검은줄이 보인다
    -> date 변수에 '1967-06-30' 처럼 '연월일'을 나타낸 문자가 담겨 있는데, 이 값이 x축에 가로로 여러번 겹쳐 표시되어서

* 칼럼(열)의 데이터 타입 바꾸기 : astype()

#'unemploy'의 데이터 타입을 int -> float 으로 변경
>>> economics['unemploy'] = economics['unemploy'].astype('float')
	economics.info()

#date의 데이터 타입을 object -> datetime 으로 변경
>>> economics['date'] = economics['date'].astype('datetime64')
	economics.info()    

>>> sns.lineplot(data = economics, x = 'date', y = 'unemploy')
  • 날짜 시간 타입 변수 만들기 : pd.to_datetime()
>>> economics['date'] = economics['date'].astype('object')
	economics.info()
    
#교재에 나와있는 방법
>>> economics['date'] = pd.to_datetime(economics['date'])
	economics.info()

(4) 상자 그림 만들기

>>> sns.boxplot(data = mpg, x = 'drv')
TypeError: Horizontal orientation requires numeric `x` variable.

>>> sns.boxplot(data = mpg, x = 'drv', y = 'hwy')
#변수가 2개 이여야 그려진다

>>> sns.boxplot(data = mpg, y = 'hwy')

7. 한국복지패널 데이터 분석

>>> pip install pyreadstat

#복지패널 데이터 불러오기 : pd.read_spss()
>>> raw_welfare = pd.read_spss("Koweps_hpwc14_2019_beta3.sav")
	raw_welfare
    
#변수명 바꾸기
>>> welfare = raw_welfare.loc[:, ['h14_g3','h14_g4','h14_g10','h14_g11',
'p1402_8aq1','h14_eco9','h14_reg7']]
	welfare
    
>>> welfare = welfare.rename(columns = {'h14_g3':'gender', 'h14_g4':'birth',
'h14_g10':'marriage_type','h14_g11':'religion','p1402_8aq1':'income',
'h14_eco9':'code_job','h14_reg7':'code_region'})
	
>>> welfare    

(1) 성별에 따른 월급 차이 (성별에 따른 월급 평균)

>>> welfare.head()

#na값 빈도수 확인
>>> welfare['gender'].value_counts()
	welfare['gender'].unique()
    
#성별에 따른 월급 평균값
>>> welfare.groupby('gender')['income'].mean()    

>>> welfare['gender'] = np.where(welfare['gender'] == 1.0, 'male', 'female')
	welfare.head()
    
>>> welfare.groupby('gender')[['income']].mean()    

>>> df = welfare.groupby('gender', as_index = False)[['income']].mean()
	df
    #df.reset_index() : 인덱스 변경
    
>>> sns.barplot(data = df, x = 'gender', y = 'income')    

(2) 나이와 월급의 관계 (나이별 월급 평균)

>>> welfare.head()

>>> print(min(welfare.birth))
	print(max(welfare.birth))
    
#'age'라는 새로운 칼럼 생성
>>> welfare['age'] = 2019.0 - welfare['birth']
	welfare[:2]
    
#na값 있는지 확인
>>> welfare.isna().sum()

#'age'의 데이터 타입을 int로 변경
>>> welfare['age'] = welfare['age'].astype('int')
	welfare.info()
    
>>> df1 = welfare.groupby('age', as_index = False)[['income']].mean()
	df1    

>>> sns.lineplot(data = df1, x = 'age', y = 'income')

(3) 연령대에 따른 월급의 차이

#'age_gen'이라는 새로운 칼럼 생성
#30세 이하 : young / 60세 이하 : middle / 나머지 : old
>>> welfare['age_gen'] = np.where(welfare['age'] <= 30, 'young',
np.where(welfare['age'] <= 60, 'middle', 'old'))
	welfare[:2]
    
>>> welfare['age_gen'] = welfare['age_gen'].astype('category')
	welfare.info()    
    
#df_gen = df_gen.reset_index()
>>> df_gen = welfare.groupby(['age_gen', 'gender'], as_index = False)[['income']].mean()
	df_gen    
    
#세대별 소득평균
>>> sns.barplot(data = df_gen, x = 'age_gen', y = 'income',
order = ['young', 'middle', 'old'], palette = 'Set1')   

#세대별, 성별 소득평균
>>> sns.barplot(data = df_gen, x = 'age_gen', y = 'income',
order = ['young', 'middle', 'old'], hue = 'gender')

8. 텍스트 마이닝

텍스트 마이닝 : 문자로 된 데이터에서 정보를 얻어내는 분석 기법

(1) 대통령 연설문 텍스트 마이닝

#KoNLPY 패키지 : 한글 텍스트로 형태소 분석을 할 수 있다
>>> pip install konlpy

#파일 읽기
>>> with open("speech_moon.txt", 'r', encoding = 'UTF-8') as f:
    	moon = f.read()
        
>>> moon = open("speech_moon.txt", 'r', encoding = 'UTF-8').read()
	moon        
    
#한글을 제외한 문자는 지우기
>>> import re
>>> p = re.compile("[^가-힣]")
	p.sub("  ", moon)

>>> moon = p.sub("  ", moon)
	moon

#명사 추출하기
>>> import konlpy
>>> hannanum = konlpy.tag.Hannanum()  

>>> nouns = hannanum.nouns(moon)
	nouns
    
>>> df_word = pd.DataFrame(nouns)
	df_word
    
#글자수 세기 : str로 변환 후 len()으로 확인
>>> df_word.iloc[:,0].str.len()

#글자수 칼럼 'count' 추가
>>> df_word['count'] = df_word.iloc[:,0].str.len()
	df_word[:2]
>>> df_word.rename({0:'word'}, axis = 1, inplace = True)
	df_word[:4]  
    
#두 글자 이상의 단어만 남기기
>>> df_word = df_word[df_word['count'] >= 2]
	df_word
    
#단어의 빈도 구하기
>>> df_word.groupby('word', as_index = False).agg('count').
sort_values('count', ascending = False)

>>> top20 = df_word.groupby('word', as_index = False).agg('count').
sort_values('count', ascending = False).head(20)
	top20  

* 그래프로 나타내기

>>> sns.barplot(data = top20, x = 'word', y = 'count')
#변수 이름이 한글로 되어있어 잘 나타나지 않는다

>>> import matplotlib.pyplot as plt
>>> plt.rcParams['font.family'] = 'Malgun Gothic'

>>> plt.rcParams({'font.family' : 'Malgun Gothic'})
				  'figure.dpi' : '120'})
                  'figure.figsize' : [6.5, 6]})

>>> sns.barplot(data = top20, x = 'word', y = 'count')
>>> plt.xticks(rotation = 20)    #글자 회전

>>> sns.barplot(data = top20, x = 'count', y = 'word')
	plt.xticks(rotation = 20)

* 워드 클라우드 만들기

>>> pip install wordcloud
>>> top20[:5]

#'word' 칼럼을 index로
>>> df = top20.set_index("word")
	df
    
>>> from wordcloud import WordCloud

#wordcloud 패키지의 WordCloud() 를 이용해 워드 클라우드를 만들 때 사용할 wc 만들기
>>> wc = WordCloud()

#워드 클라우드 만들기
>>> wc.generate_from_frequencies(df)
TypeError: cannot convert the series to <class 'float'>

>>> top20.set_index('word').to_dict()
>>> dict_word = top20.set_index('word').to_dict()['count']
	dict_word
    
>>> from wordcloud import WordCloud
>>> wc = WordCloud(font_path = 'malgun.ttf', background_color = 'white')    

#만들기 : wc.generate_from_frequencies()
#출력하기 : plt.imshow()
#워드 클라우드 이미지를 출력하는 코드는 한 셀에 넣어 함께 실행해야 한다
>>> img = wc.generate_from_frequencies(dict_word)
	plt.imshow(img)

0개의 댓글