카테고리 보관물: 미분류

데이터과학하려면 R과 Python 중 어떤 걸 배워야 하나?

요즘 추세로 본다면 데이터과학, 데이터분석, 딥러닝, 기계학습 등을 하려면 R과 Python 중 하나를 선택해야 합니다.

R과 Python은 둘 다 모두 스크립트(script) 언어이면서 둘다 대화형 언어(Interpretor)이기도 합니다.

스크립트 언어라는 것은 C++이나 Java 처럼 컴파일을 하거나 중간코드를 빌드하지는 않는 것을 말하는 것이고 대화형 언어라는 것은 코드를 입력하고 그 결과를 즉시 확인할 수 있다는 것입니다.

그래서 가능하다면 R과 Python을 둘 다 하는 것이 훨씬 좋습니다. 하지만 R이 PYthon보다는 학습장벽이 매우 높기 때문에 둘 중에 어떤 것을 먼저해야 하냐고 묻는다면

대답은 Python 입니다.
현재는 Python을 먼저 선택하는 것이 대체로 유리합니다.

그럼 R은 생각할 필요도 없는 것인가? 라고 묻는다면 당연히 그렇지 않습니다. 자신이 어떤 쪽의 일을 할 것인지 하고 있는지, 어떤 스타일로 하는지에 따라 달라질 수 있습니다.

데이터과학 랭귀지를 선택할 때 고려할 것

선택을 할 때 아래와 같은 간단한 체크 리스트를 만들어 봤습니다.

  • 앞으로 통계 분석을 더 많이 하게 될 것 같다. R
  • 시각화가 편하고 빠르면 좋겠다. R
  • 일괄 처리 작업이나 텍스트마이닝 같은 처리도 하고 싶다. Python
  • 기계학습 모델을 자주 만들고 많이 만들것 같다. Python
  • 데이터 전처리와 이관, 자동화 같은 것도 해야 한다. Python
  • 최신 통계 패키지(새 알고리즘, 기법같은 것들)가 많아야 한다. R
  • 최신 기계학습 패키지가 많아야 한다. Python
  • 딥러닝을 해야 한다. Python
  • IOT도 해야 하고 로그 분석도 해야한다. Python
  • 시계열 분석, 수리 통계, 금융 분석 이런 고급 통계나 수학과 관련된 것을 앞으로 할 것이다. R
  • 빅데이터 플랫폼들에 접속해서 비정형 데이터를 가져오거나 처리해야 한다. Python
  • 나는 금융공학에 관심이 있다. Python
  • UI가 있는 웹개발도 좀 해야 한다. Python
  • 웹개발도 해야하긴 하지만 복잡한 것은 안하고 위젯 정도나 간단한 시각화 수준이면 된다. R (Shiny가 있으므로)
  • 주로 연구하고 논문쓰는 일을 많이 할 것 같다. R
  • 나는 의사이고 실험을 많이 한다. R
  • 분석 리포트를 많이 쓰거나 논문을 많이 써야 한다. R
  • 바이오인포메틱스이고 유전자 데이터 이런 일과 관련이 있다. Python
  • 앞으로 클라우드의 자원 활용도 많이 하게될 것 같다. Python
  • 범접할 수 없는 레벨의 과학자처럼 보여지고 싶다. R
  • 데이터과학의 귀재로 보여지고 싶다. Python

대부분 R과 Python 둘다 가능한 것이지만 둘 중에 더 유리한 것 하나를 답으로 적어두었습니다. 경험을 바탕으로 적은 것입니다. 의견의 차이가 있을 수 있지만 무분별한 비난은 사절합니다.

위의 목록을 쭉 훑어보면 대체로 PYthon이 답인 경우가 많으니 그냥 Python 선택하면 된다는 쪽으로 보여집니다만 위에 열거한 것들에서 선택된 것의 숫자만 보고 그렇게 판단하면 안됩니다.

R의 좋은 점

R을 옹호하는 입장이 되서 장점을 어필해 보겠습니다.

R의 강점은 커뮤니티와 커뮤니티에서 제공되는 패키지가 있습니다. 최신 통계 분석, 알고리즘이나 기법들이 패키지가 가장 빨리 제공되고 있으며 품질도 상당히 좋습니다.

