blogging

나쁜 데이터 - 바람아 멈추어 다오

hongiiv 2013. 7. 11. 12:52
반응형
나쁜 데이터는 데이터가 누락된 값이나 잘못된 기록과 같은 기술적인 부분뿐만 아니라 그보다 훨씬 더 많다. 이러한 데이터 문제를 이겨내기 위한 다양한 영역의 전문가들의 이야기를 나쁜데이터 핸드북에서 제시하고 있다. 물론 이쪽 업계(Bioinformatics)에서도 이런 나쁜 데이터를 흔히 접할 수 있다. 하지만, 오늘은 간단한 웹프로그래밍을 하면서 만난 나쁜 데이터에 대해서 이야기 해보려고 한다. 덧) 몰랐는데 이책의 역자가 KT에서 근무하는군요. ㅋ 사인이라도 받고 싶은데 말이죠.



요즘 민간뿐만 아니라 정부나 이쪽 업계 (genome research)에도 데이터의 공유와 더 나아가서는 big data에 대한 이야기와 함께 data science라는 말을 흔히 듣을 수 있게 되었다. 요즘에야 KTH API STORE (http://www.apistore.co.kr/main.do)나 공공데이터 포털(http://www.data.go.kr)등 민간의 데이터를 API등을 활용하여 손쉽게? 얻을 수 있지만 아직까지 웹상에 존재하는 수많은 주옥같은 데이터는 HTML에 꽁꽁 싸여 있다.

기상청에서는 다양한 기상관측 자료를 제공하고 있는데 이중 전국의 700여개의 AWS(Automated Weather Station)이라는 자동기상관측장비를 이용하여 실시간 관측데이터를 홈페이지를(http://www.kma.go.kr/weather/observation/currentweather.jsp) 통해 제공하고 있다.


나쁜 데이터의 시작 HTML 파싱
우선 웹페이지를 긁어와 해당 내용을 파싱하여 JSON 포맷으로 저장하고 이를 visualization하기로 결정하고 그 첫단계를 Python BeautifulSop을 이용하여 웹페지의 HTML 태그내의 table안에 들어있는 지역, 풍향, 풍속 데이터를 가져왔다. 뒤에서 이야기 하겠지만 이를 Visualization 했더니 다수의 지점(지역)에서 거의 태풍급의 바람 세기를 보여주고 있었다.

문제?는 바로 기상청에서 제공하는 데이터는 매분마다 관측된 자료를 제공하는데 이중 제대로 관측되지 않아 값이 누락된 데이터를 가져오는데에서 발생했다. 기상청에서는 이러한 값을 테이블내에 빈공간 (&nbsp)으로 표시하거나 dot(.) 또는 대시(-)로 표시하는데에서 발생한 문제였다. 숫자(풍속)나 문자(풍향, 예 S, SSW)가 들어가야 할 부분에 이러한 특수문자로 인해 잘못된 계산결과가 나오고 이는 바로 태풍급 풍속을 지도상에 표시하는 오류를 범하게 된것이다.

누락값의 대체
테이블내의 td 태그에 들어있는 풍향, 풍속 값을 가져오는데에 있어서 예외 처리를 수행하였다. 첫번째는 빈공간을 처리하는 부분인데 여기서도 단순히 python의 비교문을 통해 null을 체크했지만, 실제로는  &nbsp (HTML에서 공백을 의미)에 둘러쌓여져 있었던 것이었다. UTF8으로 '\xc2\xa0' -.-;; 급하게 코드를 if values == '\xc2\xa0' or values =='.' or values == '-':로 변경하여 누락된 값을 0으로 지정하여 누락된 지점은 visualization시 나타나지 않도록 설정했다.

위/경도 데이터
기상청의 데이터는 지역정보를 "동"까지의 주소로 제공하고 있다. 따라서 지도상에서 제공하기 위해서는 정확한 위/경도 데이터를 얻어야만 했다. 다음에서도 이러한 기상청의 데이터를 제공하고 있다. 기상청 페이지에서 파싱한 각 AWS의 고유 코드를 가지고 간단한 API 호출을 통해 정확한 위/경도를 얻을 수 있다. 다음에서는 SensoQL을 이용하여 SQL문과 비슷한 형태로 질의를 만들면 해당 질의를  RESTful URL로 제공하고 해당 URL을 통해서 기상센서가 위치한 위/경도를 알 수 있다.

질의문
SELECT * FROM sensorMetaCollection WHERE resourceId=100 (AWS장비번호)

RESTful URL
http://apis.daum.net/sensorql/weather.json?apikey=DAUM_SENSORQL_DEMO_APIKEY&q=SELECT%20*%20FROM%20sensorMetaCollection%20WHERE%20resourceId%3D100

반환값
{
   "sensorQL":
   [
       {
           "resourceId": 100,
           "latitude": 37.6771,
           "longitude": 128.7183,
           "altitude": 772.57,
           "firstObservationTime":
           {
               "$date": "2012-03-05T10:55:00.000Z"
           },
           "lastObservationTime":
           {
               "$date": "2013-01-28T15:18:00.000Z"
           }
       }
   ]
}



이제 JSON 형태의 위치(위/경도), 풍향, 풍속에 대한 정보를 갖추어졌고, 이를 visualization하는 일만 남았다. JSON 포맷 lat(위도), lon(경도), S(풍속), D(풍향)으로 S는 m/s, 풍속은 동서남북을 모두 16등분한 값이다.

var weather={'sensorQL': [{'lat': 38.2509, 'S': '1.0', 'lon': 128.5647, 'D': 'NW'}, {'lat': 38.0667, 'S': '1.0', 'lon': 128.6667, 'D': 'N'}, {'lat': 38.1479, 'S': '4.1', 'lon': 127.3042, 'D': 'SSW'}, {'lat': 37.2395, 'S': '0', 'lon': 131.8698, 'D': 'N'}, {'lat': 37.9019, 'S': '2.0', 'lon': 127.0607, 'D': 'S'}, {'lat': 37.8859, 'S': '3.0', 'lon': 126.7665, 'D': 'SSW'}, {'lat': 37.6771, 'S': '6.6', 'lon': 128.7183, 'D': 'WSW'}, {'lat': 37.9026, 'S': '2.0', 'lon': 127.7357, 'D': 'S'}]}

데이터 시각화 - 지도 이미지 만들기
지도 이미지 작성은 다음과 같은 순서로 진행한다. 지도의 shape 데이터를  얻고 이를 JSON 형태로 변경하여 웹페이지에 표시한다. 이에 대한 상세한 튜토리얼은 
http://bost.ocks.org/mike/map/를 참고하기 바란다. 

지도 이미지에 Line 그리기
D3 javascript를 이용하여 지도상에 line을 표시한다. 이때 풍속에 따라 서로 다른 line 길이를 나타내도록 하며, 라인의 첫 시작위치로 부터 풍향을 계산하여 라인이 향하는 방향이 풍향과 일치하도록 한다.

이렇게 해서 만들어진 지도는  바람아 멈추어다오 홈페이지에서 확인 가능하며 다음과 같다. 


다음은 기상청에서 제공하는 이미지 형태의 바람의 방향과 속도에 대한 것으로 내륙 경기남부 및 강원 남서부 충북 북동쪽이 바람이 비교적 없으며 서해와 제주도쪽이 바람이 센것을 확인할 수 있다. 물론 이 이미지는 동적이지 않으며, 위의 홈페이지에서는 동적인 바람 정도를 확인 할 수 있다.


참고
다음 SensorQL http://dna.daum.net/tools/pg/sensorql
Let's Make a Map http://bost.ocks.org/mike/map/
UK Wind Chart http://prcweb.co.uk/lab/ukwind/
Wind Map http://hint.fm/wind/
반응형