6.1 샘플 프로젝트

 

이 장에서는 간단한 프로젝트를 개발한다. 이 프로젝트는 지금까지 배운 많은 기술과 개념을 하나로 묶어준다. 또한, 이 프로젝트는 이 수업의 텀 프로젝트의 구조를 보여준다. 여기서 제시되는 샘플은 좋은 프로젝트 형식의 본보기가 될 것이다.

 

이 프로젝트의 주요 구성은 다음과 같다:

  • 데이터 스트림 : 빅 데이터 스트림의 특성, 구조, 내용 설명
  • 탐구 목적 : 무엇을 위해 데이터 스트림을 분석할 것인가? 왜 이러한 목적들이 중요한가? 어떤 사람(들)이 이러한 분석 결과에 관심이 있을 것인가?
  • 한계 : 데이터의 특성이나 분석 방법에 의해 제한되는 결론의 보편성의 원인들
  • 프로그램 개발 : 컴퓨팅적 분석을 수행하기 위해서 개발된 코드와 알고리즘의 제시
  • 시각화 : 데이터 스트림의 컴퓨팅적 분석에 의해 생성된 정보의 시각적 표현
  • 결론: 탐구 목적에 대한 해답과 그 의미
  • 사회적 영향: 이해관계자들과 그들에게 미칠 수 있는 이익과 손해 분석
  • 감사의 글 : 이 프로젝트의 발전에 기여를 한 사람들에 대한 공로를 인정

 

이상 7개의 구성 요소들은 이 장의 다음 절에서 설명될 것이다.

 

6.1.1 데이터 스트림

이 프로젝트는 지진 데이터 스트림을 사용한다. 이 데이터 스트림은 미국 지질 조사국에서 공개적으로 이용이 가능하며, 전 세계적으로 보고 된 모든 지진에 대한 기록이 포함되어 있다. 지진의 추상화는 속성의 집합으로 표현된다. 데이터 스트림은 이 프로젝트에서 사용되는 것보다 더 많은 속성을 가지고 있다.

 

지진 데이터 스트림은 earthquakes.py 모듈을 통해 파이썬에서 접근할 수 있다. 이 모듈은 지진의 시간과 강도 범위라는 2개의 매개변수를 기반으로 최근의 지진에 대한 정보를 반환하는 get_report 함수를 포함한다. 기간은 “hour”, “day”, “week”, 또는 “month”일 수 있다. 강도 범위는 정보에 포함될 진도의 범위를 정의하고 “significant”, “all” “4.5”, “2.5”, 또는 “1.0” 중에 하나의 값이 될 수 있다. 이 프로젝트에 대한 데이터 스트림을 얻기 위해서 파이썬 코드를 다음과 같이 사용한다.

import earthquakes

quakes = earthquakes.get_report('month','all')

 

이 스트림은 지난달에 보고된 모든 지진들로 구성된다.

 

복잡한 자료구조의 맵(Map)은 스파이더의 변수 탐색기(Variable explorer)창을 사용하여 생성될 수 있다. 맵은 관심 있는 데이터의 일부에 접근하는 방법에 대한 지침을 제공하고, 데이터 스트림의 구조를 간략하게 설명할 수 있는 시각적 표현이다. 스파이더 창의 일부가 다음 그림에 나타나 있다. 다양한 자료형의 속성들이 편집기 창에 정의되어 있다. 변수 탐색기(Variable explorer)창의 Run버튼을 누르면 다음과 같이 나타난다. 코드 안에서 사용되는 모든 변수들은 변수 탐색기 안의 항목에 있다.

 6-1

그림 6-1. 스파이더의 속성 탐색기

 

변수 탐색기 창 안에서 나타난 각각의 변수는 네 개의 열을 가진다. Name열은 변수의 이름을 제공한다. Type열은 변수가 가지고 있는 자료형을 보여준다. Type열에서 사용 된 자료형들은 아래의 표에 요약되어 있다. 변수 namestr(문자열), whole_numberint(정수), numberfloat(실수)이다.

표 6-1. Type

Type 필드의미
dict키워드에 의해 접근 되는 사전
list위치에 의해 접근되는 리스트 구조
str문자열
float소수점 수
int모든 정수(소수점이 없는)

 

변수 탐색기 안의 Size 열은 기본 자료형(숫자와 문자열)에 대해서 값이 하나이므으로 1이다. Size 는 문자열에서 문자의 수나, 숫자에서 숫자의 자릿수가 아니다. 이러한 값의 종류들은 하나의 단위로 간주된다. name, number 그리고 whole_number의 크기가 모두 1이라는 것을 알 수 있다. 리스트의 Size 는 리스트의 요소들의 개수이다. number_list는 5개의 값으로 정의되어 있으므로, 크기가 5임을 알 수 있다. 사전의 Size 는 사전에서 키-값 쌍의 수이다. weather 은 3쌍의 키-값을 가지므로, Size 가 3임을 알 수 있다.

 

