반응형

이번 포스팅은 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학기는 시험보랴 프로젝트하랴 정말 바빴었고 힘들었는데 지금보니 느낌이 또 색다르다! 역시 지나고보면 다 추억인가보다 !!(???)ㅋㅋㅋㅋㅋ

반응형
반응형

Dataset 가져온 출처: https://www.kaggle.com/c/titanic

 

Titanic - Machine Learning from Disaster | Kaggle

 

www.kaggle.com

 

Machine Learning 분석을 적용하여 어떤 사람들이 타이타닉호에서 생존할 수 있었는가에 대해 분석해봄.

ㅇ 활용 모델

- Logistic Regression

- k-Nearest Neighbors

- Support Vector Machines

- Naive Bayes classifier

- Decision Tree

- Artificial neural network

1. 데이터 전처리

kaggle에서 다운받은 excel의 데이터가 공백, 데이터형식 등 다른 부분이 많다.

그것들을 정제하기 위한 절차를 수행

 

1-1. 함수 선언 및 데이터 확인

1) 함수 선언

# 데이터 분석

import pandas as pd

import numpy as np

import random as rnd

# 시각화

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) 데이터 로딩 및 확인

# 데이터 로딩 // df: dataframe 데이터 읽음

train_df = pd.read_csv('./train.csv')

test_df = pd.read_csv('./test.csv')

combine = [train_df, test_df] // 데이터 합침

print(train_df.columns.values) // values 열 출력

# preview the data

train_df.head() // method를 불러서 예쁘게 보여줌. head(): 5lines까지만 보여줌.

train_df.tail() // tail(): 뒤에서 5lines 보여줌.

# train data와 test data info 출력

train_df.info()

print('_'*40)

test_df.info()

train_df.describe()

1-2. Missing Value 처리 - Data 삽입을 위해 기존 Data의 중간값 / 평균값 구하기

# check missing values in train, test dataset

train_df.isnull().sum()

test_df.isnull().sum()

missing된 value는 age, cabin, 그리고 test dataset의 Fare.

# training data의 age, cabin의 경우 누락 값들은 전체 값 중 몇프로일까?

sum(pd.isnull(train_df['Age']))/len(train_df["PassengerId"]) // 전체 length에서 null값의 갯수를 나눈다.

sum(pd.isnull(train_df['Cabin']))/len(train_df["PassengerId"])

# Train의 Age분포를 히스토그램으로 확인해보자

ax = train_df["Age"].hist(bins=15, color='teal', alpha=0.8) // bins=bar 갯수, alpha=투명도

ax.set(xlabel='Age', ylabel='Count') // x, y축 레이블

plt.show()

# 중간값은 약 20-30대로 보인다. 정확한 중간값을 알아보자

train_df["Age"].median(skipna=True)

글쿤.

# 이번엔 train data의 Embarked 중간값을 알아보자

countplot 하나 써보장. 딱봐도 S가 제일 많다

# 마지막으로 Fare의 평균값은?

train_df["Fare"].mean(skipna=True)

정수써야하므로 32로 생각하자.

1-3. Missing Value 처리 - Data입력

- Embarked는 S가 가장 많으니 누락값에 S를 채워넣고,

- Fare는 평균값인 32를 취해서 누락값에 넣는다. (항구/티켓에 따라 다르지만 편의상)

- Cabin은 누락값 많았지만, 값들이 char형으로 평균/중간값 구하기 애매함.

그래서 Cabin 속성 제거.

# 누락된 값을 적절한 값으로 채워넣기

train_df["Age"].fillna(28, inplace=True)

test_df["Age"].fillna(28, inplace=True)

train_df["Embarked"].fillna("S", inplace=True)

test_df["Fare"].fillna(32, inplace=True)

# 누락된 값이 너무 많은 속성 제거

train_df.drop('Cabin', axis=1, inplace=True)

test_df.drop('Cabin', axis=1, inplace=True)

1-4. 데이터 속성별 값에 따라 생존자 확인

# 각 속성(열)에 따른 생존자 확률

train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["Sex", "Survived"]].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["Parch", "Survived"]].groupby(['Parch'], as_index=False).mean().sort_values(by='Survived', ascending=False)

Parch와 SibSp는 딱히 패턴이 안보인다. 버리자.

1-5. 데이터 시각화

# 나이별 비생존자와 생존자

g = sns.FacetGrid(train_df, col='Survived')

g.map(plt.hist, 'Age', bins=20)

# 나이 및 객실 등급별 생존여부

