Bagaimana membuat kode Natural Language Processing pada Android dengan IBM Watson
Indonesian (Bahasa Indonesia) translation by Yanti Baddolo (you can also view the original English article)
Berkat gelombang kecerdasan buatan yang meningkat, pengguna akhir-akhir ini mengharapkan aplikasi yang cerdas dan sadar akan konteks penggunaan mereka. IBM Watson menawarkan berbagai layanan yang berhubungan dengan bahasa alami yang dapat Anda gunakan untuk membuat aplikasi semacam itu.
Misalnya, Anda dapat menggunakan layanan Natural Language Understanding untuk mengekstrak kata kunci, entitas, sentimen, dan banyak detail semantik lainnya dari teks yang dibaca pengguna. Dan jika teks itu ada dalam bahasa asing, Anda dapat menggunakan layanan Penerjemah Bahasa untuk mengidentifikasi bahasa dan menerjemahkannya ke bahasa yang dimengerti oleh pengguna.
Dalam tutorial ini, saya akan memperkenalkan beberapa layanan tersebut kepada Anda dengan menunjukkan kepada Anda cara membuat aplikasi yang dapat menerjemahkan laman web berbahasa Jerman ke bahasa Inggris dan mengekstrak sentimen, entitas penting, dan emosi dari mereka.
Sebelum melanjutkan, saya menyarankan agar Anda membaca tutorial pendahuluan berikut tentang layanan IBM Watson:
Mengaktifkan Layanan
Kita akan bekerja dengan tiga layanan Watson hari ini, dan masing-masing harus diaktifkan secara terpisah. Jadi buka dasbor IBM Bluemix Anda dan tekan tombol Create.
Layanan pertama yang akan kita aktifkan adalah layanan Document Conversion, yang memungkinkan kita untuk mengkonversi dokumen HTML, PDF, dan DOCX menjadi teks biasa atau JSON. Pilih dari katalog, berikan nama yang berarti, dan tekan tombol Create.



Selanjutnya, kembali ke katalog dan pilih layanan Language Translator. Language Translator mendukung beberapa bahasa yang banyak digunakan dan dapat, secara default, menangani teks dalam tiga domain: berita, percakapan, dan hak paten. Sementara dua domain pertama cukup memadai untuk kebanyakan teks, domain terakhir bisa lebih akurat untuk teks yang mengandung banyak istilah teknis atau hukum.
Di halaman konfigurasinya, beri nama layanan yang berarti dan tekan tombol create.



Kembali ke katalog dan pilih layanan Natural Language Understanding. Kita akan menggunakan layanan ini untuk mengekstrak sentimen, entitas, dan emosi dari teks yang tidak terstruktur. Sekali lagi, berikan nama yang berarti di layar konfigurasi dan tekan tombol create.



Jika Anda membuka dasbor sekarang, Anda harus bisa melihat hal seperti ini:



