no image
[AWS] DataBase
1. 활용 방법 1) EC2 인스턴스에 Database를 설치해서 사용 거의 모든 종류의 데이터베이스 사용 가능 관리 직업해야하므로 데이터베이스에 익숙해야 함 라이센스가 있는 데이터베이스 (Oracle이나 MySQL 등) 사용 시 주의! 2) AWS가 제공하는 관리형 데이터베이스 이용 데이터베이스에 제한이 있음 관계형 데이터베이스의 경우 Oracle, MySQL, Maria DB, Postgre SQL, MS SQL Server, IBM DB2만 사용 가능 Oracle과 MS SQL Server, DB2는 라이센스 비용이 같이 청구 No SQL 지원 Key - Value 데이터베이스 (Redis 호환) 와 Document DB (Mongo DB 호환) 지원 Dynamo DB는 아마존이 직접 만든 데이터베..
2024.04.18
AWS
[AWS] EC2 Service
1. 개요 - Amazon Elastic Compute Cloud의 약자 - 컴퓨팅 용량을 제공하는 서비스 - IaaS (Infrastructure as a Service) - 운영체제(AMI)가 설치된 컴퓨터를 임대해주는 서비스 서버를 만들고자 할 때 항상 켜져 있고 고정된 IP를 갖는 컴퓨터가 필요한 경우 사용 - Managed Service가 아니므로 네트워크나 컴퓨터 자체의 운영은 AWS가 담당하지만 나머지는 사용자가 결정 - 장점 클릭 몇번으로 서버 생성 생성과 삭제 편리 고장난 경우 자동 복구 부하 증가하면 같은 구성의 서버 복제하면 됨 - 단점 서버 한 대로 서비스가 가능하고 트래픽에 거의 변화가 없는 경우 비용이 부담될 수 있다. 2. 주요 구성 요소 - 인스턴스: 가상 서버 - AMI: ..
2024.04.18
AWS
[AWS] 개요
1. AWS (Amazon Web Service) - 시스템 운영에 관련된 다양한 서비스 제공하는 클라우드 기반 서비스 컴퓨팅, 스토리지, 데이터베이스, 분석 툴, 네트워크, 모바일, 개발자 도구 등 - 서비스 조합이 쉽다. - 요금이 종량제 사용한만큼 지불 특별한 경우 최소 요금이 설정되어 있다. 일반적으로 사용자의 트래픽이 수시 변경되는 경우라면 퍼블릭 클라우드가 유리하지만 일정한 트래픽이라면 On Premiss가 유리하다. 이런 경우는 고려할 사항 중 하나가 관리자의 인건비 - 사용이 쉽다. - 글로벌 확장이 쉽다. 현재 사용 가능한 Public Cloud 중 Region 과 AZ(가용 영역)이 가장 많음 한국에는 서울 리전이 있고 4개의 가용 영역 운영 중 - 보안 기준: ISMS (한국 정보보호..
2024.04.11
AWS
no image
[딥러닝] CNN _ 도로 교통 표지판 인식
1. 데이터 가져오기 - 43개의 교통 표지판 과 관련된 4만여 개의 이미지로 만들어진 데이터 셋 - https://sid.erda.dk/public/archives/daaeac0d7ce1152aea9b61d9f1e19370/published-archive.html Public Archive: daaeac0d7ce1152aea9b61d9f1e19370 Support ERDA User Guide Questions about ERDA? Please contact us at support@erda.dk sid.erda.dk - https://drive.google.com/drive/folders/1AktNCWqVBv-4xxme4OUC82OLJTHzMFsq?usp=sharing - 데이터 다운로드 colab !..
2024.03.22
no image
[딥러닝] CNN _ 패션 이미지 분류
1. 데이터 가져오기 from tensorflow import keras from sklearn.model_selection import train_test_split #데이터 읽어오기 (train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data() rint(train_input.shape) 2. 스케일링 및 차원 수정 # 흑백 이미지라서 차원을 1개 늘려서 255 로 나눔 train_scaled = train_input.reshape(-1, 28, 28, 1) / 255.0 print(train_scaled.shape) train_scaled, val_scaled, train_target, v..
2024.03.22
no image
[전처리] 인구 소멸 지역 Cartogram
- 국가 통계 포털에서 인구 정보 내려받기 http://kosis.kr/statHtml/statHtml.do?orgId=101&tblId=DT_1IN1509& KOSIS kosis.kr 기본코드 import pandas as pd import numpy as np import platform import matplotlib.pyplot as plt %matplotlib inline path = "c:/Windows/Fonts/malgun.ttf" from matplotlib import font_manager, rc if platform.system() == 'Darwin': rc('font', family='AppleGothic') elif platform.system() == 'Windows': fo..
2024.03.20
no image
[전처리] 서울시 범죄 현황 시각화
- https://data.seoul.go.kr/ - 서울시 5대 점죄 발생현황 통계 데이터 - crime.txt 1. 데이터 가져오기 import pandas as pd import folium import json criminal = pd.read_csv('./data/crime.txt', sep='\t', thousands=',', encoding='utf-8') 2. 데이터 전처리 # 불필요한 컬럼 제거 criminal.drop(['기간', '합계검거', '살인검거', '강도검거', '강간검거', '절도검거', '폭력검거'], axis=1, inplace=True) criminal.drop([0], inplace=True) # 컬럼 이름 설정 criminal.rename(columns={'살인발생..
2024.03.20
no image
[전처리] 지도 출력 Choropleth
https://github.com/southkorea/southkorea-maps 한국 지리정보 사이트 1. 데이터 읽어오기 state_unemployment = 'data/US_Unemployment_Oct2012.csv' state_data = pd.read_csv(state_unemployment) print(state_data.head()) State Unemployment 0 AL 7.1 1 AK 6.8 2 AZ 8.1 3 AR 7.2 4 CA 10.1 2. 단계 구분도 출력 folium.Map으로 만든 지도에 choropleth 함수 호출 geo_data 옵션에 아이디와 위도 및 경도를 가진 json 파일의 경로를 설정해주고 data에 출력한 DF 설정 key_on에 json 파일에서 사용되는..
2024.03.20

[AWS] DataBase

0ㅑ채
|2024. 4. 18. 21:18

1. 활용 방법

1) EC2 인스턴스에 Database를 설치해서 사용

  • 거의 모든 종류의 데이터베이스 사용 가능
  • 관리 직업해야하므로 데이터베이스에 익숙해야 함
  • 라이센스가 있는 데이터베이스 (Oracle이나 MySQL 등) 사용 시 주의!

 

2) AWS가 제공하는 관리형 데이터베이스 이용

  • 데이터베이스에 제한이 있음
    • 관계형 데이터베이스의 경우 Oracle, MySQL, Maria DB, Postgre SQL, MS SQL Server, IBM DB2만 사용 가능
    • Oracle과 MS SQL Server, DB2는 라이센스 비용이 같이 청구
  • No SQL 지원
    • Key - Value 데이터베이스 (Redis 호환) 와 Document DB (Mongo DB 호환) 지원
    • Dynamo DB는 아마존이 직접 만든 데이터베이스

 

 

 

2. 저장소 종류

1) RDBMS

  • Amazon Aurora
  • Amazon RDS
    • Oracle, MySQL, Maria DB, Postgre SQL, IBM DB2
  •  Amazon Redshift

 

2) Key-Value Database

  • Amazon DynamoDB
  • 높은 트래픽의 Web Applicatoin에 추천

 

3) In-Memory DB

  • ElsastiCache, Memory DB for Redis
  • Caching, 세션 관리, 게임 순위표, 자리 공간 애플리케이션 등에 추천

 

4) Document DB

  • Amazon의 Document DB - MongoDB 호환
  • 콘텐츠 관리, 카탈로그, 사용자 프로필 등 읽기 전용 애플리케이션에 추천

 

5) Wide Column DB

  • Amazon의 Keyspaces
  • 장비관리나 경로 최적화 등에 추천

 

6) Graph DB

  • Amazon의 Neptune
  • 부정 탐지, 소셜 네트워킹, 추천 엔진 등에 추천

 

7) Time Series

  • Amazon Timestream
  • IoT Application, DevOps, 산업용 텔레메트리 등에 추천

 

8) Ledger

  • QLDB: Amazon Ledger Database Service
  • 레코드 시스템, 공급망 관리, 은행 거래, 블록체인 등에 추천

 

9) S3와 같은 파일 저장소

 

 

 

3. Amazon RDS

  • Amazon에서 제공하는 관계형 데이터베이스 서비스
  • 장점: Managed Service, 관리나 업데이트를 직접 할 필요가 없음
  • 단점: 종류나 버전이 한정

 

1) 종류

  • MySQL: 현재까지 가장 많이 사용된 관계형 데이터베이스
  • Maria DB: MySQL의 fork
  • Oracle: 대기업에서 많이 사용되는 가장 안정적인 RDBMS
    • 금융이나 대기업이 주로 사용
    • 라이센스 비용 추가됨. 사용하려면 컴퓨터에 Oracle 설치하고 포트포워딩 이용해서 사용
  • MS SQL Server: 중소규모 기업에서 많이 사용하는 데이터베이스, 유료
    • 우리나라 게임 회사들은 MS SQL Server에서 MySQL이나 Maria DB 또는 Postgre SQL로 많이 이전
  • IBM DB2: 예전에 금융에서 많이 사용
  • Aurora MySQL, Aurora Postgre SQL: Amazon에서 코드를 수정해서 제공하는 RDBMS, 견고하고 성능이 뛰어남 
  •  

 

2) 외부에서 접속 가능한 RDS 서비스 생성

RDS 서비스 접속 > 데이터베이스 생성 클릭

표준 생성