grid = sns.FacetGrid(train_df, col='Survived', row='Pclass', size=2.2, aspect=1.6) # 행: 객실 등급, 열: 생존여부

grid.map(plt.hist, 'Age', alpha=.5, bins=20) // plt.hist, alpha = 투명도, bins = 갯수

grid.add_legend();

# 꺾은선 그래프

Embarked, PClass, Sex에 따른 생존 여부

grid = sns.FacetGrid(train_df, col='Embarked', size=2.2, aspect=1.6)

grid.map(sns.pointplot, 'Pclass', 'Survived', 'Sex', palette='deep', order=[1, 2, 3], hue_order=None)

grid.add_legend()

1-6. 데이터 전처리: 속성 조정

# 우선 현재 보유하고 있는 속성을 다시 한 번 확인해보자

train_df.head()

# 속성 조정

PassengerId는 샘플별로 다르기 때문에 제거

Survived: 예측해야할 output

Age, Fare: 그대로 채택

Sex, Pclass, Embarked: 카테고리 값이므로 처리.

SibSp, Parch: Binary 값으로 수정

Ticket: 표 번호이므로 상관성이 없는 값이라 제거

Name: 한 번 살펴볼 것.

1-6-1. SibSp, Parch를 Binary 값으로 수정

# 신규 속성인 TravelSibSp, TravelParch 만들어줌

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

train_df['TravelSibSp'] = np.where(train_df['SibSp']>0, 1, 0)

train_df['TravelParch'] = np.where(train_df['Parch']>0, 1, 0)

# 이후 SibSp, SibSp 제거

train_df.drop('SibSp', axis=1, inplace=True)

train_df.drop('Parch', axis=1, inplace=True)

# test 데이터도 마찬가지로 적용

test_df['TravelSibSp'] = np.where(test_df['SibSp']>0, 1, 0)

test_df['TravelParch'] = np.where(test_df['Parch']>0, 1, 0)

test_df.drop('SibSp', axis=1, inplace=True)

test_df.drop('Parch', axis=1, inplace=True)

1-6-2. Pclass, Embarked, Sex 처리

Pclass에 세 가지가 있으니 Pclass 라는 속성을 세 개로 쪼갠다. Pclass_1, Pclass_2, Pclass_3

Embarked도 마찬가지. S, C, Q 가 있으니 Embarked_S, Embarked_C, Embarked_Q

Sex도 마찬가지, female, male 이 있으니 Sex_female, Sex_femal

1-6-3. 쓸모없는 속성 제거

train_df4.drop('PassengerId', axis=1, inplace=True)

train_df4.drop('Name', axis=1, inplace=True)

train_df4.drop('Ticket', axis=1, inplace=True)

train_df4.drop('Sex_male', axis=1, inplace=True) // 어차피 성별은 0 아님 1이므로 하나 제거

train_df4.head() //

1-6-4. test_df에도 똑같이 해주자

test_df2 = pd.get_dummies(test_df, columns=["Pclass"])

test_df3 = pd.get_dummies(test_df2, columns=["Embarked"])

test_df4 = pd.get_dummies(test_df3, columns=["Sex"])

#test_df4.drop('PassengerId', axis=1, inplace=True) <--- 이건 나중에 평가를 위해 일단 지금은 지우지 말자

test_df4.drop('Name', axis=1, inplace=True)

test_df4.drop('Ticket', axis=1, inplace=True)

test_df4.drop('Sex_male', axis=1, inplace=True)

test_df4.head()

드디어 데이터 전처리 끝.

이제 ML(Machine Learning)을 이용하여 생존자를 예측해보자.

2. Machine Learning 활용한 생존자 예측

ㅇ 활용 모델

2.1 Logistic Regression

2.2 k-Nearest Neighbors

2.3 Support Vector Machines

2.4 Naive Bayes classifier

2.5 Decision Tree

2.6 Artificial neural network

2-0. 일단 학습집합과 테스트 집합 준비

나머지는 졸려서 to be continued...

반응형
반응형

이번 포스팅은 Linear Regression 구현으로 예제는 집 크기에 따른 집 값 예측을 하는 Housing prices(Example of ndrew Ng)이다.

1. Import, data loading

import num as np

import matplotlib.pyplot as plt

data = np.loadtxt("house_prices.txt", delimiter=",")

data #데이터 확인.

* 출력이 안예쁘다. numpy 패키지의 숫자 프린팅 옵션으로 숫자 포맷을 변경한다.

np.set_printoptions(suppress=True)