대부분 패키지를 만들어서 제공하시는 분들이 그 분야의 석박사이거나 교수들입니다. 100% 믿을 수 있는 것은 아니지만 보통은 쓰는 사라들보다 그 부분에 대해서는 훨씬 전문적인 분들이라서 믿고 쓸 수 있습니다.

또 패키지가 중앙집중식으로 엄격하게 관리되고 있습니다. 패키지가 등록될 때 절차도 까다롭고 검증도 까다롭습니다. 그래서 패키지가 작동하지 않는다거나 하는일이 거의없고 오래된 패키지들도 비교적 관리가 잘됩니다.

Python의 좋은 점

Python을 옹호하는 입장에서 장점을 어필해보면.

Python을 쓰는 사람이 워낙 많아서 자료를 구하기 쉽고 샘플 코드를 구하기도 쉽습니다. 사용자 층이 두텁다고 하죠. 이제 가장 사용자가 많은 랭귀지가 되었습니다.

Python은 다런 언어에 비해 배우기 쉬운 편입니다. 물론 그렇다고 해서 책 한 권 읽고 바로 할 수 있을 만큼 정말 쉽다는 얘기는 또 아닙니다. 다른 랭귀지에 비해서 비교적 쉽다는 거입니다.

직군별로 간단하게 선택하는 방법

“하는 일” 또는 “하려고 하는 일”의 직군을 보고 간단하게 선택할 때는 이렇게 하면 됩니다.

  • 엔지니어, 개발자 쪽에 가깝다면 Python
  • 분석가, 연구원에 가깝다면 R
  • 그냥 과학자라면 아무렇게나 하세요. 아마 둘 다 안 쓸 가능성이 큽니다.

기획자, 세일즈, 비즈니스 직군인데 분석용 언어를 배워보려면 어떤 것을 써야 하나?

데이터분석이나 데이터과학을 하려고 하는데 그 일이 꼭 컴퓨터랭귀지를 쓰지 않아도 엑셀이나 다른 도구로 할 수 있는 것이 아닌지 먼저 확인해 보세요. 대부분 간단한 것은 다 할 수 있습니다.

그럼에도 불구하고 취미이든, 도전이든, 자기계발이든, 미래를 위해서 이든, 컴퓨터 언어를 하나 배우고 싶다면?

Python을 선택하면 됩니다.

왜냐면 R이 더 안좋아서가 아니라 배우기 더 어렵기 때문입니다.

그다지 궁금하지 않겠지만 이 포스트를 보고 또 Python에 너무 편향된 것이 아니냐고 하실 분들이 있을 것 같아서 마지막으로 말씀드리면 저는 Python 보다는 R을 더 좋아합니다.

Docker proxy 설정

Docker를 사용할 때 docker를 구동시킬 서버가 방화벽 안쪽에 있거나 외부 네트워크(인터넷)에 직접 접속하지 못해서 docker image를 당겨오거나 docker container를 빌드하지 못할 때가 있습니다.

Proxy를 사용해야 하는데 다음과 같이 하면 됩니다.

구동할 서버의 구동할 계정에 디렉토리를 하나 생성하고 파일을 만듭니다.

mkdir ~/.docker
vim ~/.docker/config.json

아래의 내용을 추가해줍니다. proxy 서버의 주소와 port는 각자의 네트워크에 해당하는 것으로 바꾸면 됩니다.

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://proxy.test.com:8080",
     "httpsProxy": "http://proxy.test.com:8080",
     "noProxy": "localhost,127.0.0.1"
   }
 }
}

그리고 나서 다시 docker로 container를 빌드하면 됩니다.

Python 소스 컴파일에서 Error in `python': corrupted size vs. prev_size 에러

리눅스에 문제가 있거나 너무 오래된 버전의 리눅스 배포판을 사용할 때 Python source를 다운로드 받아서 빌드해야 하는 경우가 있습니다

이때 configure를 실행한 뒤 make 를 실행하면 다음과 같은 에러가 나올 수 있습니다.

Error in `python': corrupted size vs. prev_size

해결책은 다음과 같이 하면 됩니다.

sudo apt-get install libtcmalloc-minimal4
export LD_PRELOAD="/usr/lib/libtcmalloc_minimal.so.4"

