본문 바로가기

프로젝트 정리

국비 데이터 분석 2차 프로젝트 결산 -1

2차 프로젝트 결산

 

데이터 분석 프로젝트였다. 2월 10일  ~ 2월  20일 (평일 7일)동안 작업했다.

주제는 그 전부터 생각하고 있던 것이 있었지만,

(부동산 경매 시세 예측, 국제 에너지 변화 예측, 택시비 인상과 사람들의 실 사용 비율, 전기차 시장과 물류 시장 미래 예측, 금리 시장 변화 예측 등..)

한 조원이 '코로나 사망률'과 '의사수의 관계'를 강하게 주장했다.

이게 관계가 있을까 싶긴 했지만,

그리고 자료도 열심히 찾길래 (그냥) 그대로 하기로 했다.

영가설로 '코로나 사망률과 의사수는 관계가 없을 것이다. ' 라고 세웠고 

대립가설로는 '의사수가 많으면 코로나 사망률이 줄어든다.' 라고 세웠다.

 

데이터는 많은 종류를 찾았지만 그중에서

 

전세계 코로나19 현황 데이터(깃허브)

https://www.kaggle.com/d atasets/themrityunjaypathak/covid-cases-and-deaths-w orldwide

OECD 국가별 1000명당 의사 수 데이터

https://data.oecd.org/h ealthres/doctors.htm

 

두 데이터를 합쳐서 사용하기로 했다.

 

우선 pandas 라이브러리를 불러오고 '전세계 코로나19 현황 데이터(깃허브)'를 가져왔다.

import pandas as pd

cov_g = pd.read_csv('https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/owid-covid-data.csv')
cov_g

pandas로 불러온 데이터

위 데이터의 info를 찍어보면 약 26만데이터가 있고 66개의 컬럼 있으며 그 중 다섯개는 object컬럼임을 알 수있다.

이중 date는 시간형식으로 바꿔줘서 사용하는 것이 바람직하나, 우리는 이 데이터의 마지막 날 하루만 가져다 사용할 것이므로 굳이 Dtype을 바꾸지 않았다.

아래 데이터는 각 나라별 1000명당 의사 수의 비율이다.

<사진첨부>

 

이 데이터는 22년 12월에 최신화된 데이터인데 21년도까지의 데이터만 나온다.

우리가 구하고자 하는 코로나의 데이터는 23년이고 의사 데이터는 21년까지이므로 원래는 사용할 수 없지만,

예상을 통해 23년 value를 구하고 이를 이용하기로 하였다.

우리는 1960년 부터 2021까지 의사의 증가 수가 일정하게 증가한다고 가정하였다.

 

import seaborn as sns
from scipy import stats

으로 seaborn과 scipy의 stats 라이브러리를 가져왔다.

이를 토대로 선점도 그래프와 피어슨 상관계수를 따져봤다.

그 결과 피어슨 값은 0.988로 1에 아주 가까운 값을 가지고 있고, pvalue는 e^-50으로 아주 작은 우연성을 가지고 있다.

즉, 23년에도 비슷한 추세로 증가할 것이라고 예상된다.

 

하지만 위 데이터의 21년도에 갑작스럽게 증가한다. 그 이유를 분석하기 위해 두 가지로 가정하고 체크했다.

우선 첫 번째로는 '코로나 유행으로 의사 인구수가 갑작스레 증가한 경우',

두 번째로는 '21년 데이터의 경우 상대적으로 조사가 빠른 국가들(일종의 선진국들)이 조사된 경우'.

로 나눴다. 전자의 경우를 가정하면 새로운 데이터를 찾아야하고, 후자의 경우에는 그냥 20년까지의 데이터로 사용해도 무방했다.

 

가정을 체크하기 위해서 21년도 데이터가 있는 12개 국가의 평균으로 상관관계 그래프를 그려봤다.

2021 있는 국가들

2021 있는 국가들의 그래프를 비교해보기 위해 각 국가들의 년도와 평균을 dataframe으로 바꾸었다.

그리고 이를 그래프로 바꾸어 그렸다.

 

위의 그래프를 비교해본 결과 2021년 데이터가 있는 국가들은 전체적인 평균보다 큰 값을 가짐을 알 수있다. 결국 2021년도 급격하게 증가한 이유는 '2021년 데이터가 있는 국가들의 평균이 높기 때문'이라는 결론을 내렸다.

그래서 '20년도까지의 의사 데이터를 23년 데이터에 넣어도 무방하다'는 결론을 내렸다.

 

20년 까지의 의사데이터와 전세계 코로나 현황 데이터를 melt화 시켜서 합쳤다.

이 새로운 newCov2020 데이터의 사용가능 할 컬럼들만 남기고 지웠다.

그 중 우리가 사용할 가장 최신 데이터를 Y를 변수로 두었다.