엔진 옵션
템플릿 - 프리티어가 가장 저렴
사용자 이름과 비밀번호 생성



인스턴스 선택 (하드웨어 선택)
스토리지 선택 (저장 공간의 크기 선택)
EC2 인스턴스에 접근 가능 여부 설정

외부에서 접근 가능 여부 설정
추가 구성으로 처음 만들어지는 데이터베이스 생성

 

 

3) 외부에서 접속

  • RDS를 생성할 때 퍼블릭 엑세스가 가능하도록 생성을 하면 IPv4 주소가 주어지면서 End point가 만들어진다.
    • End Point: 외부에서 접속할 수 있는 URL이 됨 
  • 외부 접속이 되지 않는 경우
    • 보안 그룹에서 포트를 개방하지 않은 경우:
      보안 그룹을 확인해서 인바운드 규칙에 포트를 추가하고 0.0.0.0/0 으로 CIDR을 설정
    • 접속 정보가 잘못된 경우

 

4) MySQL의 파라미터 수정

- MySQL을 설치하면 설정 파일 수정해서 MySQL의 설정을 원하는 형태로 변경

- RDS는 직접 설치한 데이터베이스가 아니라서 환경 설정 파일을 직접 수정할 수 없음

- 파라미터 그룹을 만들어서 수정

- 수정 및 적용

RDS에서 파라미터 그룹을 클릭
파라미터 그룹 생성을 클릭  
파라미터 그룹 세부 정보 설정
> 데이터베이스 종류 선택
> 그룹 이름 과 설명을 작성
 
생성된 파라미터 그룹을 선택해서 파라미터를 수정  
편집 버튼을 클릭하고 원하는 파라미터 수정  
RDS의 데이터베이스를 선택  
수정 버튼을 누르고 추가 구성으로 가서 파라미터 그룹을 생성한 것으로 수정

 

RDS는 파라미터를 수정하면 재부팅을 해야 적용!!!

 

 

 

 

4. Mongo DB는 Document DB

1) 클러스터 생성

 

2) 클러스터를 클릭하면 접속 방법이 제공

- wget 명령은 linux 명령어라서 인증서를 받아올 수 없으므로 브라우저에 url을 직접 입력

  • global-bundle.pem 파일을 다운로드

- mongo shell에서 접속

  • mongosh --ssl --host docdb-2024-04-16-01-41-17.cluster-cesn3uejbkwe.ap-northeast-2.docdb.amazonaws.com:27017 --sslCAFile pem파일경로 --username 사용자계정 --password 사용자비밀번호

- 응용 프로그램에서 접속

  • mongodb://계정:비밀번호@docdb-2024-04-16-01-41-17.cluster-cesn3uejbkwe.ap-northeast-2.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=pem파일경로&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false

- 파이썬이나 자바에서 사용하고자 하는 경우는 pem 파일의 경로가 절대로 변하면 안되기 때문에 s3 와 같은 저장소를 이용하거나 프로젝트 안에 포함

  • 프로젝트 안에 포함시키면 소스 코드를 다른 곳에 업로드하면 같이 업로드가 된다는 문제가 발생

 

 

 

 

5. 기본적인 CQRS 구현

- 읽기 서비스와 그 이외의 작업을 처리하는 서비스로 나눔

- 각 서비스는 별도의 데이터베이스를 사용

- 읽기 서비스는 NoSQL을 그 이외의 작업을 처리하는 서비스는 RDBMS를 사용하는 것을 권장

- 2개의 데이터베이스 동기화는 Kafka와 같은 Message Queue 프로그램을 이용해서 수행

 

 

 

 

 

 

 

 

 

 

'AWS' 카테고리의 다른 글

[AWS] EC2 Service  (1) 2024.04.18
[AWS] 개요  (0) 2024.04.11

[AWS] EC2 Service

0ㅑ채
|2024. 4. 18. 21:13

1. 개요

- Amazon Elastic Compute Cloud의 약자

- 컴퓨팅 용량을 제공하는 서비스 - IaaS (Infrastructure as a Service)

- 운영체제(AMI)가 설치된 컴퓨터를 임대해주는 서비스

  • 서버를 만들고자 할 때 항상 켜져 있고 고정된 IP를 갖는 컴퓨터가 필요한 경우 사용

- Managed Service가 아니므로 네트워크나 컴퓨터 자체의 운영은 AWS가 담당하지만 나머지는 사용자가 결정

- 장점

  • 클릭 몇번으로 서버 생성
  • 생성과 삭제 편리
    • 고장난 경우 자동 복구
    • 부하 증가하면 같은 구성의 서버 복제하면 됨

- 단점

  • 서버 한 대로 서비스가 가능하고 트래픽에 거의 변화가 없는 경우 비용이 부담될 수 있다.

 

 

2. 주요 구성 요소

- 인스턴스: 가상 서버

- AMI: 가상 이미지 - 운영체제 이미지

- Key Pair: 외부에서 SSH를 이용해서 접속할 때 사용하기 위한 인증을 위한 키

  • 최근에는 ID와 PW를 사용해서 로그인하지 않음

- EBS: 스토리지

- 보안그룹: 특정 포트에 접속할 수 있는 그룹을 설정하는 기능

- Elastic IP: 고정된 IPv4 주소

 

 

 

3. 접속 방법

- AWS 웹 서비스에 로그인을 해서 관리 콘솔에서 조작

- 외부에서 SSH를 이용해서 접속

 

 

 

4. 인스턴스 생성

- AWS의 EC2 서비스에 접속

 

1) 인스턴스를 생성하고자 하는 region 선택 

2) 인스턴스 시작을 클릭한 후 작업

- 이름 작성

- 운영체제(AMI) 선택

- 인스턴스(하드웨어) 유형 선택

- 외부에서 로그인을 하기 위한 키페어 생성 또는 선택

- 네트워크 설정에서 기본적으로 사용할 포트를 설정

  • 보안 그룹을 생성하거나 선택하고 기본 포트 중 SSH, HTTP, HTTPs 설정 가능
  • 22, 80, 443 - 나중에 변경 설정이 가능하지만 22번은 포트 개방을 하지 않으면 수정을 못함

- 스토리지 설정: 저장 공간에 대한 설정

- 고급 세부 정보나 요약 (컴퓨터 대수를 설정 가능)은 기본 옵션 사용

- 인스턴스 시작을 누르면 새로운 인스턴스가 생성

 

 

 

5. 인스턴스 접속

1) 관리 콘솔에서 접속

- EC2 대시보드에서 인스턴스 ID를 클릭

- 연결 버튼을 클릭하고 새로 나오는 화면에서 다시 연결을 클릭

 

2) SSH를 이용해서 외부에서 접속 

- key pair 파일 필요 (pem 파일),  ec2의 public IP(인스턴스 ID를 눌러서 확인 - 13.125.244.153)

- Mac은 SSH가 바로 사용 가능하지만 windows는 open SSH를 설치해야 한다. 

  • Windows 기능에 포함되어 있다.

터미널에서 ssh -i 키페어파일경로 AMI이름@publicIP

 ssh -i pem파일경로 이미지이름(ubuntu)@IP 나 DNS

 

 

 

6. Web Server 생성

1) 리눅스에 접속

 

2) 웹 서버 생성

- 패키지 정보 업데이트: sudo apt-get update

- apache2 패키지 설치: sudo apt-get install apache2 -y

- apache2 서비스 시작: sudo service apache2 start

- 서비스 확인: ps aux | grep apache2

 

3) 보안 그룹 설정

- EC2 서비스는 모든 포트를 차단한다.

  • 외부에서 접속하는 것을 허용하지 않는다.

- 보안 그룹에서 필요한 포트를 외부에 개방해줘야 한다. 

  • webserver는 http 프로토콜을 사용하고 기본 포트가 80번이다.

- 인스턴스 상세 정보 화면으로 이동

  • 보안 탭으로 이동해서 열려 있는 포트 확인
  • 편집을 하고자 하는 경우 상단의 보안 그룹 링크를 클릭
    • 인바운드는 외부에서 접속할 때 보안을 설정하는 것이고 아웃 바운드는 내부에서 외부로 나갈 대 보안을 설정하는 것
  • 인바운드 규칙 편집을 누르고

 

4) 다른 컴퓨터에서 웹 페이지 접속

http://공인IP

 

 

 

7. 인스턴스 중지 및 삭제

1) 인스턴스 중지

- 현재 EC2 컴퓨터를 끄는 것과 비슷한 효과

2) 인스턴스 종료

- 인스턴스 삭제

 

 

 

8. MySQL 서버

1) EC2 인스턴스에 접속

 

2) 설치

- sudo apt-get update

- sudp apt-get install mysql-server

- 버전 확인: mysql --version

- mysql 접속

  • sudo mysql -u root -p
  • (기본 비밀번호는 없거나 관리자 비밀번호 - ubuntu)

- MySQL에 접속해서 관리자 비밀번호 재설정

  • use mysql;

- 관리자는 로컬에서만 접속하게 하고 비밀번호 수정

  • alter user "root"@"localhost" identified with mysql_native_password by "wnddkd";

- 변경 내용 적용:

  • flush privileges;

- 외부 접속

  • 관리자 권한을 가진 설정 파일 변경: sudo su
    • 다른 계정으로 접속: sudo su 계정
  • MySQL 설정 파일 변경
    • cd /etc/mysql/mysql.conf.d 명령으로 프롬프트 이동
      vi mysqld.cnf 명령으로 파일 편집으로 이동
      • i를 눌러서 편집 모드로 전환한 후 bind-address = 0.0.0.0 으로 수정
      • esc를 눌러서 명령 모드로 전환한 후 :wq! 를 입력해서 저장하고 종료
  • 서비스 재시작
    service mysql restart