Ubuntu 14.04에 Python 3.7 설치하기

오래된 Ubuntu 14.04에 Python 3.7을 설치할 때 필요한 간단한 절차입니다. 이 글을 쓰는 시점에서의 최신 Ubuntu 18.04이고 곧 20.04 버전이 나올 예정입니다.

그리고 현재 Python은 3.7.x가 최신 버전인데 Ubuntu 14.04에는 3.6.x가 설치되어 있고 14.04에 3.7.x는 그냥은 설치되지 않습니다.

3.6.x를 그냥 쓰면 되지 않겠냐고 하겠지만 3.6과 3.7은 마이너 버전 하나의 차이로 보이지만 실제로는 많은 부분에서 차이가 있습니다. 성능, 보안, 문법과 같은 것들입니다. 최신 패키지들도 3.6에서는 오작동하는 사례가 많습니다.
3.7을 설치해서 사용하는 것이 좋습니다.

sudo apt update  # 깨끗하게 한번 apt 정보 갱신
sudo apt install software-properties-common  # add-apt-repository 명령어를 설치하기 위한 것
sudo add-apt-repository ppa:deadsnakes/ppa  # 레파지토리를 등록합니다.
sudo apt update  # apt에 정보를 업데이트합니다.
sudo apt install python3.7  # python 3.7을 설치합니다.

Banker’s Rounding – 은행원 방식 반올림

아실지 모르겠지만 반올림은 여러가지 계산 방식이 있습니다.

한가지가 아닙니다.

이 차이를 모르면 소숫점이 있는 수치 계산을 하다가 반올림 처리 방식의 차이로 인해 오차가 생겼다고 생각하고 정합성을 맞추려다 헤메는 경우가 있을 수도 있습니다.

물론 평생 이런 일이 없을 수도 있습니다.

제가 학생이던 시절에 금전 계산을 자동으로 복잡하게 하는 정산 소프트웨어를 의뢰받아 만든 적이 있었는데, 의뢰인이 제시해준 계산 방법과 확인용 정산 출력물을 기반으로 계산 소프트웨어를 작성하는 흐름으로 진행했었습니다. 단위 계산이 조금 복잡했고 반복 계산을 한 뒤에 복잡하게 역산하는 것을 한 뒤에 총 결과를 산출하는 것이었습니다. 요즘 용어로 바꾸자면 최적화 비슷한 것이었습니다.

그런데 문제가 생겼습니다.
만들 때 적은 양의 데이터로 단위 계산을 몇 개 실험해서 해본 뒤에 나온 결과를 보고 정확하게 계산되었는지를 정확하게 확인했고 문제가 없었습니다, 그 후에 전체 계산을 수행하는 것을 진행해서 총합을 확인해보니 정답지와 결과값이 미세하게 달랐습니다. 다시 단위 계산을 몇개 임의로 선택해서 결과가 어떻게 다른지 점검해 봤는데 몇개가 다르게 나온다는 것을 알았습니다. 이 문제의 원인을 찾느라 시간을 쓸데없이 허비한 적이 있습니다.

물론 이 차이로 인해 큰 일이 생기는 것은 아니었습니만 숫자는 틀려도 문제의 원인을 알지 못하면 곤란하다는 의뢰인의 말에 원인을 찾아야 했습니다.

찾아 본 결과 원인은 제가 사용하던 컴퓨터 랭귀지에서 제공하는 round 함수가 사사오입이 아닌 뱅커스 라운딩(Bankers’ rounding)을 채택했기 때문에 발생한 문제였고 round 함수를 사사오입 방식의 다른 round로 변경해서 해결했었습니다. 그 뒤로는 round를 하게될 일이 있으면 반드시 사용하는 소프트웨어의 round가 사사오입 방식인지 뱅커스 라운딩인지 확인을 하고 작업을 시작하는 습관이 있습니다. 그게 아니면 오차가 좀 크더라도 정합성을 위해서 무조건 소숫점이하는 절사 시켜버리곤 했습니다. 물론 요즘은 이것마저도 잘 하지 않는 늙은이가 되었습니다만.

