Mã hóa địa lý cho các nhà khoa học dữ liệu - KDnuggets

Mã hóa địa lý cho các nhà khoa học dữ liệu – KDnuggets

Nút nguồn: 2713218

Khi các nhà khoa học dữ liệu cần biết mọi thứ cần biết về “vị trí” của dữ liệu của họ, họ thường chuyển sang Hệ thống thông tin địa lý (GIS). GIS là một tập hợp các công nghệ và chương trình phức tạp phục vụ nhiều mục đích khác nhau, nhưng Đại học Washington đưa ra một định nghĩa khá toàn diện, nói rằng “hệ thống thông tin địa lý là sự sắp xếp phức tạp của các sự vật hoặc đối tượng liên quan hoặc được kết nối với nhau, với mục đích là để truyền đạt kiến ​​thức về các đặc điểm trên bề mặt trái đất” (Lawler et al). GIS bao gồm một loạt các kỹ thuật để xử lý dữ liệu không gian từ thu thập đến trực quan hóa, nhiều trong số đó là những công cụ có giá trị ngay cả khi bạn không phải là chuyên gia về GIS. Bài viết này cung cấp một cái nhìn tổng quan toàn diện về mã hóa địa lý với các minh họa bằng Python về một số ứng dụng thực tế. Cụ thể, bạn sẽ xác định chính xác vị trí của một tiệm pizza ở Thành phố New York, New York bằng cách sử dụng địa chỉ của nó và kết nối nó với dữ liệu về các công viên lân cận. Mặc dù phần trình diễn sử dụng mã Python nhưng các khái niệm cốt lõi có thể được áp dụng cho nhiều môi trường lập trình để tích hợp mã hóa địa lý vào quy trình làm việc của bạn. Những công cụ này cung cấp cơ sở để chuyển đổi dữ liệu thành dữ liệu không gian và mở ra cơ hội cho những phân tích địa lý phức tạp hơn. 

 

XXXXX

Mã hóa địa lý được định nghĩa phổ biến nhất là việc chuyển đổi dữ liệu địa chỉ thành tọa độ ánh xạ. Thông thường, điều này liên quan đến việc phát hiện tên đường trong một địa chỉ, khớp đường đó với ranh giới của đường tương ứng trong thế giới thực trong cơ sở dữ liệu, sau đó ước tính vị trí trên đường để đặt địa chỉ bằng cách sử dụng số đường. Ví dụ: chúng ta hãy thực hiện quy trình mã địa lý thủ công đơn giản cho địa chỉ của một tiệm bánh pizza ở New York trên đường Broadway: 2709 Broadway, New York, NY 10025. Nhiệm vụ đầu tiên là tìm các tệp hình dạng thích hợp cho hệ thống đường của địa điểm địa chỉ của bạn. Lưu ý rằng trong trường hợp này thành phố và tiểu bang của địa chỉ là “New York, NY.” May mắn thay, thành phố New York đã công bố thông tin chi tiết về đường đi trên Dữ liệu mở NYC trang (CSCL PUB). Thứ hai, hãy kiểm tra tên đường “Broadway”. Bây giờ bạn biết rằng địa chỉ có thể nằm trên bất kỳ đường phố nào có tên là “Broadway” ở thành phố New York, vì vậy bạn có thể thực thi mã Python sau để truy vấn API SODA dữ liệu mở NYC cho tất cả các đường phố có tên “Broadway”.

import geopandas as gpd
import requests
from io import BytesIO # Request the data from the SODA API
req = requests.get( "https://data.cityofnewyork.us/resource/gdww-crzy.geojson?stname_lab=BROADWAY"
)
# Convert to a stream of bytes
reqstrm = BytesIO(req.content)
# Read the stream as a GeoDataFrame
ny_streets = gpd.read_file(reqstrm)

 

Có hơn 700 kết quả cho truy vấn này, nhưng điều đó không có nghĩa là bạn phải kiểm tra 700 con phố để tìm thấy chiếc bánh pizza của mình. Trực quan hóa dữ liệu, bạn có thể thấy có 3 đường Broadway chính và một số đường nhỏ hơn.

 

XXXXX
 