변수 탐색기에 의해 보여 지는 사전과 리스트는 변수 탐색기의 항목을 더블 클릭함으로써 상세한 내용을 볼 수 있다. 예를 들면, 아래의 그림은 number list를 더블 클릭한 결과를 보여준다. 새로운 창은 리스트의 각 요소들의 세부 항목을 보여 준다. 이 예시에서는, 리스트의 모든 요소들이 int이고 크기는 1이다. 리스트 요소의 값은 Python 코드에서 정의된 것과 정확히 일치한다. 리스트를 검토하는 것을 완료했을 때, OK 버튼을 클릭하여 리스트를 보여주는 창을 닫을 수 있다.

 6-2

그림 6-2. 스파이더의 변수 탐색기를 사용한 리스트의 확장

 

이와 유사하게, 사전도 더욱 상세하게 내용을 표시하기 위해 동일한 방식으로 확장될 수 있다. 다음의 그림은 변수 탐색기에서 weather 사전을 더블 클릭한 결과를 보여준다. 사전의 내용을 보여주기 위해서 새로운 창이 나타난다. 창의 항목은 모든 키-값 쌍을 보여준다. 예를 들면, 첫 번째 행은 ‘humidity’ 키와 int 자료형의 값을 갖는다. 이 값은 숫자 20이다. 창에서 보여 지는 세 쌍의 키-값 쌍은 Python 코드에서 정의한 것과 동일하다. 이 창은 OK 버튼을 클릭하여 닫을 수 있다.

6-3 

그림 6-3. 스파이더의 변수 탐색기로 사용한 사전의 확장

 

지금까지 스파이더의 변수 탐색기를 기본 자료형(숫자와 문자열)과 간단한 자료구조(리스트와 사전)를 보여주는 데 사용할 수 있다는 것을 설명하였다. 그러나 실습에서 가장 흥미로운 데이터는 사람들이 모델링할 수 있는 실제 세계의 복잡한 현상들이며, 추상화의 여러 계층을 반영하는 복잡한 구조를 가지고 있다. 다음으로 스파이더에서 더 복잡한 자료구조를 탐구하기 위해 사용하는 방법과 “map”-(데이터의 구조를 위한 시각적 가이드)을 개발하는 방법을 알아본다.

 

 맵과 복잡한 자료구조가 어떻게 상호작용하는 지에 대한 설명을 위해 미국 지질 조사에서 얻은 지진 데이터에 대한 자료구조를 사용할 것이다. 이 예시에서는 지난주의 모든 지진에 대한 데이터 스트림을 가져온다. 이 데이터 스트림은 아래 그림에서처럼 get_report 함수에 의해 반환 된다. 데이터 스트림은 quakes 변수로 지정된다. 이 변수는 변수 탐색기 영역에 표시된다.

 6-4

그림 6-4. 지진 데이터의 탐구 (1 단계)

 

변수 탐색기에서 quakes 속성이 세 개의 키-값 쌍을 가진 사전이라는 것을 볼 수 있다. 사전의 세부 항목을 검색하기 위해서 이전에 했던 것과 같이 변수 탐색기의 속성 개체를 더블 클릭할 수 있다. 그 결과로, 다음의 그림에서와 같이 제목이 “quakes”인 새 창이 나타난다. 이 창은 quakes 사전의 시각적 설명을 제공한다. 이 경우에서, 사전이 3개의 키-값 쌍을 가지는 것을 볼 수 있다. 그 키들은 ‘area’, ‘earthquakes’ 그리고 ‘title’이다. “area”키와 연결되어 있는 값은 사전형이다. ‘earthquakes’키와 연결되어 있는 값은 2412개의 요소를 갖는 리스트이다. ‘title’ 키와 연결되어 있는 값은 문자열이다.

 6-5

그림 6-5. 지진 데이터의 탐구 (2 단계)

 

‘earthquakes’키와 관련 있는 리스트 값을 살펴봄으로써 데이터를 더 탐구할 수 있다. 스파이더에 의해 보여 지는“quakes” 창의 ‘earthquakes’ 개체를 클릭하면 제목이 “earthquakes”인 리스트를 보여주는 새로운 창이 만들어진다. 다음 그림에서 이를 볼 수 있다.

 6-6

그림 6-6. 지진 데이터의 탐구 (3 단계)

 