어쨌든 그 당시에는 컴퓨터 랭귀지의 기본 함수에 버그가 있는 줄 알고 컴파일러 판매회사에 문의하려고 했었으나 함수 매뉴얼을 먼저 찾아보니 천절하게 설명을 해 두었더군요. 함수 매뉴얼을 자세히 읽지 않은 제가 문제였던 것이고 그리고 관련 자료를 더 찾아보고는 제가 반올림에 대해서 상당히 무식했다는 사실을 알았습니다.

“세상에 반올림 방법은 딱 하나 인 줄 만 알았어” 라고 생각했습니다. 배운 것이 그것뿐이라서요.

앞서 말씀드린 것 처럼 반올림은 여러가지 방식이 있습니다. 꽤 많은 방식들이 있습니다만 우리가 흔히 접할 수 있는 것은 위에서 말한 2가지인 사사오입과 뱅커스 라운딩입니다.
이 포스트에서 사사오입과 뱅커스라운딩의 차이를 설명하겠습니다.

사사오입( 四捨五入 ) 반올림

우선, 흔히 아는 반올림은 사사오입(四捨五入, Normal rounding)인데 4는 버림, 5는 올림을 뜻합니다. 보통은 우리는 그냥 “반올림”이라고 하지만 명확환 구분과 설명을 위해서 “사사오입”이라고 하겠습니다.
사사오입 방식은 영어로는 Round, away from zero (0으로부터 멀어지는 이라는 뜻) 라고 합니다.
사사오입으로 소숫점이 있는 숫자들을 정수로 반올림한다고 하면 다음과 같은 결과가 나옵니다.

0.4 반올림 하면 0
0.5 반올림 하면 1
0.6 반올림 하면 1
1.4 반올림 하면 1
1.5 반올림 하면 2
1.6 반올림 하면 2
2.4 반올림 하면 2
2.5 반올림 하면 3
2.6 반올림 하면 3

잘 알고 있는 그 방식입니다.

뱅커스 라운딩 (오사오입 반올림)

뱅커스 라운딩은 올려질 값이 5인 경우에 만들어질 수의 끝이 짝수가 되도록(짝수에 수렴) 하는 방식입니다.

짧게 “짝수로 맞춘다”로 기억하면 편합니다.

오사오십의 영어 표현은 Round, half to even (절반을 짝수쪽으로)라고 합니다. 금융권에서 많이 채택해서 쓰기 때문에 뱅커스 라운딩이라는 별칭으로 많이 불립니다. 이건 미국의 경우이고 한국 금융권에서도 이것을 채택해서 쓰는지는 모르겠습니다.

어쨌든 뱅커스라운딩으로 계산하면 다음과 같이 됩니다.
굵은 글씨 부분을 자세히 보세요.

0.4 반올림 하면 0
0.5 반올림 하면 0 <– 여기
0.6 반올림 하면 1
1.4 반올림 하면 1
1.5 반올림 하면 2
1.6 반올림 하면 2
2.4 반올림 하면 2
2.5 반올림 하면 2 <– 여기
2.6 반올림 하면 3
2.45 반올림 하면 2 <– 여기

숫자 몇개를 반올림해서 사사오입과 뱅커스라운딩 둘을 비교해보면 이렇습니다.

대상값 / 방식사사오입뱅커스 라운딩
0.400
0.510
1.411
1.522
1.622
2.422
2.532
2.633
4.554
4.444554
사사오입가 뱅커스라운딩의 비교표

뱅커스 라운딩은 미국 측정 계산의 표준이라고 알려져 있습니다. 직접 물어봐서 확인해 보지 않았지만 온라인 문서에 그렇게 적혀 있습니다. 그래서 최신의 컴퓨터 언어나 계산 관련 소프트웨어들에서 기본으로 지원하는 반올림 함수는 우리가 아는 사사오입 방식이 아닌 뱅커스 라운딩을 사용하는 것이 많습니다.

소프트웨어들이 여전히 미국산이 많기 때문인데 특히 과학계산 용도로 쓰는 것들이 그렇습니다.

반올림? 이라는 용어

사사오입은 엄밀히 말하면 반올림이 아닙니다. 우리가 쓰는 반올림은 영어로 round라고 하는데 round라고 하는 것의 원래 뜻은 숫자를 단순하게 만드는 것을 말합니다.

round 는 둥글게 심플하게 밋밋하게 한다는 뜻입니다.

