Visualisasi Kriminalitas dengan Merekayasa Citra Geospasial (GEO-AI), Serumit Apa, sih?

Faurel Gema
Dipantry
Published in
6 min readNov 23, 2020
Sumber Gambar: https://www.geospatialworld.net/blogs/geospatial-ai/

Bro, lu kan anak IT? Tolong hack Google dong biar di aplikasi Sistem Informasi Geografisnya nampilin kalo kota x itu banyak kejahatan? Soalnya emak gue ngotot pengen kesana mulu,”

Sebagai pembuka, itulah cuplikan drama fiktif yang bakalan dialami oleh setiap mahasiswa rumpun Teknologi dan Informasi yang katanya jago meretas, tapi untuk kali ini, kita gak bakal bicara tentang retas-meretas. Kita bakal seru-seruan menjelajah dunia dengan ilmu matematika sebagai bensinnya, dan mengoding sebagai kendaraannya.

Lalu, bagaimanakah konsep dan kasus singkatnya?

Begini, singkat cerita, ada kumpulan data yang mencatat kasus kriminalitas tiap tahunnya. Lalu, bagaimana cara agar data tersebut menjadi lebih bermakna dan mudah diinformasikan? Agar lebih kekinian, kita gunakan konsep Machine Learning.

Apa itu Machine Learning? Lengkapnya kalian bisa memahami dari salah satu kasus di tulisan rekan saya mengenai Image Recognition disini. Yang pasti jika kalian tertarik di bidang ilmu komputer dan kecerdasan buatan yang satu ini, diwajibkan untuk menguasai bahasa pemrograman, matematika dan statistika sebagai fondasi utamanya.

Dalam kasus sekarang, penulis bakal merekayasa data terkait kasus kriminalitas di kota Chicago, suatu kota terbesar di negara bagian Amerika Serikat, menggunakan bahasa program Python. Tanpa basa-basi lagi, mari kita langsung ngoding.

PREPARATION

Kita akan menggunakan Google Colab, atau Jupyter Notebook dalam menyusunnya.

Pertama, kita siapkan library yang dibutuhkan untuk membangun sebuah programnya.

# Kita gunakan pandas dan numpy untuk mengolah dataframe
import pandas as pd
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

import numpy as np
# Gunakan inline untuk membuat plot pada peramban
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("darkgrid")
font = {'size': 12}
mpl.rc('font', **font)
# Gunakan Folium untuk visualisasi peta
import folium
from folium.plugins import MarkerCluster
from folium.plugins import FastMarkerCluster
from folium import plugins

# Modul untuk konversi alamat ke nilai latitude dan longitude
from geopy.geocoders import Nominatim
import yaml

with open("./capstone_data/config.yaml", "r") as f:
cfg = yaml.load(f)

search_params = {
'client_id': cfg['client_id'],
'client_secret': cfg['client_secret'],
'intent': 'browse',
'limit': 50,
'v': cfg['version']
}
# Modul di library SciKit yang digunakan
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import BernoulliNB
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
from sklearn.model_selection import KFold, cross_val_score
def cross_validate(model, n_splits = 10):
k_fold = KFold(n_splits = n_splits)
scores = [model.fit(X[train], y[train]).score(X[test], y[test]) for train, test in k_fold.split(X)]
scores = np.percentile(scores, [40, 50, 60])
return scores

Selanjutnya, kita unduh dataset agar bisa kita olah, data bisa diunduh disini

IMPORT AND SERVE THE DATA

# Kita akan membuat kolom yang akan disimpan
# Kolom dalam tabel yang tidak tercantum, tidak akan ikut diolah

crime_keep_columns = ['CASE#',
'DATE OF OCCURRENCE',
'BLOCK',
' PRIMARY DESCRIPTION',
'WARD',
'LATITUDE',
'LONGITUDE']

# unduh csv
!wget -O crimes.csv https://data.cityofchicago.org/api/views/x2n5-8w5q/rows.csv?accessType=DOWNLOAD

# import data csv sesuai lokasi data yang telah diunduh disimpan
df = pd.read_csv('#lokasi data yang disimpan ',
usecols=crime_keep_columns)

Mari kita lihat tabelnya

df.head()
df.tail()
Data utama

DATA ANALYZING, CLEANING AND PREPARING

Selanjutnya, kita analisis dan “bersihkan” datanya. Kita akan mengubah beberapa strukturnya dengan opsi yang mudah untuk dipelajari.

