Bisnis rumah makan dan restoran merebak di Indonesia dan di negara-negara lain. Sepertinya Covid-19 tidak benar-benar menutup bisnis ini walaupun jumlah pengunjung mengalami penurunan saat kondisi-kondisi lockdown diberlakukan. Penurunan pengunjung tidak menjadi masalah dengan adanya servis antar makanan dari gojek dan grab. Sebagai bukti anekdotal, di daerah Cinere saja ada 40 tempat makan menurut foursquare places API. Sebagai seseorang yang berminat untuk membuka sebuah tempat makan baru, misalnya restoran atau kafe, saya bisa melihat peta tempat populer dengan rumah makan dan melakukan clustering untuk melihat apakah tempat-tempat makan di suatu daerah bisa dikelompokkan berdasarkan ciri-ciri tertentu. Dengan metode clustering ini, saya seharusnya bisa memprediksi di daerah manakah restoran yang akan saya buka akan berhasil.
salah satu restoran yang populer di Indonesia
Memprediksi lokasi yang baik untuk membuka restoran atau rumah makan baru bisa dilakukan dengan melakukan survei dengan mengunjungi tempat - tempat potensial dan melihat restoran - restoran apa saja yang terdapat di situ. Tentu saja cara ini memerlukan waktu yang tidak sedikit. Apalagi jika ada pembatasan - pembatasan karena pandemi misalnya yang menyulitkan atau tidak memungkinkan bagi saya untuk mengunjungi tempat - tempat tersebut.
Untuk mempermudah survei lokasi-lokasi yang mungkin cocok untuk membuka restoran baru, saya akan menggunakan Foursquare Places API untuk mengumpulkan data - data dari restoran dan rumah makan yang ada di Cinere dan sekitarnya. Foursquare Places API adalah API yang dirancang untuk bisa mengumpulkan data lokasi serta peta dan juga data review dan bahkan foto mengenai tempat-tempat makan tersebut. Setelah data terkumpul saya akan membuat sebuah model clustering dan mungkin juga dimensionality reduction untuk mengklaster rumah-rumah makan tersebut dan dengan demikian memilih daerah yang tepat untuk membuka restoran baru.
Dataset untuk proyek ini diambil menggunakan Foursquare Places API. Dataset mentah dari API ini adalah objek JSON. JSON ini diproses menjadi bentuk dataframe dengan 40 baris dan 15 kolom Setelah nama-nama kolom dirapihkan, kolom-kolom tersebut adalah:
Selanjutnya model clustering yang akan digunakan kemungkinan adalah k-means clustering atau hierarchical clustering. Dimensionality reduction dengan menggunakan principal component analysis (PCA) mungkin akan digunakan juga dalam proyek ini.
Output atau hasil akhir dari proyek ini adalah dashboard yang menujukkan hasil clustering di atas peta cinere dan jakarta selatan dan panel teks yang menerangkan daerah mana yang baik untuk membuka restoran baru saya. Ada 1 halaman lagi untuk menunjukkan data tabular dari tempat-tempat yang telah ditarik dari places API.
halaman pertama dashboard
halaman kedua dashboard
Business Impact Proyek ini bisa menolong board of directors menentukan lokasi mana yang baik untuk membuka restoran atau cabang baru. Proyek ini dapat dikembangkan untuk memprediksi lokasi potensial di kota lain, provinsi lain, dan bahkan negara lain. Selain itu, wawasan dari pengolahan dan analisis klastering restoran ini bisa diterapkan juga untuk jenis bisnis lain seperti bisnis boutique, bisnis mall atau supermarket.
Target Audience Target audience dari proposal dan proyek ini adalah bagian administratif seperti board of directors dari rantai restoran saya.
Mendapatkan data dengan API.
Pertama, kita mencari data lintang dan bujur untuk daerah cinere dengan kode pos 16514 dengan google. Setelah mendapatkan koordinat lintang dan bujur, kita mengunakan API explore dari foursquare dengan section = “food” untuk mencari rumah-rumah makan di radius 1 km dari koordinat tadi.
lat <- "-6.3361"
long <- "106.7883"
section <- "food"
v <- "20210625"
rad <- "1000"
lim <- "100"
query = paste("https://api.foursquare.com/v2/venues/explore?client_id=",clientid,"&client_secret=",clientsecret,"&ll=",lat,",",long,"§ion=",section,"&v=",v,"&radius=",rad,"&limit=",lim,sep="")
result = getURL(query)
data <- fromJSON(result)
Setelah mendapatkan data dalam bentuk JSON, kita akan mengubah JSON menjadi R data frame dengan fungsi kustom. Di sini saya akan menggunakan venue_state untuk mengumpulkan data propinsi dari rumah makan. Venue_state saya pilih dan bukannya venue_province supaya kalau API ini digunakan untuk mencari restoran di negara lain, saya tidak perlu mengubah lagi sesuai negara yang akan di explore.
venue_id = c()
venue_name = c()
venue_lat = c()
venue_long = c()
venue_city = c()
venue_state = c()
venue_country = c()
venue_checkins = c()
venue_users = c()
if (length(data$response$groups[[1]]$items) > 0) {
for (r in 1:length(data$response$groups[[1]]$items)) {
tmp = data$response$groups[[1]]$items[[r]]$venue
venue_id = c(venue_id,tmp$id)
venue_name = c(venue_name,tmp$name)
venue_lat = c(venue_lat,tmp$location$lat)
venue_long = c(venue_long,tmp$location$lng)
venue_city = c(venue_city,tmp$location$city)
venue_state = c(venue_state,tmp$location$state)
venue_country = c(venue_country,tmp$location$country)
venue_checkins = c(venue_checkins,tmp$stats[1])
venue_users = c(venue_users,tmp$stats[2])
}
}
data <- as.data.frame(cbind(venue_id, venue_name,venue_lat,venue_long,venue_city,venue_state,venue_country,venue_checkins,venue_users))
saveRDS(data,file='RestaurantResults.RDS')
restaurants <- readRDS(file = "RestaurantResults.RDS")
restaurants
Ternyata ada 40 tempat makan di Cinere. Selanjutnya saya akan menambahkan informasi penting yang berkaitan dengan rumah makan menggunakan API details dari foursquare.
venue_id = c()
venue_category = c()
venue_tip_count = c()
venue_price_tier = c()
venue_price_category=c()
venue_rating = c()
venue_rating_signals = c()
venue_like_count = c()
venue_dislike = c()
for (ven in restaurants$venue_id) {
query = paste("https://api.foursquare.com/v2/venues/",ven,"?client_id=",clientid,"&client_secret=",clientsecret,"&v=20210625","&time=any",sep="")
result = getURL(query)
DetailsData <- fromJSON(result)
tmp = DetailsData$response$venue
venue_id = c(venue_id,tmp$id)
venue_category = c(venue_category, tmp$categories[[1]]$name)
venue_tip_count = c(venue_tip_count, tmp$tips$count)
venue_price_tier = c(venue_price_tier, tmp$price$tier)
venue_price_category=c(venue_price_category, tmp$price$message)
venue_rating = c(venue_rating, tmp$rating)
venue_rating_signals = c(venue_rating_signals, tmp$ratingSignals)
venue_like_count = c(venue_like_count, tmp$likes$count)
venue_dislike = c(venue_dislike, tmp$dislike)
}
details <- as.data.frame(cbind(venue_id, venue_category,venue_tip_count,venue_price_tier,venue_price_category,venue_rating,venue_rating_signals,venue_like_count,venue_dislike))
restaurants_details <- merge(restaurants, details, by='venue_id')
saveRDS(restaurants_details,file='RestaurantDetails.RDS')
restaurants_details <- readRDS('RestaurantDetails.RDS')
restaurants_details
glimpse(restaurants_details)
#> Rows: 40
#> Columns: 15
#> $ venue_id <chr> "4bc9f3b368f976b00c385e83", "4bd95a70e914a593533e…
#> $ venue_name <chr> "Roti & Pisang Bakar | Sesama Oke", "Rice Bowl", …
#> $ venue_lat <chr> "-6.33433355128712", "-6.33027309321198", "-6.339…
#> $ venue_long <chr> "106.782405414406", "106.78375335802", "106.79339…
#> $ venue_city <chr> "Depok", "Depok", "Jakarta", "Depok", "Depok", "D…
#> $ venue_state <chr> "Jawa Barat", "Jawa Barat", "Jakarta", "Jawa Bara…
#> $ venue_country <chr> "Indonesia", "Indonesia", "Indonesia", "Indonesia…
#> $ venue_category <chr> "Food Truck", "Asian Restaurant", "Indonesian Res…
#> $ venue_tip_count <chr> "1", "9", "8", "4", "5", "0", "5", "4", "0", "2",…
#> $ venue_price_tier <chr> "1", "1", "2", "3", "1", "2", "2", "1", "1", "1",…
#> $ venue_price_category <chr> "Cheap", "Cheap", "Moderate", "Expensive", "Cheap…
#> $ venue_rating <chr> "6.7", "6.9", "6.9", "7", "7.3", "6.7", "6.4", "6…
#> $ venue_rating_signals <chr> "11", "12", "12", "9", "16", "11", "12", "12", "1…
#> $ venue_like_count <chr> "2", "0", "3", "1", "5", "0", "0", "1", "0", "0",…
#> $ venue_dislike <chr> "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FAL…
Ada kolom yang jenis datanya kurang tepat dan ada kolom venue_city yang isinya Jawa Barat dan kolom venue_state yang isinya Indonesia, saya akan melakukan cleaning data.
restaurants2 <- restaurants_details %>% mutate(venue_city = str_replace_all(venue_city, c("Jawa Barat" = "Depok", "Cinere" = "Depok")),
venue_state = str_replace(venue_state, "Indonesia", "Jawa Barat"),
venue_lat = as.numeric(venue_lat),
venue_long = as.numeric(venue_long),
venue_tip_count = as.numeric(venue_tip_count),
venue_price_tier = as.numeric(venue_price_tier),
venue_rating = as.numeric(venue_rating),
venue_rating_signals = as.numeric(venue_rating_signals),
venue_like_count = as.numeric(venue_like_count),
venue_dislike = as.logical(venue_dislike),
across(where(is.character),factor)
) %>%
select(-venue_id) %>%
mutate(venue_name = as.character(venue_name))
Setelah cleaning jenis data dalam kolom sudah tepat dan juga venue_city dan venue_state isinya juga sudah benar.
restaurants2
summary(restaurants2)
#> venue_name venue_lat venue_long venue_city
#> Length:40 Min. :-6.341 Min. :106.8 Depok :38
#> Class :character 1st Qu.:-6.338 1st Qu.:106.8 Jakarta: 2
#> Mode :character Median :-6.336 Median :106.8
#> Mean :-6.335 Mean :106.8
#> 3rd Qu.:-6.333 3rd Qu.:106.8
#> Max. :-6.328 Max. :106.8
#>
#> venue_state venue_country venue_category venue_tip_count
#> Jakarta : 2 Indonesia:40 Food Truck :12 Min. : 0.00
#> Jawa Barat:38 Indonesian Restaurant: 8 1st Qu.: 0.00
#> Asian Restaurant : 4 Median : 1.00
#> Seafood Restaurant : 4 Mean : 2.90
#> Fast Food Restaurant : 2 3rd Qu.: 5.25
#> Food Court : 2 Max. :12.00
#> (Other) : 8
#> venue_price_tier venue_price_category venue_rating venue_rating_signals
#> Min. :1.0 Cheap :14 Min. :6.200 Min. : 9.00
#> 1st Qu.:1.0 Expensive: 2 1st Qu.:6.625 1st Qu.:11.00
#> Median :2.0 Moderate :24 Median :6.900 Median :12.00
#> Mean :1.7 Mean :6.825 Mean :12.22
#> 3rd Qu.:2.0 3rd Qu.:7.100 3rd Qu.:15.00
#> Max. :3.0 Max. :7.300 Max. :16.00
#>
#> venue_like_count venue_dislike
#> Min. : 0.0 Mode :logical
#> 1st Qu.: 0.0 FALSE:40
#> Median : 1.0
#> Mean : 3.3
#> 3rd Qu.: 5.0
#> Max. :24.0
#>