반응형

이번 포스팅은 3-1학기 데이터마이닝 수업 기말 개인프로젝트로 제출했던 전세계 1985-2016 자살률 분석 건이다.

자유주제여서 주제를 고민하다가 캐글에서 흥미로운 데이터를 찾아 가져왔다.

1. 분석할 데이터 및 목표

- 분석할 데이터: Suicide Rates Overview 1985 to 2016 from Kaggle

- 목표: 전세계 자살률을 알아보고, 각 속성이 자살률에 영향을 미치는지 그리고 어느 속성이 가장 영향을 미치는지 분석

https://www.kaggle.com/russellyates88/suicide-rates-overview-1985-to-2016

 

Suicide Rates Overview 1985 to 2016

Compares socio-economic info with suicide rates by year and country

www.kaggle.com

 

- DataSet

. Columns: 12개

country, year, sex, age, suicides_no, population, suicides/100k pop, country-year, HDI for year,

gdp_for_year ($), gdp_per_capita ($), generation

. Rows count: 27820개

2. 전처리 과정​

1) 패키지 선언

#데이터분석용 pkg

import pandas as pd

import numpy as np

import random as rnd #시각화용 pkg

import seaborn as sns

import matplotlib.pyplot as plt

%matplotlib inline #기계학습

from sklearn.linear_model

import LogisticRegression from sklearn.svm

import SVC, LinearSVC from sklearn.ensemble

import RandomForestClassifier from sklearn.neighbors

import KNeighborsClassifier from sklearn.naive_bayes

import GaussianNB from sklearn.linear_model

import Perceptron from sklearn.linear_model

import SGDClassifier from sklearn.tree

import DecisionTreeClassifier from sklearn.neural_network

import MLPClassifier

2) 데이터 로딩 및 확인

#데이터로딩

data = pd.read_csv('master.csv') # 데이터 시각화용. 원본

data_train = pd.read_csv('master_train.csv') #원본 데이터를 7:3으로 train:test로 편집함

data_test = pd.read_csv('master_test.csv') #train:70%, test:30%

print ("Data_train shape:", data_train.shape, "\n")

print ("Data_test shape:", data_test.shape, "\n")

print (data_train.info())

print('_'*40)

print (data_tnfo())

 

* 핵심 속성인 자살률에 대해 mean 값을 확인해봄

#suicides/100k pop의 mean 값 확인=12.16

data_train.describe()

#suicides/100k pop의 mean 값 확인=14.35

data_test.describe()

3) Missing Data 확인

: Missing Data가 많은 속성값은 해당 속성에 따라 결과값이 나온다고 가정하기 어려우므로 삭제 위함

#check missing values in test dataset

print(data_train.isnull().sum())

print('_'*40)

print(data_test.isnull().sum())

 

# 몇프로가 누락되었는지 퍼센트로 확인 = 0.6869 =>70% 누락

sum(pd.isnull(data_train['HDI for year']))/len(data_train["HDI for year"])

4) 누락 및 중복값 삭제

# 누락 및 중복값 Data 삭제. 70%가 누락된 HDI for year

data_train.drop('HDI for year', axis=1, inplace=True)

data_test.drop('HDI for year', axis=1, inplace=True)

 

#suicides_no와 population을 나눈 값이 'suicides/100k pop' * 10^-5 이므로 중복 속성 제거.

data_train.drop('suicides_no', axis=1, inplace=True)

data_train.drop('population', axis=1, inplace=True)

data_train.drop('country-year', axis=1, inplace=True)

 

# country 및 year 속성 별도 존재하여 삭제

data_train.drop(' gdp_for_year ($) ', axis=1, inplace=True)

 

#gdp_per_capita($)와 비례하므로 중복 속성. 삭제

data_train['age']=data['age'].str.strip(" years") # years 텍스트 제거

data_test.drop('suicides_no', axis=1, inplace=True)

data_test.drop('population', axis=1, inplace=True)

data_test.drop('country-year', axis=1, inplace=True)

# country 및 year 속성 별도 존재하여 삭제

data_test.drop(' gdp_for_year ($) ', axis=1, inplace=True)

 

#gdp_per_capita($)와 비례하므로 중복 속성. 삭제

data_test['age']=data['age'].str.strip(" years") # years 텍스트 제거 data_train.head()

5) 새로운 속성값 생성

- Over_mean_suicides: 평균보다 자살률이 클 경우 1, 작을 경우 0으로 열 추가