# Strip leading & trailing whitespace
df.columns = df.columns.str.strip()

# Mengubah spasi ganda menjadi
df.columns = df.columns.str.replace('\s{2,}', ' ')

# Mengubah tanda '#' menjadi ruang kosong
df.columns = df.columns.str.replace('#', '')

# Mengubah spasi menjadi _
df.columns = df.columns.str.replace(' ', '_')

# Konversi ke huruf kecil
df.columns = df.columns.str.lower()

# Ubah Tanggal Bulan September 2017 ke September 2018
df.date_of_occurrence.replace(to_replace="(09/\\d+)/2017", value=r"\1/2018", regex=True, inplace=True)
# Tampilkan jenis dari masing-masing kolom
df.dtypes
Jenis kolom yang baru

Selanjutnya mari kita field tanggal kejadian peristiwa ke date/ time object, tambahkan kolom baru untuk jam, hari, bulan dan tahun saat kejadian kriminal, dan yang terakhir, pisahkan zip_code dan street.

# Mengubah format date/time object
df['date_of_occurrence'] = pd.to_datetime(df['date_of_occurrence'], format='%m/%d/%Y %I:%M:%S %p')
# Tambahkan kolom baru
df['hour'] = df['date_of_occurrence'].dt.hour df['day_name'] = df['date_of_occurrence'].dt.day_name() df['day'] = df['date_of_occurrence'].dt.dayofweek + 1 df['month_name'] = df['date_of_occurrence'].dt.month_name() df['month'] = df['date_of_occurrence'].dt.month df['year'] = df['date_of_occurrence'].dt.year df['year_month'] = df['date_of_occurrence'].dt.to_period('M')
# Pisahkan blok zip_code dan street
df['zip'] = df.block.str.split(' ').str[0] df['street'] = df.block.str.split(' ').str[1:].apply(', '.join)

Selanjutnya, kita verifikasi bahwa baris-baris tabel telah valid

df.isna().sum()

Tampilkan tabelnya

df.dropna(inplace=True)
df.reindex()
df.head()

Data telah siap untuk divisualisasikan.

DATA VISUALIZATION

Visualisasi kasus kejahatan tiap bulan

df.groupby('year_month').count().plot(y = 'case', 
kind='bar',
figsize=(10,6),
width=0.85,
fontsize=12,
colormap='tab20')
.legend(bbox_to_anchor=(1,1),
prop={'size': 12})
plt.xlabel('Month')
plt.ylabel('Count of Cases')
plt.title('Count of Cases Per Month', loc='left', fontsize=18)
Kejahatan tiap bulan

Visualisasi kasus kejahatan tiap hari

df.groupby('day').count().plot(y = 'case',
kind='bar',
figsize=(10,6),
width=0.85,
fontsize=12,
colormap='tab20')
.legend(bbox_to_anchor=(1,1),
prop={'size': 12})

plt.xlabel('Day of Week')
plt.ylabel('Count of Cases per Day')
plt.title('Count of Cases Per Day of Week [1 is a Tuesday]', loc='left', fontsize=18)
Kejahatan tiap hari

Selanjutnya, mari kita kategorikan daftar sesuai jenis kriminalnya

