티스토리 뷰

네이버 Data Science Competition 2019에 참가하게 되어 추천강의를 받았다.

 

5. 캡스톤 : 파이썬을 이용한 데이터 검색, 처리 및 시각화
머신러닝을 위한 Python
R을 활용한 통계학개론 : 6. 통계적 추론 I
R을 활용한 통계학개론 : 7. 통계적 추론 II
R을 활용한 통계학개론 : 8. 두 모집단의 비교
R을 활용한 통계학개론 : 10. 범주형 자료의 분석
R을 활용한 통계학개론 : 11. 분산분석
R을 활용한 통계학개론 : 12. 비모수 통계학
Statistics 110 from Harvard (Advanced - 선택)
Data Science from MIT
인공지능 및 기계학습 개론 I : 2. Fundamentals of Machine Learning
인공지능 및 기계학습 개론 I : 4. Logistic Regression
인공지능 및 기계학습 개론 I : 5. Support Vector Machine
인공지능 및 기계학습 개론 I : 6. Training Testing and Regularization

 

 

일단 추천강의부터 먼저 듣고, 다른 강의를 들으면서 준비해야겠다고 생각이 들어서.. 강의만 보는것보다는 블로그에 쓰면서 남기는게 좋겠다.. 생각이 들어서 (따라하는거지만) 해보기~~

 

파이썬을 이용한 데이터 검색, 처리 및 시각화 강의에서 구글의 JSON API를 사용하여 구글 지도 만들기!

전체적인 프로세스는 아래와 같습니다.

 

 

Google geodata를 API를 통해서 가지고 오고 where.data는 위치에 대한 입력값을 담는 큐입니다.

where.js는 자바스크립트 파일안에 데이터를 담아서 where.html을 이용해서 시각화를 하는 것이라고 하네요.

 

where.data에 장소 및 위도 경도 위치 데이터를 가지고와서 Google Places API를 이용해 해당 장소들을 찾고 지도에 그 위치를 나타내는 것입니다.

where.data의 안에 있는 데이터 형식

이 데이터는 geoload.py에 의해서 읽어지게 되죠!

 

일단 geoload.py 코드부터 살펴보겠습니다.

 

import urllib.request, urllib.parse, urllib.error 
import http 
import sqlite3 
import json 
import time 
import ssl 
import sys


api_key = False

#밑에는 Google API 가 있다면 사용하면 됩니다. 하지만 속도면에서 느리기 때문에 아래 경로를 사용합니다
# If you have a Google Places API key, enter it here 
# api_key = 'AIzaSy___IDByT70' 

if api_key is False: 
    api_key = 42

    #이 서버에서 가지고 오게 되면 속도 제한도 없고 매우 빠르다고 하네요.
    serviceurl = "http://py4e-data.dr-chuck.net/json?" 
else : 
    serviceurl = "https://maps.googleapis.com/maps/api/geocode/json?" 

# Additional detail for urllib 
# http.client.HTTPConnection.debuglevel = 1 

conn = sqlite3.connect('geodata.sqlite') 
cur = conn.cursor()



#DB 생성하는데 테이블 없으면 만들라는 것 입니다.
cur.execute(''' 
CREATE TABLE IF NOT EXISTS Locations (address TEXT, geodata TEXT)''') 

# Ignore SSL certificate errors

# 파이썬이 SSL 과 관련된 에러를 무시하는 코드 입니다.
ctx = ssl.create_default_context() 
ctx.check_hostname = False 
ctx.verify_mode = ssl.CERT_NONE 

fh = open("where.data") 
count = 0 
for line in fh: 
    if count > 200 : 
        print('Retrieved 200 locations, restart to retrieve more') 
        break 
    #파일에서 주소를 읽어드립니다.
    address = line.strip() 
    print('')

    #그리고 해당 주소와 일치하는 geodata를 선택
    cur.execute("SELECT geodata FROM Locations WHERE address= ?", 
        (memoryview(address.encode()), ))

    #만약 DB에서 이미 주소를 가지고있다면 SELECT을 실행 안합니다.
    try: 
        data = cur.fetchone()[0] 
        print("Found in database ",address) 
        continue 
    except: 
        pass 

    parms = dict() 
    parms["address"] = address 
    if api_key is not False: parms['key'] = api_key

    #딕셔너리를 쿼리 문자열로 바꿔줍니다.
    url = serviceurl + urllib.parse.urlencode(parms) 

    print('Retrieving', url) 
    uh = urllib.request.urlopen(url, context=ctx) 
    data = uh.read().decode() 
    print('Retrieved', len(data), 'characters', data[:20].replace('\n', ' ')) 
    count = count + 1 

    try:

        #json data를 읽어옵니다
        js = json.loads(data) 
    except: 
        print(data)  # We print in case unicode causes an error 
        continue 

    if 'status' not in js or (js['status'] != 'OK' and js['status'] != 'ZERO_RESULTS') : 
        print('==== Failure To Retrieve ====') 
        print(data) 
        break 

    cur.execute('''INSERT INTO Locations (address, geodata) 
            VALUES ( ?, ? )''', (memoryview(address.encode()), memoryview(data.encode()) ) ) 
    conn.commit()
    #카운트 10마다 5초동안 멈추게 해서 이때 멈추게 할 수 있습니다

    if count % 10 == 0 : 
        print('Pausing for a bit...') 
        time.sleep(5) 