그래서 “무조건 올림”은 영어로 round-up이라고 하고 “무조건 내림”은 영어로 round-down이라고 합니다. round라는 단어가 들어 있지만 “무조건 내림”과 “무조건 올림”은 반올림이 아닙니다. 반만 올리는 것이 아니라 그냥 올리고 내리는 것이지요.

그러니까 영어로 round라고 하는 것을 우리식으로 반올림이라고 표현하는 것은 맞지 않다라고 말씀하시는 분이 있는데 저도 그게 맞다고 생각합니다.

그리고 사사오입 반올림의 영문 표현이 away from zero인데 뜻을 보면 5를 0에서 멀어지게 하는 것이라서 반올림이라고 표현하는 것에 무리가 있다고 합니다. 반면 half to even 방식은 짝수방향으로 반을 올려주거나 절사하기 때문에 이것이 진짜 반올림 방식 중 하나입니다.

하지만 이미 관행으로 다들 사사오입을 반올림이라고 말하기 때문에 편의상 여기에서도 모두 합쳐서 다 “반올림”이라고 하겠습니다.

뱅커스 라운딩을 사용하는 이유

계산과정에서 반올림 때문에 발생하는 오차를 줄이기 위해서 고안된 것입니다. 반복계산을 하면서 반올림이 계속 반복되면 결국 오차를 만들게 되는데 반복 계산 후 최종 결과에서 이 반올림들에 의해 발생하는 오차를 줄이도록 하려는 것입니다.

지인 분이 알려주셨는데 해석학에서 이걸 증명하는 것이 나온답니다.

하지만 간단하게 설명하면 숫자 0과 1이 있습니다.
이 사이에 존재하는 소숫점 첫째자리까지의 수만 보면 다음과 같이 9개의 숫자가 있습니다.
10개가 아닙니다.

0.10.20.30.40.50.60.70.80.9

이 숫자들을 다 반올림한다고 할 때 0.5는 정확하게 한가운데 있기 때문에 절사해서 버릴 것인지 1로 올려줄 것인지가 고민이 됩니다. 그리고 어느쪽으로 하든 오차를 만듭니다.

사사오입 방식은 5를 항상 위로 올리기 때문(away from zero)에 여기서 숫자가 원래 올리지 않았을 때 보다 오차가 커지는 일이 많아집니다. 그리고 잘 생각해 보면 어딘가 공평하지 않은 구석이 있다는 것을 느낄 수 있습니다.

대신 뱅커스 라운딩처럼 짝수쪽으로 수렴하게 해서 조금은 더 공평해집니다. 그리고 이 방식이 오차가 덜 발생한다는 것은 오래전에 여러가지 방법과 실험을 통해 증명되었다고 합니다.

그 외의 반올림 방식

위키피디아의 rounding 페이지를 보면 반올림(rounding)방식이 상당히 많다는 것을 보고 놀랄 수 있습니다. 반올림 문제는 메소포타미아에도 기록이 남아 있는 오래된 문제라고 되어 있습니다. 그리고 뱅커스 라운딩이라고 불리는 half to even 방식은 1940년도 나온 것이라고 적혀 있습니다.

상당히 오래되었죠.

위키피디아: https://en.wikipedia.org/wiki/Rounding

반올림 비교표

너무 많은 round를 알 필요는 없겠지만 대략 아래와 같은 것이 있습니다.

round 함수의 방식 차이로 인한 정합성 문제

뱅커스 라운딩을 기본으로 채택해서 제공하는 컴퓨터 언어나 소프트웨어가 생각보다 좀 많습니다.

R, Python3과 같은 것들이 그렇습니다. 그 외의 랭귀지도 꽤 많습니다. Excel과 RDBMS 같은 소프트웨어의 반올림 함수는 대부분 우리가 아는 “사사오입”으로 되어 있습니다. 그러다보니 행수가 많은 데이터에서 나누기, 곱하기 같은 것들이 여러번 반복하고 그 결과를 모두 합한다거나 평균을 구한다거나 하면 동일한 데이터를 가지고 계산을 해도 사용하는 컴퓨터 언어나 툴에 따라 양쪽의 결과값에 미묘한 차이가 발생합니다.