Lý do cho điều này là mỗi con phố được chia thành các phần tương ứng với một dãy nhà, cho phép xem dữ liệu chi tiết hơn. Bước tiếp theo của quy trình là xác định chính xác địa chỉ nằm ở khu vực nào trong số này bằng cách sử dụng mã ZIP và số đường. Mỗi đoạn đường trong tập dữ liệu chứa các dải địa chỉ dành cho địa chỉ của các tòa nhà ở cả bên trái và bên phải của đường phố. Tương tự, mỗi đoạn chứa mã ZIP cho cả bên trái và bên phải của đường phố. Để xác định đoạn đường chính xác, đoạn mã sau áp dụng các bộ lọc để tìm đoạn đường có mã ZIP khớp với mã ZIP của địa chỉ và phạm vi địa chỉ chứa số đường của địa chỉ.

# Address to be geocoded
address = "2709 Broadway, New York, NY 10025"
zipcode = address.split(" ")[-1]
street_num = address.split(" ")[0] # Find street segments whose left side address ranges contain the street number
potentials = ny_streets.loc[ny_streets["l_low_hn"] street_num]
potentials = potentials.loc[potentials["l_high_hn"] > street_num]
# Find street segments whose zipcode matches the address'
potentials = potentials.loc[potentials["l_zip"] == zipcode]

 

Điều này thu hẹp danh sách thành một đoạn đường được thấy bên dưới.

 

XXXXX
 

Nhiệm vụ cuối cùng là xác định địa chỉ nằm ở đâu trên dòng này. Điều này được thực hiện bằng cách đặt số đường bên trong phạm vi địa chỉ cho đoạn đó, chuẩn hóa để xác định khoảng cách dọc theo đường của địa chỉ và áp dụng hằng số đó cho tọa độ của các điểm cuối của đường để có tọa độ của địa chỉ. Đoạn mã sau phác thảo quá trình này.

import numpy as np
from shapely.geometry import Point # Calculate how far along the street to place the point
denom = ( potentials["l_high_hn"].astype(float) - potentials["l_low_hn"].astype(float)
).values[0]
normalized_street_num = ( float(street_num) - potentials["l_low_hn"].astype(float).values[0]
) / denom # Define a point that far along the street
# Move the line to start at (0,0)
pizza = np.array(potentials["geometry"].values[0].coords[1]) - np.array( potentials["geometry"].values[0].coords[0]
)
# Multiply by normalized street number to get coordinates on line
pizza = pizza * normalized_street_num
# Add starting segment to place line back on the map
pizza = pizza + np.array(potentials["geometry"].values[0].coords[0])
# Convert to geometry array for geopandas
pizza = gpd.GeoDataFrame( {"address": , "geometry": [Point(pizza[0], pizza[1])]}, crs=ny_streets.crs, geometry="geometry",
)

 

Sau khi mã hóa địa chỉ xong, giờ đây bạn có thể vẽ vị trí của tiệm pizza này trên bản đồ để hiểu vị trí của nó. Vì mã ở trên đã xem xét thông tin liên quan đến phía bên trái của đoạn đường nên vị trí thực tế sẽ hơi lệch về bên trái so với điểm được vẽ trong một tòa nhà ở phía bên trái đường. Cuối cùng bạn cũng biết nơi bạn có thể mua một ít bánh pizza.

 

XXXXX
 

Quá trình này bao gồm những gì thường được gọi là mã hóa địa lý, nhưng đó không phải là cách duy nhất thuật ngữ này được sử dụng. Bạn cũng có thể thấy mã hóa địa lý đề cập đến quá trình chuyển tên mốc sang tọa độ, mã ZIP sang tọa độ hoặc tọa độ sang vectơ GIS. Bạn thậm chí có thể nghe thấy mã hóa địa lý ngược (sẽ được đề cập sau) được gọi là mã hóa địa lý. Một định nghĩa nhẹ nhàng hơn cho mã hóa địa lý bao gồm những điều này sẽ là “sự chuyển giao giữa các mô tả ngôn ngữ tự nhiên, gần đúng về các vị trí và tọa độ địa lý”. Vì vậy, bất cứ khi nào bạn cần di chuyển giữa hai loại dữ liệu này, hãy xem xét mã hóa địa lý như một giải pháp.