print("Run geodump.py to read the data from the database so you can vizualize it on a map.")

코드가 그렇게 어렵진 않아서 데이터도 이미 가공이 다 된 상태이고.. geoload.py를 돌려보겠습니다.

아나콘다에서 실행하니 손쉽게 실행되는 모습이네요!

 

아나콘다에서 geoload.py 돌려보기

자세히 보시면 Arizona+State+University&key=42 처럼 +기호가 붙어있는데 이게 바로 urlencode입니다.

돌려보시면 잠깐식 멈추는게 아까 소스에서 sleep을 5초로 줘서 그런 것이겠죠!

 

그러면 geodata.sqlite가 생길겁니다! 아래처럼요!

geodata.sqlite

멈추었다고 다시 실행해도 들어오는 데이터를 체크하고 있으면 건너뛰게 만들어놔서 멈추었다가 다시 실행해도 됩니다.

 

    try: 
        data = cur.fetchone()[0] 
        print("Found in database ",address) 
        continue 
    except: 
        pass 

멈추었다 다시 실행해도 DB에서 데이터 찾아서 건너뛰는 모습

이제 geodump.py 코드를 보도록 하죠!

아마 DB에 있는것을 select 해와서 알맞게 데이터를 클리닝 하는거 같습니다.

 

import sqlite3 
import json 
import codecs 

conn = sqlite3.connect('geodata.sqlite') 
cur = conn.cursor()

#Locations 테이블은 위치와 geodata를 포함하고 있습니다.

cur.execute('SELECT * FROM Locations')

#where.js 파일을 열기
fhand = codecs.open('where.js', 'w', "utf-8") 
fhand.write("myData = [\n") 
count = 0 
for row in cur : 
    #row[0]은 Locations row[1]은 geodata가 되네요

    data = str(row[1].decode())

    #해당 데이터를 파싱합니다 파싱하기 전에 str로 바꿔줍니다
    try: js = json.loads(str(data)) 
    except: continue 
    #json에 status 영역이 있는지 확인
    if not('status' in js and js['status'] == 'OK') : continue



    #아래 데이터 형태를 보시면 아시겠지만 results 키를 찾고 그 안에서 geometry를 찾아

    #위도와 경도를 뽑아 내는 것입니다.
    lat = js["results"][0]["geometry"]["location"]["lat"] 
    lng = js["results"][0]["geometry"]["location"]["lng"] 
    if lat == 0 or lng == 0 : continue 
    where = js['results'][0]['formatted_address'] 
    where = where.replace("'", "") 
    try : 
        print(where, lat, lng) 

        count = count + 1 
        if count > 1 : fhand.write(",\n") 
        output = "["+str(lat)+","+str(lng)+", '"+where+"']" 
        fhand.write(output) 
    except: 
        continue 

fhand.write("\n];\n") 
cur.close() 
fhand.close() 
print(count, "records written to where.js") 
print("Open where.html to view the data in a browser")

 

 

이쯤에서 DB에 어떤 값이 들어가 있는지 확인해보겠습니다.

DB에 데이터는 JSON 형태로

그렇다면 이제 geodump.py 파일을 실행시켜보도록 하죠

 

geodump.py 실행

61개의 레코드를 썼다고 나오네요 즉 where.js 파일에 기록했다는 것이죠

61개 데이터

 

 

아래에 Open where.html 열라고 되어있으니 그전에 where.html 코드입니다.

<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>A Map of Information</title>
    <link href="https://google-developers.appspot.com/maps/documentation/javascript/examples/default.css" rel="stylesheet">

    <!-- If you are in China, you may need to use theis site for the Google Maps code
    <script src="https://maps.google.cn/maps/api/js" type="text/javascript"></script> -->
    
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <script src="where.js"></script>
    <script>

      function initialize() {
        alert("To see the title of a marker, hover over the marker but don't click.");
        var myLatlng = new google.maps.LatLng(37.39361,-122.099263)
        var mapOptions = {
          zoom: 3,
          center: myLatlng,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

        i = 0;
        var markers = [];
        for ( pos in myData ) {
            i = i + 1;
            var row = myData[pos];
		    window.console && console.log(row);
            // if ( i < 3 ) { alert(row); }
            var newLatlng = new google.maps.LatLng(row[0], row[1]);
            var marker = new google.maps.Marker({
                position: newLatlng,
                map: map,
                title: row[2]
            });
            markers.push(marker);
<!-- New options for MarkerClusterer function to display markers -->
	    var options = {
			imagePath: 'http://rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m'
			}	
        }
<!-- New var -->
	var markerCluster = new MarkerClusterer(map, markers, options);
      }
    </script>
  </head>
  <body onload="initialize()">
<div id="map_canvas" style="height: 500px"></div>
<p><b>한성</b></p>
<p>
DSC2019 열심히 하자 
</p>
</body>
</html>

 

 

where.html을 열어보면 오.. 잘 나오네요! 

 

결과물

 

댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31