- 사용자 등록

  • mysql 관리자로 접속: mysql -u root -p
  • 데이터베이스 생성: create database 이름;
    create database adam;
  • 유저생성: create user 유저이름@'%'identified by '비밀번호';
    create user 'adam@%' identified by 'wnddkd';
    • @은 유저 이름과 %를 구분하기 위한 것, 0.0.0.0과 의미가 같다.
    • % 대신에 IP를 작성하면 그 IP를 가진 곳에서만 접속 가능
  • 권한 부여: grant all privileges on * 또는 데이터베이스 이름.* to 유저이름;
    grant all privileges on *.* to adam;
  • 변경 내용 적용: flush privileges;

 

3) 3306번 포트에 대한 인바운드 규칙 설정

- EC2 인스턴스 콘솔에 접속해서 보안 탭에서 보안 그룹 ID를 클릭해서 수정

  • 인바운드 규칙 편집을 눌러서 3306번 모든 IP가 접속 가능하도록 설정

 

4) 외부에서 접속 프로그램을 이용해서 접속

- DB HOST: EC2의 public IP

- Port: 3306

- DB NAME: itstudy

- USER: adam

- Password: wnddkd

 

 

 

4. Docker 설치

- Linux의 중앙 저장소에 도커 프로그램이 등록되어 있지 않아서 도커는 저장소를 리눅스에 등록하고 설치

  • 일부 프로그램은 도커처럼 키 등록을 하고 저장소를 등록한 후 패키지 정보를 업데이트 한 후 설치하기도 함

 

1) 저장소를 등록

- 패키지 덥데이트:

  • sudo apt-get update

- 키등록을 위한 패키지 설치

  • sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

- 키를 추가

- 저장소를 추가

 

2) 설치

- 패키지 업데이트

  • sudo apt-get update

- 설치

  • sudo apt-get install docker-ce docker-ce-cli containerd.io

- 버전 확인

  • sudo docker version

- 서비스 등록 및 실행

  • sudo systemctl enable docker
  • sudo systemctl start docker

 

3) 실행 확인

  • sudo docker run hello-world
  • sudo docker ps -a

'AWS' 카테고리의 다른 글

[AWS] DataBase  (1) 2024.04.18
[AWS] 개요  (0) 2024.04.11

[AWS] 개요

0ㅑ채
|2024. 4. 11. 17:35

1. AWS (Amazon Web Service)

- 시스템 운영에 관련된 다양한 서비스 제공하는 클라우드 기반 서비스

  • 컴퓨팅, 스토리지, 데이터베이스, 분석 툴, 네트워크, 모바일, 개발자 도구 등

- 서비스 조합이 쉽다.

- 요금이 종량제

  • 사용한만큼 지불
  • 특별한 경우 최소 요금이 설정되어 있다.
    일반적으로 사용자의 트래픽이 수시 변경되는 경우라면 퍼블릭 클라우드가 유리하지만
    일정한 트래픽이라면 On Premiss가 유리하다. 이런 경우는 고려할 사항 중 하나가 관리자의 인건비

- 사용이 쉽다.

- 글로벌 확장이 쉽다.

  • 현재 사용 가능한 Public Cloud 중 Region 과 AZ(가용 영역)이 가장 많음
  • 한국에는 서울 리전이 있고 4개의 가용 영역 운영 중

- 보안 기준: ISMS (한국 정보보호 관리체계) 인증 취득

 

 

 

2. 제공되는 서비스

- 165개 이상의 서비스 제공

- 목적에 따라 다양한 서비스

  • 서버 전체 및 관리에 필요한 기능을 제공
  • 분석 시스템
  • 가상 데스크톱
  • 머신 러닝 과 인공 지능, 블록체인 서비스도 제공

 

 

- 대표적 서비스

  • EC2: 컴퓨터(서버 - 24시간 서비스가 가능해야 하고 고정된 IP를 가져야 함)를 빌려주는 개념
  • S3: 파일 스토리지의 개념으로 최근에는 데이터 저장소의 역할을 하는 경우가 많음
    • 외부에서 수집된 데이터를 이 공간에 저장해두고 사용하기도 하고 정적 웹 페이지를 배포하는 용도 또는 백업용으로 사용
  • VPN: 가상 네트워크
  • Database
  • Route 53: 도메인 관련 작업
  • Elastic IP: 공인 IP 주소를 제공
  • SageMaker: 머신러닝 기능을 제공
  • QuickStart: 시각화 기능 제공
  • Managed BlockChain
  • Cloud9: 통합 개발 도구
  • GameLift: 게임 호스팅 서비스
  • ECR, ECS, EKS: 이미지 저장소, 도커 배포, 쿠버네티스 배포

 

- Free Tier 계정

  • EC2 인스턴스 1대,  RDS 1 대, S3 5GB 의 공간을 1년 동안 무료로 사용할 수 있도록 계정

- 관리 콘솔

  • Web에 접속해서 GUI로 AWS를 조작하는 화면

- Managed Service 

  • AWS가 관리하는 서비스
  • 가상 서버인 EC2는 Managed Service가 아니지만 스토리지 인 S3 와 데이터베이스 서버인 RDS는 Managed Service
  • Managed Service는 백업 및 업데이트가 자동으로 이루어지므로 사용자가 수동으로 관리할 필요가 없다.

- 보안 문제

  • 일반적으로는 On-Premiss 가 보안성이 우수하다.
  • On-Premiss는 기업에 보안에 대한 전문가 필요함.

- 도입 사례

  • 현대 건설 기계는 Amazon S3를 이용해서 빅데이터 플랫폼 과 데이터 레이크를 구축하고 
    Sage Maker를 이용해서 수요 예측 시스템을 구축해서 건설 장비에 대한 수요를 예측

 

 

 

3. 기본 개념

Region

- AWS의 모든 서비스가 위치하고 있는 물리적 장소. 그 안에 다시 여러 개의 가용 영역 (AZ - 데이터센터) 존재

- Region 별로 제공하는 서비스가 다르면 요금도 다름

- 클라이언트가 사용하는 앱을 배포하는 경우 Region을 반드시 확인

 

Edge Location

- AWS의 CDN 서비스인  CloudFront를 위한 Cache Server

- CDN(Content Delivery Network)은 콘텐츠를 사용자들이 빠르게 받아볼 수 있도록 전 세계 곳곳에 위치한 캐시 서버에 복제해주는 서비스

- CDN 서비스와 사용자가 만나는 지점을 Edge Location

 

 

 

 

 

4. IAM

- AWS에 회원 가입을 하면 모든 작업을 수행할 수 있는 루트 계정이 만들어 진 것

- 기업을 사용을 하다 보면 여러 다른 사람에게 서비스를 사용할 수 있도록 해주어야 하는 경우가 발생

- 사용자를 생성해주는 기능

 

Factor

- 사용자의 신원을 확인하는 방법

- 종류

  • 지식 기반: ID/PW 와 같이 알고있는 인증 정보를 이용하는 방식
  • 소유 기반: 사용자가 소유한 것을 이용하여 인증하는 방식 - 인증서, 휴대폰 인증
  • 속성 기반: 고유의 속성을 이용하는 것으로 지문, 홍채 인식 등

- AWS는 Multi Factor 인증 지원

 

사용자 생성

- 사용자를 생성하고 권한을 반드시 부여

- 권한 부여를 하지 않으면 아무일도 할 수 없다.

- 권한 설정 방법

  • 그룹에 권한을 부여한 후 사용자를 그룹에 포함시키는 방식
  • 기존 사용자의 권한을 복사하는 방법
  • 기존 정책을 연결하는 방법

 

 

 

 

5. Network

IP Address

- TCP/IP 라는 프로토콜을 사용하는 인터넷 망에서 컴퓨터를 구분하기 위한 숫자의 조합

- 인터넷 망에서 데이터를 송수신 할 때 Port 와 함께 사용

  • IP Address 는 컴퓨터를 구분하고 Port 컴퓨터 안에서 동작하는 Application을 구분
  • 실제 데이터의 송수신은 컴퓨터의 애플리케이션이 수행하기 때문
  • 인터넷 망에서 각 컴퓨터의 IP는 구별되어야 하고 하나의 컴퓨터에서 각각의 Application이 사용하는 Port는 구분되어야 함
  • 하나의 컴퓨터에서 여러 개의 Application을 동작할 때는 포트를 확인해봐야 함

- IPv4 와 IPv6

  • IPv4: 32비트 주소 체계로 8비트씩 나누어서 표현을 하는데 일반적으로 10진수로 변환해서 표현
    • 00000000.00000000.00000000.00000000 ~ 11111111.11111111.11111111.11111111
    • 0.0.0.0 ~ 255.255.255.255
  • IPv6: IPv4 의 주소 개수 한계로 등장한 주소 체계, 현재는 전부 IPv6를 사용하는데 IPv4로 설정하면 자동으로 변환을 수행. 128비트 주소 체계로 16비트씩 8개의 영역으로 구분을 하고 각 16비트는 16진수 4자리로 표현하고 중복되는 부분을 생략할 수 있도록 설계
    • 00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000 ~ 11111111.11111111.11111111.11111111
      .11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111
    • 0000:0000:0000:0000:0000:0000:0000:0000 ~ FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
  • Loopback(자기 자신)을 표현할 때 
    IPv4는 127.0.0.1로,  IPv6는 0:0:0:0:0:0:0:1 로 표현
    Windows7 이상에서는 로컬 호스트에서 자신의 웹 서버에게 접속하면 IPv6로 표현됨