Y를 Y1으로 재가공했다. 중국의 데이터는 많이 의문스러워서 제거하기로 했다.

#index 새로 주기
Y1=Y.reset_index(inplace=False)

# china 제거 // 뒤로 미뤄서 하기
Y1.drop([22],axis=0,inplace=True)

#TIME,index,date 필요 없는 컬럼 제거
Y1.drop(['index','date','TIME'],axis=1,inplace=True)

 이후 우리의 초기 가설이 맞는지 확인하기 위해 Y1의 선점도 그래프와 피어슨 계수를 구했다.

그 결과 우리의 대립가정은 틀렸음을 알 수 있었다.

코로나 사망률과 의사수는 관계가 없을 것이다. 라는 결론을 내렸다.

 

이대로 끝내기에는 프로젝트 시간이 너무 많이 남아서

코로나 사망률에 관계있는 다른 상관관계를 찾아보기로 했다.

 

Y1의 빈 값을 체크해보니 너무 많았다.

이를 다 채워서 데이터로 사용하기로 했다.

Y1.isnull().sum()

데이터를 뜯어본 겨로가

극빈층 비율(extreme_poverty)의 데이터의 경우 아예 조사가 이뤄지지 않은 국가들이 있음을 파악할 수 있었다.

나머지 NaN 값이 있는 데이터들은 여러 이유로 갱신이 안 된 데이터들이다.

코로나 종식을 선언해 토탈이 변하지 않았거나, 마찬가지로 백신도 더는 기록하지 않는 국가들이다.

 

아래 코드로 우선 갱신일의 값을 체크 후 NaN값으로 사용해도 되는지 파악하였다.

# 2번 실행 (체크용)

columsList =['total_tests','total_tests_per_thousand','total_vaccinations','total_vaccinations_per_hundred','people_vaccinated','people_fully_vaccinated_per_hundred']
newList=[] #totoal_test 마지막값
allList=[]
newDate=[]
for i in columsList:
    for contry in X['LOCATION'][~X['LOCATION'].duplicated()].values:
        newList.append(X[X['LOCATION']==contry][X[X['LOCATION']==contry][i].notnull()].tail(1)['date'].values[0])
    allList.append(newList)
    newList=[]
import datetime
format = '%Y-%m-%d'
for j in range(len(allList)):
    for i in allList[j]:
        newDate.append(datetime.datetime.strptime(i,format))
    print(f'{columsList[j]} 의 마지막 데이터가 있는 값 : {sorted(allList[j])[0]}')

이 국가들은 마지막 값과 현재 값의 큰 차이가 없기에 갱신일을 기준으로 넣어주기로 했다.

(무방하다고 예상했다.)

 

이 데이터들을 가공하기 쉽게끔 dict형태로 바꿨다.

# 4번 실행 -> data 가공하기 쉬운 형태로 바꾸기

columsList =['total_tests','total_tests_per_thousand','total_vaccinations','total_vaccinations_per_hundred','people_vaccinated','people_fully_vaccinated_per_hundred']
newList=[] #totoal_test 마지막값
allList=[]
allList2=[]
newDate=[]
newDict={}
for i in columsList:
    for contry in X['LOCATION'][~X['LOCATION'].duplicated()].values:
        newDict['x'] = X[X['LOCATION']==contry][X[X['LOCATION']==contry][i].notnull()].tail(1)['date'].values[0]
        newDict['country'] = contry
        newDict['columns'] = i
        allList.append(newDict)
        newDict={}
    allList2.append(allList)
    allList=[]
print(allList2[2])

data들의 NaN 값을 아래 코드로 채워주었다.

#5번 실행 -> data의 nan 값을 가장 최신의 값들을 찾아서 채워 넣기

for j in range(len(allList2)):
    for i in range(len(allList2[j])):
        # print(allList2[j][i]['x'],allList2[j][i]['country'],allList2[j][i]['columns'])
        YY=X[X['date']==allList2[j][i]['x']]
        # print(YY[YY['LOCATION']==allList2[j][i]['country']][YY[YY['LOCATION']==allList2[j][i]['country']][allList2[j][i]['columns']].notnull()].tail(1)[allList2[j][i]['columns']].values[0])
        newData = YY[YY['LOCATION']==allList2[j][i]['country']][YY[YY['LOCATION']==allList2[j][i]['country']][allList2[j][i]['columns']].notnull()].tail(1)[allList2[j][i]['columns']].values[0]
        Y1.loc[list(X['LOCATION'][~X['LOCATION'].duplicated()].values==allList2[j][i]['country']).index(True),allList2[j][i]['columns']]=newData

극빈층 비율(extreme_poverty)의 NaN 값을 구하기 위해, '극빈층 비율'과 '인간개발지수('human_development_index')'가 반비례 형태의 높은 상관 관계를 가질 것이라 예상했다. '이 상관 관계가 높다면 반비례에 맞게 NaN 값을 채워도 크게 달라지지 않을 것이다.'라는 가정을 세웠다.

 

