ITS's Dev Story

오늘은 오랜만에 아르코미술관에 갔다. 무진 형제와 함께 미디어 아트를 만들어 보는 것인데 무진 형제는 제일 큰 누나가 문학을 전공했고, 둘째 누나가 미술 (키네틱 아트)을 전공했고, 막내 남동생이 사진을 전공했는데 이 세 사람이 어떻게 융합적으로 전공이 아닌 미디어 아트를 표현했을까 궁금했다. 

그들의 작품인 '결구' 는 자신들의 생각을 표현하여 관객들에게 알리기 보단, 관객이 질문을 던지고 해답을 찾아가는 형태의 작품인 것 같았다. 미디어 아트는 어떻게 해석하느냐에 따라 다양한 결론을 얻을 수 있는 것 같아 재미있다.

2시간 안에 스토리를 작성하고, 촬영과 편집까지 마쳐야 해서 완성도는 좀 떨어지지만, 한번 만들어 보니 미디어 아트가 어렵고 난해한 것이 아니라, 자유롭고 재미있게 표현하는 것이라고 생각하게 되었다. 우리 팀은 둘을 빼고는 처음 만나는 사이라 처음에는 어색하고 서먹하여 자기 표현에 소극적이었으나, 금방 친해져 다른 팀에 비해 완성도가 높은 작품을 만들 수 있었다. 작품의 이름은 'Number One' 이다.

이 작품은 우리의 현실을 비판하고, 다른 사람들은 그 현실을 어떻게 바라보는지 그런 접근에서 만들게 되었다. 음악은 발로 만들었다.


제작은 카메라를 이용해 약 100컷의 사진을 찍어 Adobe Premier에 올리는 형식으로 제작하였다.

'예술은 삶을 예술보다 더 흥미롭게 하는 것'이다.


'My Library' 카테고리의 다른 글

동물 농장을 읽고  (0) 2016.04.04




오늘 Statistical Inference, Regression Models 이 두 강좌를 수료하였다. 

Data Science 강좌들은 이번년도에 내가 개발하고 있는 프로젝트를 위해 (자세한 내용은 만든 후 공지할 것임) 공부하고 있다. 이 강좌에 나온 기술들이 일부분 쓰일 것이다.

먼저, Statistical Inference는 4주 동안 강좌를 듣고 하나의 데이터 도출 결과를 R 소스코드와 시각화 자료와 함께 논문으로 만들어 제출하는 과정이다. 수료 요건을 충족하였지만, 컴퓨터에 문제가 있어 인증을 못한 것으로 인해 다시 제출해 성적처리를 받아 수료하였다.

2016년도에 첫번째로 들은 강좌인 Reproducible Research보다 성적이 높다. 총성적 100점을 맞을 수 있었지만 Quiz 2를 86점을 맞아 95.4점으로 점수가 내려갔다. 아쉽지만 다음에 더 잘 해보기로 다짐했다.

그 다음, Regression Models는 mtcars Data를 가지고 하나의 R 요약 자료를 제출하는 과정이다. 그 중 나의 Report를 평가한 사람들의 반응은 아래와 같았다. 

얼마 전에 인증 문제로 Statistical Inference 강좌에서 사람들의 채점 결과(?) 를 날려 먹은 적이 있다. 그 강좌의 평가에서는 "디자인이 마음에 안 들지만 점수를 깎지는 않겠다", "폰트 사이즈가 좀 더 컸으면 좋겠다" 등 다양한 평가들이 나왔었다.

여기서는 성적을 Statistical Inference보다 0.1%(...) 높은 95.5점을 취득하였다. 


오늘 2016년도 첫 번째 Coursera 강좌를 수료하였다. 수료증은 기간이 안 되어 2월 18일에 나온다. 

이제부터 Coursera가 Machine Learning 강좌 뿐만이 아닌 대부분의 강좌들이 모두 On-Demand Course로 전환되었다고 한다. 이 제도는 Coursera에서 형식적인 수료증은 정해진 기간에 받지만, 수료는 자신의 실력에 따라 조기수료를 할 수 있도록 만든 시스템이다. 