# 신규 속성인 Over_mean_suicides 만들어줌. 자살률이 전체 mean 자살률대비 크면 1, 작으면 0

# 해당 속성이 0보다 크면 1, 아니면 0

data_train['Over_mean_suicides'] = np.where(data_train['suicides/100k pop']>12.16, 1, 0) data_test['Over_mean_suicides'] = np.where(data_test['suicides/100k pop']>14.35, 1, 0)

data_train.head()

2. 데이터 시각화 및 간단 분석

1) 국가(Country)별 자살률 확인 및 시각화

2) 년도(year)별 자살률 확인 및 시각화

3) 성별(Sex)별 자살률 확인 및 시각화

4) 연령(age)별 자살률 확인 및 시각화

5) 1인당 GDP(gdp_per_capita($)) 별 자살률 확인 및 시각화

6) 세대(Generation)별 자살률 확인 및 시각화

1) 국가별 자살률 확인 및 상위 5개 국가 출력

#1) 국가별 자살률 확인

fig = plt.figure(figsize=(20,5))

plt.title('Suicide Rates by Country')

sns.barplot(x='country', y='suicides/100k pop', data=data[['country', 'suicides/100k pop']].groupby('country', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)); plt.xticks(rotation=90);

 

#x축(country) 회전 ​ # 상위 5개 국가 출력 ==> 상위5국가: 리투아니아, 스리랑카, 러시아, 헝가리, 벨라루스 // 한국: 11위 data[['country','suicides/100k pop']].groupby('country', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False).head()

 

2) 년도별 자살률 시각화 및 상위 5개 년도 출력

: 1995년대 자살률이 높다. 이유는? 뒤에서...

#2)년도(year)별 자살률 확인 및 시각화 #시각화

fig, ax = plt.subplots(figsize=(20, 5))

plt.title('Suicide rates by year')

sns.lineplot(x='year', y='suicides/100k pop', data=data[['year','suicides/100k pop']].groupby('year',as_index=False).mean().sort_values(by='year',ascending=True),marker='o',color='RED');

ax.set(xticks=data['year'].unique());

 

# 상위 5개 년도 출력 ==> 상위5국가: 리투아니아, 스리랑카, 러시아, 헝가리, 벨라루스 // 한국: 11위

data[['year', 'suicides/100k pop']].groupby('year', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False).head()

3) 성별에 따른 자살률 확인 및 순위 출력

: 남성이 여성대비 4배이상 자살률이 높다.

#3) 성별(Sex)별 자살률 확인 및 시각화 => 남성이 여성 대비 4배 높음

fig = plt.figure(figsize=(2,3))

plt.title('Suicide rates by sex') sns.barplot(x='sex', y='suicides/100k pop', data=data[['sex', 'suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)); data[['sex','suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

4) 연령대에 따른 자살률 확인 및 순위출력

: 고령일수록 자살률이 높다.

#4) 연령(age)별 자살률 확인 및 시각화 ==> 고령일수록, 남성일수록 자살률이 높다. fig=plt.figure(figsize=(5,4)); plt.title('Suicide rates by Age')

sns.barplot(x='age', y='suicides/100k pop',hue='sex', data=data[['age','suicides/100k pop','sex']].groupby(['age','sex'],as_index=False).mean().sort_values(by='suicides/100k pop',ascending=False));

data[['age','suicides/100k pop']].groupby('age', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

 

5) 1인당 GDP(gdp_per_capita($))별 자살률 확인 및 시각화

: GDP는 자살률과 관련이 없는 것으로 추측된다.

#5) 1인당 GDP(gdp_per_capita($)) 별 자살률 확인 및 시각화 ==> GDP와 자살률은 관련이 없다. 높든 낮든 자살률의 분포는 유사하다.

fig = plt.figure(figsize=(30,10))

plt.title('Suicide rates by gdp_per_capita ($)') sns.barplot(x='gdp_per_capita ($)', y='suicides/100k pop', data=data[['gdp_per_capita ($)', 'suicides/100k pop']].groupby('gdp_per_capita ($)', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False));

#data[['gdp_per_capita ($)','suicides/100k pop']].groupby('gdp_per_capita ($)', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False) data['gdp_per_capita ($)'].describe()

 

6) Generation에 따른 자살률 확인

: Generation X(세계 2차대전 이후, 대략 1970년대생), Silent 세대 (1920-40년대생. 유년기를 전쟁통으로 겪은, 조용히 지낼 수 밖에 없었던 세대) 자살률이 가장 높다.

6)generation별 자살률 및 시각화 => Genearation X세대 자살률이 가장 높음

