Numpy를 이용한 기계학습 프로젝트 - 2
이번에는 k-최근접 이웃 알고리즘을 Python으로 시연해 보기로 하였다. k-최근접 이웃 알고리즘의 장점은 높은 정확도와 데이터에 대한 가정이 없다는 것이고, 단점은 계산 비용이 높고 많은 리소스를 요구한다는 것이다. 흔히 매우 간단한 기계학습 알고리즘에 속한다고 한다.
-------------------------------------------------------------------------------------------
* Numpy 기계학습의 모든 문서는 제가 머신러닝을 공부하고, 제 프로젝트에 필요한 알고리즘을 찾기 위해 정리하는 일종의 '요점정리 노트' 입니다. 혹여나 오해 없으시기 바랍니다. (2016.03.14 추가)
-------------------------------------------------------------------------------------------
훈련 데이터는 각각이 항목 분류명을 갖는 다차원 특징 공간에서의 벡터이다. 알고리즘의 훈련 단계는 오직 훈련 표본의 특징 벡터와 항목 분류명을 저장하는 것이다. 분류 단계에서 k는 사용자 정의 상수이고 분류명이 붙지 않은 벡터(질의 또는 검증점)는 k개의 훈련 표본 사이에서 가장 빈번한 분류명을 할당함으로써 분류된다. 연속 변수에서 가장 흔하게 사용되는 거리 척도는 유클리드 거리이다. 문자 분류와 같은 이산 변수의 경우 중첩 거리(또는 해밍 거리)와 같은 다른 척도가 사용될 수 있다. 예를 들어 유전자 표현 미세 배열 데이터의 경우, k-NN은 피어슨과 스피어만 같은 상관 계수를 사용해 왔다.종종 거리 척도가 큰 여백 최근접 이웃이나 이웃 성분 분석과 같은 특별한 알고리즘으로 학습된다면 k-NN의 분류의 정확성을 상당히 향상시킬 수 있다. (위키피디아 인용)
우선, kNN을 이용한 여러 프로젝트들을 구현하기 위해 파이썬 파일을 생성하고, 소스 코드를 추가할 것이다. 내가 추가한 kNN의 모듈의 소스코드는 아래와 같다.
from numpy import * import operator from os import listdir def classify0(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] diffMat = tile(inX, (dataSetSize,1)) - dataSet sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) distances = sqDistances**0.5 sortedDistIndicies = distances.argsort() classCount={} for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] def createDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) labels = ['A','A','B','B'] return group, labels def file2matrix(filename): fr = open(filename) numberOfLines = len(fr.readlines()) returnMat = zeros((numberOfLines,3)) classLabelVector = [] fr = open(filename) index = 0 for line in fr.readlines(): line = line.strip() listFromLine = line.split('\t') returnMat[index,:] = listFromLine[0:3] classLabelVector.append(int(listFromLine[-1])) index += 1 return returnMat,classLabelVector def autoNorm(dataSet): minVals = dataSet.min(0) maxVals = dataSet.max(0) ranges = maxVals - minVals normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] normDataSet = dataSet - tile(minVals, (m,1)) normDataSet = normDataSet/tile(ranges, (m,1)) return normDataSet, ranges, minVals def datingClassTest(): hoRatio = 0.50 #hold out 10% datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') normMat, ranges, minVals = autoNorm(datingDataMat) m = normMat.shape[0] numTestVecs = int(m*hoRatio) errorCount = 0.0 for i in range(numTestVecs): classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3) print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]) if (classifierResult != datingLabels[i]): errorCount += 1.0 print "the total error rate is: %f" % (errorCount/float(numTestVecs)) print errorCount def img2vector(filename): returnVect = zeros((1,1024)) fr = open(filename) for i in range(32): lineStr = fr.readline() for j in range(32): returnVect[0,32*i+j] = int(lineStr[j]) return returnVect def handwritingClassTest(): hwLabels = [] trainingFileList = listdir('trainingDigits') m = len(trainingFileList) trainingMat = zeros((m,1024)) for i in range(m): fileNameStr = trainingFileList[i] fileStr = fileNameStr.split('.')[0] classNumStr = int(fileStr.split('_')[0]) hwLabels.append(classNumStr) trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr) testFileList = listdir('testDigits') errorCount = 0.0 mTest = len(testFileList) for i in range(mTest): fileNameStr = testFileList[i] fileStr = fileNameStr.split('.')[0] classNumStr = int(fileStr.split('_')[0]) vectorUnderTest = img2vector('testDigits/%s' % fileNameStr) classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr) if (classifierResult != classNumStr): errorCount += 1.0 print "\nthe total number of errors is: %d" % errorCount print "\nthe total error rate is: %f" % (errorCount/float(mTest))
-----------------------------------------------------------------------
나는 이 중, 내가 옛날에 C#으로 개발했었던 Handwriting 알고리즘을 개발하고 싶었다. 이를 kNN을 활용해서 테스트를 해 보았다. 이미지 파일은 아래와 같다.
바이너리 이미지를 쉽게 다루도록 하기 위해 텍스트로 변환하였다.
이를 실제로 돌려 보면 아래와 같이 된다.
이 소스에서는 2000여개 Data 중 11개 오차가 발생했다. (1.2% 오류율)
이 실험을 해 보면서 kNN 알고리즘은 간단하며 데이터를 분류하는 데 효과적인 알고리즘이고, 데이터 구조에 대한 어떠한 정보도 알 수 없다는 것이 가장 큰 단점이라는 결론을 내리게 되었다. 오늘은 여기까지 하기로 하였다. 다음에는 kNN을 이용한 다른 시험도 해 보도록 해야 겠다.
'Project > Dev Story' 카테고리의 다른 글
Numpy를 이용한 기계학습 프로젝트 - 5 (0) | 2016.01.09 |
---|---|
Numpy를 이용한 기계학습 프로젝트 - 4 (0) | 2016.01.08 |
Numpy를 이용한 기계학습 프로젝트 - 3 (0) | 2016.01.07 |
[MathProject] C언어로 약수 계산기 만들기 & Github 업로드 (0) | 2016.01.04 |
Numpy를 이용한 기계학습 프로젝트 테스트 - 1 (0) | 2016.01.04 |
[MathProject] C언어로 약수 계산기 만들기 & Github 업로드
이번에는 중학교 1학년 수학에 나오는 약수를 구하는 방법을 C언어로 만들어 보았다.
소스 코드는 아래와 같다.
#include <stdio.h>
int main()
{
int i, number;
printf("Input number");
scanf("%d", &number);
for(i=1; i<=number; i++)
{
if(number%i==0)
{
printf("%d ", i);
}
}
printf("\n");
}
이 소스코드는 자연수를 입력하면 for문으로 반복하여 숫자와 for문 카운트의 나머지가 0이 나오면 숫자를 출력하도록 만든 소스 코드이다. 이를 계속 반복하여 약수를 구하도록 만들었다.
그리고, Github에 내가 만든 소스코드를 업로드하였다. 방법은 아래와 같다.
먼저, Git을 설치한다. https://git-scm.com/download/win에서 Windows Git을 다운받는다.
다 설치한 후 Git Bash를 실행 > 사용자 이름과 메일 주소를 설정한다. 설정 Command는 아래와 같다.
$ git config --global user.name "이름"
$ git config --global user.email "이메일"
커맨드를 입력한 후 다양한 명령어 출력을 읽기 쉽게 하기 위해 아래 명령어를 친다.
$git config --global color.ui auto
그 다음, ssh key를 생성해 Github에 등록해야 한다. 이를 위해
$ssh-keygen -t rsa -C "이메일" 을 친다. 정상적으로 과정이 완료되면
id_rsa.pub라는 공개 키가 생성된다. 이를 메모장으로 열고 전부 복사해서 Github 환경설정 > SSH Keys 부분에 붙여넣기 한다. 이후 실제로 동작하는지 확인하기 위해 $ssh -T git@github.com을 입력한다.
정상적으로 처리가 되었다면, Hi itsss! You've successfully... 라는 메시지가 출력될 것이다.
이후 Github에서 리포지토리 작성을 해야 하는데 이름은 아무거나 해도 된다. 이미 있다면 그냥 그걸로 해도 된다. 우선 Code를 작성한 후 그 코드를 사용자 디렉토리 (windows를 기준으로 현재 로그인된 사용자이름이 itsc인 경우 시작-ITSC로 가면 나오는 디렉토리)에 붙여 넣는다.
이후 이 명령어를 순차적으로 입력한다. (자신의 리포지토리에 들어가서 Code 내용을 보는게 더 정확함)
echo # 리포지토리 이름 >> 파일 이름
git init
git add 파일 이름
git commit -m "커밋 내용"
git remote add origin https://github.com/사용자 이름/리포지토리 이름.git
git push -u origin master
명령어를 다 입력하면 Github의 ID와 PW를 알려 달라고 한다. 알려 준 후 Github에 가서 확인해 보면 자신의 소스 코드가 올라간 것을 볼 수 있다.
오늘은 여기까지 하기로 했다.
'Project > Dev Story' 카테고리의 다른 글
Numpy를 이용한 기계학습 프로젝트 - 5 (0) | 2016.01.09 |
---|---|
Numpy를 이용한 기계학습 프로젝트 - 4 (0) | 2016.01.08 |
Numpy를 이용한 기계학습 프로젝트 - 3 (0) | 2016.01.07 |
Numpy를 이용한 기계학습 프로젝트 - 2 (0) | 2016.01.05 |
Numpy를 이용한 기계학습 프로젝트 테스트 - 1 (0) | 2016.01.04 |
Numpy를 이용한 기계학습 프로젝트 테스트 - 1
최근 머신러닝을 위한 프로젝트를 준비하고 있다. 이를 위해 Coursera에서 MOOC를 수강하며 R 프로그래밍 등의 머신러닝 스킬들을 익힐 수 있었다. 하지만 이로만은 충분치 않아 머신러닝 책을 사서 책에 나오는 내용들을 공부하면서 이를 블로그에 꾸준히 게재하려고 한다.
-------------------------------------------------------------------------------------------
* Numpy 기계학습의 모든 문서는 제가 머신러닝을 공부하고, 제 프로젝트에 필요한 알고리즘을 찾기 위해 정리하는 일종의 '요점정리 노트' 입니다. 혹여나 오해 없으시기 바랍니다. (2016.03.14 추가)
-------------------------------------------------------------------------------------------
언어는 수학 라이브러리들을 더 쉽게 연결하고, 인기가 많으면서 오픈소스이며, 내 프로젝트를 쉽게 공유하기 위해 Python이라는 언어를 선택했다.
* Python이란? 파이썬(Python)은 1991년 프로그래머인 귀도 반 로섬(Guido van Rossum)이 발표한 고급 프로그래밍 언어로, 플랫폼 독립적이며 인터프리터식, 객체지향적, 동적 타이핑(dynamically typed) 대화형 언어이다. (위키피디아 인용)
우선 기계학습을 하기 위해 필요한 라이브러리인 numpy를 다운받아야 한다. 지금 내가 글을 쓰고 있는 시점에서는 numpy for python 3.5버전이 아직 출시되지 않았다. 그래서 파이썬 2.7버전을 다운받기로 하였다. 이후 numpy를 다운받기 위해 Sourceforge에 들어간다.
다운로드 링크는 이와 같다. (http://sourceforge.net/projects/numpy/files/NumPy/1.10.2/)
설치 후에는 아래와 같이 from numpy import * 를 파이썬 커맨드에 쳐 제대로 설치가 되었는지 확인한다.
이후 위 사진과 같이 numpy 함수가 제대로 작동하는지 테스트 해 보았다. 일단 여기까지 하고 이따가 더 올리기로 하겠다.
'Project > Dev Story' 카테고리의 다른 글
Numpy를 이용한 기계학습 프로젝트 - 5 (0) | 2016.01.09 |
---|---|
Numpy를 이용한 기계학습 프로젝트 - 4 (0) | 2016.01.08 |
Numpy를 이용한 기계학습 프로젝트 - 3 (0) | 2016.01.07 |
Numpy를 이용한 기계학습 프로젝트 - 2 (0) | 2016.01.05 |
[MathProject] C언어로 약수 계산기 만들기 & Github 업로드 (0) | 2016.01.04 |