새로운 창(제목이 “earthquakes”인)에서 ‘earthquakes’키와 관련 있는 리스트의 각 요소가 사전형이라는 것을 볼 수 있다. size 필드는 이 사전이 각각 15개의 키-값 쌍을 가진다는 것을 나타낸다. 이러한 사전의 구조를 알아보기 위해서, “earthquakes” 창에 나타나는 리스트의 특정 항목을 더블 클릭한다. 그 결과, 리스트의 선택된 항목에 대한 15개의 키-값 쌍이 보이는 또 다른 창이 나타난다. 다음 그림에서 그 예를 볼 수 있다.

 6-7

그림 6-7. 지진 데이터의 탐구 (4 단계)

 

 

새로 나타난 창은 각 15개의 키-값 쌍을 보여준다. 하나의 키 magnitude는 리히터 단위로 측정된 지진 규모로 float형이다. ‘location’ 키와 관련 있는 값은 전 세계적으로 지진이 발생한 위치를 나타낸다. 지진 데이터 스트림의 주된 요소는 지진의 리스트이다. 이 프로젝트에서 사용된 지진의 추상화는 두 가지 속성을 가지고 있다.

  • 위치 : 세계에서 지진이 발생한 위치
  • 진도 : 리히터 단위로 측정 된 지진의 강도

 

또한 이 그림은 location 속성이 3개의 요소로 구성되었음을 보여준다.

  • 위도 : 세계에서 지진의 위도
  • 경도 : 세계에서 지진의 경도
  • 깊이 : 지진의 중심이 되는 곳의 지구 지각의 깊이

 

요약하면, 이 프로젝트에서 사용되는 데이터 스트림의 부분은 아래의 그림에서 보여 진다.

 6-8

그림 6-8. 지진 데이터 스트림의 구조

 

6.1.2 탐구 질문

지진 데이터 스트림에 대한 분석은 다음의 질문에 답할 수 있다.

  • 지진 규모의 분포는 어떠한가?
  • 위도와 경도는 상관관계가 있는가?
  • 지진은 세계 어디에서 발생하는가?
  • 진도와 깊이 사이에는 관계가 있는가?

 

첫 번째 질문은 모든 진도의 지진이 동등한 가능성으로 일어나는지 혹은 특정 범위의 진도를 가진 지진이 다른 진도를 가진 지진보다 더 일어날 가능성이 높은 지에 대한 통찰력을 제공한다. 두 번째 질문에 대한 답은 지진이 특정 장소에서 발생할 가능성이 있는지 혹은 지진이 발생하기 쉬운 지역이 있는 지의 여부를 나타낸다. 세 번째 질문에 대한 답은 지진의 위치와 대륙의 위치 사이의 관계를 알 수 있게 해준다. 만약 두 번째 질문이 지진이 특정 지역에서 발생할 가능성이 더 높다는 것을 나타낸다면, 세 번째 질문에 대한 답인 지진이 더 많이 일어나는 경향이 있는 지리적인 영역을 식별하는데 도움을 줄 것이다. 마지막 질문에 대한 답은 지진의 형성에 대한 성질 정보를 생성한다. 더 강한 강도의 지진은 깊은 지각에서 발생하는가? 깊은 지진은 특정 지리적 영역과 관련이 있는가?

 

지진이 큰 손상 및 인명 손실에 대한 잠재적인 가능성을 가지고 있기 때문에, 지진의 성질 또는 위치에 대한 정보는 유용하다. 또한, 지진은 매우 예측이 어렵기 때문에 그 발생 패턴에 대한 어떤 통찰도 매우 소중하다.

 

지진 분석은 과학자, 정부 계획자, 기업 및 일반 대중에게 유용하다. 지구 과학자들은 지진을 더 잘 설명하고 궁극적으로 예측하기 위해 일반적인 지진의 현상에 관심이 많다. 정부 계획자들은 발전, 배수, 운송 등의 중요 기반 시설을 개발하는 데 지진의 잠재적 영향을 생각할 필요가 있다. 또한 정부 계획자들은 잠재적인 지진의 충격을 고려해야 할 필요가 있는 건설 규제를 만드는 것에 관심을 갖는다. 기업은 부지 선정과 보험 혜택의 적용 범위에 대한 결정을 위해 지진의 잠재적 피해를 고려할 수 있다.

 

6.1.3 한계점

이 연구의 결론의 가장 큰 한계점은 분석되는 데이터 스트림의 기간이다. 데이터 스트림은 가장 최근의 몇 달 동안의 지진 정보만 포함한다. 이러한 제한된 기간에는 오랜 기간에 걸쳐 일어나는 지진의 특성이나 패턴은 나타나지 않을 수 있다. 예를 들어, 가장 최근 몇 달 간은 상대적으로 잠잠한 기간이 있는 지진이 발생하기 쉬운 지역이 있다면, 이 연구의 결과는 지진의 지리적인 분포를 적절하게 반영하지 못할 것이다. 두 번째 한계는 지진에 대한 주어진 정보가 그 강도와 위치뿐이라는 것이다. 지진 발생에 대해 중요한 통찰력을 제공하는 데 포함되지 않은 다른 특징들이 있을 수 있다.

 