Để thay thế cho việc lặp lại quy trình này bất cứ khi nào bạn cần mã hóa địa chỉ, nhiều điểm cuối API khác nhau, chẳng hạn như Bộ mã hóa địa lý của Cục điều tra dân số Hoa KỳAPI mã hóa địa lý của Google, cung cấp dịch vụ mã hóa địa lý chính xác miễn phí. Một số tùy chọn trả phí, chẳng hạn như ArcGIS của Esri, GeocodioSmarty thậm chí còn cung cấp độ chính xác trên tầng thượng cho các địa chỉ được chọn, điều đó có nghĩa là tọa độ trả về sẽ nằm chính xác trên nóc tòa nhà thay vì trên đường phố gần đó. Các phần sau phác thảo cách sử dụng các dịch vụ này để khớp mã hóa địa lý vào đường dẫn dữ liệu của bạn bằng cách sử dụng Bộ mã hóa địa lý của Cục điều tra dân số Hoa Kỳ làm ví dụ.

Để có được độ chính xác cao nhất có thể khi mã hóa địa lý, bạn phải luôn bắt đầu bằng cách đảm bảo rằng địa chỉ của bạn được định dạng để phù hợp với tiêu chuẩn của dịch vụ bạn đã chọn. Điều này sẽ hơi khác nhau giữa mỗi dịch vụ, nhưng định dạng phổ biến là định dạng USPS của “PRIMARY# STREET, CITY, STATE, ZIP” trong đó STATE là mã viết tắt, PRIMARY# là số đường và tất cả đề cập đến số căn hộ, tòa nhà số và hộp PO sẽ bị xóa. 

Sau khi địa chỉ của bạn được định dạng, bạn cần gửi địa chỉ đó tới API để mã hóa địa lý. Trong trường hợp Bộ mã hóa địa lý của Cục điều tra dân số Hoa Kỳ, bạn có thể gửi địa chỉ theo cách thủ công thông qua tab Xử lý địa chỉ một dòng hoặc sử dụng API REST được cung cấp để gửi địa chỉ theo chương trình. Bộ mã hóa địa lý của Cục điều tra dân số Hoa Kỳ cũng cho phép bạn mã hóa địa lý toàn bộ tệp bằng cách sử dụng bộ mã hóa địa lý hàng loạt và chỉ định nguồn dữ liệu bằng tham số điểm chuẩn. Để mã hóa địa lý tiệm pizza từ trước đó, liên kết này có thể được sử dụng để chuyển địa chỉ tới API REST, có thể được thực hiện bằng Python với mã sau.

# Submit the address to the U.S. Census Bureau Geocoder REST API for processing
response = requests.get( "https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address=2709+Broadway%2C+New+York%2C+NY+10025&benchmark=Public_AR_Current&format=json"
).json()

 

Dữ liệu trả về là tệp JSON, được giải mã dễ dàng thành từ điển Python. Nó chứa trường “tigerLineId” có thể được sử dụng để khớp với tệp hình dạng cho đường phố gần nhất, trường “bên” có thể được sử dụng để xác định địa chỉ nằm ở phía nào của đường phố đó và các trường “fromAddress” và “toAddress” chứa phạm vi địa chỉ cho đoạn đường. Quan trọng nhất, nó chứa trường “tọa độ” có thể được sử dụng để xác định địa chỉ trên bản đồ. Đoạn mã sau trích xuất tọa độ từ tệp JSON và xử lý nó thành GeoDataFrame để chuẩn bị cho phân tích không gian.

# Extract coordinates from the JSON file
coords = response["result"]["addressMatches"][0]["coordinates"]
# Convert coordinates to a Shapely Point
coords = Point(coords["x"], coords["y"])
# Extract matched address
matched_address = response["result"]["addressMatches"][0]["matchedAddress"]
# Create a GeoDataFrame containing the results
pizza_point = gpd.GeoDataFrame( {"address": [matched_address], "geometry": coords}, crs=ny_streets.crs, geometry="geometry",
)

 

Hình dung điểm này cho thấy nó hơi lệch về phía bên trái của điểm đã được mã hóa địa lý theo cách thủ công.

 

XXXXX