- Private IP & Public IP

  • Public IP는 인터넷에서 외부 망에서 구별하기 위한 주소로 이 주소는 컴퓨터 마다 유일 무이해야 한다.
  • Private IP는 인터넷에서 내부 망에서 구별하기 위한 주소로 이 주소는 내부 망에서만 유일 무이하면 된다.
    • 10.0.0.0 ~ 10.255.255.255
    • 172.16.0.0 ~ 172.31.255.255
    • 192.168.0.0 ~ 192.168.255.255
    • 이 대역은 외부에서 사용할 수 없음
    • Docker에서 Network 만들 때, Kubernetes 에서 Pod를 생성할 때, 유동 IP를 사용하는 인터넷을 이용할 때 확인 가능

- 유동 IP 와 고정 IP

  • 유동 IP는 IP Address 가 계속해서 변하는 것
    • 전용선을 사용하지 않고 통신 회사의 라우터를 이용해서 인터넷을 사용하는 경우 통신 회사에서는 라우터에 몇 개의 IP만 할당하고 각 개인에게는 Port Forwarding 이라는 기술로 분배해서 사용하는 경우에 할당됩니다.
  • 고정 IP는 IP Address 가 고정되는 것
    • 전용선을 사용하는 환경에서 배정
    • 서버가 될려면 이 고정 IP를 사용해야 합니다.
  • Elastic IP(탄력적 IP)
    • AWS에서 클라우드 서버에게 배정하는 IP로 하나의 고정 IP를 부여하는 것
    • 컴퓨터를 임대해서 사용하는 EC2 서비스를 사용할 때 임대한 컴퓨터를 서버로 활용할려면 이 탄력적 IP를 부여받아서 사용해야 한다.
    • 최근에는 EC2 서비스의 인스턴스를 생성하면 Public IP가 부여된다.

 

Domain 과 DNS(Domain Name Service)

- IP Address 는 숫자로 된 주소이므로 사람이 기억하기가 어렵습니다.

- 숫자로 된 주소를 문자의 조합으로 사용할 수 있도록 만든 것 중 하나가 Domain 

  • 인터넷 망에서는 IP Address 를 이용해서 다른 컴퓨터에 요청을 할 수 있고 Domain을 이용해서 요청을 할 수 있음

- Domain을 입력했을 때 Domain을 해석해서 IP Address 로 변환해주는 서비스가 DNS

- AWS에서 DNS 서비스가 Route53

- 도메인은 이름이기 때문에 호스트 또는 서비스 이름이 안들어가는데 실제 사용을 할 대는 호스트 이름 과 도메인을 합쳐서 사용을 해야 하는데(https://www.naver.com) 이것을 FQDN(Fully Qualified Domain Name) 

  • 맨 앞은 프로토콜을 의미하고 도메인 앞 부분이 호스트 이름
  • 가끔 http 나 https를 붙이지 않고 //로 시작하는 경우가 있는데 이는 필요에 따라 http 나 https로 접속

 

- URI(Uniform Resouce Identifier), URN(Name), URL(Locator)

  • URI: 자원 식별자로 가장 큰 개념으로 URN 과 URL이 하위 개념으로 존재
  • URL: 네트워크 상에서 자원이 어디에 위치해 잇는지 알려주기 위한 규칙
  • URN: 자원을 구별하기 위해서 붙이는 이름

- ARN: AWS 안에서 자원을 구별하기 위해서 붙이는 이름

 

 

 

 

 

 

6. VPN(Virtual Private Network)

- Private Network: 외부에서는 접근할 수 없는 네트워크

  • 최근에는 건물 내부 뿐 아니라 다른 건물 또는 외부에서 인터넷을 이용해서 Private Network를 사용해야 하는 경우가 많은데 이 때 내부 구성원을 제외한 사람들이 접근할 수 없도록 해야 하는데 이렇게 구축한 것을 VPN 이라고 한다.

- AWS에서는 이를 VPC 라는 개념으로 제공한다.

  • 최근에는 서비스를 만들면 데이터 - 애플리케이션 - API 형태로 만들어지는데 이 때 API는 외부로 노출이 되지만 데이터 와 애플리케이션은 외부로 노출되지 않도록 하는 것을 권장
  • 하나의 서비스를 만들 때 데이터 와 애플리케이션 그리고 API는 하나의 VPC로 구성해서 내부 통신이 가능하도록 하고 API 만 외부로 노출을 시켜서 클라이언트나 다른 API 와 통신을 할 수 있도록 만드는 것을 권장

- VPN 안에는 보안 그룹이나 ACL의 개념이 있어서 특정 네트워크 또는 컴퓨터나 접속할 수 있도록 설정을 할 수 있다.

- NAT(Network Address Translation)를 이용해서 내부에서는 사설 IP를 사용하고 외부로 나갈 때 Public IP로 변환해서 나가도록 한다.

 

 

 

 

 

 

7. Network 범위와 CIDR 표기

- 하나의 컴퓨터를 구별하기 위해서는 IP Address 를 사용하는데 여러 개의 컴퓨터 특히 연속된 IP 대역을 가진 컴퓨터를 표현하기 위한 방법이 CIDR 표기법

- IP주소/공통된 주소의 개수를 비트 단위로 입력

  • 공통된 주소 부분을 포함하는 모든 컴퓨터를 하나의 대역으로 표현 가능

192.168.0.0/16

  • 앞의 16개의 비트는 고정이고 나머지는 자유롭게 사용
  • 192.168.0.0 ~ 192.168.255.255 까지를 의미

192.168.1.0/24

  • 192.168.1.0 ~ 192.168.1.255 를 의미

0.0.0.0/0

  • 고정되어야 하는 것이 하나도 없음, 모든 IP를 의미

192.168.0.1/32

  • 모든 비트가 고정되어야 합니다. 하나의 IP를 의미
  • 이 방식은 지금은 거의 사용하지 않는데 데이터베이스에 애플리케이션 서버가 하나만 연결되는 경우 이런식으로 작성해서 다른 컴퓨터는 데이터베이스에 접속을 못하도록 하는 경우가 사용

 

 

 

 

8. 알려진 포트(well-known port)

- 포트 중에서 0 ~ 1023번까지는 대부분 정해져 있다.

http: 80
https: 443
SSH(원격 접속): 22
FTP(파일 전송): 20, 21
DNS: 53
Mail: 25, 110, 143

 

- 애플리케이션이 사용하는 포트

RDP(원격 데스크톱): 3389

DB:

  • 1433(SQL Server)
  • 1521(Oracle)
  • 3306(MySQL 이나 Maria DB)
  • 5432(Postgre SQL)
  • 27017(Mongo DB)
  • 6397(Redis)
  • zookiper(2181)
  • Kafka(9092)
  • logstash(5044)
  • elastic search(9200, 9300)
  • kibana(5601)

 

 

 

 

9. End Point

- 외부에서 접속하기 위한 접속점

- 외부에서 AWS 서비스에 접속을 할 때 IP가 부여되면 IP 주소를 이용해서 접속을 하면 되지만 IP를 부여하지 않는 경우에는 End Point를 이용해서 접속을 해야 한다.

  • EC2 같은 서비스는 IP도 부여되고 End Point도 부여되므로 2가지 모두로 외부에서 접속이 가능하지만 RDS 같은 데이터베이스 서비스는 IP를 알려주지 않고 End Point만 알려주므로 End Point를 이용해서 접속을 해야 합니다.

 

'AWS' 카테고리의 다른 글

[AWS] DataBase  (1) 2024.04.18
[AWS] EC2 Service  (1) 2024.04.18

1. 데이터 가져오기

- 43개의 교통 표지판 과 관련된 4만여 개의 이미지로 만들어진 데이터 셋

- https://sid.erda.dk/public/archives/daaeac0d7ce1152aea9b61d9f1e19370/published-archive.html

 

Public Archive: daaeac0d7ce1152aea9b61d9f1e19370

Support ERDA User Guide Questions about ERDA? Please contact us at support@erda.dk

sid.erda.dk

- https://drive.google.com/drive/folders/1AktNCWqVBv-4xxme4OUC82OLJTHzMFsq?usp=sharing

 

 

- 데이터 다운로드

   colab
	!wget https://sid.erda.dk/public/archives/daaeac0d7ce1152aea9b61d9f1e19370/GTSRB_Final_Training_Images.zip
	!unzip -qq "GTSRB_Final_Training_Images.zip"
  • GTSRB\Final_Training\Images 디렉토리 안에 디렉토리 별로 이미지가 ppm 확장자로 분류되어 있다.

 

- ppm: 무손실 압축 이미지 파일 형식

 

- image 크기: 32 x 32

 

 

- 신경망 구조를 만들 때 선택 사항

  • 2차원 컨볼루션에서 필터 개수 와 커널 크기
  • Max Pool 에서의 커널 크기
  • Fully Connected 계층(Dense)에서의 유닛 개수
  • 계층 별 배치 크기, 최적화 알고리즘, 학습률, 할성화 함수, epoch 수 등

 

- 이미지 전처리

  • 이미지 크기를 32*32로 수정
  • 43개의 레이블을 생성: 디렉토리 이름이 레이블
  • 표지판의 경우 구분해야 할 것은 색상이 아니라 모양: 이미지를 흑백으로 변경
  • 데이터를 다룰 때 목적을 먼저 생각하고 작업을 시작해야 한다. (도메인)

 

- 필요한 패키지 와 상수 선언

  • 클래스 개수와 이미지의 크기를 변수에 저장
  • 이 두개의 절대로 변하지 않을 값
  • 변하지 않는 값을 장할 변수의 이름은 모두 대문자로 작성하는 것이 좋다.
    • SNAKE 표기법이라고 한다.
N_CLASSES = 43
RESIZED_IMAGE = (32, 32)

 

 

# 모듈

import matplotlib.pyplot as plt
#디렉토리를 핸들링 할 때 사용하는 모듈
import glob

from skimage.color import rgb2lab
from skimage.transform import resize
import numpy as np

from collections import namedtuple

from sklearn.model_selection import train_test_split

 

 

- 이미지 전처리를 위한 함수

  • 이름이 있는 튜플 생성 - 다른 언어에서는 튜플을 이런 형태로 만든다.
  • 튜플의 원래 목적은 변경할 수 없는 하나의 행(record, row)을 표현하기 위한 것
  • 인덱스가 아니라 이름으로 구별하는 것이 타당
Dataset = namedtuple('Dataset', ['X', 'y'])

 

 

# 포맷 변경해주는 함수

def to_tf_format(imgs):
    return np.stack([img[:, :, np.newaxis] for img in imgs], axis=0).astype(np.float32)

 

 

- 이미지 디렉토리에 있는 모든 이미지들에 라벨링을 하기 위한 작업
- 이미지의 크기 변경도 여기서 수행

def read_dataset_ppm(rootpath, n_labels, resize_to):
    #이미지 데이터 와 라벨을 저장할 list
    images = []
    labels = []
    
    for c in range(n_labels):
        #루트경로/00001/ 형태로 이미지 경로를 생성
        full_path = rootpath + "/" + format(c, '05d') + "/"
        #각 이미지 디렉토리를 순회하면서 확장자가 ppm 인 파일의 경로를 가지고
        for img_name in glob.glob(full_path + "*.ppm"):
            #이미지 읽어오기
            img = plt.imread(img_name).astype(np.float32)
            #이미지를 정규화
            img = rgb2lab(img / 255.0)[:, :,0]
            #이미지 크기를 조정
            if resize_to:
                img = resize(img, resize_to, mode='reflect')
            #라벨 생성
            #43개 짜리 배열을 만들어서 자신의 인덱스에 해당하는 값에만 1을 대입
            #원핫 인코딩 된 라벨
            label = np.zeros((n_labels, ), dtype=np.float32) 
            label[c] = 1.0
            
            images.append(img.astype(np.float32))
            labels.append(label)

    return Dataset(X = to_tf_format(images).astype(np.float32), y = np.matrix(labels).astype(np.float32))

 

 

# 이미지 전처리를 수행해서 데이터 만들기

dataset = read_dataset_ppm('./data/GTSRB/Final_Training/Images',
                          N_CLASSES,
                          RESIZED_IMAGE)
print(dataset.X.shape)
print(dataset.y.shape)
(39209, 32, 32, 1)
(39209, 43)

 

 

# 이미지 확인

plt.imshow(dataset.X[0, :, :, :].reshape(RESIZED_IMAGE))
print(dataset.y[0, :])
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]

 

 

 

