머신러닝 : 인간의 학습 능력과 같은 기능을 컴퓨터가 하게 만드는 기술
- 분류(classification) : 주어진 데이터 분류하기
- 회귀(regression) : 과거의 수치를 기반으로 미래의 수치 예측하기
- 클러스터링(clustering) : 데이터를 비슷한 집합으로 분류하기
- 추천(recommendation) : 관련된 데이터 제공하기
- 차원 축소(dimensionality reduction) : 데이터의 실질적인 특징과 관련 없는 특징 없애기
교사 학습(지도 학습)
- 데이터와 함께 정답이 주어짐
- 미지의 데이터를 예측
비교사 학습(비지도 학습)
- 정답 데이터가 주어지지 않음
- 미지의 데이터에서 규칙성을 발견
강화 학습
- 행동을 기반으로 정답인지 알려줌
- 데이터에서 최적의 답을 찾아냄
- 목표 결정
- 데이터 수집
- 데이터 가공
- 데이터 학습
- 머신러닝 방법 선택
- 매개변수 조정
- 데이터를 학습해서 모델 구축
- 모델 평가
- 충분한 정밀도가 나오지 않으면 4번으로 돌아감
- 업무에 활용
머신러닝은 일반적으로 일정량 이상의 데이터가 있어야 함.
크롤링, open API 등 이용 가능
데이터 수집 아이디어
- 트렌드 정보 수집 : SNS와 블로그
- 인터넷 쇼핑 상품 데이터 : 아마존, 네이버 쇼핑 등
- 금융 정보 : 환율, 주식, 금 가격 등
- 오픈 데이터 : 인구와 소비 등의 통계 자료, 기상 정보 등
- 이미지, 동영상, 음성 데이터 : 미디어 공유 사이트
- 사전 데이터 : 위키피디아 등
- 머신러닝 전용 데이터 세트
데이터는 머신러닝 시스템에 전달하기 전에 정규화 해야함
정규화 : 데이터를 일정한 규칙을 기반으로 가공해서 사용하기 쉽게 만드는 것
ex) 데이터의 최솟값과 최댓값을 확인한 뒤 데이터의 중심을 0에 두고 -1부터 1 사이의 범위로 데이터를 가공
- 다양한 머신러닝 알고리즘 제공
- 곧바로 머신러닝을 테스트할 수 있게 다양한 샘플 데이터 제공
- 머신러닝 결과를 검증하는 기능 있음
- 머신러닝에서 많이 사용되는 라이브러리와 함께 사용하기 쉬움
- BSD 라이선스라서 무료로 상업적 사용 가능
교사 학습 프로그램 제작
- 입력(X, Y)와 결과(X and Y)의 모든 패턴을 학습시킴
- 다시 입력(X, Y)의 모든 패턴을 줬을 때 제대로 된 결과(X and Y)를 내는지 평가
알고리즘 선택 도움 : scikit-learn algorithm cheat-sheet
알고리즘 선택 start - category - labeled data - <100K - Linear SVC
원래 데이터 수가 50 이하여서 category로 안 가지지만 무시하고 진행
결과적으로 Linear SVC 알고리즘 사용
# 라이브러리 읽어 들이기
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score
# 학습 전용 데이터와 결과 준비하기
# X, Y
learn_data = [[0,0], [1,0], [0,1], [1,1]]
# X and Y
learn_label = [0, 0, 0, 1]
# 알고리즘 지정하기 (LinearSVC)
clf = LinearSVC()
# 학습 전용 데이터와 결과 학습하기
clf.fit(learn_data, learn_label)
# 테스트 데이터로 예측하기
test_data = [[0,0], [1,0], [0,1], [1,1]]
test_label = clf.predict(test_data)
# 예측 결과 평가하기
print(test_data, '의 예측 결과 : ', test_label)
print('정답률 = ', accuracy_score([0, 0, 0, 1], test_label))
# 라이브러리 읽어 들이기
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score
# 학습 전용 데이터와 결과 준비하기
# X, Y
learn_data = [[0,0], [1,0], [0,1], [1,1]]
# X and Y
learn_label = [0, 1, 1, 0]
# 알고리즘 지정하기 (LinearSVC)
clf = LinearSVC()
# 학습 전용 데이터와 결과 학습하기
clf.fit(learn_data, learn_label)
# 테스트 데이터로 예측하기
test_data = [[0,0], [1,0], [0,1], [1,1]]
test_label = clf.predict(test_data)
# 예측 결과 평가하기
print(test_data, '의 예측 결과 : ', test_label)
print('정답률 = ', accuracy_score([0, 1, 1, 0], test_label)) # accuracy_score는 정답과 예측 결과를 매개 변수로 지정하면 정답률 반환
정답률이 낮게 나왔음, 아예 예측을 못하고 있는 상태
접근방법
- 알고리즘을 그대로 두고 매개변수를 조정
- 알고리즘을 변경
cheat-sheet에서 LinearSVC가 not working이고 text data가 아닌 상황이니 KNeighbors Classifier 알고리즘 제시
# 라이브러리 읽어 들이기
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
# 학습 전용 데이터와 결과 준비하기
# X, Y
learn_data = [[0,0], [1,0], [0,1], [1,1]]
# X and Y
learn_label = [0, 1, 1, 0]
# 알고리즘 지정하기 (KNeighborsClassifier)
clf = KNeighborsClassifier(n_neighbors = 1)
# 학습 전용 데이터와 결과 학습하기
clf.fit(learn_data, learn_label)
# 테스트 데이터로 예측하기
test_data = [[0,0], [1,0], [0,1], [1,1]]
test_label = clf.predict(test_data)
# 예측 결과 평가하기
print(test_data, '의 예측 결과 : ', test_label)
print('정답률 = ', accuracy_score([0, 1, 1, 0], test_label))
열 | 칼럼 이름 | 칼럼의 의미 | 값의 예 |
---|---|---|---|
1 | SepalLength | 꽃받침의 길이 | 5.1 |
2 | SepalWidth | 꽃받침의 너비 | 3.5 |
3 | PetalLength | 꽃잎의 길이 | 1.4 |
4 | PetalWidth | 꽃잎의 너비 | 0.2 |
5 | Name | 붓꽃의 품종 | iris-setosa |
붓꽃의 품종 |
---|
Iris-Setosa |
Iris-Versicolor |
Iris-Virginica |
- 붓꽃 데이터를 내려받은 'iris.csv'를 읽어옴
- 읽어 들인 붓꽃 데이터에서 꽃받침과 꽃잎의 너비와 길이 정보(데이터 부분), 붓꽃 품종 정보(레이블 부분)을 분리
- 전체 데이터 중에서 80%를 학습 전용 데이터, 20%를 테스트 전용 데이터로 분리
- 학습 전용 데이터를 사용해 학습하고 테스트 전용 데이터를 사용해 품종 분류를 제대로 하는지 확인
LinearSVC, KNeighborsClassifier를 사용했었으니 SVC 알고리즘 사용
import pandas as pd
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
# 붓꽃 데이터 읽어 들이기
iris_data = pd.read_csv('./data/iris.csv', encoding = 'utf-8')
# 붓꽃 데이터를 레이블과 입력 데이터로 분리하기
y = iris_data.loc[:,'Name']
x = iris_data.loc[:, ['SepalLength','SepalWidth','PetalLength','PetalWidth']]
# 학습 전용 데이터와 테스트 전용 분리하기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, train_size = 0.8, shuffle = True)
# 학습하기
clf = SVC()
clf.fit(x_train, y_train)
# 평가하기
y_pred = clf.predict(x_test)
print('정답률 : ',accuracy_score(y_test, y_pred))
from urllib.request import urlretrieve
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv'
savepath = './data/winequality-white.csv'
urlretrieve(url, savepath)
와인 데이터 내용
11가지 종류의 와인 성분 데이터가 있고 12번째 열에 와인 전문가가 평가한 품질 데이터가 있음
품질은 0 : 나쁨 ~ 10 : 좋음
치트 시트 사용 결과 랜덤 포레스트 알고리즘 선택
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
# 데이터 읽어 들이기
wine = pd.read_csv('./data/winequality-white.csv', sep = ';', encoding = 'utf-8')
# 데이터를 레이블과 데이터로 분리하기
y = wine['quality']
x = wine.drop('quality', axis = 1)
# 학습 전용과 테스트 전용 분리하기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)
# 학습하기
model = RandomForestClassifier()
model = model.fit(x_train, y_train)
# 평가하기
y_pred = model.predict(x_test)
print(classification_report(y_test, y_pred))
print('정답률 : ', accuracy_score(y_test, y_pred))
classification_report() : 분류와 관련된 리포트를 만들어 출력
- precision : 정답률 (정답과 예측 레이블 데이터 중에서 정답인 것의 비율)
- recall : 재현율 (실제로 정답인 것 중에서 정답인 것과 예측인 것의 비율을 나타냄, 실제 정답의 비율로 볼 수 있음)
- f1-score : 정답률과 재현율의 조화 평균
- support : 정답 레이블 데이터 수
위에서 'UndefinedMetricWarning'이라고 경고 메세지가 출력되는데 이는 일부 레이블에 데이터 분류가 돼 있지 않다는 의미
현재 와인 데이터는 와인의 품질을 0부터 10까지 11등급으로 분류
와인 데이터의 설명을 보면 저장된 데이터의 등급 수 분포가 다를 수 있다고 나와 있음
# quality 데이터가 몇 개씩 있는지 확인
import matplotlib.pyplot as plt
import pandas as pd
# 데이터 읽어 들이기
wine = pd.read_csv('./data/winequality-white.csv', sep = ';', encoding = 'utf-8')
# 품질 데이터별로 그룹을 나누고 수 세어보기
count_data = wine.groupby('quality')['quality'].count()
print(count_data)
# 수를 그래프로 시각화
count_data.plot()
plt.show
품질 데이터 대부분이 5~7이고, 이외의 데이터는 별로 없음
이처럼 데이터 수의 분포 차가 큰 데이터를 '불균형 데이터'라고 부름
그래서 11등급의 데이터를 '4 이하', '5와 7 사이', '8 이상'이라는 3개로 분류
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
# 데이터 읽어 들이기
wine = pd.read_csv('./data/winequality-white.csv', sep = ';', encoding = 'utf-8')
# 데이터를 레이블과 데이터로 분리하기
y = wine['quality']
x = wine.drop('quality', axis = 1)
# y 레이블 변경하기
new_list = []
for v in list(y):
if v <= 4:
new_list += [0]
elif v <= 7:
new_list += [1]
else:
new_list += [2]
y = new_list
# 학습 전용과 테스트 전용 분리하기
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)
# 학습하기
model = RandomForestClassifier()
model = model.fit(x_train, y_train)
# 평가하기
y_pred = model.predict(x_test)
print(classification_report(y_test, y_pred))
print('정답률 : ', accuracy_score(y_test, y_pred))
train_test_split(arrays, test_size, train_size, random_state, shuffle, stratify)
Parameter
- arrays : 분할시킬 데이터를 입력 (리스트, nparray, dataframe 등등)
- test_size : 테스트 데이터셋의 비율(float)이나 갯수(int) (default = 0.25)
- train_size : 학습 데이터 셋의 비율(float)이나 갯수(int) (default = test_size의 나머지)
- random_state : 데이터 분할시 셔플이 이루어지는데 이를 위한 시드값 (int나 RandomSatate로 입력)
- shuffle : 셔플 여부 설정 (default = True)
- stratify : 지정한 Data 의 비율을 유지, 원래 데이터셋의 비율을 유지해서 나눠 나눠진 데이터셋들도 원래 데이터셋과 같은 비율을 가진다
Return
- X_trin, X_test, Y_train, Y_test : arrays에 데이터와 레이블을 둘 다 넣었을 경우의 반환, 데이터와 레이블의 순서쌍 유지
- X_train, X_test : arrays에 레이블 없이 데이터만 넣었을 경우의 반환
- 정답률 반환
- 예측 결과 반환
- 클래스를 구분하는 분류 문제에서, 각 클래스를 잘 구분하는 선을 그어주는 방식
- 두 클래스의 가운데 선을 긋고, 가장 가까이 있는 점들과의 거리가 가장 큰 직선을 찾음
- 이때 가장 가까운 점들을 Support Vector라고 하고 찾은 직선과 서포트 벡터 사이의 거리를 최대 마진이라 함
- 마진을 최대로 하는 서포트 벡터와 직선을 찾는 것이 목표
- 선형 분류에 특화
- 직선, 평면으로 선을 긋는다
- 가장 가깝게 위치하는 멤버로 분류하는 방식
- 임의의 k개의 이웃을 고려
- 하나 이상의 이웃 데이터 포인트를 고려할 때, 다수결 이용
- 여러 개의 분류 트리를 사용해 성능을 올린 앙상블 알고리즘 중 하나
- 학습 전용 데이터를 샘플링해서 다수의 결정 트리를 생성하고 생성된 결정 트리를 기반으로 다수결로 결과를 결정하는 방식