6.1.4 프로그램 개발

프로그램 개발의 첫 단계는 지진 정보 서비스를 불러와서 지난 달의 지진 데이터를 생성하는 것이다. 이 과정은 다음의 코드에 나와 있다.

import earthquakes

 

# 모든 지진 데이터 수집

quakes = earthquakes.get_report('month', 'all')

 

진도의 분포에 관련된 첫 번째 질문에 답을 하려면, 데이터 스트림은 오직 진도 정보만 포함하여 생성되어야 한다. 그리고 이 데이터를 막대그래프 형태로 나타낸다. 다음은 이 과정에 대한 코드이다.

 

import matplotlib.pyplot as plt

 

# 진도의 정보를 담은 리스트 생성

magnitudes = []

for qk in quakes['earthquakes']:

magnitudes.append(qk['magnitude'])

 

# 진도를 막대그래프로 표현

plt.hist(magnitudes, bins=[0,1,2,3,4,5,6,7])

 

# 축 라벨

plt.xlabel('Magnitudes')

plt.ylabel('Occurrences')

plt.title('Histogram of Magnitudes')

 

# 막대그래프 표시

plt.show()

 

# 다음 그래프를 그리기 전에 지우기

plt.clf()

 

지진의 진도들의 리스트를 생성한 후, 진도의 평균은 리스트의 값들을 이용하여 계산한다. 이 코드에 의해 생성된 막대 그래프는 다음 장에서 볼 수 있다. matplotlib 모듈이 호출되어 있고, hist 함수가 막대 그래프를 만들기 위해 사용되는 것을 알 수 있다. bins 인수는 진도 데이터가 여러 그룹으로 묶여 표시되도록 지정한다. 첫 번째 bin은 진도가 0이상 1미만인 모든 지진을 포함하고, 두 번째 bin은 진도 1이상 2미만의 모든 지진을 포함하는 식으로 진행된다. 막대 그래프의 라벨은 막대 그래프가 표시되기 전에 알맞게 그려진다.  

 

 또한 진도 중앙값과 진도 평균(평균 지진)을 결정함으로써 진도의 분포에 대한 몇 가지 추가적인 정보를 얻을 수 있다. 값의 반은 중앙값보다 낮고, 값의 반은 중앙값보다 높으므로, 중앙값은 리스트 값의 중간 지점이다. 이러한 두 통계 치를 계산하는 코드는 아래와 같다. 이러한 두 통계 치를 계산하는 코드가 아래에 나타난다.

# 평균 진도를 계산

magnitudeMean = round(sum(magnitudes)/len(magnitudes),2)

 

# 중간 진도를 계산

sortedMagnitudes = sorted(magnitudes)

magnitudeMedian = sortedMagnitudes[int(len(magnitudes)/2)]

 

print('mean = ', magnitudeMean)

print('median = ', magnitudeMedian)

 

이 코드는 리스트를 다루기 위해 많은 Python의 내장 함수를 사용한다. 이것들은 다음과 같다.

  • sum : 리스트의 모든 값을 더한 값을 반환
  • len : 리스트 값의 개수를 반환
  • sorted : 정렬된 순서로 리스트의 모든 원소를 가진 새 리스트를 반환

 

또한 코드는 주어진 숫자의 정수 부분만 반환하는 함수인 int()를 사용한다. 즉, int(2.5)는 2이고 int(2.9) 도 2이다.

 

위의 코드는 진도 리스트의 길이로 sum을 나눔으로써 평균값을 계산한다. 중앙값은 정렬된 리스트 값에서 중간 원소이다. 분석된 데이터에 대한 결과는 다음과 같다.

mean = 1.47

median = 1.2

 

두 번째 질문은 지진의 경도와 위도 사이에 상관 관계가 있는지 여부이다. 다시 말해서, 지진이 자주 발생하는 장소가 있는 것인지, 전 세계에 걸쳐 무작위로 발생하는 지를 알아본다. 이 질문은 경도와 위도의 산포도 그래프를 그림으로써 답을 얻을 수 있다. 그래프에서 상대적으로 무작위인 패턴은 지진이 무작위로 발생한다는 것을 나타내고, 그에 반해 지진의 군집(cluster)은 그 영역이 지진이 더 발생하는 경향이 있다는 것을 나타낸다. 산포도 그래프를 생성하는 코드는 다음과 같다.

latitudes = []

longitudes = []

 

# 위도와 경도 리스트를 생성

for qk in quakes['earthquakes']:

        latitudes.append(qk['location']['latitude'])

        longitudes.append(qk['location']['longitude'])

 