- 훈련 데이터와 테스트 데이터 분리

#훈련 데이터 와 테스트 데이터 분리
idx_train, idx_test = train_test_split(range(dataset.X.shape[0]), test_size=0.25,
                                      random_state=42)

X_train = dataset.X[idx_train, :, :, :]
X_test = dataset.X[idx_test, :, :, :]

y_train = dataset.y[idx_train, :]
y_test = dataset.y[idx_test, :]

print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
(29406, 32, 32, 1)
(9803, 32, 32, 1)
(29406, 43)
(9803, 43)

 

 

- 모델 생성

model = keras.Sequential()

#입력층 - Convolution 
model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu',
                             padding='same', input_shape=(32, 32, 1)))
model.add(keras.layers.MaxPooling2D(2))

model.add(keras.layers.Conv2D(64, kernel_size=3, activation='relu',
                             padding='same'))
model.add(keras.layers.MaxPooling2D(2))

model.add(keras.layers.Conv2D(128, kernel_size=3, activation='relu',
                             padding='same'))
model.add(keras.layers.MaxPooling2D(2))

model.add(keras.layers.Flatten())

model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dropout(0.4))

model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dropout(0.4))

model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dropout(0.4))

model.add(keras.layers.Dense(43, activation='softmax'))

model.summary()

 

 

- 모델 컴파일

model.compile(optimizer='adam',
             loss='categorical_crossentropy',
             metrics=['accuracy'])

 

 

- 훈련

checkpoint_cb = keras.callbacks.ModelCheckpoint('best-cnn-models.keras')
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2,
                                                 restore_best_weights=True)
history = model.fit(X_train, y_train, epochs=20,
                   callbacks = [checkpoint_cb, early_stopping_cb])

 

 

- 평가

print(model.evaluate(X_test, y_test))
307/307 ━━━━━━━━━━━━━━━━━━━━ 3s 10ms/step - accuracy: 0.8567 - loss: 0.3981
[0.39652204513549805, 0.853820264339447]

 

!git clone https://github.com/MachineLearning2020/Homework2-Caltech101.git

 

 

 

 

 

 

 

1. 데이터 가져오기

from tensorflow import keras
from sklearn.model_selection import train_test_split

#데이터 읽어오기
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
rint(train_input.shape)

 

 

 

 

2. 스케일링 및 차원 수정

# 흑백 이미지라서 차원을 1개 늘려서 255 로 나눔
train_scaled = train_input.reshape(-1, 28, 28, 1) / 255.0
print(train_scaled.shape) 

train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)
(60000, 28, 28, 1)

 

 

 

 

3. 모델 생성

#모델 만들기
model = keras.Sequential()

#입력 층을 합성곱 층을 사용
model.add(keras.layers.Conv2D(32, kernel_size=3, activation="relu",
                             padding='same', input_shape=(28, 28, 1)))
model.add(keras.layers.MaxPooling2D(2))

model.add(keras.layers.Conv2D(64, kernel_size=3, activation="relu",
                             padding='same'))
model.add(keras.layers.MaxPooling2D(2))

#데이터를 1차원으로 만들어주는 층
model.add(keras.layers.Flatten())

#Dense 는 1차원의 데이터만 사용
model.add(keras.layers.Dense(100, activation="relu"))

#드랍 아웃 적용
model.add(keras.layers.Dropout(0.4))

model.add(keras.layers.Dense(10, activation="softmax"))

 

# 모델 확인

model.summary()

 

 

 

 

 

4. 모델 컴파일 (훈련)

model.compile(optimizer="adam", loss="sparse_categorical_crossentropy",
             metrics=["accuracy"])

#체크 포인트
checkpoint_cb = keras.callbacks.ModelCheckpoint("best-cnn-model.keras")

#2번의 epoch 동안 점수가 좋아지지 않으면 조기 종료
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2,
                                                 restore_best_weights=True)
history = model.fit(train_scaled, train_target, epochs=20,
                   validation_data=(val_scaled, val_target),
                   callbacks=[checkpoint_cb, early_stopping_cb])

 

 

 

 

 

4. 모델 평가

model.evaluate(val_scaled, val_target)
  • 아래 합성곱 층으로 내려갈 때 뉴런의 개수를 늘렸는데 중간에 MaxPooling2D(Dropout을 적용해도 동일) 을 적용했기 때문에 실제 파라미터의 개수가 줄어들어 사용되므로 늘린 티가 나지 않음
#클래스 이름
classes = ['티셔츠', '바지', '스웨터', '드레스', '코트',
          '샌달', '셔츠', '스니커즈', '가방', '앵클 부츠']


preds = model.predict(val_scaled[0:1])
print(preds)
print(classes[np.argmax(preds)])

plt.imshow(val_scaled[0].reshape(28, 28), cmap='gray_r')
plt.show()

 

 

# 훈련에 사용한 데이터가 스케일되어 있으므로, 예측 데이터도 스케일링

test_scaled = test_input.reshape(-1, 28, 28, 1)/255.0
model.evaluate(test_scaled, test_target)

 

 

# 모델 저장

model.save("best-cnn-models.keras")
  • 이전 API에서는 확장자를 h5를 권장했는데 최근에는 keras를 권장

 

 

 

- 국가 통계 포털에서 인구 정보 내려받기

http://kosis.kr/statHtml/statHtml.do?orgId=101&tblId=DT_1IN1509&

 

KOSIS

 

kosis.kr

 

기본코드

import pandas as pd
import numpy as np
import platform
import matplotlib.pyplot as plt

%matplotlib inline
path = "c:/Windows/Fonts/malgun.ttf"
from matplotlib import font_manager, rc
if platform.system() == 'Darwin':
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('알 수 없는 시스템')    
plt.rcParams['axes.unicode_minus'] = False

 

 

 

 

1. 데이터 읽어오기

population = pd.read_excel('./data/population.xlsx', header=1)
population

 

 

 

 

2. 데이터 전처리

 

#결측치를 앞의 데이터로 채우기

population.fillna(method='ffill', inplace=True)

 

 

#컬럼이름 변경하기

population.rename(columns = {'행정구역별(시군구)(1)':'광역시도', 
                             '행정구역별(시군구)(2)':'시도', 
                             '합계':'인구수'}, inplace=True)
population.head()

 

 

# 소계를 제외한 데이터만 가져오기

population = population[(population['시도'] != '소계')]
population.head()

 

 

# 컬럼 이름 변경

population.is_copy = False
population.rename(columns = {'성별(1)':'구분'}, inplace=True)
population.loc[population['구분'] == '계', '구분'] = '합계'
population.head()

 

 

# 청년과 노년 구분

population['20-39세'] = population['20~24세'] + population['25~29세'] + \
                        population['30~34세'] + population['35~39세']
    
population['65세이상'] = population['65~69세'] + population['70~74세'] + \
                        population['75~79세'] + population['80~84세'] + \
                        population['85세이상']

population.head(5)

 

 

# 피벗 테이블 생성

pop = pd.pivot_table(population, 
                     index = ['광역시도', '시도'], 
                     columns = ['구분'],
                     values = ['인구수', '20-39세', '65세이상'])
pop.head()

 

 