우선 Y1의 NaN값이 아닌 데이터의 변수를 Y_ext로 했다.

#7 Y1 가공 <- 가정 human_development_index  와 extreme_poverty 은 높은 상관관계를 가질 것이다.
# extreme_poverty 가 NaN이 아닌 애들만 뽑아옴
Y_ext = Y1[~Y1['extreme_poverty'].isnull()]

이를 토대로 상관관계와 피어슨 계수를 구하면 아래와 같다.

피어슨 계수가 -0.83 정도이고 pvalue도 아주 작은 값이기에 높은 상관관계를 가짐을 알 수 있었다.

그래서 Y1의 NaN 값을 그 국가의  '인간개발지수'에 반비례하게 채웠다.

Y1.loc[i,'extreme_poverty'] = Y_ext['extreme_poverty'].mean() / (Y1.loc[i,'human_development_index'] * Y_ext['human_development_index'].mean())

2. hospital_beds_per_thousand 와 total_deaths_per_million (수치,수치)

인구 1000명당 병상 비율과 사망자비율은 관계가 없음을 알 수 있다.


3. extreme_poverty 와 total_deaths_per_million 

밑의 오류는 나중에 버전이 업데이트 되면서 regplot을 못쓸 수 있다는 얘기인데 10년 넘게 고쳐지지 않고 있다.

무시해도 되는 오류

극빈층 비율과 사망자비율은 관계가 없음을 알 수 있다.

 

4. total_cases_per_million 와 total_deaths_per_million

테스트 숫자와 사망률도 관계가 없음을 알 수 있다.

 

5. gdp_per_capita 와 total_deaths_per_million

GDP와 사망률의 관계가 없음을 알 수 있다.

 

6. total_vaccinations_per_hundred와 total_deaths_per_million의 관계

백신 맞은 비율과 사망률은 피어슨 계수 -0.48, pvalue 0.01 정도이다.

이 데이터는 99%의 신뢰도를 가지며, 이 값은 미약하지만 반비례한 관계를 가짐을 알 수 있다.

 

여러 컬럼을 가지고 와서 사망률을 비교했을 때 대체로 관계가 없었다. 하지만 전혀 생각지도 못한 데이터에서 연관성을 발견했다. 그건 바로 female_smokers와 total_deaths_per_million의 관계이다.

여성 흡연자 비율이 높을 수록 상대적으로 코로나 사망률이 높았다.

피어슨 값도 0.58로 유의미한 수준을 가지고 있고, 유의확률도 0.001로 매우 낮다.

 

이 이유를 우선 크게 두 가지 가설을 세우고 탐색해봤다.

첫 번째로 단순히 흡연율이 높을 수록 코로나 사망률이 높을 경우

두 번째로 여성이 코로나 사망률이 높을 경우 두 가지로 나누었다.

 

우선 남자 흡연자 비율과 코로나 사망률을 비교해봤는데

크게 관계가 없음을 알 수 있다. 하지만, 이건 단순히 남자의 담배를 피는 비율과 코로나의 관계이므로, 코로나와 담배의 위험성 연관 관계는 파악할 수 없다.  그렇기에 담배 피는 사람 중 코로나로 사망한 사람의 비율과 관련된 데이터를 가져와 사용해야 이를 알 수 있다. 이 데이터를 직접 찾아서 해볼 수는 있지만, 프로젝트가 너무 산으로 가는 느낌이라서 기사를 찾아와 관계를 파악했다.  여성의 흡연 비율은 상관이 있을 수 있다고 봤는데 그 이유는 남성의 경우 표준편차가 좁게 분포되어 전체적인 흡연률에 큰 관계가 없을 것으로 예상되지만, 여성의 경우는 0~30까지 편차가 크고 넓게 분포되어, 남성 흡연률이 5정도 차이나는 국가에서 여성 흡연률은 10정도 차이가 ... 아닌가? 뭔소리지

https://m.health.chosun.com/svc/news_view.html?contid=2021012701783 

 

흡연자 코로나19 사망 위험, 비흡연자의 '2배'

흡연자 코로나19 사망 위험, 비흡연자의 '2배' 이해나 헬스조선 기자 | 류지현 헬스조선 인턴기자 흡연자의 코로나 사망률은 비흡연자의 2배에 달한다는 연구 결과가 나왔다. 미국 클리블랜드 클

m.health.chosun.com

모 논문결과 위와 같다고 한다.

 

이상으로 코로나 사망률과 다른 관계를 가정하고 그 상관관계를 알아봤다.

여성 흡연률의 두 번째 가설 분석과 이대로 끝내기에는 너무 이도저도 못한 느낌이 들어서 새로운 데이터 셋을 가지고 분석하기로 했다.