지난 2015년도 강좌 (일부 On-Demand Course 제외)들은 퀴즈를 3번 틀리면 그 퀴즈는 재시험을 칠 수 없지만 (물론 내가 재시험을 쳤다는 이야기는 아니다. ㅎㅎ) On-Demand Course로 지정된 강좌들은 Quiz를 3번 틀릴 시, 8시간을 기다린 후 다시 틀린 횟수를 리셋되도록 만들었다. 즉, 학생들에게 더 많은 수료의 기회를 주기 위함이다.

또한, 조기수료를 하기 위해 도전하는 사람들이 있지만 그 수가 적어 서로의 과제를 평가할 학생이 부족해 수료가 안되는 경우가 있다. 이번에 내가 그랬다. 그래서 1월 13일에 할 수 있는 수료를 28일이 되어서야 할 수 있었다.

이번에 내가 들은 Reproducible Research 강좌는 모아진 데이터 결과를 가지고 다시 그 데이터를 연구 및 재가공하는 강좌이다. 미국의 환경 데이터를 주면 이를 이용해서 통계 및 재가공을 위한 R 코드 및 결과를 GitHub에 업로드하는 방식이다. 프로젝트가 딱 2개지만 아직 접하지 못한 수학공식들이 쓰여 다른 강좌들보다는 약간 어려웠던 면들이 있었다.

오늘은 로지스틱 회귀를 이용한 말의 배앓이 치사율 평가를 위한 로지스틱 회귀를 사용하는 예제를 풀어 보기로 하였다. 우선, 데이터에서 누락된 값이 있기 때문에 이를 다루는 효과적인 방법들이 필요하게 된다. 이에는 몇 가지 선택사항이 있다. 선택사항은 아래와 같다.

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

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

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

* 사용 가능한 모든 데이터에서 속성의 평균값 사용

* 알려지지 않은 값은 특별한 값으로 채우기

* 혹은 무시

* 유사한 아이템들의 평균값 사용

* 값을 예측하기 위한 기계학습 알고리즘 사용

이 경우, 사용하게 될 데이터 집합은 전처리가 된것이다. 따라서 기존의 알고리즘으로 쉽게 사용할 수 있다는 장점이 있다. 내가 사용하는 로지스틱 회귀 분류 함수 소스코드는 아래와 같다.


def classifyVector(inX, weights):
    prob = sigmoid(sum(inX*weights))
    if prob > 0.5: return 1.0
    else: return 0.0

def colicTest():
    frTrain = open('horseColicTraining.txt'); frTest = open('horseColicTest.txt')
    trainingSet = []; trainingLabels = []
    for line in frTrain.readlines():
        currLine = line.strip().split('\t')
        lineArr =[]
        for i in range(21):
            lineArr.append(float(currLine[i]))
        trainingSet.append(lineArr)
        trainingLabels.append(float(currLine[21]))
    trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 1000)
    errorCount = 0; numTestVec = 0.0
    for line in frTest.readlines():
        numTestVec += 1.0
        currLine = line.strip().split('\t')
        lineArr =[]
        for i in range(21):
            lineArr.append(float(currLine[i]))
        if int(classifyVector(array(lineArr), trainWeights))!= int(currLine[21]):
            errorCount += 1
    errorRate = (float(errorCount)/numTestVec)
    print "the error rate of this test is: %f" % errorRate
    return errorRate

def multiTest():
    numTests = 10; errorSum=0.0
    for k in range(numTests):
        errorSum += colicTest()
    print "after %d iterations the average error rate is: %f" % (numTests, errorSum/float(numTests))
 

그 다음, 파이썬 쉘에 아래와 같이 입력한다.

내가 사용하는 데이터 값은 아래와 같다.

누락된 값은 아래와 같이 0.35가 나왔다.

