Machine Learning Example with Class
Page content
강의 홍보
- 취준생을 위한 강의를 제작하였습니다.
- 본 블로그를 통해서 강의를 수강하신 분은 게시글 제목과 링크를 수강하여 인프런 메시지를 통해 보내주시기를 바랍니다.
스타벅스 아이스 아메리카노를 선물
로 보내드리겠습니다.
- [비전공자 대환영] 제로베이스도 쉽게 입문하는 파이썬 데이터 분석 - 캐글입문기
I. 개요
- 간단하게 클래스를 만들어보고 한다.
- 지금까지 배운 내용을 바탕으로
Class
를 활용한 머신러닝 예제를 작성한다.
II. Class와 Instance는 무엇인가?
- 클래스는 결국 함수의 연장선이다.
- 지금까지 함수가 얼마나 편한 것인지를 배웠다.
- 그런데, 시스템이 복잡해지면 함수 하나로 충분하지 않음을 알게 된다.
- 간단한 예시를 들어보자.
result = 0
def add(num):
global result
result += num
return result
print(add(10))
print(add(20))
10
30
(1) 똑같은 기능을 가진 여러개의 함수
- 그런데, 2대의 계산기가 필요한 상황이 되었다고 가정하자.
result1 = 0
result2 = 0
def add1(num):
global result1
result1 += num
return result1
def add2(num):
global result2
result2 += num
return result2
print(add1(10))
print(add1(20))
print(add2(10))
print(add2(10))
10
30
10
20
- 똑같은 일을 하는데, 2개의 함수가 필요할까?
- 이 때 필요한 개념이
Class
라는 개념이다.
(2) 사람 클래스
- 사람을 어떻게 정의할 수 있을까?
- 기본적인 신상: 이름, 나이, 취미
- 일상생활: 밥 먹기, 운동하기, 잠자기
- 그런데, 현재 우리 클래스 안에 몇명의 사람이 있는가?
- 이러한 신상을 파악하고, 일상생활을 파악하는 공통적인 설문지가 있으면 어떨까?
- 설문지라는
틀
이 일종의 클래스가 되는 것이다.
class Human:
name = "Rain" # 필드
age = 30 # 필드
def exercise(self): # 메서드(Method), 객체가 할 수 있는 행동(=객체가 할 수 있는 함수)
print("운동합시다")
- 여기에서
self
는 첫번째 매개변수를 의미하며,자기 자신
을 의미한다.
(3) 인스턴스
- 인스턴스는 설문지를 받는 개개인의 사람을 떠올리자.
rain = Human()
print(rain.name)
print(rain.age)
rain.exercise()
Rain
30
운동합시다
III. How to define Class
- 이제 지난 시간에 배운 함수의 정의들을 활용하여
Class
를 만들어본다.
(1) 기본 함수 활용한 Class
예제
- 기본
__init__
메서드를 클래스안에 만든다. - 두명의 다른 사람을 만들어내자.
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
if __name__ == '__main__':
evan = Human("Evan", 9)
minyoung = Human("SeoYoung", 8)
print(evan.name)
print(minyoung.name)
Evan
SeoYoung
(2) 인스턴스 메서드
- 이번에는 그 사람의 특징을 만들어 낼 수 있는 인스턴스 메서드를 작성 해보자.
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def describe(self):
return f"{self.name}의 나이는 {self.age}이다."
def say(self, content):
return f"{self.name}이 {content}에 대해 말하고 있다."
if __name__ == '__main__':
evan = Human("Evan", 9)
print(evan.describe())
Evan의 나이는 9이다.
(3) 상속
- 상속은 부모가 가진 재산을 자녀에게 물려줄 때는 쓰는 말
- 여기에서 말하는 재산은
함수, 변수
등을 의미함.
- 여기에서 말하는 재산은
Asian
,European
,African
Class
를 만들어본다.- 단, 이 때,
skin color
함수를 부모인Human
클래스에서 만든다.
- 단, 이 때,
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def describe(self):
return f"{self.name}의 나이는 {self.age}이다."
def say(self, content):
return f"{self.name}이 {content}에 대해 말하고 있다."
def skinColor(self, color):
return f"{self.name}의 피부 색상은 {color}이다."
class Asian(Human):
pass
class European(Human):
pass
class African(Human):
pass
if __name__ == '__main__':
evan = Asian("Jihoon", 9)
rose = European("Rose", 10)
sam = African("Sam", 11)
print(evan.skinColor("Yellow"))
print(rose.skinColor("white"))
print(sam.skinColor("black"))
Jihoon의 피부 색상은 Yellow이다.
Rose의 피부 색상은 white이다.
Sam의 피부 색상은 black이다.
IV. 머신러닝 with Class
- 본 장에서는 Class를 활용하는 머신러닝에 대해 배울 예정이다.
- 이 때, 동일한 데이터를 사용하지만, Column명이 조금 상이한 경우 어떻게 대응하는지에 관해 작성한다.
(1) Colab + Drive 연동
- 먼저
weather.csv
와weather2.csv
파일 데이터를 구글 드라이브에 올려 놓는다. - 그 후, 구글 드라이브와 구글 코랩을 연동한다.
# Mount Google Drive
from google.colab import drive # import drive from google colab
ROOT = "/content/drive" # default location for the drive
print(ROOT) # print content of ROOT (Optional)
drive.mount(ROOT) # we mount the google drive at /content/drive
/content/drive
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
- 다음 데이터 파일이 있는 곳으로 경로를 이동한다.
# import join used to join ROOT path and MY_GOOGLE_DRIVE_PATH
from os.path import join
# path to your project on Google Drive
MY_GOOGLE_DRIVE_PATH = 'My Drive/Colab Notebooks/your/folder'
PROJECT_PATH = join(ROOT, MY_GOOGLE_DRIVE_PATH)
%cd "{PROJECT_PATH}"
!ls
/content/drive/My Drive/Colab Notebooks/your/folder
weather2.csv weather.csv
(2) 두개의 서로 다른 데이터 확인
- 각각의 데이터의 컬럼명이 어떻게 다른지 확인해본다.
data = pd.read_csv("weather.csv")
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 96453 entries, 0 to 96452
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Formatted Date 96453 non-null object
1 Summary 96453 non-null object
2 Precip Type 95936 non-null object
3 Temperature (C) 96453 non-null float64
4 Apparent Temperature (C) 96453 non-null float64
5 Humidity 96453 non-null float64
6 Wind Speed (km/h) 96453 non-null float64
7 Wind Bearing (degrees) 96453 non-null float64
8 Visibility (km) 96453 non-null float64
9 Loud Cover 96453 non-null float64
10 Pressure (millibars) 96453 non-null float64
11 Daily Summary 96453 non-null object
dtypes: float64(8), object(4)
memory usage: 8.8+ MB
data_columns = data.columns.tolist()
data_columns
['Formatted Date',
'Summary',
'Precip Type',
'Temperature (C)',
'Apparent Temperature (C)',
'Humidity',
'Wind Speed (km/h)',
'Wind Bearing (degrees)',
'Visibility (km)',
'Loud Cover',
'Pressure (millibars)',
'Daily Summary']
data2 = pd.read_csv("weather2.csv")
data2.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000 entries, 0 to 9999
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Formatted.Date 10000 non-null object
1 Summary 10000 non-null object
2 Precip.Type 10000 non-null object
3 Temperature..C. 10000 non-null float64
4 Apparent.Temperature..C. 10000 non-null float64
5 Humidity 10000 non-null float64
6 Wind.Speed..km.h. 10000 non-null float64
7 Wind.Bearing..degrees. 10000 non-null int64
8 Visibility..km. 10000 non-null float64
9 Loud.Cover 10000 non-null int64
10 Pressure..millibars. 10000 non-null float64
11 Daily.Summary 10000 non-null object
dtypes: float64(6), int64(2), object(4)
memory usage: 937.6+ KB
(3) Class 작성
- 머신러닝 클래스를 작성한다. 자료는
Medium
에 있는 코드를 적용했다.
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
class Model:
def __init__(self, datafile, model_type = None):
self.datafile = datafile
self.df = pd.read_csv(datafile)
data_columns = ['Formatted Date', 'Summary', 'Precip Type',
'Temperature (C)', 'Apparent Temperature (C)',
'Humidity', 'Wind Speed (km/h)', 'Wind Bearing (degrees)',
'Visibility (km)', 'Loud Cover', 'Pressure (millibars)','Daily Summary']
self.df.columns = data_columns
if model_type == 'rf':
self.user_defined_model = RandomForestRegressor()
else:
self.user_defined_model = LinearRegression()
def split(self, test_size):
X = np.array(self.df[['Humidity', 'Pressure (millibars)']])
y = np.array(self.df['Temperature (C)'])
self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(X, y, test_size = test_size, random_state = 42)
def fit(self):
self.model = self.user_defined_model.fit(self.X_train, self.y_train)
def predict(self, input_value):
if input_value == None:
result = self.user_defined_model.predict(self.X_test)
else:
result = self.user_defined_model.predict(np.array([input_value]))
return result
- 위 클래스는 4개의 함수로 구성되어 있다.
__init__
: 데이터를 불러오고 간단한Column명
처리를 진행했다.split
: 데이터 셋을 나누는 함수이다.fit
: 모형을 적합하는 함수이다.predict
: 예측 후 결과를 보여준다.
(4) 클래스 재사용성 확인
- 이렇게 작성된 클래스를
a_model
과b_model
을 확인해서 클래스 내의 함수를 재 사용해본다.
if __name__ == '__main__':
a_model = Model(datafile="weather.csv", model_type=None)
a_model.split(0.2)
a_model.fit()
print(a_model.predict([.9, 1000]))
print("Accuracy: ", a_model.model.score(a_model.X_test, a_model.y_test))
[6.83625473]
Accuracy: 0.39578560465686424
if __name__ == '__main__':
b_model = Model(datafile="weather2.csv", model_type=None)
b_model.split(0.3)
b_model.fit()
print(b_model.predict([.9, 1000]))
print("Accuracy: ", b_model.model.score(b_model.X_test, b_model.y_test))
[7.15581866]
Accuracy: 0.35698882811391797
- 위와 같이 클래스를 활용한다면, 앞으로는 위
6줄
만 추가하면, 추가적인weather
데이터가 들어와도, 훨씬 간결하게 소스코드를 작성할 수 있다.