Mã hóa địa lý ngược là quá trình lấy tọa độ địa lý và khớp chúng với các mô tả ngôn ngữ tự nhiên của một khu vực địa lý. Khi được áp dụng chính xác, đây là một trong những kỹ thuật mạnh mẽ nhất để đính kèm dữ liệu bên ngoài vào bộ công cụ khoa học dữ liệu. Bước đầu tiên của mã hóa địa lý ngược là xác định khu vực địa lý mục tiêu của bạn. Đây là khu vực sẽ chứa dữ liệu tọa độ của bạn. Một số ví dụ phổ biến là vùng điều tra dân số, mã ZIP và thành phố. Bước thứ hai là xác định xem điểm đó nằm trong vùng nào, nếu có. Khi sử dụng các vùng chung, Bộ mã hóa địa lý điều tra dân số Hoa Kỳ có thể được sử dụng để đảo ngược mã địa lý bằng cách thực hiện các thay đổi nhỏ đối với yêu cầu API REST. Yêu cầu xác định khu vực địa lý Điều tra dân số nào có tiệm pizza trước đó được liên kết tại đây. Kết quả của truy vấn này có thể được xử lý bằng các phương pháp tương tự như trước đây. Tuy nhiên, việc xác định khu vực một cách sáng tạo để phù hợp với nhu cầu phân tích và đảo ngược mã hóa địa lý theo cách thủ công sẽ mở ra nhiều khả năng. 

Để đảo ngược mã địa lý theo cách thủ công, bạn cần xác định vị trí và hình dạng của một vùng, sau đó xác định xem điểm đó có nằm trong vùng đó hay không. Việc xác định xem một điểm có nằm trong đa giác hay không thực sự là một vấn đề khá khó khăn, nhưng thuật toán truyền tia, trong đó một tia bắt đầu tại một điểm và truyền vô hạn theo một hướng cắt ranh giới của vùng một số lẻ lần nếu nó nằm trong vùng và một số lần chẵn trong trường hợp khác (Shimrat), có thể được sử dụng để giải nó trong hầu hết các trường hợp các trường hợp. Đối với những người thiên về toán học, đây thực sự là một ứng dụng trực tiếp của Định lý đường cong Jordan (Hosch). Xin lưu ý, nếu bạn đang sử dụng dữ liệu từ khắp nơi trên thế giới, thuật toán truyền tia thực sự có thể thất bại do tia cuối cùng sẽ quấn quanh bề mặt Trái đất và trở thành một vòng tròn. Trong trường hợp này, thay vào đó bạn sẽ phải tìm số quanh co (Weisstein) cho vùng và điểm. Điểm nằm trong vùng nếu số cuộn dây không bằng 0. May mắn thay, thư viện geopandas của Python cung cấp chức năng cần thiết để vừa xác định phần bên trong của một vùng đa giác vừa kiểm tra xem một điểm có nằm trong vùng đó mà không cần tất cả các phép toán phức tạp hay không.

Mặc dù mã hóa địa lý thủ công có thể quá phức tạp đối với nhiều ứng dụng, mã hóa địa lý ngược thủ công có thể là một bổ sung thiết thực cho bộ kỹ năng của bạn vì nó cho phép bạn dễ dàng khớp điểm của mình với các khu vực được tùy chỉnh cao. Ví dụ: giả sử bạn muốn mang miếng bánh pizza của mình đến công viên và đi dã ngoại. Bạn có thể muốn biết liệu tiệm pizza có cách công viên một quãng ngắn hay không. Thành phố New York cung cấp các tệp hình dạng cho công viên của họ như một phần của Bộ dữ liệu thuộc tính công viên (Nhóm dữ liệu mở của Công viên NYC) và họ cũng có thể được truy cập thông qua API SODA bằng mã sau.

# Pull NYC park shapefiles
parks = gpd.read_file( BytesIO( requests.get( "https://data.cityofnewyork.us/resource/enfh-gkve.geojson?$limit=5000" ).content )
)
# Limit to parks with green area for a picnic
parks = parks.loc[ parks["typecategory"].isin( [ "Garden", "Nature Area", "Community Park", "Neighborhood Park", "Flagship Park", ] )
]

 

Bạn có thể thêm những công viên này vào hình ảnh trực quan để xem những công viên nào ở gần tiệm pizza.

 