Ketiga layanan tersebut memiliki kredensial masuk unik yang terkait dengannya. Anda harus mencatat semuanya karena Anda akan membutuhkannya nanti. Untuk menentukan kredensial layanan apa pun, pilih di dasbor, buka tab service credentials, dan tekan tombol view credentials.
Setup Proyek
Untuk dapat menggunakan ketiga layanan ini dalam proyek Android Studio, kita harus menambahkan SDK Java Watson sebagai ketergantungan implementasi
pada file build.gradle modul aplikasi
.
1 |
implementation 'com.ibm.watson.developer_cloud:java-sdk:3.9.1' |
Sebagai tambahan kita akan menggunakan pustaka Fuel sebagai klien HTTP, jadi tambahkan itu sebagai dependensi implementation
.
1 |
implementation 'com.github.kittinunf.fuel:fuel-android:1.10.0' |
Baik Fuel dan SDK Watson Java bisa bekerja hanya jika aplikasi kita memiliki izin ke INTERNET
, maka dari itu tambahkan itu di file manifest.
1 |
<uses-permission android:name="android.permission.INTERNET"/> |
Selanjutnya, tambahkan tags <string>
berisi username dan password dari ketiga layanan ke file strings.xml
1 |
<string name="document_conversion_username">USERNAME1</string> |
2 |
<string name="document_conversion_password">PASSWORD1</string> |
3 |
|
4 |
<string name="language_translator_username">USERNAME2</string> |
5 |
<string name="language_translator_password">PASSWORD2</string> |
6 |
|
7 |
<string name="natural_language_understanding_username">USERNAME3</string> |
8 |
<string name="natural_language_understanding_password">PASSWORD3</string> |
Terakhir, untuk menjaga agar kode kita tetap ringkas, dalam tutorial ini kita akan menggunakan Kotlin dan bukan Java, jadi pastikan bahwa Anda telah mengaktifkan dukungan Kotlin.
Menggunakan Layanan Konversi Dokumen
Kita akan menggunakan layanan Konversi Dokumen Watson untuk mengubah halaman web HTML menjadi teks biasa. Untuk mengizinkan pengguna mengetikkan alamat halaman web, tambahkan widget EditText
ke layout activity Anda. Selain itu, sertakan widget TextView
untuk menampilkan isi halaman web sebagai teks biasa. Untuk memastikan bahwa isi halaman web yang panjang tidak terpotong, saya sarankan Anda menempatkannya di dalam widget ScrollView
.
1 |
<EditText
|
2 |
android:layout_width="match_parent" |
3 |
android:layout_height="wrap_content" |
4 |
android:id="@+id/documentURL" |
5 |
android:inputType="textUri" |
6 |
android:hint="URL" |
7 |
android:imeOptions="actionGo" |
8 |
/>
|
9 |
|
10 |
<ScrollView
|
11 |
android:layout_width="wrap_content" |
12 |
android:layout_height="match_parent" |
13 |
android:layout_below="@+id/documentURL"> |
14 |
<TextView
|
15 |
android:layout_width="match_parent" |
16 |
android:layout_height="match_parent" |
17 |
android:id="@+id/documentContents" |
18 |
/>
|
19 |
</ScrollView>
|
Pada kode di atas, Anda dapat melihat bahwa atribut imeOptions
dari widget EditText
diatur ke actionGo
. Ini memungkinkan pengguna menekan tombol "Go" di keyboard virtual mereka saat mereka selesai mengetik alamat. Untuk langsung mendengarkan event ketika tombol itu ditekan, tambahkan kode Kotlin berikut ke metode onCreate()
kegiatan Anda:
1 |
documentURL.setOnEditorActionListener { _, action, _ -> |
2 |
if (action == EditorInfo.IME_ACTION_GO) { |
3 |
|
4 |
// More code here
|
5 |
|
6 |
}
|
7 |
false
|
8 |
}
|
Di dalam event listener, hal pertama yang perlu kita lakukan adalah menentukan URL yang diketik pengguna. Kita dapat melakukannya dengan mudah dengan mengakses properti text
dari widget EditText
. Begitu kita memiliki URL, kita bisa menggunakan metode Fuel's httpGet()
untuk mendownload isi halaman web.
Karena kita ingin metode httpGet()
dijalankan secara asinkron, kita harus menambahkan sebuah callback ke sistem tersebut dengan menggunakan metode responseString()
, yang juga memungkinkan kita memproses konten yang didownload sebagai string.
1 |
val url:String = documentURL.text.toString() |
2 |
url.httpGet().responseString { _, _, result -> |
3 |
val (document, _) = result |
4 |
if (err == null) { |
5 |
// More code here
|
6 |
}
|
7 |
}
|
Sekarang saatnya untuk membuat sebuah instance dari kelas DocumentConversion
, yang memiliki semua metode yang kita butuhkan untuk berinteraksi dengan layanan Konversi Dokumen. Konstruktornya mengharapkan tanggal versi beserta kredensial masuk layanan.
1 |
val documentConverter = DocumentConversion( |
2 |
DocumentConversion.VERSION_DATE_2015_12_01, |
3 |
resources.getString(R.string.document_conversion_username), |
4 |
resources.getString(R.string.document_conversion_password) |
5 |
)
|
SDK Watson Java tidak memungkinkan kita untuk langsung mengirimkan string ke layanan Konversi Dokumen. Ini membutuhkan file
objek sebagai gantinya. Oleh karena itu, mari kita buat file sementara menggunakan metode createTempFile()
dari kelas File
, dan tulis isi halaman web yang telah kita download dengannya menggunakan metode writeText()
.
1 |
val tempFile = File.createTempFile("temp_file", null) |
2 |
tempFile.writeText(document, Charsets.UTF_8) |
Pada titik ini, kita bisa memanggil metode convertDocumentToText()
dan meneruskan file sementara untuk memulai konversi. Metode ini juga mengharapkan tipe MIME dari file sementara, jadi jangan lupa untuk memasukkannya. Setelah konversi selesai, Anda dapat menampilkan teks biasa dengan hanya menugaskannya ke properti text
widget TextView
.
Kode berikut menunjukkan cara melakukan konversi di dalam thread baru dan memperbarui TextView
di thread UI:
1 |
AsyncTask.execute { |
2 |
val plainText = documentConverter |
3 |
.convertDocumentToText(tempFile, "text/html") |
4 |
.execute() |
5 |
runOnUiThread { |
6 |
documentContents.text = plainText |
7 |
}
|
8 |
}
|
Anda dapat menjalankan aplikasi sekarang dan mengetikkan URL laman web Jerman untuk melihat layanan Konversi Dokumen bekerja.



