Workflow Machine Learning Pada Citra Satelit dan Data Geospasial Menggunakan Pyspatialml

What if a country has an open and easy access to geospatial data…

Aviandito
SedStrat
10 min readMay 5, 2020

--

Pesan sponsor: seluruh konten dan kode yang saya tulis akan selalu gratis dan dapat digunakan oleh siapa saja. Apabila Anda merasa terbantu, dukung saya melalui laman Saweria berikut. 10% dari dukungan Anda akan saya sumbangkan melalui Kitabisa. Terima kasih :)

Kalau dipikir-pikir, selama saya kuliah geologi dulu, pengenalan GIS dari kurikulum bisa dibilang… “cukup”. Yang penting kami bisa membedakan WGS84 dan UTM, bisa memplot stasiun pengamatan lapangan dari gawai GPS, bisa mendapatkan peta kontur untuk lapangan pemetaan, serta memanfaatkan citra satelit untuk picking kelurusan. I only know the bare minimum…

Padahal, kemampuan analisis geospasial adalah salah satu kemampuan paling dicari di berbagai industri saat ini.

Karena itulah, ketika mas Hazred Umar Fathan dari Dunia Tambang bertanya mengenai analisis prediktif pada data geospasial, saya agak bingung dalam menjawabnya. Pada saat itu saya langsung bilang bahwa saya belum pernah melakukannya, dan saya harus mempelajari dulu…

Tantangan Evergreen

Sebagai konteks, Mas Fathan membagikan tautan Evergreen: Generate new knowledge by predicting all Australian mineral deposits kepada saya. Seperti judulnya, Evergreen adalah kontes yang ambisius, dan menuntut peserta untuk mencoba memprediksi keberadaan endapan mineral di Australia. Kontes ini diadakan oleh Unearthed, sebuah organisasi inkubator startup teknologi di bidang industri sumber daya alam yang berbasis di Australia.

Peserta diberikan data ASTER yang mencitrakan gelombang elektromagnetik dari permukaan bumi. Dari panjang gelombang elektromagnetik tersebut, dapat disimpulkan unsur yang memancarkannya, seperti misalnya oksida besi, indeks silika, dan sebagainya. Selain itu, terdapat pula data-data geofisika seperti survei magnetik, survei radiometri, serta survei gravity. Semua data tersebut berformat GeoTIFF. Tidak ada yang fancy dari data yang diberikan. Mahasiswa dan praktisi geosains di Indonesia sudah biasa berinteraksi dengan data-data tersebut.

Citra satelit dan survei geofisika yang diberikan untuk peserta (Sumber: Evergreen challenge)
Aussie oi-oi-oi! (Sumber: Evergreen challenge)

Sebagai ground truth, terdapat 1.863 koordinat endapan mineral berharga seperti emas, nikel, dan lainnya. Menariknya, semua data di atas adalah data terbuka yang dirilis oleh Pemerintah Australia melalui Geoscience Australia (Badan Geologi-nya Australia). Semua data ini dapat diakses melalui portal satu data Pemerintah Australia. Keren!

Melihat tantangan yang diberikan, menurut saya siapapun pemenangnya, akan sulit menemukan solusi yang sempurna karena kompleksnya kondisi bawah permukaan. Menyadari hal ini, Unearthed tidak hanya menggunakan leaderboard untuk menentukan pemenang kontes, tetapi lebih mementingkan kegunaan model/aplikasi yang dibuat peserta, serta hal-hal teknis seperti bagaimana cara peserta memastikan bahwa model yang dibuat tidak overfit, dan sebagainya.

Terlepas dari itu, kontes ini menunjukkan apa yang mungkin terjadi apabila data geosains di Indonesia dibuka seluas-luasnya untuk publik!

Pyspatialml dan cara prediksi dengan data raster

Tujuan tulisan ini bukan untuk memenangkan Evergreen, melainkan untuk menunjukkan penggunaan Pyspatialml dan Python dalam melakukan prediksi menggunakan data geospasial, khususnya data raster seperti citra satelit. Perlu diketahui, saat ini Pyspatialml (ditulis oleh Steven Pawley) masih dalam tahap pengembangan dan belum tersedia di PyPI: pengguna harus menginstall melalui repo GitHub. Adanya bug dalam alur kerja harus dimaklumi.