# 2차원 좌표평면에 지진 발생 위치 산포도를 그림

# 각 지진 발생 위치 (longitude[i], latitude[i])에 붉은 '+' 표시

 

plt.scatter(longitudes, latitudes, c='r', marker='+')

 

# 축 라벨

plt.xlabel('Longitude')

plt.ylabel('Latitude')

plt.title('Earthquake Longitude vs. Latitude')

plt.show()

 

# 다음 그래프를 그리기 전에 지우기

plt.clf()

 

첫 번째 질문으로 만들었던 quakes 데이터 스트림은 여기서 재사용된다. mapplotlib의 함수 scatter 산포도 그래프를 생성하는 함수)가 별개의 리스트 데이터를 필요로 하기 때문에, 코드의 첫 단계는 필요한 두 개의 리스트로 데이터를 필터링하는 것이다. 이 코드에 의해 생성된 산포도는 다음 장에서 볼 수 있다. 세 번째 질문의 답을 찾으려면 2차원 지구본에 데이터를 표시해야 한다. 이 단계에서 필요한 데이터는 위에서 생성된 위도와 경도와 같다. 시각화를 생성하기 위해 필요한 새로운 코드는 다음과 같다.

 

from mpl_toolkits.basemap import Basemap

 

# Hammer (eliptical, equal-area) 투영을 사용하여 지도 그리기

# 위도 180도를 기준으로 (즉, 시각화된 지도의 0도가

# 실제 지구의 180도가 되도록)

 

map = Basemap(projection='hammer',lon_0=180)

 

# 대륙의 외곽선을 그린다

map.drawcoastlines()

 

# 위도와 경도를 지도상의 좌표로 변환

x, y = map(longitudes,latitudes)

 

# 지도에 위치 표시

map.scatter(x, y)

 

plt.title('Locations of earthquakes')

plt.show()

 

plt.clf()

 

이 코드에서 Basemap 유틸리티는 mpl_toolkits으로부터 불러온다. Basemap은 Hammer 투영을 사용하여 지구본의 이차원 지도를 만드는데 사용한다. 대륙의 윤곽은 drawcoast lines 함수를 사용하여 지구본에 그려진다. 다음으로, 위도와 경도를 지도 상 좌표로 변환하고, 이를 지도에 표시한다. 그래프에 제목을 추가하고, 사용자에게 보여준다. 이 코드에 의해 생성된 세계 지도 그래프는 다음 장에서 확인할 수 있다. 지구본을 이차원으로 나타내는 다양한 방법이 있으므로, 두 번째 시각화는 Lambert Conformal 투영을 사용하여 만들어볼 것이다. 이 투영도를 생성하기 위한 코드는 아래와 같다.

# Lambert Conformal 투영을 사용하여 지도 그리기

# 좌표 (90, -107)을 중심으로 높이 6000km, 넓이 4500 km

lambertMap = Basemap(projection='lcc',lat_0= 90, lon_0=-107,                                                 height=60000000, width= 45000000)

 

# 지도 외곽선을 그린다

lambertMap.drawcoastlines()

lambertMap.drawmapboundary()

 

# 위도와 경도를 지도상의 좌표로 변환

x, y = lambertMap(longitudes,latitudes)

 

# 지도에 위치 표시

lambertMap.scatter(x, y)

 

plt.title('Locations of earthquakes')

 

# 지도 표시

plt.show()

 

plt.clf()

 

여기서, 각각의 투영도를 생성하는 코드는 매우 유사한 것을 알 수 있다. 그러므로 공통적으로 쓰이는 부분을 취합한 함수를 정의하여 사용하도록 이 코드를 재작성할 수 있다. drawMap함수는 Basemap함수에 의해 반환되는 map 구조인 한 개의 매개변수(parameter)를 가지고 있다. 두 지도를 생성하기 위한 함수를 정의하고 사용하는 코드는 아래와 같다.

def drawMap(map):

# 주어진 지도에 위치 표시

       #지도 외곽선을 그린다

       map.drawcoastlines()

       map.drawmapboundary()

 

       # 위도와 경도를 지도상의 좌표로 변환

       x, y = map(xValues, yValues)

 

       # 지도에 위치 표시

       map.scatter(x, y)

 

       plt.title('Locations of Earthquakes')

       plt.show()

 

       plt.clf()

 

# drawMap 함수를 사용하여 위도 180도를 중심으로

       # Hammer (eliptical, equal-area) 투영을 사용한 지도를 그린다

hammer_map = Basemap(projection='hammer',lon_0=180)

# 지도를 그린다

drawMap(hammer_map)

# drawMap 함수를 사용하여 좌표 (50, -107)를 중심으로 하고