f,ax=plt.subplots(1,2,figsize=(15,5)) data['generation'].value_counts().plot.pie(explode=[0.1,0.1,0.1,0.1,0.1,0.1],autopct='%1.1f%%',ax=ax[0],shadow=True)

ax[0].set_title('Suicide Rates by Generation') ax[0].set_ylabel('Suicides/100k pop') sns.countplot('generation',data=data,ax=ax[1]) ax[1].set_title('Suicide Rates by Generation')

plt.show() data[['generation','suicides/100k pop']].groupby('generation', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

* 데이터마이닝 과제에서는 속성별 분석은 여기까지만 진행했으나

데이터시각화 과목 프로젝트에서도 해당 주제를 선택하여

엑셀을 통해 추가적 분석을 진행하였다. 이또한 나름 시각화이므로 중간에 끼워넣어본다!!

다시 데이터마이닝으로 돌아와서...

3. Machine Learning 기법을 활용한 자살률 예측

- 사용 알고리즘

1) Logistic Regression

2) Support Vector Machines

3) Decision Tree

4) KNN

5) Naive Bayes

6) Linear SVC

7) Perceptron

8) Random Forest

9) Stochastic Gradient Decent

3-1) 데이터 추가 전처리: string값을 정수형으로 변환

#1) age 의 string을 정수로 바꾸기

def func(dataset): if dataset['age'] == '75+': # 75+ ==> 80 치환

return '80'

elif dataset['age'] =='55-74': # 55-74 ==> 65 치환

return '65'

elif dataset['age'] =='35-54': # 35-54 ==> 45 치환

return '45'

elif dataset['age'] =='25-34': # 25-34 ==> 30 치환

return '30'

elif dataset['age'] =='15-24': # 15-24 ==> 20 치환

return '20'

else: return '10' # 5-14 = 10 치환

 

#TrainData 적용

data_train['age'] = data_train.apply(func, axis=1)