즉, round함수의 방식이 다른 것을 각각 따로 어떤 데이터의 사칙 연산을 하면서 반올림이 섞인 계산을 반복하는 경우에는 양쪽에서 똑같이 계산해도 round의 방식으로 인해 서로 결과값이 안맞는 문제가 발생합니다.
이때 정합성 오류가 부동소숫점 연산 문제나 반올림 방식의 차이로 인한 문제라는 것을 알면 그것은 해결하기도 어렵고 원인을 알면 오차를 감수하고 넘어갈 수도 있지만, 그것을 모르면 오차가 어디서 발생했는지 원인를 찾기 위해서 시간을 허비하게 됩니다.

버그인지 계산을 잘못한 것인지…

그래서 차이가 있다는 것을 알고 있는 것이 좋습니다.
물론 뱅커스 라운딩을 기본으로 채택한 것들은 별도로 사사오입을 지원하는 함수를 따로 제공하는 것이 많습니다. (아닌 것도 있는데 그럴 때는 구현해야 합니다)

컴퓨터 언어, 소프트웨어의 기본 반올림 방식

직접 몇 개를 확인해 봤습니다. 결과는 아래 테이블에 있습니다.

언어/소프트웨어방식
Linux shell (printf)뱅커스 라운딩
R뱅커스 라운딩
Python2사사오입
Python3뱅커스 라운딩
C/C++사사오입
Object-C사사오입
C#뱅커스 라운딩
Visual Basic뱅커스 라운딩
Go사사오입
Ruby사사오입
Scala사사오입
PHP사사오입
Julia뱅커스 라운딩
Javascript사사오입
Java사사오입
Erlang사사오입
Pascal뱅커스 라운딩
Cobol뱅커스 라운딩 (기본으로 되어 있습니다. 변경 가능해요)
Fortran사사오입
Excel사사오입
Google Spread Sheet사사오입
MySQL사사오입
Hive사사오입
Redshift (PostgreSQL?)사사오입
BigQuery사사오입
Oracle사사오입
SQLite사사오입
Matlab사사오입
Mathematica뱅커스 라운딩
WolframAlpha뱅커스 라운딩 (매쓰메티카와 같은 언어를 쓰므로)
Tableau사사오입 (시각화 도구는 역시 짤 없습니다)

정리하면

  • Linux에 있는 printf뱅커스 라운딩 (리눅스 코맨드마다 다를 수도 있겠지만 이것만 확인했어요)
  • Java 계열사사오입
  • 닷넷(.net) 계열뱅커스 라운딩 (.net이 아닌 MFC를 확인 안해봤습니다. 귀찮아요)
  • 데이터에 중점을 둔 것들은 사사오입
  • 과학, 공학에 중점을 둔 것은 뱅커스 라운딩
  • 함수형 언어뱅커스 라운딩
  • 시스템 개발에 중점을 둔 언어는 사사오입
  • Python은 2에서 3으로 바뀔 때 뱅커스 라운딩을 기본으로 바꿈
  • 시각화 도구는 DB에서 데이터를 끌어와서 표현하는 일이 많기 때문에 DB와 같은 방식을 사용

그리고 매우 오래전부터 사용해온 소프트웨어들은 일관성과 변경한 후 달라질 정합성으로 인해 별도로 뱅커스 라운딩 함수를 사용할 수 있게 제공하고 기본 함수의 방식을 바꾸지는 않는 것 같습니다.

하지만 뱅커스 라운딩이 더 권고되는 표준이기 때문에 새로 만들어지는 것들은 뱅커스 라운딩을 지원해야 한다고 하는 사람이 많습니다.

데이터베이스의 경우에는 잘 쓰고 있는데 어느날 업그레이드를 하고 나서 계산값이 달라지거나 합계를 했는데 총합이 달라지거나 하게 되면 문제가 커질 수도 있을 것입니다.

반올림의 인해 엄청난 문제가 발생하는 경우는 일상 생활에 별로 없겠습니다. 하지만 수능점수같은 것은 반올림 문제로 학생의 인생이 바뀔 수도 있어서 매우 골치가 아플것 같습니다. 작은 차이가 큰 문제를 만드는 경우도 있습니다.

뭘 하시든지 정밀한 수치 확인이 필요한 작업을 혹시 하게 되는 경우를 위해서 알아두면 좋을 것 같습니다.