ITS's Dev Story

오늘은 나이브 베이스 확률이론을 사용해서 스팸메일 필터링 소프트웨어를 동작시키고 구현해 보았다.

먼저, 텍스트 토큰을 생성한다. 나는 아래와 같이 생성하였다.

그 다음, 이메일 데이터 집합 (예제 파일로 제공하는 샘플 데이터이다.)을 꺼낸다. 그 후, 파일 구문 분석 소스와 전체스팸 검사 함수를 Python으로 만들어 보았다. 

-------------------------------------------------------------------------------------------

* Numpy 기계학습의 모든 문서는 제가 머신러닝을 공부하고, 제 프로젝트에 필요한 알고리즘을 찾기 위해 정리하는 일종의 '요점정리 노트' 입니다. 혹여나 오해 없으시기 바랍니다. (2016.03.14 추가)

-------------------------------------------------------------------------------------------

소스코드는 아래와 같다.

def textParse(bigString):
    import re
    listOfTokens = re.split(r'\W*', bigString)
    return [tok.lower() for tok in listOfTokens if len(tok) > 2] 
    
def spamTest():
    docList=[]; classList = []; fullText =[]
    for i in range(1,26):
        wordList = textParse(open('email/spam/%d.txt' % i).read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList = textParse(open('email/ham/%d.txt' % i).read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
    vocabList = createVocabList(docList)
    trainingSet = range(50); testSet=[]          
    for i in range(10):
        randIndex = int(random.uniform(0,len(trainingSet)))
        testSet.append(trainingSet[randIndex])
        del(trainingSet[randIndex])  
    trainMat=[]; trainClasses = []
    for docIndex in trainingSet:
        trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))
    errorCount = 0
    for docIndex in testSet:      
        wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
        if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
            errorCount += 1
            print "classification error",docList[docIndex]
    print 'the error rate is: ',float(errorCount)/len(testSet)


맨 마지막 실행 화면은 사진으로 못 찍었지만 글로 써 본다.

>>> bayes.spamTest()

the error rate is : 0.0

초등학교 5학년 때 서울교대 영재원을 다니면서 오바마와 박근혜 대통령의 연설문 데이터에서 가장 많이 쓰인 단어를 추출해내는 프로그램을 교수님이 만들어 보라고 하신 적이 있다. 단순히 기술만 생각한다면 이 수업은 별 효과가 없을 것이라고 생각한다. 아마도 머신러닝도 그럴 것이다.

오늘은 여기까지 하기로 했다.

오늘은 타작마당에서 열리는 로봇 파티에 다녀 왔다. 이곳의 로봇들은 우리가 생각하는 기계적인 로봇이 아니라 인간들이 서로 소통할 수 있도록 도와주는 매개체로서의 감성 로봇들이다. 좀 이상하고 상상력을 자극시키는 로봇들이 많아 참 재미있게 관람하였다. 1시간 여 전시를 관람하면서 인간이 이런 감성로봇과 소통을 하면서 많은 즐거움과 위안을 얻을 수 있겠다는 생각도 들었지만, 한편으로는 인간들 사이의 소통과 대화의 부재에 대해서 다시 한번 생각해 보는 시간이 되었다.

언론에서도 많이 나왔던 드링키는 혼자서 술을 마실 때 술친구가 있으면 좋겠다라는 아이디어에서 나온 것이라 한다. 내가 보기에는 혼자서 드링키와 술을 마시는 것도 좋겠지만 여럿이 모이는 파티에서 드링키와 함께 한다면 분위기를 더욱더 업시켜 화기애애하게 하고 모두를 웃게 해주는 소통의 역할을 할 것 같다는 생각이 들었다.

나는 로봇이 인간과의 소통을 대신하여 인간을 위로해 주고, 인간과 정을 나누며, 인간이 의존하는 로봇이 되기(즉, 로봇이 인간의 역할을 대신할 수 있다.) 보다는 인간들과의 소통을 도와주는 로봇이기를 바라는 마음이 있다.

▲ SK텔레콤 통섭인재양성소 타작마당

▲ 욕쟁이 할머니 [그랜봇] 사람이 말을 걸면 할머니 로봇이 대답한다.

▲ 아메리칸 19 인형

▲ 드럼 연주 로봇 (+가야금)

▲ 로봇 메이킹 FAB

▲ 쓰레기 로봇 (Umbra Infractus)

▲ 임신한 로봇 '신인류의 초상' (자세히 살펴보면 오른쪽 다리에 또 다른 로봇이 있다.)

▲ 최재필 작가님의 '우리 에그'

▲ Tasko Inc의 MMI 로봇밴드 로봇

▲ 박은찬 작가님의 '드링키' 로봇

▲ 공장에서 돌아가는 로봇. 실행 시 '공존'이라는 글자를 쓴다.

▲ 김용승 작가님의 쓰레기를 뱉어내는 로봇 '보미'. 로봇은 인간의 노동력만을 대신하는 것이 아니라 우리에게 재미와 즐거움을 줄 수도 있다.

▲ SK텔레콤의 음성인식 기술을 사용한 홍상화 작가님의 반려로봇 '동행'. 말을 걸면 대답을 한다.


오늘은 머신러닝 알고리즘인 나이브 베이스 확률이론에 대해 공부해 보기로 하였다. 이 방식은 데이터가 각 분류에 속할 확률을 구하고, 이중 가장 높은 확률을 가지는 분류를 선택하는 것이다. 나는 오늘 이 알고리즘을 사용해서 문서를 분류하는 알고리즘을 만들어 보았다.

먼저, 실험을 위해 몇개의 예제 데이터를 생성한다. 그리고 모든 문서에 있는 모든 유일한 단어 목록을 생성한다. 마지막으로 어휘 목록을 만든 다음 단어가 존재하는지 아닌지를 구별하는 함수를 사용할 것이다.

-------------------------------------------------------------------------------------------

* Numpy 기계학습의 모든 문서는 제가 머신러닝을 공부하고, 제 프로젝트에 필요한 알고리즘을 찾기 위해 정리하는 일종의 '요점정리 노트' 입니다. 혹여나 오해 없으시기 바랍니다. (2016.03.14 추가)

-------------------------------------------------------------------------------------------

내가 만들어 본 소스 코드는 아래와 같다.

from numpy import *

def loadDataSet():
    postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                 ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                 ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                 ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                 ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0,1,0,1,0,1]
    return postingList,classVec
                 
def createVocabList(dataSet):
    vocabSet = set([])
    for document in dataSet:
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else: print "the word: %s is not in my Vocabulary!" % word
    return returnVec

직접 확인해 보기 위해 아래와 같이 실습을 해 본다.

오늘은 여기까지 하기로 했다.