# 새로운 컬럼 추가 - 소멸 비율

pop['소멸비율'] = pop['20-39세','합계'] / (pop['65세이상','합계'] / 2)
pop.head()

 

 

# 새로운 컬럼 추가 - 소멸 위기 지역

pop['소멸위기지역'] = pop['소멸비율'] < 1.0
pop.head()
print(pop[pop['소멸위기지역']==True].index.get_level_values(1))
Index(['영월군', '남해군', '산청군', '의령군', '하동군', '함양군', '합천군', '군위군', '면부', '봉화군',
       '영덕군', '영양군', '의성군', '청도군', '청송군', '강화군', '면부', '강진군', '고흥군', '곡성군',
       '구례군', '면부', '보성군', '신안군', '완도군', '장흥군', '진도군', '함평군', '해남군', '고창군',
       '면부', '무주군', '부안군', '순창군', '임실군', '장수군', '진안군', '부여군', '서천군', '청양군',
       '괴산군', '단양군', '보은군'],
      dtype='object', name='시도')

 

 

# 인덱스 초기화

pop.reset_index(inplace=True) 
pop.head()

 

 

 

 

 

3. 시도 이름 합치기

# 새로운 컬럼 추가 - 첫번째와 두번째 컬럼 이름 합치기

tmp_coloumns = [pop.columns.get_level_values(0)[n] + \
                pop.columns.get_level_values(1)[n] 
                for n in range(0,len(pop.columns.get_level_values(0)))]

pop.columns = tmp_coloumns
pop.head()

 

 

# 데이터 확인