XXXXX
 

Rõ ràng có một số tùy chọn gần đó, nhưng việc tìm ra khoảng cách bằng cách sử dụng các tệp hình dạng và điểm có thể khó khăn và tốn kém về mặt tính toán. Thay vào đó, mã hóa địa lý ngược có thể được áp dụng. Bước đầu tiên, như đã đề cập ở trên, là xác định vùng bạn muốn gắn điểm vào. Trong trường hợp này, khu vực này “cách công viên ở Thành phố New York 1/2 dặm”. Bước thứ hai là tính toán nếu điểm nằm trong một vùng, việc này có thể được thực hiện bằng toán học bằng cách sử dụng các phương pháp đã đề cập trước đó hoặc bằng cách áp dụng hàm “chứa” trong geopandas. Đoạn mã sau được sử dụng để thêm vùng đệm 1/2 dặm vào ranh giới của các công viên trước khi kiểm tra xem vùng đệm của công viên nào hiện chứa điểm.

# Project the coordinates from latitude and longitude into meters for distance calculations
buffered_parks = parks.to_crs(epsg=2263)
pizza_point = pizza_point.to_crs(epsg=2263)
# Add a buffer to the regions extending the border by 1/2 mile = 2640 feet
buffered_parks = buffered_parks.buffer(2640)
# Find all parks whose buffered region contains the pizza parlor
pizza_parks = parks.loc[buffered_parks.contains(pizza_point["geometry"].values[0])]

 

Vùng đệm này hiển thị các công viên gần đó, được đánh dấu bằng màu xanh lam trong hình ảnh bên dưới

 

XXXXX
 

Sau khi mã hóa địa lý ngược thành công, bạn đã biết rằng có 8 công viên trong vòng nửa dặm tính từ tiệm pizza mà bạn có thể đi dã ngoại. Thưởng thức lát đó.
 

XXXXX
Pizza Slice của j4p4n

nguồn

  1. Lawler, Josh và Schiess, Peter. ESRM 250: Giới thiệu về Hệ thống thông tin địa lý về tài nguyên rừng. Định nghĩa về GIS, ngày 12 tháng 2009 năm XNUMX, Đại học Washington, Seattle. Bài giảng trên lớp. https://courses.washington.edu/gis250/lessons/introduction_gis/definitions.html
  2. CSCL PUB. Dữ liệu mở New York. https://data.cityofnewyork.us/City-Government/road/svwp-sbcd
  3. Tài liệu mã hóa địa lý của Cục điều tra dân số Hoa Kỳ. Tháng 2022 năm XNUMX. https://geocoding.geo.census.gov/geocoder/Geocoding_Services_API.pdf 
  4. Shimrat, M., “Thuật toán 112: Vị trí của điểm so với đa giác” 1962, Communications of the ACM Tập 5 Số 8, tháng 1962 năm XNUMX. https://dl.acm.org/doi/10.1145/368637.368653 
  5. Hosch, William L.. “Định lý đường cong Jordan”. Bách khoa toàn thư Britannica, Ngày 13 tháng 2018 năm XNUMX, https://www.britannica.com/science/Jordan-curve-theorem
  6. Weisstein, Eric W. “Số cuộn dây theo đường viền.” Từ thế giới toán học–Tài nguyên web Wolfram. https://mathworld.wolfram.com/ContourWindingNumber.html
  7. Nhóm dữ liệu mở của Công viên NYC. Thuộc tính công viên. Ngày 14 tháng 2023 năm XNUMX. https://nycopendata.socrata.com/Recreation/Parks-Properties/enfh-gkve
  8. j4p4n, “Lát pizza.” Từ OpenClipArt. https://openclipart.org/detail/331718/pizza-slice

 
 
Evan Miller là Thành viên Khoa học Dữ liệu tại Tech Impact, nơi anh sử dụng dữ liệu để hỗ trợ các cơ quan chính phủ và phi lợi nhuận thực hiện sứ mệnh vì lợi ích xã hội. Trước đây, Evan đã sử dụng máy học để đào tạo phương tiện tự lái tại Đại học Central Michigan.
 

Dấu thời gian:

Thêm từ Xe đẩy