data

printoptions 함수는 아래 링크 참고.

https://docs.scipy.org/doc/numpy/reference/generated/numpy.set_printoptions.html

numpy.set_printoptions — NumPy v1.16 Manual

Scipy.org Docs NumPy v1.16 Manual NumPy Reference Routines Input and output index next previous numpy.set_printoptions numpy. set_printoptions ( precision=None , threshold=None , edgeitems=None , linewidth=None , suppress=None , nanstr=None , infstr=None , formatter=None , sign=None , floatmode=None...

docs.scipy.org

2. 데이터 셋을 X와 Y로 분리

x = data[:, :2] #모든 행 : 0, 1열

y= data[:, -1] #모든 행: 마지막 열. 이 문제에선 data[:,2]와 동일

3. 학습 데이터 및 테스트 데이터 분할

* 일부는 학습데이터에 활용하고, 일부는 학습 후 테스트 데이터로 활용함

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=4)

/*

- test_size: 테스트 데이터 비중. 여기선 값 중 20%만 테스트 값으로 하고 80%는 training data로 씀

- random_state: 랜덤으로 선택되는 데이터

random_state

:랜덤으로 선택하는 이유는 데이터가 이미 내림차순 등으로 정렬되어있을 경우 순서대로 50개를 뽑으면,

그건 랜덤학습이 아니라 이미 사람 손을 한번 탄 데이터임. 사람이 원하는 값이 나올 가능성이 높아짐.

중구난방으로 데이터를 학습시켜야 실제 예측값과 실제값이비슷하게 나올 수 있음.

*/

4. 학습 데이터와 테스트 데이터 plotting

plt.scatter(x_train[:,0], y_train, color='black') #학습데이터

plt.scatter(x_test[:,0], y_test, color='red') #테스트데이터

5. 선형회귀 모델 학습

model = linear_model.LinearRegression()

model.fit(x_train, y_train) #linearregression 모델에 x_train, y_train 학습

6. 테스트 데이터 넣어서 예측

result = model.predict(x_test)

7. 실제 가격과 예측 가격 비교

print(np.column_stack((x_test, y_test, result)))

#result가 6.에서 x_test로 돌린 예측 값인데 실제 값(y_test)과 거의 비슷하게 나옴.

첫 행의 집값은 314900이나, 예측값은 334034.---- 가 나왔음.

8. 그래프 제대로 그려보기

real = plt.scatter(x_test[:,0], y_test, color='red')

predict=plt.scatter(x_test[:,0], result, color='blue')

plt.legend((real, predict), ('real', 'prediction'))

plt.title('Real price vs. Predicted price')

plt.ylabel('Price')

plt.xlabel('House size')

plt.show()

9. 학습된 선형 모델과 예측 결과 plotting

plt.plot( [min(x_train[:,0]), max(x_train[:,0]) ],

[min(model.predict(x_train)), max(model.predict(x_train))])

#선을 그려보자. min <-> max간 선을 그려줌.

plt.scatter(x_test[:,0], y_test, color='red') #실제 결과

plt.scatter(x_test[:,0], result, color='blue') #예측한 결과

반응형
반응형

데이터마이닝 수업 듣다가.. 코드부분은 2학년때 배웠던 것들이라 슝슝 넘어가서 정리할겸 상세하게 써본다.

실습 예제는 iris data set이다. 여기서 0, 1행(Sepal length, Sepal width)를 data로 넣어 target(Type)을 구할 것이다.

1. 패키지 import

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.colors improt Listed Colormap

from sklearn import neighbors, datasets

// import 와 from의 차이:

import 모듈: 모듈 전체 추출. 일반적으로 이걸 씀. 후자(from 모듈) 사용할 경우 해당 변수와 코드에서 사용하는 변수와 겹칠우려.

from 모듈 import 변수나 함수: 모듈에서 필요한 변/함수만 추출

2. 데이터 로딩

n_neighbors = 15 #최근접 이웃 개수 미리 설정. k=15

iris = datasets.load_iris() # sklearn에 기본적으로 내장된 iris 데이터셋 로딩

print(iris) #로딩한 데이터 확인

print(iris.keys()) #데이터셋 종류 확인(딕셔너리 키값)

3. 데이터 확인 # iris key중 두개 keys에 대해 값 확인

print(iris.data)

print(iris.target)

4. 속성 두 개 선택

X = iris.data[ :, :2] #행은 전체를 가져오고, 열은 속성값 2개만. 2개만해야 그래프 그릴때 보기 쉬움