Pyspatialml berpusat pada objek Raster(), yang mengumpulkan semua raster-raster yang akan digunakan dalam prediksi dalam satu objek (“stack”). Objek Raster() ini kompatibel dengan scikit-learn: setelah Raster() berisi citra satelit yang ingin kita gunakan siap, tahapan selanjutnya terasa seperti workflow machine learning pada umumnya.

Dalam tantangan Evergreen, kita diberikan data raster yang memiliki coverage sebesar area observasi, dan ground truth berupa data endapan yang merupakan titik koordinat. Lalu bagaimana kita dapat membangun model machine learning? Salah satu cara menyelesaikan masalah ini (yang menjadi filosofi Pyspatialml) adalah dengan:

  1. Mengekstrak nilai raster pada titik-titik ground truth tersebut
  2. Menggunakan titik ground truth sebagai target dan hasil ekstraksi nilai raster pada koordinat ground truth sebagai prediktor, kemudian melakukan training model seperti biasa
  3. Menggunakan model yang sudah di-train untuk melakukan prediksi pada keseluruhan raster

Gambar di bawah ini mengilustrasikan tahapan ekstraksi nilai raster pada koordinat titik ground truth.

Ekstrak nilai raster-raster pada koordinat target, kemudian lakukan training (Sumber: Pyspatialml)

Sekarang saatnya memulai analisis! Berikut package yang digunakan dalam tulisan ini.

Mengunduh data

Unearthed telah menulis package untuk memudahkan pengunduhan data raster dari National Computational Infrastructure Australia. Dalam package tersebut, juga sudah disiapkan dependency yang dibutuhkan. Untuk menghindarkan konflik, disarankan untuk membuat virtual environment Anaconda dalam menggunakan package tersebut. Panduan lengkap cara instalasi dapat dilihat di repo GitHub explore_australia.

Untuk menggunakan package tersebut, kita harus:

  1. Membuat clone repo explore_australia dari GitHub
  2. Membuat virtual environment Anaconda (atau Miniconda)
  3. Menjalankan setup.py di clone repo melalui virtual environment tersebut

Untuk memilih wilayah yang akan kita unduh raster-nya, kita harus membuat objek Stamp() yang berisi koordinat titik tengah dari kotak, dan panjang sisi dari kotak tersebut. Saya menggunakan koordinat latitude -31.125° dan longitude 121.75° sebagai titik pusat kotak, dan 100 km sebagai panjang sisi. Stamp() ini menghasilkan segiempat berdimensi 100 x 100 km di sekitar Feysville, Western Australia. Ya, WA memang dikenal sebagai salah satu daerah penghasil sumberdaya alam — baik migas maupun minerba — terbesar di Australia.

Untuk mengunduh data raster, langkah selanjutnya adalah memasukkan stamp tersebut ke dalam fungsi get_coverages(). Fungsi ini akan mengunduh file GeoTIFF ke sistem Anda, dalam direktori dengan nama yang telah dimasukkan dalam argumen name (dalam hal ini nama direktorinya adalah ‘feysville’).

Feysville, WA (Google Maps)

Memuat data sebagai objek Raster( )

Setelah berhasil menjalankan get_coverages(), semua file raster berformat GeoTIFF akan tersimpan di sistem Anda. Untuk memuat data sebagai objek Raster() di Pyspatialml, kita hanya perlu memasukkan semua nama-nama file raster yang ingin digunakan dalam pemodelan. Nama-nama ini bisa dikumpulkan dalam bentuk list.

Dalam kasus ini, entah kenapa saya tidak bisa mendapatkan hasil yang benar apabila menggunakan proyeksi asli dari data raster. Oleh karena itu, saya melakukan reproyeksi ke WGS84 (kode EPSG:4326) dengan method to_crs(). Anda bisa melakukan reproyeksi ke Coordinate Reference System (CRS) lainnya dengan menggunakan cara ini. Perlu diketahui bahwa tahapan ini membuat saya pusing, dan ini karena pemahaman GIS saya yang minim.