# 넓이 4500km, 높이 6000km인 Lambert Conformal 투영을 사용하여 지도를 그린다

lambert_map = Basemap(projection='lcc',lat_0= 90, lon_0=-107,                                                 height=60000000, width= 45000000)

#지도를 그린다

drawMap(lambert_map)

 

이 코드는 불필요한 중복을 제거함으로써 코드를 매우 단순화시켜 Basemap에 의해 반환되는 추가적인 지도들을 생성하는 것을 쉽게 만들어준다.

 

네 번째 질문에 답하기 위한 적절한 방법은 지진들의 진도와 깊이 간의 산포도를 그려보는 것이다. 진도 정보는 첫 번째 질문에 대한 답으로 생성되었다. 이 질문에 답하기 위해 필요한 새로운 코드는 다음과 같다.

#각 지진의 깊이들의 리스트 생성

for qk in quakes['earthquakes']:

          depths.append(qk['location']['depth'])

 

# 진도와 깊이의 관계를 그린 산포도를 2차원 좌표에 그린다

# 각 지진마다 좌표 (longitude[i], latitude[i])에 붉은 '+' 표시

 

plt.scatter(magnitudes, depths, c='r', marker='+')

 

# 축 라벨

plt.xlabel('Magnitude')

plt.ylabel('Depth')

plt.title('Earthquake Magnitude vs. Depth')

plt.show()

 

plt.clf()

 

이 코드는 지진의 진도와 깊이 사이의 산포도를 그리기 위해 앞서 사용했던 maplotlib 함수를 사용한다. 이 코드에 의해 생성된 산포도의 시각화는 다음 장에서 볼 수 있다.

 

‘위도와 경도’의 산포도를 생성하는 코드와, ‘진도와 깊이’의 산포도를 생성하는 코드 사이에도 아주 많은 중복이 있다. 이 중복을 제거하기 위해 새로운 함수를 정의한다. 재정의된 코드의 핵심 부분은 아래와 같다.

def drawPlot(xValues, yValues, xLabel='X Axis', yLabel='Y Axis',

                      figureLabel='Scatter Plot'):

     # xValues와 yValues의 관계를 담은 산포도를 2차원 좌표에 그린다

    # 각 데이터 점마다 붉은 '+' 표시

 

    plt.scatter(longitudes, latitudes, c='r', marker='+')

 

    # 축 라벨

    plt.xlabel(xLabel)

    plt.ylabel(yLabel)

    plt.title(figureLabel)

 

    #그림을 표시하고 창이 닫히면 지운다

    plt.show()

    plt.clf()

 

# 지진 데이터 수집

quakes = earthquakes.get_report('month', 'all')

 

# 지진의 위도와 경도를 담은 리스트 생성

longitudes = []

latitudes = []

for qk in quakes['earthquakes']:

        latitudes.append(qk['location']['latitude'])

        longitudes.append(qk['location']['longitude'])

 

# 지진의 위도와 경도에 따른 산포도를 그린다

drawPlot(latitudes, longitudes, 'Latitudes', 'Longitudes',

               'Earthquake Occurrences')

 

# 지진의 진도와 깊이를 담은 리스트 생성

magnitudes = []

depths = []

for qk in quakes['earthquakes']:

     magnitudes.append(qk['magnitude'])

     depths.append(qk['location']['depth'])

 

 

# 지진의 진도와 깊이에 따른 산포도를 그린다

 

drawPlot(magnitudes, depths, 'Magnitude','Depth',

               'Earthquake Magnitude vs. Depth')

 

이 재정의된 코드에서 산포도를 그리기 위해 공통적으로 사용되는 코드를 묶어 drawPlot 함수를 정의하였다. 아래는 drawPlot 함수의 매개변수에 대한 설명이다.

  • xValues : 각 데이터 점의 x축 값 리스트
  • yValues : 각 데이터 점의 y축 값 리스트
  • xLabel : x의 label로 사용되는 텍스트
  • yLabel : y축의 label로 사용되는 텍스트
  • figureLabel : 전체 그림의 label로 사용되는 텍스트

 

세 개의 텍스트 매개변수는 기본 값이 있으므로 x축, y축의 세부항목에 대한 걱정 없이 간단하게 그래프를 그릴 수 있다.

 

drawPlot 함수를 사용함으로써 두 산포도를 그리는 코드가 그래프로 그려질 데이터 리스트를 생성하는 부분과 이 리스트로 drawPlot함수를 호출하는 부분으로 간소화되었다.

 

이곳에서 전체 코드를 다운로드할 수 있다.

 

6.1.5 시각화