Menggunakan Layanan Penerjemah Bahasa
Dengan layanan Translator Bahasa, kita sekarang akan mengubah teks biasa, yang berbahasa Jerman, ke bahasa Inggris.
Alih-alih memperbarui layout kita, untuk memungkinkan pengguna memulai terjemahan secara manual, marilah kita menambahkan sebuah menu ke activity kita. Untuk melakukannya, mulailah dengan membuat file sumber daya menu baru dan menambahkan kode berikut ke dalamnya:
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<menu xmlns:android="https://schemas.android.com/apk/res/android" |
3 |
xmlns:app="http://schemas.android.com/apk/res-auto"> |
4 |
|
5 |
<item android:id="@+id/action_translate" |
6 |
android:title="Translate" |
7 |
app:showAsAction = "never" /> |
8 |
|
9 |
<item android:id="@+id/action_analyze" |
10 |
android:title="Analyze" |
11 |
app:showAsAction = "never" /> |
12 |
|
13 |
</menu>
|
Seperti yang dapat Anda lihat, kode di atas membuat menu dengan dua pilihan: translate and analyse. Pada langkah ini, kita akan bekerja dengan pilihan pertama saja.
Untuk membuat menu, kita harus memasukannya di dalam metode onCreateOptionsMenu()
aktivitas kita.
1 |
override fun onCreateOptionsMenu(menu: Menu?): Boolean { |
2 |
menuInflater.inflate(R.menu.my_menu, menu) |
3 |
return super.onCreateOptionsMenu(menu) |
4 |
}
|
Dengan meng-override metode onOptionsItemSelected()
, kita dapat mengetahui kapan pengguna menggunakan menu. Selanjutnya, kita bisa menentukan item mana yang ditekan pengguna dengan memeriksa itemId
. Kode berikut memeriksa apakah pengguna memilih opsi translasi.
1 |
override fun onOptionsItemSelected(item: MenuItem?): Boolean { |
2 |
if(item?.itemId == R.id.action_translate) { |
3 |
// More code here
|
4 |
}
|
5 |
return true |
6 |
}
|
Sama seperti Document Service, layanan Language Translator juga memiliki kelas khusus yang memungkinkan kita untuk berinteraksi dengannya. Seperti yang bisa Anda tebak, ini disebut LanguageTranslator
. Untuk membuat instance dari kelas, kita hanya perlu mengirimkan kredensial masuk layanan ke konstruktornya.
1 |
val translator = LanguageTranslator( |
2 |
resources.getString(R.string.language_translator_username), |
3 |
resources.getString(R.string.language_translator_password) |
4 |
)
|
Kelas memiliki metode translate()
yang bisa kita gunakan untuk menerjemahkan teks bahasa Jerman kita ke bahasa Inggris. Sebagai argumennya, teks tersebut diharapkan diterjemahkan sebagai string, bahasa teks saat ini, dan bahasa yang diinginkan.
Setelah terjemahan selesai dengan sukses, kita akan memiliki akses ke objek TranslationResult
, yang properti FirstTranslation
berisi teks terjemahannya.
Kode berikut menunjukkan cara melakukan terjemahan dan memberikan hasilnya di widget TextView
.
1 |
AsyncTask.execute { |
2 |
val translatedDocument = translator |
3 |
.translate( |
4 |
documentContents.text |
5 |
.toString(), |
6 |
Language.GERMAN, |
7 |
Language.ENGLISH |
8 |
).execute() |
9 |
runOnUiThread { |
10 |
documentContents.text = translatedDocument |
11 |
.firstTranslation |
12 |
}
|
13 |
}
|
Sekarang Anda dapat menjalankan aplikasi lagi, ketik URL laman web Jerman, dan gunakan menu untuk menerjemahkan isinya ke bahasa Inggris.