data_train[['age','suicides/100k pop']].groupby('age', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

#TestData도 같이 적용

data_test['age'] = data_test.apply(func, axis=1)

data_test[['age','suicides/100k pop']].groupby('age', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

2) sex의 string을 정수로 바꾸기

def func(dataset): if dataset['sex'] == 'female': # 여자 = 0 으로 치환

return '0' else: return '1' # 남자 = 1 로 치환. spelling이 겹치므로 여자부터 치환해야함.

 

data_train['sex'] = data_train.apply(func, axis=1)

data_train[['sex','suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False) data_test['sex'] = data_test.apply(func, axis=1)

data_test[['sex','suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

3) Generation 의 string을 정수로 바꾸기

def func(dataset):

if dataset['generation'] == 'G.I. Generation': # G.I generation = 1

return '1'

elif dataset['generation'] =='Silent': # Silent = 2

return '2'

elif dataset['generation'] =='Boomers': # Boomers = 3

return '3'

elif dataset['generation'] =='Generation X': # Generation X = 4

return '4'

elif dataset['generation'] =='Millenials': # Millenials = 5

return '5'

else:

return '6' # Generation Z = 6

 

data_train['generation'] = data_train.apply(func, axis=1)

data_train[['generation','suicides/100k pop']].groupby('generation', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

data_test['generation'] = data_test.apply(func, axis=1)

data_test[['generation','suicides/100k pop']].groupby('generation', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

3-2) 학습집합 및 테스트 집합 준비

: 만들어 준 속성(Over_mean_suicides)을 예측값으로 사용.

이에 영향을 미치는 요소인 suicides/100k pop 은 제거하고, Country의 경우 나라가 100개이상이므로

String제거 복잡하여 속성 제거

- 비율: Training data(19474, 70%), Test Data(8346, 30%)

X_train = data_train.drop("Over_mean_suicides", axis=1)

X_train = X_train.drop("suicides/100k pop" , axis =1)

X_train = X_train.drop("country", axis=1) Y_train = data_train["Over_mean_suicides"]

 

X_test = data_test.drop("Over_mean_suicides" , axis=1).copy()

X_test = X_test.drop("suicides/100k pop" , axis =1)

X_test = X_test.drop("country" , axis =1)

X_train.shape, Y_train.shape, X_test.shape

 

3-3) 알고리즘 시작

#1. Logistic Regression

logreg = LogisticRegression(solver='lbfgs')

logreg.fit(X_train, Y_train)

Y_pred = logreg.predict(X_test)

acc_log= round(logreg.score(X_train, Y_train) * 100, 2)

acc_log

 

#2. Support Vector Machines

svc = SVC() solver='liblinear' svc.fit(X_train, Y_train)

Y_pred = svc.predict(X_test)

acc_svc = round(svc.score(X_train, Y_train) * 100, 2)

print(acc_svc)

 

#3. Decision Tree

decision_tree = DecisionTreeClassifier()

decision_tree.fit(X_train, Y_train)

Y_pred = decision_tree.predict(X_test)

acc_decision_tree = round(decision_tree.score(X_train, Y_train) * 100, 2)

acc_decision_tree

 

# 4. KNN

knn = KNeighborsClassifier(n_neighbors = 3)

knn.fit(X_train, Y_train)

Y_pred = knn.predict(X_test)

acc_knn = round(knn.score(X_train, Y_train) * 100, 2)

acc_knn ​

 

# 5. Gaussian Naive Bayes

gaussian = GaussianNB() gaussian.fit(X_train, Y_train)

Y_pred = gaussian.predict(X_test)

acc_gaussian = round(gaussian.score(X_train, Y_train) * 100, 2)

acc_gaussian

 

# 6. Linear SVC

linear_svc = LinearSVC()

linear_svc.fit(X_train, Y_train)

Y_pred = linear_svc.predict(X_test)

acc_linear_svc = round(linear_svc.score(X_train, Y_train) * 100, 2)

acc_linear_svc

# 7. Perceptron perceptron = Perceptron()

perceptron.fit(X_train, Y_train)

Y_pred = perceptron.predict(X_test)

acc_perceptron = round(perceptron.score(X_train, Y_train) * 100, 2)

acc_perceptron

 

#8. Random Forest

random_forest = RandomForestClassifier(n_estimators=100)

random_forest.fit(X_train, Y_train)

Y_pred = random_forest.predict(X_test)

random_forest.score(X_train, Y_train)

acc_random_forest = round(random_forest.score(X_train, Y_train) * 100, 2)

acc_random_forest

 

#9. Stochastic Gradient Descent

sgd = SGDClassifier() sgd.fit(X_train, Y_train)

Y_pred = sgd.predict(X_test)

acc_sgd = round(sgd.score(X_train, Y_train) * 100, 2)

acc_sgd

 

3-4. 알고리즘별 Score 정렬

models = pd.DataFrame({ 'Model': ['Support Vector Machines', 'KNN', 'Logistic Regression', 'Random Forest', 'Naive Bayes', 'Perceptron', 'Stochastic Gradient Decent', 'Linear SVC', 'Decision Tree'], 'Score': [acc_svc, acc_knn, acc_log, acc_random_forest, acc_gaussian, acc_perceptron, acc_sgd, acc_linear_svc, acc_decision_tree]}) models.sort_values(by='Score', ascending=False)

3-5) 최종 파일 생성

submission = pd.DataFrame({ "Country": data_test["country"], "If_over_mean_of_suicide": Y_pred }) submission.to_csv('final_pjt_20.csv', index=False) data_final = pd.read_csv('final_pjt_20.csv') data_final.info() data_final.describe()

 

결론적으로 전세계 자살률은 남성일수록, 고령일수록, gdp와는 관계가 없고, 전쟁과 가까운 세대일수록 높았다.

개인적인 생각으로는 못사는 나라일수록 자살률이 높다기보다는, 본인이 처한 경험과 환경에 따라 다른 것이 아닐까 생각이 든다. 후진국의 사람들은 다른 나라를 경험해보았을까? TV조차 없을텐데 그들에게 비교대상은 그 주위사람들뿐이지 않을까. 특히 나이가 먹을수록 몸도 마음도 약해지고, 주도적으로 할 수 있는 것 조차 한계가 생기기 때문에 안좋은 생각을 하기 상대적으로 쉬울 것 같다. 여기까진 내 생각일 뿐이고 또 다른 재미있는 주제가 있으면 들고오겠다 : )

 

3-1학기는 시험보랴 프로젝트하랴 정말 바빴었고 힘들었는데 지금보니 느낌이 또 색다르다! 역시 지나고보면 다 추억인가보다 !!(???)ㅋㅋㅋㅋㅋ

반응형

+ Recent posts