첫 번째로 살펴볼 시각화는 막대그래프이다. 여기서는 첫 번째 유효 숫자가 동일한 진도를 모두 그룹화 하였다. 즉, 진도가 1.0보다 작은 지진은 모두 카테고리 0으로 그룹화 되고, 진도가 2.0보다 작고 1.0이상인 지진은 모두 카테고리 1로 그룹화 되는 식이다. 평균 진도 값이 1.47임을 상기하라.

 6-9

그림 6-9. 지진 진도의 막대그래프

 

두 번째로 살펴볼 시각화는 위도와 경도의 산포도를 보여준다. 데이터 점이 균일하게 분포되지 않는 것으로부터, 지진 발생 위치에 특정 패턴이 존재함을 알 수 있다. 지진이 자주 발생하는 지역과 선을 볼 수 있다.

 6-10

그림 6-10. 지진 위치의 분포

 

세 번째와 네 번째로 살펴볼 시각화에는 지표면의 2차원 투영도 위에 지진의 위치들이 나타나 있다. 세 번째 시각화에는 Hammer 투영, 네 번째 시각화에는 Lambert Conformal 투영이 사용되었다. 세 번째 시각화는 지진의 발생 패턴이 가장 잘 보이도록 태평양 바다를 중심으로 하였다. 네 번째 시각화는 북극을 중심으로 한다.

 6-11

그림 6-11.  Hammer Projection을 사용한 지구본 위의 지진 위치

 

 6-12

그림 6-12. Lambert Conformal Projection을 사용한 지구본 위의 지진 위치

 

마지막으로 살펴볼 시각화는 지진의 깊이와 진도의 산포도이다. 진도는 수평축에 그려지고, 깊이는 수직축에 그려진다. 각각의 지진은 붉은 ‘+’로 나타나 있다.

 6-13

그림 6-13. 지진의 깊이 vs 진도

 

이러한 시각화로부터 유추할 수 있는 결론은 다음 장에서 볼 수 있다.

 

6.1.6 결론

첫 번째 질문은 지진의 진도의 분포를 탐구한다. 데이터 분석의 결과는 위의 “지진의 진도 막대그래프”라는 제목의 그림에서 볼 수 있다. 진도의 분포는 작은 크기의 지진에 대다수가 편향되어 있다. 매우 큰 진도의 지진들은 극히 일부이다. 중앙값과 평균값에서도 이를 확인할 수 있다. 이 데이터 집합의 중앙값은 1.2밖에 안되지만 평균값은 1.47이다. 그러므로 지진의 진도의 평균값은 1.47인 반면에 발생한 모든 지진의 절반은 1.2 이하의 진도를 갖는다. 소수의 아주 강한 지진에 영향을 받아 평균값이 중앙값보다 크다.

 

두 번째 질문은 전 세계에서 지진이 같은 가능성으로 발생하는지 아니면 지진이 발생하기 쉬운 지역이 있는지를 탐구한다. 이 질문에 대한 답은 위의 “지진 위치의 분포” 그림에서와 같이 각 지진의 위도와 경도를 그래프로 그림으로써 알아볼 수 있다. 그림에서 나타난 바와 같이 지진은 전 세계에 균일하게 분산되어 있지 않다. 몇몇 위치 혹은 선을 따라 지진의 군집이 존재함을 명확히 볼 수 있다.

 

지진의 발생 위치의 군집과 대륙의 위치간의 관계는 지진 위치의 그래프인 2차원 지표면 투영도에서 볼 수 있다. “Hammer 투영을 사용한 지구상의 지진 발생 위치”와 “Lambert Conformal 투영을 사용한 지구상의 지진 발생 위치” 그림들을 보라. 이 두 가지 그림에서 많은 수의 지진이 태평양 연안을 따라 발생한다는 것을 명백히 볼 수 있다. 물론 이 분석 결과는 지각 판의 가장자리와 일치한다.

 

마지막 질문은 지진의 크기와 깊이 사이의 관계를 탐구한다. 이는 아주 심한 지진이 지구 깊은 곳에서 발생하는 것인지 지표면 가까운 곳에서 발생하는 것인지에 관한 질문이다. 깊이와 크기의 산포도는 위의 “지진의 깊이 vs 진도”라고 이름 붙여진 그림에서 볼 수 있다. 이 시각화로부터 아주 깊은 곳에서의 지진은 모두 크기가 크다는 것을 알 수 있다. 그러나 큰 크기의 지진은 어느 깊이에서나 발생할 수 있다.

 

이 결론은 다음과 같이 요약된다.

  • 대부분의 지진들은 작은 크기의 지진이고, 큰 크기의 지진은 드물다.
  • 지진은 지구의 특정 지역에서 발생하기 쉽고, 특히 태평양 연안을 따라서 자주 발생한다.
  • 지각의 깊은 곳에서 발생하는 지진은 항상 크기가 큰 지진이다.

 

물물론, 위에서 언급한 한계점(“한계점” 참조)은 계속 염두에 둬야 한다.

 