Sekarang saatnya memplot semua raster untuk mengecek apakah semua raster sudah dimuat atau belum. Pyspatialml sudah dilengkapi dengan method untuk memplot stack, tetapi karena keterbatasannya, saya membuat fungsi sendiri untuk memplot sebuah stack.

Plot semua raster yang telah dimuat sebagai objek Raster(). Voila!

Dengan ini, tahap pemuatan data raster ke dalam stack sudah beres. Tentunya kita bisa melakukan penambahan/pengurangan layer, subsetting, dan bahkan melakukan operasi matematika antar layer dalam stack. Ke depannya, kita hanya perlu berurusan dengan stack ini.

Feature Engineering geolokasi

Seperti yang sudah dijelaskan sebelumnya, pada akhirnya kita akan meng-ekstrak nilai raster pada titik-titik koordinat ground truth. Artinya, kita akan kehilangan feature posisi dari raster-raster tersebut. Padahal menurut Hukum Pertama Geografi, “everything is related to everything else, but near things are more related than distant things”.

Untungnya, Pyspatialml telah menyiapkan fungsi xy_coordinates() untuk feature engineering koordinat X-Y, dan distance_to_corners() untuk feature engineering jarak dari sudut kotak. Hasilnya akan tersimpan dalam bentuk raster, dan dapat digunakan dalam training model kita nanti. Tambahkan raster-raster baru ini ke stack utama kita dengan menggunakan method append().

Sekarang raster kita sudah siap! Saatnya menyiapkan data ground truth untuk melakukan prediksi.

Memuat data endapan mineral

Untuk memuat data endapan mineral, kita akan menggunakan geopandas. geopandas adalah dataframe mirip pandas, tapi dengan tambahan informasi sistem koordinat CRS. Dari sisi penggunaan, selain embel-embel ‘geo’ pada namanya, hampir tidak ada perbedaan antara dataframe pandas dan geopandas.

Untuk memuat data GeoJSON, kita dapat menggunakan method read_file. Saya melakukan subsetting menggunakan koordinat sudut bounding box dari raster, dan menyisakan hanya titik-titik yang berada dalam area observasi. Dari 1.863 titik di seluruh Australia, terdapat 150 titik endapan di dalam area observasi kita.

Untuk memastikan data endapan telah termuat dengan benar dan memiliki sistem koordinat yang sama dengan raster, saya melakukan pengeplotan titik di atas salah satu raster yaitu raster anomali gravity Bouguer. Dapat kita lihat bahwa titik-titik endapan kebanyakan berada di atas lokasi dengan nilai anomali tinggi.

Selain itu, dapat dilihat bahwa satu titik endapan bisa terdiri dari beberapa mineral yang disimpan dalam bentuk string dengan pemisah semikolon (;) di data asli. Banyak taktik yang dapat dilakukan tergantung kebutuhan model, tetapi saya memilih untuk melakukan one-hot encoding untuk setiap mineral. Misalnya, apabila suatu titik terdiri dari Ni;Co, maka saya akan membuat dua kolom baru untuk flag is_Ni dan is_Co.

Mengekstrak nilai raster pada koordinat titik endapan

Setelah berhasil memuat data, kita harus menyiapkan data dalam format yang bisa diproses oleh scikit-learn. Untuk itu, kita harus menyiapkan dataframe geopandas berisi flag endapan mineral dan nilai raster-raster pada koordinat endapan tersebut.

Pyspatialml punya fungsi extract_vector untuk melakukan hal ini.

Dataframe sudah siap, saatnya melakukan workflow ML pada umumnya menggunakan scikit-learn!

Machine Learning dan CV pada data spasial

Tahap berikutnya relatif mudah apabila Anda sudah familiar dengan scikit-learn. Kita cukup membagi prediktor dan target, kemudian melakukan training pada data-data tersebut. Dalam contoh ini, saya ingin menjadikan emas sebagai target (variabel y), dan nilai-nilai raster sebagai prediktor (variabel X). Algoritma random forest digunakan dalam contoh ini. Ya, model kita sudah siap…