Menggunakan Layanan Pengenalan Bahasa Alami
Akhirnya, untuk melakukan analisis semantik pada teks terjemahan dan ekstrak berbagai rincian penting darinya, kita dapat menggunakan kelas NaturalLanguageUnderstanding
, yang berfungsi sebagai klien untuk layanan Pengenalan Bahasa Alami.
Kode berikut menunjukkan cara menginisialisasi klien hanya saat pengguna menekan opsi kedua dari menu yang kita buat pada langkah sebelumnya:
1 |
if(item?.itemId == R.id.action_analyze) { |
2 |
val analyzer = NaturalLanguageUnderstanding( |
3 |
NaturalLanguageUnderstanding.VERSION_DATE_2017_02_27, |
4 |
resources.getString( |
5 |
R.string.natural_language_understanding_username), |
6 |
resources.getString( |
7 |
R.string.natural_language_understanding_password) |
8 |
)
|
9 |
|
10 |
// More code here
|
11 |
}
|
Dibandingkan dengan layanan yang berhubungan dengan bahasa alami lainnya, menggunakan layanan Pengenalan Bahasa Alami perlu banyak hal yang terlibat, terutama karena memiliki sejumlah fitur yang sangat banyak.
Untuk saat ini, katakanlah kita ingin menentukan keseluruhan sentimen dari teks terjemahan, dan ekstrak semua entitas besar yang disebutkannya. Setiap entitas itu sendiri dapat memiliki emosi dan sentimen yang terkait dengannya, jadi katakanlah kita juga ingin mengekstraknya.
Untuk memberi tahu layanan bahwa kita ingin mengekstrak semua entitas dan emosi serta sentimen yang terkait dengannya, kita memerlukan objek EntitasOptions
, yang dapat dibuat menggunakan kelas EntitiesOptions.Builder
.
1 |
val entityOptions = EntitiesOptions.Builder() |
2 |
.emotion(true) |
3 |
.sentiment(true) |
4 |
.build() |
Demikian pula, untuk memberi tahu layanan bahwa kita menginginkan keseluruhan sentimen teks, kita memerlukan objek SentimentOptions
.
1 |
val sentimentOptions = SentimentOptions.Builder() |
2 |
.document(true) |
3 |
.build() |
Objek SentimentOptions
and EntitiesOptions
sekarang harus digabungkan untuk membentuk objek Features
, yang dapat digunakan untuk menyusun objek AnalyzeOptions
. Objek AnalyzeOptions
adalah yang paling penting dari semua objek di atas karena di situlah Anda menentukan teks yang ingin Anda analisis.
1 |
val features = Features.Builder() |
2 |
.entities(entityOptions) |
3 |
.sentiment(sentimentOptions) |
4 |
.build() |
5 |
|
6 |
val analyzerOptions = AnalyzeOptions.Builder() |
7 |
.text(documentContents.text.toString()) |
8 |
.features(features) |
9 |
.build() |
Setelah objek AnalyzeOptions
siap, kita bisa mengirimkannya ke metode analisis()
untuk memulai proses analisis.
1 |
AsyncTask.execute { |
2 |
val results = analyzer.analyze(analyzerOptions).execute() |
3 |
|
4 |
// More code here
|
5 |
}
|
Hasil analisis adalah objek AnalysisResults
, berisi semua informasi yang kita minta.
Untuk menentukan keseluruhan sentimen teks, pertama-tama kita harus mengekstrak keseluruhan skor sentimen menggunakan properti sentiment.document.score
. Nilai sentimen tidak lain hanyalah angka floating-point. Jika nol, sentimennya netral. Jika negatif atau positif, sentimen juga negatif atau positif.
1 |
val overallSentimentScore = results.sentiment.document.score |
2 |
var overallSentiment = "Positive" |
3 |
if(overallSentimentScore < 0.0) |
4 |
overallSentiment = "Negative" |
5 |
if(overallSentimentScore == 0.0) |
6 |
overallSentiment = "Neutral" |
7 |
|
8 |
var output = "Overall sentiment: ${overallSentiment}\n\n" |
Selanjutnya, dengan melakukan pengulangan pada daftar entities
yang ada di objek AnalysisResults
, kita dapat memproses setiap entitas secara terpisah. Secara default, setiap entitas memiliki tipe yang terkait dengannya. Misalnya, layanan dapat mengetahui apakah suatu entitas adalah seseorang, perusahaan, atau kendaraan. Saat ini, dapat mengidentifikasi lebih dari 450 jenis entitas yang berbeda.
Karena kita meminta mereka, masing-masing entitas sekarang juga akan memiliki skor sentimen dan emosi yang terkait dengannya.
Kita bisa menentukan skor sentimen dengan hanya menggunakan properti sentiment.score
. Menentukan emosi yang terkait dengan entitas, bagaimanapun, tidak begitu mudah. Watson mendukung lima emosi saat ini: kemarahan, sukacita, jijik, ketakutan, dan kesedihan. Setiap entitas akan memiliki semua lima emosi, namun nilai yang berbeda terkait dengan masing-masing, menentukan seberapa yakin layanannya bahwa emosinya benar. Karena itu, untuk menentukan emosi yang tepat, kita harus memilih salah satu dengan nilai yang tertinggi.
Kode berikut mencantumkan setiap entitas beserta jenis, skor sentimen, dan emosinya:
1 |
for(entity in results.entities) { |
2 |
output += "${entity.text} (${entity.type})\n" |
3 |
|
4 |
val validEmotions = arrayOf("Anger", "Joy", "Disgust", |
5 |
"Fear", "Sadness") |
6 |
val emotionValues = arrayOf( |
7 |
entity.emotion.anger, |
8 |
entity.emotion.joy, |
9 |
entity.emotion.disgust, |
10 |
entity.emotion.fear, |
11 |
entity.emotion.sadness |
12 |
)
|
13 |
val currentEmotion = validEmotions[ |
14 |
emotionValues.indexOf( |
15 |
emotionValues.max() |
16 |
)
|
17 |
]
|
18 |
|
19 |
output += "Emotion: ${currentEmotion}, " + |
20 |
"Sentiment: ${entity.sentiment.score}" + |
21 |
"\n\n"
|
22 |
}
|
Untuk menampilkan output yang dihasilkan, kita bisa mengupdate widget TextView
lagi.
1 |
runOnUiThread { |
2 |
documentContents.text = output |
3 |
}
|
Pada titik ini, Anda dapat menjalankan aplikasi lagi untuk melihat ketiga layanan bekerja sama.



Kesimpulan
Anda sekarang tahu bagaimana menggunakan tiga layanan berbahasa alami yang paling banyak digunakan yang ditawarkan Watson. Dalam tutorial ini, Anda juga melihat betapa mudahnya menggunakan SDK Java Watson untuk membuat semua layanan bekerja sama untuk menciptakan aplikasi Android yang cerdas.
Untuk mempelajari lebih lanjut tentang layanan dan SDK, Anda dapat melihat ke repositori GitHub SDK. Dan untuk mempelajari lebih lanjut tentang penggunaan mesin Watson di aplikasi Anda sendiri, lihat beberapa tulisan kami yang lain di sini di Envato Tuts+!
- Android SDKBagaimana Cara Menggunakan Layanan Machine Learning Google Cloud pada AndroidAshraff Hathibelagal
- Android ThingsAndroid Things dan Machine LearningPaul Trebilcox-Ruiz
- Android SDKPengenalan Komponen Arsitektur AndroidTin Megali
- Machine LearningKoding Aplikasi Android dengan Machine Learning IBM WatsonAshraff Hathibelagal