이는 누락된 값이 30% 이상이므로 나쁘지 않은 결과이다. colicTest() 함수에서 반복 횟수를 변경할 수 있고, 오류율 20%에 근접하기 위해 stochGradAscent1()에서 alpha의 크기를 변경할 수 있다.

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

오늘은 머신러닝 중 최적화 알고리즘, 로지스틱 회귀에 대해 탐구해 보기로 하였다. 가장 빠른 시간에 A에서 B로 가기 위해서는 가장 빨리 갈 수 있는 길을 컴퓨터가 찾아야 할 것이다. 이러한 것을 처리할 수 있는 가장 효과적인 방법이 바로 최적화 알고리즘이다.

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

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

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

중학교 1학년 수학에서 처음으로 좌표평면을 이용한 함수를 배우게 되는데, 이도 이 알고리즘과 연관이 있다. 데이터가 표시된 좌표평면을 가로지르는 선을 최적선이라고 하고, 이 선을 그리는 것을 회귀라고 한다고 한다. 우선 나는 로지스틱 회귀 모델을 사용해서 기울기 상승 최적화 함수를 탐구해 보기로 하였다. 소스코드는 아래와 같다.

 

from numpy import *

def loadDataSet():
    dataMat = []; labelMat = []
    fr = open('testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
        labelMat.append(int(lineArr[2]))
    return dataMat,labelMat

def sigmoid(inX):
    return 1.0/(1+exp(-inX))

def gradAscent(dataMatIn, classLabels):
    dataMatrix = mat(dataMatIn)             
    labelMat = mat(classLabels).transpose() 
    m,n = shape(dataMatrix)
    alpha = 0.001
    maxCycles = 500
    weights = ones((n,1))
    for k in range(maxCycles):              
        h = sigmoid(dataMatrix*weights)     
        error = (labelMat - h)             
        weights = weights + alpha * dataMatrix.transpose()* error #matrix mult
    return weights


이후 매스플롯라이브러리를 사용해서 직접 풀룻하는 코드이다. 소스코드는 아래와 같다.

 
def plotBestFit(weights):
    import matplotlib.pyplot as plt
    dataMat,labelMat=loadDataSet()
    dataArr = array(dataMat)
    n = shape(dataArr)[0] 
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    for i in range(n):
        if int(labelMat[i])== 1:
            xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
        else:
            xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    ax.scatter(xcord2, ycord2, s=30, c='green')
    x = arange(-3.0, 3.0, 0.1)
    y = (-weights[0]-weights[1]*x)/weights[2]
    ax.plot(x, y)
    plt.xlabel('X1'); plt.ylabel('X2');
    plt.show()


▲ Python Shell Code

▲ 플롯으로 출력한 모습

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


오늘은 Coursera에서 Exploratory Data Analysis를 수료하였다.

이 수업은 Coursera의 특색, 동료 평가 (Peer Evaluation)의 특징을 제대로 살려, 정확한 데이터를 추출할 수 있도록 가이드를 제시해 주는 수업이었다. 조금 자랑이긴 하지만 나는 이 두 평가에서 만점을 맞았고, 개인적으로 굉장히 실력이 늘고 발전했다는 생각이 든다. 지금까지 해본 코세라 수업 중에는 동료 평가가 가장 부각된 수업이었다.

코세라의 전체적인 수업 형태를 보면 과제를 의무적으로 Github로 제출하도록 하여 소셜 코딩을 스스로 입문할 수 있도록 돕고, Codeskulptor와 R 등의 신형 기술을 빨리 접해볼 수 있는 기회 (한국 기준)를 많이 준다. 현재 미국의 여러 스타트업들에서는 이러한 기술을 사용할 줄 아는 능력을 굉장히 중요시 평가하고 있고, 이력서에 있는 학력 란에 자신이 취득한 Coursera 수료증을 기입할 수 있도록 하였다.

내가 지금까지 취득한 인증 수료증 (이력이나 학력으로 인정되는)은 아래와 같다. 수료증에 의미를 두고 공부한 것이 아니여서 모두 인증 수료증을 받진 않았는데 그 부분이 좀 아쉽다. 원래 인증 수료증을 취득하려면 미화로 49달러를 내야 한다. 하지만 나는 학생의 신분에서 49달러를 매 강좌마다 지불하기에는 너무 벅차다.

지금까지 취득한 모든 수료증 (인증 수료증 포함) 은 아래와 같다.

1년 전부터 시작해 지금까지 총 10개의 수료증을 취득하였다. 어려운 강좌는 중간에 재수강을 해서 수료증을 시간대비 많이 취득하지는 못했다. 하지만 점수는 거의 모두 90점대 이상이다.

나는 훌륭한 교육의 기회는 모두에게 균등하게 주어져야 한다고 생각한다. 내가 사설학원에 다니지 않으면서 그 시간에 Coursera를 듣는 이유이기도 하다.

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

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

그 다음, 이메일 데이터 집합 (예제 파일로 제공하는 샘플 데이터이다.)을 꺼낸다. 그 후, 파일 구문 분석 소스와 전체스팸 검사 함수를 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

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

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

내가 만든 소스코드를 실험해 보기 위해 TreePlotter 모듈을 만들어 컴파일했는데 이렇게 에러가 났다.

ImportError : No moudle named matplotlib

에러 : matplotlib 모듈이 없습니다!!!

왜 이런 에러가 날까? 내가 짠 TreePlotter 모듈의 소스코드를 일부부분만 공개한다.

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

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

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


import matplotlib.pyplot as plt

decisionNode = dict(boxstyle="sawtooth", fc="0.8")
leafNode = dict(boxstyle="round4", fc="0.8")
arrow_args = dict(arrowstyle="<-")

def getNumLeafs(myTree):
    numLeafs = 0
    firstStr = myTree.keys()[0]
    secondDict = myTree[firstStr]
... (이하 생략)

이 부분에 matplotlib을 import해주는 부분이 있어서이다. 그렇다면 그 라이브러리를 설치해야 한다.

우선 공식 홈페이지에 가서, 64비트 기반 Installer를 다운로드 받았다.


근데... 파이썬 경로를 못 잡는다. 어쩔 수 없다. whl 파일로 설치해보는 걸로 한다. 근데 이번에는 pip이 없다. whl파일을 설치하려면 pip이 필요하다. 공식 홈페이지에 있는 get-pip.py 파일로 설치해보는걸로 한다.

이제 내가 구한 파일을 실행한다.

이게 무슨 일인고?

어? 어? 어어어? 제대로 된 파일이름이 아니란다. 알아보니 중간에 수정하면 설치가 안된다고 한다.

다시 파일을 다운받아서 설치한다.

어? 되는 것 같은데?

이번에도 설치가 안된다.

그래서 구글에 에러 내용을 똑같이 쳤다. Could not find a version that satisfies the requirement mathplotlib...

검색해보니 한 스택오버플로우 게시글이 나온다. 여기서는 미러 서버를 이용한 해결방법을 제시하고 있다.

그대로 실행해 본다.

Sucessfully installed!

그럼 지금까지 한게 헛수고란 말인가? (커맨드로 수동 설치할 경우 잘못 설치하면 그 과정이 헛수고가 되는 경우가 많음)

matplotlib import도 잘 된다.

에러가 나던 treePlotter 모듈 import도 잘 된다!

이제 의사결정 트리를 직접 동작해 본다.

제대로 동작하는 모습을 볼 수 있다. 이를 해결하기 위해 1시간 정도가 소요되었다. 1시간 동안 헛수고를 하면서 수동설치기의 근본적인 문제를 찾아내고 이를 해결해 나가는 시간이 꼭 헛수고만은 아닐 것이라 생각한다. 오늘은 여기까지 하기로 했다.