Namun, ada satu hal yang penting dan agak berbeda apabila kita menganalisis data spasial, yaitu di tahapan cross validation (CV). Apabila kita mengambil data train dan validation secara random seperti CV pada umumnya, bisa jadi kita mendapatkan hasil yang terlalu optimis. Padahal, kebetulan poin-poin train dan validation letaknya berdekatan (sehingga berkorelasi).

Untuk mengatasinya, kita dapat melakukan k-means clustering, lalu melakukan validation fold antar cluster. Hal ini dapat meminimalisir korelasi spasial antara poin-poin train dan validation dan membuat hasil CV lebih valid. Gambar oleh Schratz dkk (2018) mengilustrasikan masalah ini, dan bagaimana clustering dapat meminimalisir hal tersebut.

Perbedaan antara non-spatial/random CV (atas) vs. spatial CV (bawah) (Schratz dkk., 2018)
Hasil k-means clustering dengan fitur koordinat x-y pada data kita

Untuk implementasinya, pertama-tama kita melakukan clustering kepada semua titik endapan berdasarkan koordinat x-y nya. Artinya, kita mengelompokkan titik-titik yang berdekatan. Kemudian, kita gunakan cluster itu sebagai grouping dalam cross_validate.

Setelah cukup yakin dengan model yang kita buat, saatnya kita melakukan prediksi pada keseluruhan raster. Objek Stack() didesain untuk workflow scikit-learn, dan kita bisa menggunakan method predict_proba untuk membuat raster berisi probabilitas kehadiran target (dalam hal ini emas) dengan nilai antara 0–1.

Hasil prediksi dengan model yang kita buat

Dari raster di atas, sepertinya lokasi memegang peranan penting dalam analisis kita. Terlihat bahwa nilai probabilitas kehadiran emas di bagian utara wilayah observasi relatif lebih tinggi. Plot feature importance juga mengkonfirmasi hipotesis tersebut. Namun, saya berekspektasi bahwa pengukuran geofisika yang lebih klasik seperti anomali gravity lebih penting dibanding hal-hal tersebut.

Tentunya model yang saya buat dalam tulisan ini perlu dievaluasi lebih mendalam. Saya tidak melakukan seleksi feature, padahal ada feature yang berkorelasi antara satu dan lainnya. Selain itu, karena saya tidak familiar dengan eksplorasi emas, saya tidak tahu citra satelit apa yang seharusnya kita perhatikan lebih mendalam. Hal ini menunjukkan bahwa domain knowledge sangat penting, terlepas dari metode yang kita gunakan.

Kesimpulan dan saran

Rupanya seru juga bermain-main dengan data geospasial! Selain itu, saya salut dengan keterbukaan data geosains Pemerintah Australia, karena dengan ini, setiap orang dapat mencoba dan berkontribusi terhadap kemajuan industri! Berikut beberapa catatan yang saya rangkum dari proses ini:

  • Pemahaman mengenai sistem koordinat serta proyeksi sangat penting sebelum kita memproses data geospasial
  • Pemahaman mengenai korelasi spasial sangat diperlukan dalam ML pada data geospasial
  • Penambahan fitur dari shapefile/vektor data geologi (sesar, litologi, dll.) pastinya akan menjadikan model lebih robust
  • Contoh dalam tulisan ini hanya untuk mendemonstrasikan workflow ML pada data raster. Evaluasi hasil ML model secara mendalam dan dengan domain knowledge diperlukan untuk menghasilkan model yang robust
  • Pyspatialml sangat praktis digunakan, tetapi banyak batasan dalam penggunaannya. Apabila diperlukan kebebasan lebih, maka sepertinya workflow di luar Pyspatialml harus digunakan. Misalnya, proses raster secara manual dengan Rasterio
  • Workflow yang sama dapat diaplikasikan dalam konteks lainnya dalam geosains, misalnya pada data seismik 3D, maupun di luar geosains seperti dalam analisis ekonometrika dan/atau business intelligence

Terima kasih telah membaca tulisan ini! Seperti biasa, notebook yang saya gunakan dapat diakses dalam repo GitHub berikut. Tentunya kritik, komentar, dan pertanyaan Anda sangat ditunggu. Sampai jumpa!

--

--

Aviandito
SedStrat

Interested in cool stuff ranging from Formula One to Geoscience. All views are personal.