# Membuat 10 daftar kriminal paling banyak
top_crimes = df[['primary_description', 'case']]
.groupby(['primary_description'])
.count()
.sort_values('case', ascending=False[:10]
.axes[0]
.tolist()
# Membuat daftar 3 kriminalitas paling banyak
top_three_crimes = df[['primary_description', 'case']]
.groupby(['primary_description'])
.count()
.sort_values('case', ascending=False)[:3]
.axes[0]
.tolist()

# Membuat daftar 2 kriminalitas paling banyak
top_two_crimes = df[['primary_description', 'case']]
.groupby(['primary_description'])
.count()
.sort_values('case', ascending=False[:2]
.axes[0]
.tolist()
# Membuat dataframe baru dengan top 10 kriminalitas
df_top_crimes = df[df['primary_description'].isin(top_crimes)].copy()
# Membuat dataframe baru dengan top 3 kriminalitas
df_top3_crimes = df[df['primary_description'].isin(top_three_crimes)].copy()

df_top3_crimes[['case', 'primary_description', 'year_month']]
.pivot_table(index='year_month',
columns='primary_description',
fill_value=0,
aggfunc='count')
.plot(kind='area',
stacked=True,
figsize=(15, 6),
fontsize=12,
colormap='tab20')
Diagram top 3 kriminalitas
df_top3_crimes[['case', 'primary_description', 'hour']]
.pivot_table(index='hour',
columns='primary_description',
fill_value=0,
aggfunc='count')
.plot(kind='area',
stacked=True,
figsize=(15, 6),
fontsize=12,
colormap='tab20')
plt.xlabel('Hour of Day')
plt.ylabel('Count of Cases per Hour')
plt.title('Count of Cases Per Hour]', loc='left', fontsize=18)
Perhitungan kasus tiap jam

Menerapkan warna di peta

# Membuat daftar warna
# Menerapkan warna di Daftar 10 kriminalitas
# Membuat kamus warna
colors = [
'red',
'blue',
'gray',
'orange',
'beige',
'green',
'purple',
'pink',
'cadetblue',
'black'
]

dict_colours = dict(zip(top_crimes, colors))
# Tambahkan warna di tiap dataframe
df_top_crimes['colour'] = df_top_crimes.primary_description.map(dict_colours)
# Inisialisasi top kriminalitas di Bulan Agustus 2018
df_top_crimes_august = df_top_crimes[df_top_crimes.month_name == 'August']
df_top_crimes_august.to_pickle('crimes_august.pkl')

Tampilan Peta Pertama

# Inisialisasi koordinat geolokasi Chicago
chicago_latitude = 41.85
chicago_longitude = -87.75
# Inisialisasi peta dunia sekitar Chicago
chicago_map = folium.Map(location=[chicago_latitude, chicago_longitude], zoom_start=11)

# Menampilkan peta dunia
chicago_map
# Inisialisasi insiden grup di dataframe
incidents = folium.map.FeatureGroup()
# Loop sekitar 100 kejahatan dan tambahkan ke insiden grup
for lat, lng, col in zip(df_top_crimes_august.latitude,
df_top_crimes_august.longitude,
df_top_crimes_august.colour):
incidents.add_child(folium.features
.CircleMarker([lat, lng],radius=1,
# Inisialisasi ukuran tanda lingkaran
color=col,
fill = True,
fill_color=col,
fill_opacity=0.6
)
)

# Tambahkan Insiden ke peta
chicago_map.add_child(incidents)
Peta Pertama
mc = MarkerCluster()# Inisialisasi oeta dunia di sekitar Chicago dengan ukuran diperbesar
chicago_cluster = folium.Map(location=[chicago_latitude, chicago_longitude], zoom_start=11)

# Tampilan Peta Dunia
chicago_cluster

# Membuat tanda top kriminalitas
for row in df_top_crimes_august.itertuples():
mc.add_child(folium.Marker(
location=[row.latitude, row.longitude],
popup=row.primary_description))

chicago_cluster.add_child(mc)
chicago_cluster
Peta Kedua
from folium import plugins
from folium.plugins import HeatMap

chicago_heatmat = folium.Map(location=[chicago_latitude, chicago_longitude], zoom_start=11)

heat_data = [[row['latitude'],
row['longitude']] for index, row in df_top_crimes_august.iterrows()]

# Input ke peta
HeatMap(heat_data,
min_opacity=0.5,
max_zoom=18,
max_val=1.0,
radius=15,
blur=20,
gradient=None,
overlay=True).add_to(chicago_heatmat)

# Tampilkan Peta Final
chicago_heatmat
Citra Kriminalitas di Chicago

Bagaimana, cukup pusing bukan? Memang awalnya pasti sangat membingungkan menyatukan algoritma dari beberapa sub-ilmu berbeda. Ini hanyalah kasus sederhana dari satu kota saja. Bayangkan jika kita membuat visualisasi kriminalitas di suatu negara, atau mungkin di dunia?! Dunia IT benar-benar menantang, bukan?

Sekian pemaparan dari penulis, semoga cukup membantu dalam membuat projek sederhana dan mengembangkan minat Data Science kita. Penulis membuka sesi diskusi, dan terbuka untuk masukan agar kita bisa berkembang bersama-sama. Kalian bisa menghubungi melalui linked.in penulis.

Sampai jumpa di tulisan berikutnya, daah!

--

--

Faurel Gema
Dipantry
Writer for

Public Speaker and S-Engineering Student with a deep interest in Data Engineer, AI and Web Programming. Also love to developing the digital business nowadays.