Programming & Machine Learning/풀어쓰는 머신러닝
배치 방식과 온라인 방식의 모델 학습
Yamarae
2017. 8. 3. 01:50
배치방식, 온라인 방식에 대한 개념
일반적으로 대중화된, 아이리스 데이터 등으로 데스크탑에서 손쉽게 돌려볼 수 있는 머신러닝 자료들은
데이터를 통째로 IDE로 불러들인 다음 메모리상에 올려두고 작업하는 방식이었을 것이다.
모델을 학습함에 있어서도 모든 트레이닝 데이터셋의 결과값을 한번에 구한 뒤, 데이터셋과 쌍이 맞는
레이블과의 차이를 구해서 비용함수를 한번에 개선하는 방식의 학습을 n-iterative 하게 진행하였을 것이다.
하지만 머신러닝을 진행함에 있어서 데이터의 크기는 언제든지 늘어나게 된다. 아마 실전의 대부분은,
한 개의 데스크탑에서 불러올 수 없는 양의 데이터가 대부분일 것이다.
이런 경우 R 혹은 Python등의 툴로는 데이터를 메모리에 올려놓고 한번에 처리하기가 힘들어진다.
그렇게 되면 모델을 학습하는 경우에도 트레이닝 데이터를 쪼개서 여러 번 넣어야 하고,
프로그래머 식으로 말하자면 전자는 for loop를 한번 돌지만 후자는
'트레이닝 데이터들' 이라는 loop가 하나 더 생기는 것이라고 할 수 있다.
전자의 경우를 일괄 처리 방식, 일명 batch 방식이라고 한다. 후자는 online processing 혹은 mini batch라고 한다.
딥러닝의 영역으로 들어가게 된다면, 데이터의 양이 기하급수적으로 증가하기 때문에(딥러닝까지 가지 않더라도)
mini batch 시스템을 이용하여 모델을 학습하는 것은 거의 필수적인 일이 되어버렸다.
미니배치 기법을 사용한 파이썬 코드
### 텍스트 정제 및 token화
import numpy as np
import re
from nltk.corpus import stopwords
# import nltk
# nltk.download("stopwords")
stop = stopwords.words('english')
def tokenizer(text):
text = re.sub('<[^>]*>', '', text)
emoticons = re.findall('(?::|;|=)(?:-)?(?:\)|\(|D|P)', text.lower())
text = re.sub('[\W]+', ' ', text.lower()) + ' '.join(emoticons).replace('-', '')
tokenized = [w for w in text.split() if w not in stop]
return tokenized
### 문서를 스트리밍 형식으로 읽도록 하는 함수
def stream_docs(path):
with open(path, 'r', encoding='utf-8') as csv:
next(csv) # skip header
for line in csv:
text, label = line[:-3], int(line[-2])
yield text, label # yield 키워드를 사용하면 generator를 만들 수 있다
# generator가 잘 동작하는지 테스트
next(stream_docs(path='./movie_data.csv'))
### 미니배치를 얻어오는 함수
def get_minibatch(doc_stream, size):
docs, y = [], []
try:
for _ in range(size):
text, label = next(doc_stream)
docs.append(text)
y.append(label)
except StopIteration:
return None, None
return docs, y
### mini batch 방식으로 tf-idf 진행
from sklearn.feature_extraction.text import HashingVectorizer
from sklearn.linear_model import SGDClassifier
vect = HashingVectorizer(decode_error='ignore',
n_features=2**21,
preprocessor=None,
tokenizer=tokenizer)
clf = SGDClassifier(loss='log', random_state=1, n_iter=1)
doc_stream = stream_docs(path='./movie_data.csv')
### mini batch 방식으로 모델 학습
import pyprind
pbar = pyprind.ProgBar(45)
classes = np.array([0, 1])
for _ in range(45):
X_train, y_train = get_minibatch(doc_stream, size=1000)
if not X_train:
break
X_train = vect.transform(X_train)
clf.partial_fit(X_train, y_train, classes=classes)
pbar.update()