pop.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 303 entries, 0 to 302
Data columns (total 13 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   광역시도      303 non-null    object 
 1   시도        303 non-null    object 
 2   20-39세남자  303 non-null    int64  
 3   20-39세여자  303 non-null    int64  
 4   20-39세합계  303 non-null    int64  
 5   65세이상남자   303 non-null    int64  
 6   65세이상여자   303 non-null    int64  
 7   65세이상합계   303 non-null    int64  
 8   인구수남자     303 non-null    int64  
 9   인구수여자     303 non-null    int64  
 10  인구수합계     303 non-null    int64  
 11  소멸비율      303 non-null    float64
 12  소멸위기지역    303 non-null    bool   
dtypes: bool(1), float64(1), int64(9), object(2)
memory usage: 28.8+ KB

 

 

# 시도 고유값 확인

print(pop['시도'].unique())
['강릉시' '고성군' '동부' '동해시' '면부' '삼척시' '속초시' '양구군' '양양군' '영월군' '원주시' '읍부'
 '인제군' '정선군' '철원군' '춘천시' '태백시' '평창군' '홍천군' '화천군' '횡성군' '가평군' '고양시' '과천시'
 '광명시' '광주시' '구리시' '군포시' '권선구' '기흥구' '김포시' '남양주시' '단원구' '덕양구' '동두천시' '동안구'
 '만안구' '부천시' '분당구' '상록구' '성남시' '수원시' '수정구' '수지구' '시흥시' '안산시' '안성시' '안양시'
 '양주시' '양평군' '여주시' '연천군' '영통구' '오산시' '용인시' '의왕시' '의정부시' '이천시' '일산동구'
 '일산서구' '장안구' '중원구' '처인구' '파주시' '팔달구' '평택시' '포천시' '하남시' '화성시' '거제시' '거창군'
 '김해시' '남해군' '마산합포구' '마산회원구' '밀양시' '사천시' '산청군' '성산구' '양산시' '의령군' '의창구'
 '진주시' '진해구' '창녕군' '창원시' '통영시' '하동군' '함안군' '함양군' '합천군' '경산시' '경주시' '고령군'
 '구미시' '군위군' '김천시' '남구' '문경시' '봉화군' '북구' '상주시' '성주군' '안동시' '영덕군' '영양군'
 '영주시' '영천시' '예천군' '울릉군' '울진군' '의성군' '청도군' '청송군' '칠곡군' '포항시' '광산구' '동구'
 '서구' '달서구' '달성군' '수성구' '중구' '대덕구' '유성구' '강서구' '금정구' '기장군' '동래구' '부산진구'
 '사상구' '사하구' '수영구' '연제구' '영도구' '해운대구' '강남구' '강동구' '강북구' '관악구' '광진구' '구로구'
 '금천구' '노원구' '도봉구' '동대문구' '동작구' '마포구' '서대문구' '서초구' '성동구' '성북구' '송파구' '양천구'
 '영등포구' '용산구' '은평구' '종로구' '중랑구' '세종시' '울주군' '강화군' '계양구' '남동구' '미추홀구' '부평구'
 '연수구' '옹진군' '강진군' '고흥군' '곡성군' '광양시' '구례군' '나주시' '담양군' '목포시' '무안군' '보성군'
 '순천시' '신안군' '여수시' '영광군' '영암군' '완도군' '장성군' '장흥군' '진도군' '함평군' '해남군' '화순군'
 '고창군' '군산시' '김제시' '남원시' '덕진구' '무주군' '부안군' '순창군' '완산구' '완주군' '익산시' '임실군'
 '장수군' '전주시' '정읍시' '진안군' '서귀포시' '제주시' '계룡시' '공주시' '금산군' '논산시' '당진시' '동남구'
 '보령시' '부여군' '서북구' '서산시' '서천군' '아산시' '예산군' '천안시' '청양군' '태안군' '홍성군' '괴산군'
 '단양군' '보은군' '상당구' '서원구' '영동군' '옥천군' '음성군' '제천시' '증평군' '진천군' '청원구' '청주시'
 '충주시' '흥덕구']

 

 

# 시도 고유 이름

si_name = [None] * len(pop)

#광역시가 아닌 곳 중에서 구를 가지고 있는 시도들의 구이름 디셔너리 생성
tmp_gu_dict = {'수원':['장안구', '권선구', '팔달구', '영통구'], 
                       '성남':['수정구', '중원구', '분당구'], 
                       '안양':['만안구', '동안구'], 
                       '안산':['상록구', '단원구'], 
                       '고양':['덕양구', '일산동구', '일산서구'], 
                       '용인':['처인구', '기흥구', '수지구'], 
                       '청주':['상당구', '서원구', '흥덕구', '청원구'], 
                       '천안':['동남구', '서북구'], 
                       '전주':['완산구', '덕진구'], 
                       '포항':['남구', '북구'], 
                       '창원':['의창구', '성산구', '진해구', '마산합포구', '마산회원구'], 
                       '부천':['오정구', '원미구', '소사구']}

for n in pop.index:
    #고성이 2곳이므로 도를 추가
    if pop['광역시도'][n][-3:] not in ['광역시', '특별시', '자치시']:
        if pop['시도'][n][:-1]=='고성' and pop['광역시도'][n]=='강원도':
            si_name[n] = '고성(강원)'
        elif pop['시도'][n][:-1]=='고성' and pop['광역시도'][n]=='경상남도':
            si_name[n] = '고성(경남)'
        #그 이외의 지역은 마지막 한글자를 제거해서 군 이나 시 글자를 제거
        else:
             si_name[n] = pop['시도'][n][:-1]
        for keys, values in tmp_gu_dict.items():
            if pop['시도'][n] in values:
                if len(pop['시도'][n])==2:
                    si_name[n] = keys + ' ' + pop['시도'][n]
                elif pop['시도'][n] in ['마산합포구','마산회원구']:
                    si_name[n] = keys + ' ' + pop['시도'][n][2:-1]
                else:
                    si_name[n] = keys + ' ' + pop['시도'][n][:-1]
                        #세종은 이름을 수정    
    elif pop['광역시도'][n] == '세종특별자치시':
        si_name[n] = '세종'
    else:
        if len(pop['시도'][n])==2:
            si_name[n] = pop['광역시도'][n][:2] + ' ' + pop['시도'][n]
        else:
            si_name[n] = pop['광역시도'][n][:2] + ' ' + pop['시도'][n][:-1]
print(si_name)
['강릉', '고성(강원)', '동', '동해', '면', '삼척', '속초', '양구', '양양', '영월', '원주', '읍', '인제', '정선', '철원', '춘천', '태백', '평창', '홍천', '화천', '횡성', '가평', '고양', '과천', '광명', '광주', '구리', '군포', '수원 권선', '용인 기흥', '김포', '남양주', '안산 단원', '고양 덕양', '동두천', '동', '안양 동안', '안양 만안', '면', '부천', '성남 분당', '안산 상록', '성남', '수원', '성남 수정', '용인 수지', '시흥', '안산', '안성', '안양', '양주', '양평', '여주', '연천', '수원 영통', '오산', '용인', '읍', '의왕', '의정부', '이천', '고양 일산동', '고양 일산서', '수원 장안', '성남 중원', '용인 처인', '파주', '수원 팔달', '평택', '포천', '하남', '화성', '거제', '거창', '고성(경남)', '김해', '남해', '동', '창원 합포', '창원 회원', '면', '밀양', '사천', '산청', '창원 성산', '양산', '읍', '의령', '창원 의창', '진주', '창원 진해', '창녕', '창원', '통영', '하동', '함안', '함양', '합천', '경산', '경주', '고령', '구미', '군위', '김천', '포항 남구', '동', '면', '문경', '봉화', '포항 북구', '상주', '성주', '안동', '영덕', '영양', '영주', '영천', '예천', '울릉', '울진', '읍', '의성', '청도', '청송', '칠곡', '포항', '광주 광산', '광주 남구', '광주 동구', '광주 북구', '광주 서구', '대구 남구', '대구 달서', '대구 달성', '대구 동구', '대구 동부', '대구 면부', '대구 북구', '대구 서구', '대구 수성', '대구 읍부', '대구 중구', '대전 대덕', '대전 동구', '대전 서구', '대전 유성', '대전 중구', '부산 강서', '부산 금정', '부산 기장', '부산 남구', '부산 동구', '부산 동래', '부산 동부', '부산 면부', '부산 부산진', '부산 북구', '부산 사상', '부산 사하', '부산 서구', '부산 수영', '부산 연제', '부산 영도', '부산 읍부', '부산 중구', '부산 해운대', '서울 강남', '서울 강동', '서울 강북', '서울 강서', '서울 관악', '서울 광진', '서울 구로', '서울 금천', '서울 노원', '서울 도봉', '서울 동대문', '서울 동작', '서울 마포', '서울 서대문', '서울 서초', '서울 성동', '서울 성북', '서울 송파', '서울 양천', '서울 영등포', '서울 용산', '서울 은평', '서울 종로', '서울 중구', '서울 중랑', '세종', '세종', '세종', '세종', '울산 남구', '울산 동구', '울산 동부', '울산 면부', '울산 북구', '울산 울주', '울산 읍부', '울산 중구', '인천 강화', '인천 계양', '인천 남동', '인천 동구', '인천 동부', '인천 면부', '인천 미추홀', '인천 부평', '인천 서구', '인천 연수', '인천 옹진', '인천 읍부', '인천 중구', '강진', '고흥', '곡성', '광양', '구례', '나주', '담양', '동', '면', '목포', '무안', '보성', '순천', '신안', '여수', '영광', '영암', '완도', '읍', '장성', '장흥', '진도', '함평', '해남', '화순', '고창', '군산', '김제', '남원', '전주 덕진', '동', '면', '무주', '부안', '순창', '전주 완산', '완주', '읍', '익산', '임실', '장수', '전주', '정읍', '진안', '동', '면', '서귀포', '읍', '제주', '계룡', '공주', '금산', '논산', '당진', '천안 동남', '동', '면', '보령', '부여', '천안 서북', '서산', '서천', '아산', '예산', '읍', '천안', '청양', '태안', '홍성', '괴산', '단양', '동', '면', '보은', '청주 상당', '청주 서원', '영동', '옥천', '음성', '읍', '제천', '증평', '진천', '청주 청원', '청주', '충주', '청주 흥덕']

 

 

#도시 이름을 DataFrame에 추가하고 불필요한 데이터 삭제

pop['ID'] = si_name

del pop['20-39세남자']
del pop['65세이상남자']
del pop['65세이상여자']

pop.head()

 

 

 

 

3. Cartogram을 위한 엑셀 파일 

 

 

# 엑셀 파일 읽기

draw_korea_raw = pd.read_excel('./data/draw_korea_raw.xlsx')
draw_korea_raw

 

 

 

 

 

 

4. stack으로 묶기

# 컬럼 이름을 인덱스로 만들기

draw_korea_raw_stacked = pd.DataFrame(draw_korea_raw.stack())
draw_korea_raw_stacked

 

 

# 인덱스 초기화

draw_korea_raw_stacked.reset_index(inplace=True)
draw_korea_raw_stacked

 

 

# 컬럼 이름 변경

draw_korea_raw_stacked.rename(columns={'level_0':'y', 'level_1':'x', 0:'ID'}, 
                              inplace=True)
draw_korea_raw_stacked

 

 

 

 

 

5. cartogram의 기본이 되는 지도 그리기

BORDER_LINES = [
    [(5, 1), (5,2), (7,2), (7,3), (11,3), (11,0)], # 인천
    [(5,4), (5,5), (2,5), (2,7), (4,7), (4,9), (7,9), 
     (7,7), (9,7), (9,5), (10,5), (10,4), (5,4)], # 서울
    [(1,7), (1,8), (3,8), (3,10), (10,10), (10,7), 
     (12,7), (12,6), (11,6), (11,5), (12, 5), (12,4), 
     (11,4), (11,3)], # 경기도
    [(8,10), (8,11), (6,11), (6,12)], # 강원도
    [(12,5), (13,5), (13,4), (14,4), (14,5), (15,5), 
     (15,4), (16,4), (16,2)], # 충청북도
    [(16,4), (17,4), (17,5), (16,5), (16,6), (19,6), 
     (19,5), (20,5), (20,4), (21,4), (21,3), (19,3), (19,1)], # 전라북도
    [(13,5), (13,6), (16,6)], # 대전시
    [(13,5), (14,5)], #세종시
    [(21,2), (21,3), (22,3), (22,4), (24,4), (24,2), (21,2)], #광주
    [(20,5), (21,5), (21,6), (23,6)], #전라남도
    [(10,8), (12,8), (12,9), (14,9), (14,8), (16,8), (16,6)], #충청북도
    [(14,9), (14,11), (14,12), (13,12), (13,13)], #경상북도
    [(15,8), (17,8), (17,10), (16,10), (16,11), (14,11)], #대구
    [(17,9), (18,9), (18,8), (19,8), (19,9), (20,9), (20,10), (21,10)], #부산
    [(16,11), (16,13)], #울산
#     [(9,14), (9,15)], 
    [(27,5), (27,6), (25,6)],
]

 

 

# 지역 이름 표시

plt.figure(figsize=(8, 11))

# 지역 이름 표시
for idx, row in draw_korea_raw_stacked.iterrows():
    
    # 광역시는 구 이름이 겹치는 경우가 많아서 시단위 이름도 같이 표시
    # (중구, 서구)
    if len(row['ID'].split())==2:
        dispname = '{}\n{}'.format(row['ID'].split()[0], row['ID'].split()[1])
    elif row['ID'][:2]=='고성':
        dispname = '고성'
    else:
        dispname = row['ID']

 

 

# 시도 경계 그리기

for path in BORDER_LINES:
    ys, xs = zip(*path)
    plt.plot(xs, ys, c='black', lw=1.5)

#y축의 위아래 변경
plt.gca().invert_yaxis()
#plt.gca().set_aspect(1)

#축과 라벨 제거
plt.axis('off')

#자동 레이아웃 설정
plt.tight_layout()
plt.show()

 

 

 

# draw_korea_raw_stacked와 pop의 도시이름 일치시키기

#draw_korea_raw_stacked 와 pop 의 도시이름 비교
print(set(draw_korea_raw_stacked['ID'].unique()) - set(pop['ID'].unique()))
print(set(pop['ID'].unique()) - set(draw_korea_raw_stacked['ID'].unique()))

#일치하지 않는 데이터 삭제
tmp_list = list(set(pop['ID'].unique()) - set(draw_korea_raw_stacked['ID'].unique()))

for tmp in tmp_list:
    pop = pop.drop(pop[pop['ID']==tmp].index)
                       
print(set(pop['ID'].unique()) - set(draw_korea_raw_stacked['ID'].unique()))
{'부천 원미', '부천 오정', '부천 소사', '인천 남구'}
{'포항', '부산 면부', '대구 읍부', '성남', '용인', '인천 면부', '대구 동부', '인천 미추홀', '인천 동부', '안산', '부산 동부', '수원', '창원', '울산 면부', '읍', '인천 읍부', '부산 읍부', '고양', '천안', '동', '청주', '울산 읍부', '대구 면부', '안양', '전주', '면', '울산 동부', '부천'}
set()
pop = pd.merge(pop, draw_korea_raw_stacked, how='left', on=['ID'])
pop.head()

 

 

# 좌표와 인구수 이용해서 피벗 테이블 생성

mapdata = pop.pivot_table(index='y', columns='x', values='인구수합계')
mapdata

 

 

# Nan이 아닌 데이터 확인




 

 

 

 

 

 

6. Cartogram 그리기

# DataFrame과 컬럼 이름 및 색상 값을 받아서 Cartogram을 그려주는 함수

def drawKorea(targetData, blockedMap, cmapname):
    gamma = 0.75

    #인구수 데이터의 크고 낮음을 분류하기 위한 값 만들기
    whitelabelmin = (max(blockedMap[targetData]) - 
                                     min(blockedMap[targetData]))*0.25 + \
                                                                min(blockedMap[targetData])
    #컬럼이름을 대입하기
    datalabel = targetData
    #최대값과 최소값 구하기
    vmin = min(blockedMap[targetData])
    vmax = max(blockedMap[targetData])
    
    #x 와 y를 가지고 피봇 테이블 만들기
    mapdata = blockedMap.pivot_table(index='y', columns='x', values=targetData)
    #데이터가 존재하는 것 골라내기
    masked_mapdata = np.ma.masked_where(np.isnan(mapdata), mapdata)
    #그래프 영역 크기 만들기
    plt.figure(figsize=(9, 11))
    #색상 설정
    plt.pcolor(masked_mapdata, vmin=vmin, vmax=vmax, cmap=cmapname, 
               edgecolor='#aaaaaa', linewidth=0.5)
    
    # 지역 이름 표시
    for idx, row in blockedMap.iterrows():
        # 광역시는 구 이름이 겹치는 경우가 많아서 시단위 이름도 같이 표시 
        #(중구, 서구)
        if len(row['ID'].split())==2:
            dispname = '{}\n{}'.format(row['ID'].split()[0], row['ID'].split()[1])
        elif row['ID'][:2]=='고성':
            dispname = '고성'
        else:
            dispname = row['ID']
        # 서대문구, 서귀포시 같이 이름이 3자 이상인 경우에 작은 글자로 표시
        if len(dispname.splitlines()[-1]) >= 3:
            fontsize, linespacing = 10.0, 1.1
        else:
            fontsize, linespacing = 11, 1.
            
        #글자색상 만들기
        annocolor = 'white' if row[targetData] > whitelabelmin else 'black'
        #텍스트 출력하기
        plt.annotate(dispname, (row['x']+0.5, row['y']+0.5), weight='bold',
                     fontsize=fontsize, ha='center', va='center', color=annocolor,
                     linespacing=linespacing)
    
    # 시도 경계 그리기
    for path in BORDER_LINES:
        ys, xs = zip(*path)
        plt.plot(xs, ys, c='black', lw=2)

    plt.gca().invert_yaxis()

    plt.axis('off')

    cb = plt.colorbar(shrink=.1, aspect=10)
    cb.set_label(datalabel)

    plt.tight_layout()
    plt.show()

 

 

 

# 인구수 합계로 Catrogram 그리기

drawKorea('인구수합계', pop, 'Blues')

 

 

#소멸위기지역으로 Cartogram 그리기

pop['소멸위기지역'] = [1 if con else 0 for con in pop['소멸위기지역']]
drawKorea('소멸위기지역', pop, 'Reds')

 

 

# 여성 비율로 Catrogram 그리기

pop['여성비'] = (pop['인구수여자']/pop['인구수합계'])*100
drawKorea('여성비', pop, 'RdBu')

 

 

# 청년 층의 여성 비율을 이용한 Cartogram 그리기

pop['2030여성비'] = (pop['20-39세여자']/pop['20-39세합계'])*100
drawKorea('2030여성비', pop, 'RdBu')

 

 

# 지역 이름을 index로 설정

import folium
import json
import warnings

warnings.simplefilter(action='ignore', category=FutureWarning)
pop_folium = pop.set_index('ID')
pop_folium.head()

 

 

#인구 수 합계를 이용한 단계구분도

#한국 지도 시도 경계 좌표를 가진 파일을 가져오기
geo_path = './data/korea_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))

map = folium.Map(location=[36.2002, 127.054], zoom_start=7)
folium.Choropleth(geo_data = geo_str,
               data = pop_folium['인구수합계'],
               columns = [pop_folium.index, pop_folium['인구수합계']],
               fill_color = 'YlGnBu',
               key_on = 'feature.id').add_to(map)

map
map = folium.Map(location=[36.2002, 127.054], zoom_start=7)
folium.Choropleth(geo_data = geo_str,
               data = pop_folium['소멸위기지역'],
               columns = [pop_folium.index, pop_folium['소멸위기지역']],
               fill_color = 'YlOrRd',
               key_on = 'feature.id').add_to(map)

map

 

 

 

 

 

 

 

 

 

- https://data.seoul.go.kr/

- 서울시 5대 점죄 발생현황 통계 데이터

- crime.txt

 

 

 

1. 데이터 가져오기

import pandas as pd
import folium
import json

criminal = pd.read_csv('./data/crime.txt', sep='\t', thousands=',', encoding='utf-8')

 

 

 

 

 

2. 데이터 전처리

 

# 불필요한 컬럼 제거

criminal.drop(['기간', '합계검거', '살인검거', '강도검거', '강간검거', '절도검거', '폭력검거'], axis=1, inplace=True)
criminal.drop([0], inplace=True)

 

 

# 컬럼 이름 설정

criminal.rename(columns={'살인발생':'살인', '강도발생':'강도', '강간발생':'강간', '절도발생':'절도', '폭력발생':'폭력'}, inplace=True)

 

 

# 인덱스 설정

criminal.set_index('자치구', inplace=True)

 

 

 

 

3. 단계 구분도

geo_path = './data/seoul.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))
map = folium.Map(location=[37.5502, 126.982], zoom_start=11,
                 tiles='Stamen Toner')
folium.Choropleth(geo_data = geo_str,
               data = criminal['살인'],
               columns = [criminal.index, criminal['살인']],
               fill_color = 'YlGnBu',
               key_on = 'feature.id').add_to(map)
map

 

 

 

 

 

4. 주소와 위도 경도 가져오기

# 경찰서 이름 만들기

station_name = []
for name in criminal.index:
    station_name.append('서울' + str(name[:-1]) + '경찰서')

print(station_name)
['서울종로경찰서', '서울중경찰서', '서울용산경찰서', '서울성동경찰서', '서울광진경찰서', '서울동대문경찰서', '서울중랑경찰서', '서울성북경찰서', '서울강북경찰서', '서울도봉경찰서', '서울노원경찰서', '서울은평경찰서', '서울서대문경찰서', '서울마포경찰서', '서울양천경찰서', '서울강서경찰서', '서울구로경찰서', '서울금천경찰서', '서울영등포경찰서', '서울동작경찰서', '서울관악경찰서', '서울서초경찰서', '서울강남경찰서', '서울송파경찰서', '서울강동경찰서']

 

 

# 카카오 지오코딩 API를 이용해서 경찰서 주소와 위도, 경도 찾아오기

import requests
import json
from urllib.parse import quote

#경찰서 주소와 위도, 경도 찾아오기
station_address = []
station_lat = []
station_lng = []
for name in station_name:
    q = quote(name)
    url = 'https://dapi.kakao.com/v2/local/search/keyword.json?query=' + q
    headers = {'Authorization': 'KakaoAK {}'.format('c454c0e64688ce2bde2dfff9cceced87')}
    data = requests.post(url, headers=headers)
    result = json.loads(data.text) #파싱한 결과
    documents = result["documents"]
    
    address = documents[0]["address_name"]
    x = documents[0]["x"]
    y = documents[0]["y"]
    
    station_address.append(address)
    station_lat.append(y)
    station_lng.append(x)
print(station_address)
print(station_lat)
print(station_lng)
['서울 종로구 공평동 1', '서울 강남구 역삼동 830-23', '서울 용산구 원효로1가 12-12', '서울 성동구 행당동 192-8', '서울 광진구 구의동 254-32', '서울 동대문구 청량리동 229', '서울 중랑구 신내동 810', '서울 성북구 삼선동5가 301', '서울 강북구 번동 415-15', '서울 도봉구 창동 17', '서울 노원구 하계동 250', '서울 은평구 불광동 산 24', '서울 서대문구 미근동 165', '서울 마포구 아현동 618-1', '서울 양천구 신정동 321', '서울 강서구 화곡동 980-27', '서울 구로구 구로동 3-25', '서울 금천구 시흥동 1030', '서울 영등포구 당산동3가 2-11', '서울 동작구 노량진동 72-35', '서울 관악구 봉천동 1695-5', '서울 서초구 서초동 1726-1', '서울 강남구 대치동 998', '서울 송파구 가락동 9', '서울 강동구 성내동 541-1']

['37.57185082446809', '37.49388566996322', '37.54117933635974', '37.5617947420747', '37.54292164557882', '37.5850804205685', '37.6182390801576', '37.58989767143614', '37.637406561393085', '37.65339041848567', '37.6423345266253', '37.6285242467996', '37.5649023404956', '37.550824477077796', '37.5165549067037', '37.5513470867979', '37.5070387936593', '37.45725314643252', '37.52585220719', '37.5131469479959', '37.4745875338795', '37.49561086789221', '37.5093899463715', '37.5019757297179', '37.52867274661258']

['126.98417036713045', '127.03221660594751', '126.96777437089538', '127.036472076258', '127.08396170505674', '127.045762797538', '127.10454224897', '127.01625465308534', '127.02733870040592', '127.05270598499145', '127.071404832413', '126.928631038584', '126.966790740735', '126.95400918908302', '126.865542970902', '126.849886071842', '126.890224925815', '126.89674921449215', '126.90094457988', '126.942857105642', '126.951062346192', '127.00528097622329', '127.067070541137', '127.12716129352492', '127.12688982770433']

 

 

 

 

 

 

5. 지도 출력

criminal['lat'] = station_lat
criminal['lng'] = station_lng
map = folium.Map(location=[37.5502, 126.982], zoom_start=11)

for n in criminal.index:
    folium.Marker([criminal['lat'][n], 
                   criminal['lng'][n]]).add_to(map)
map

 

map = folium.Map(location=[37.5502, 126.982], zoom_start=11)

for n in criminal.index:
    folium.CircleMarker([criminal['lat'][n], criminal['lng'][n]],
                        radius = criminal['폭력'][n]/100.0, 
                        color='#3186cc', fill_color='#3186cc', fill=True).add_to(map)
    
map
map = folium.Map(location=[37.5502, 126.982], zoom_start=11)

folium.Choropleth(geo_data = geo_str,
               data = criminal['살인'],
               columns = [criminal.index, criminal['살인']],
               fill_color = 'YlGnBu',
               key_on = 'feature.id').add_to(map)

for n in criminal.index:
    folium.CircleMarker([criminal['lat'][n], criminal['lng'][n]],
                        radius = criminal['폭력'][n]/100, 
                        color='#3186cc', fill_color='#3186cc', fill=True).add_to(map)
    
map

https://github.com/southkorea/southkorea-maps

한국 지리정보 사이트

 

 

 

1. 데이터 읽어오기

state_unemployment = 'data/US_Unemployment_Oct2012.csv'
state_data = pd.read_csv(state_unemployment)
print(state_data.head())
  State  Unemployment
0    AL           7.1
1    AK           6.8
2    AZ           8.1
3    AR           7.2
4    CA          10.1

 

 

 

 

2. 단계 구분도 출력

  • folium.Map으로 만든 지도에 choropleth 함수 호출
    • geo_data 옵션에 아이디와 위도 및 경도를 가진 json 파일의 경로를 설정해주고 data에 출력한 DF 설정
    • key_on에 json 파일에서 사용되는 id 컬럼 지정
state_geo = 'data/folium_us-states.json'

map = folium.Map(location=[40, -98], zoom_start=4)

folium.Choropleth(geo_data=state_geo, data=state_data,
             columns=['State', 'Unemployment'],
             key_on='feature.id',
             fill_color='YlGn',
             legend_name='Unemployment Rate (%)').add_to(map)
map