6.1.7 사회적 영향

진의 발생 위치와 진도에 관한 연구는 매우 많은 수의 다양한 이해관계자들에게 영향을 미친다. 이러한 이해관계자들과 그들의 관심 사항은 다음과 같다:

  • 부동산 소유자: 개인 재산을 소유하는 개인 또는 건물을 소유하는 회사는 지진으로 인한 손실로부터 자신을 보호하는 것에 큰 관심을 갖는다. 이는 지진이 일어난 후에 재건 비용을 지불하는 보험에 가입하거나 내진 설계를 하는 형태로 나타난다.

 

  • 보험회사 : 재건에 대한 비용을 지불하는 보험을 제공하는 회사는 그들이 보험을 제공하는 지역에서 지진으로 야기되는 손상과 지진 발생 가능성을 평가해야 한다. 회사가 설정한 요율은 실제 위험에 따라야 한다.

 

  • 정부 : 정부의 각계각층은 모두 지진과 관련하여 어느 정도 역할이 있다. 연방 및 주 정부는 그들의 국가에서 시민의 안전을 위협하는 심각한 지진에 의한 비상사태에 대하여 대비 및 복구 책임이 있다. 국가 및 지방 자치 단체는 지진에 의해 영향을 받을 수 있는 병원이나 발전소와 같은 중요 인프라의 위치를 선정하고 보호하는 중요한 역할을 수행해야한다. 또한, 정부의 여러 부서는 지진 발생 시 건물 안전에 대한 규정을 만들어야 하며, 건축 법규를 정의해야 한다.

 

  • 지구과학자: 지구 과학 현상과 관련된 연구자들은 지진의 근본 원인에 관심이 많다. 석유 및 가스 생산 수단인 유압 파쇄(시추)와 지진의 관계에 대해서 현재 논쟁이 진행 중이다. 이 질문에 답을 하려면 지진의 발생과 시추 행위의 관계에 관한 오랜 연구가 필요하다.

 

이해관계자들 사이에는 지진에 관한 새로운 지식과 경험에 따라 변화하는 논쟁거리가 있다.

 

예를 들면 :

  • 정부는 지진의 발생할 가능성에 따라서 건설이나 지역 활동을 얼마나 규제해야 하는가? 원자로, 화학 공장, 또는 가스 파이프라인은 지진이 일어나기 쉬운 지역에 건설되어도 되는가? 공장이 먼 곳에 위치했을 때 제공되는 서비스가 소비자의 비용을 증가시킬 수 있다는 것을 고려하면 공장의 위치를 결정하는데 지진에 대한 허용 수준이 필요하다

 

  • 복구 및 재건을 위한 보험과 정부 사이의 책임의 균형점은 어디인가? 드물지만 가능성은 있는 경우에 이러한 균형점은 어떻게 바뀌어야 하는가?(캘리포니아의 “big one” 처럼)

 

  • 시추 행위가 지진 발생 위험과 관련이 있다는 증거가 증가한다면, 시추 기술의 예상치 못한 결과를 고려한 대중의 입장은 무엇인가? 만약 이전에 지진이 빈번하지 않았던 지역이 지진이 빈번하게 발생하는 지역이 된다면 이 에너지를 저렴하다고 할 수 있는가?

 

개인의 수준에서는, 시추 행위의 지질학적 결과가 명확하지 않음에도 시추 기술의 수준을 높이기 위해 석유와 가스 회사를 돕는 지질학자들의 도덕적 딜레마를 어떻게 해결할 수 있는가?

 

위의 설명은 국가의 관점을 취하고 있다: 정부의 여러 부처의 역할, 건축 법규와 토지 이용의 전통적인 역할, 보험 산업의 운영 방침. 하지만 이러한 문제들은 국제적인 관점에서도 볼 수 있다.

 

지진은 세계적인 현상이기 때문에 지진의 “빅데이터”연구는 잠재적으로 큰 영향력이 있다. 특히, 국가 정부와 국제기구는 가난하거나 경제가 불안정하지만 지진으로부터 큰 영향을 받을 가능성이 있는 국가들에서의 지진 피해의 예방, 재건, 복구 문제에 어떻게 대처해야 하는가?

 

6.1.8 감사의 말

이 프로젝트에 엄청난 기여를 해준 Cory Bart에게 큰 감사를 표한다. 데이터 스트림을 이용하고 Python 시각화 라이브러리를 사용하는데 그의 도움이 없었다면 이 프로젝트는 불가능 했을 것이다. 또한, 토론을 통해 사회적인 영향에 대한 논의를 정리하는데 큰 도움을 준 Bushra Chowdhury와 Dr. Yanna Lambrinidou에게도 감사를 표하고 싶다.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*