Y = iris.target #X에 따른 결과값

5. 추후 그래프 색칠위해 컬러맵 세팅

# Create color maps # http://htmlcolorcodes.com/

cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF']) # RGB Hex code

cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])

6. 모델 생성, 데이터 피팅

#k-neighbors classifier를 생성하여 학습데이터에 맞춘다.

clf = neighbors.KNeighborsClassifier(n_neighbors, weights='uniform')

# weights='uniform' 거리 상관없이 주변에 있는 label들에 모두 동일한 점수를 측정하겠다.

clf.fit(X, Y)

사진 설명을 입력하세요.

7. 신규데이터 범위 세팅

#전체 영역 만들기

x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1 # 0열(sepal length)에서의 최소, 최대값

x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1 # 1열(sepal width)에서의 최소, 최대값

# 각 값을 출력해보자

8. 신규 좌표 만들기 - x1/x2축 눈금 확인 #np.meshgrid로 격자무늬 그물망 만듦

h= .02 #격자무늬 그물망 간격

xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, h), np.arange(x2_min, x2_max, h))

하나씩 뜯어보자.

np.arange(x1_min, x1_max, h) # h간격(0.02)로 x1_min(3.3) 에서 x1_max(8.9)까지 범위 설정

np.arange(x2_min, x2_max, h)

8.2. 신규 좌표 만들기 - X1/X2좌표 준비

h= .02 #격자무늬 그물망 간격

xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, h), np.arange(x2_min, x2_max, h)) #위랑 코드 같음.

X 좌표 Y 좌표

8.3. 신규 좌표 만들기 - X1/X2 매칭

x1/x2는 행렬 형태(2차원 배열)로 되어있으니 이것들을 1차원 배열로 바꿔줌

그게 xx1.ravel(), xx2.ravel().

그럼 각각은 220행 * 280열이었으니 61600행이 됨.

이것들을 쌍으로 만들어서 한 행렬로 만듦. 그럼 이것도 역시 61600행

np.c_[xx1.ravel(), xx2.ravel()]

9. Nearest Neighbor classification

z=clf.predict(np.c_[xx1.ravel(), xx2.ravel()])

#신규 샘플들에 대한 예측, 그 결과. target은 0, 1, 2뿐이었으므로 Z는 0, 1, 2만 있음

9-1. Z formatting

Z=Z.reshape(xx1.shape)

print(Z)

# z의 포맷(1차원)을 xx1 포맷(2차원)으로 바꿔줌.

for 그래프 그릴려고. 첨부터 2차원으로 하지 왜? -> predict는 2차원이 안됨

9-3. 그래프 준비

plt.figure() # 그래프 준비

plt.pcolormesh(xx1, xx2, Z, cmap=cmap_light)

/*

xx1, xx2를 pair로 점을 만들고, 그때 label에 해당하는 것이 z.

z는 위에서 0-2 사이 값이었고 . cmap_light는 아까 5번에서 3개 색을 넣어줬었음.

따라서 z가 0이라면 #FFAAAA 값이 그래프에 칠해짐.

*/

사진 설명을 입력하세요.

Z= 빨강: 0, 파랑: 1, 초록: 2

9-4. 학습 데이터 표시

plt.pcolormesh(xx1, xx2, Z, cmap=cmap_light) #배경(신규 좌표값, 그에 대한 예측결과를 표시)

plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=cmap_bold, edgecolor='k', s=20) # 학습데이터 점 찍고

plt.xlim(xx1.min(), xx1.max()) #x,y 축 범위 수동지정인데 여기선 의미가 없어보인다.

plt.ylim(xx2.min(), xx2.max())

plt.title("3-Class classification (k=%i, weights='%s')" % (n_neighbors, 'uniform')) #제목 찍기

plt.show()

결론

그래프의 배경(pcolormesh)은

기존 X,Y 데이터의 각 최소-최대값을 구해 0.02간격으로 데이터셋을 나눠 다시 만들어준 예측값(Z)들이다.

실제 값들은(X[:,0],X[:,1]===> y) scatter 로 더 진하게(cmap_bold) 그려줌.

결국 예측값이나 실제값이나 거의 똑같은 것을 볼 수 있음.

scatter의 초록-파랑부분에 색이 섞인 이유는,

k-nearest 하다보니 주위가 파랑이 더 많으면 파랑, 초록이 더 많으면 초록이 되다보니 겹치는 구간에 색이 저렇게 나타남.

다음은 linear regression

반응형

+ Recent posts