เขียน Python API เรียกใช้ผ่าน LINE สำหรับแนะนำภาพยนต์ (Recommendation System) + ใช้ Docker ขึ้น Heroku

Karn Yongsiriwit
5 min readFeb 7, 2021

--

บทความนี้จะมาแนะนำการพัฒนา API ให้บริการแบบจำลอง Machine Learning สำหรับการแนะนำภาพยนต์ และใช้ line bot sdk เพื่อให้บริการผ่าน LINE ได้ด้วยนะครับ โดย source code ทั้งหมดสามารถดาวน์โหลดได้จาก Github ของผมได้เลยครับ

โดยผลลัพธ์ที่ต้องการคือ LINE Chat Bot ที่สามารถแนะนำภาพยนต์ได้ โดยแนะนำจากชื่อภาพยนต์ที่เราเลือกจากรายการและการพิมพ์เข้าไปเองตามด้านล่างครับ 😁

เริ่มใช้งาน Line Developer

สมัครได้ที่ https://developers.line.biz/console ด้วย LINE Account

สร้าง Provider

สร้าง Channel

สำหรับเนื้อหาโดยละเอียดเกี่ยวกับการใช้งาน Line Developer สามารถดูได้จากบทความของคุณ Thannob ได้นะครับ

ติดตั้งสภาพแวดล้อมของ API

ติดตั้งซอฟต์แวร์ดังต่อไปนี้ครับ

ติดตั้ง virtualenv ผ่าน pip

$ pip install virtualenv

ใช้ git clone source code ที่ผมเตรียมไว้แล้วมาได้เลยนะครับ

$ git clone https://github.com/KarnYong/line-movie-recommendation-api.git

cd เข้าไปในโฟล์เดอร์ของ code ก่อนนะครับ ต่อไปทุกขั้นตอนจะต้องทำที่โฟลเดอร์นี้นะครับ

$ cd line-movie-recommendation-api

สร้าง virtual environment ชื่อ venv

$ virtualenv venv

เปิดใช้ virtual environment

  • Windows:
$ venv\Scripts\activate.bat
  • Mac และ Linux:
$ source venv/bin/activate

ติดตั้ง packages ของ Python ที่จำเป็น

$ pip install -r requirements.txt

กำหนด Channel secret และ Channel access token จาก LINE

สร้างไฟล์ .env (ไม่ต้องมีนามสกุล) ที่โฟลเดอร์นี้เลยนะครับ และใส่เข้าไป 2 บรรทัดตามด้านล่าง โดยให้คัดลอก Channel secret และ Channel access token (จากใน LINE Channel ที่เราสร้างไว้ตอนต้น) มาแทนที่ตรงที่ทำตัวหนานะครับ

LINE_CHANNEL_SECRET='<<Line Channel Secret>>'
LINE_CHANNEL_ACCESS_TOKEN='<<Line Channel Access Token>>'
<<Line Channel Secret>>
<<Line Channel Access Token>>

บันทึก Cosine Similarity ข้อมูลภาพยนต์

ที่ไฟล์ movie-model.py ใช้สำหรับอ่านข้อมูลจากไฟล์ movies_metadata.csv โดยตอนนี้อ่านเฉพาะข้อมูล 5,000 แถวแรกนะครับ (บรรทัดที่ 8) เพื่อให้ไม่ใช้ memory เยอะจนเกินไป จากนั้นจึงคำนวณหาความเหมือนของภาพยนต์จากคำอธิบาย (overview) ของภาพยนต์นะครับ โดยตัดคำด้วย TfidVectorizer และคำนวณความเหมือนแบบ Cosine Similarity ด้วย linear_kernel (ขอไม่ลง detail เยอะนะครับ เดี๋ยวจะยาวเกิน 555)

จากนั้นนำค่าของรายชื่อของภาพยนต์ (movies) และผลการคำนวณ Cosine Similarity (cosine_overview) บันทึกลงไฟล์ movies.p ด้วย pickle ในบรรทัดสุดท้าย

เรียกคำสั่งด้านล่าง เพื่อสร้างไฟล์ movies.p

$ python movie-model.py

ทดสอบการแนะนำภาพยนต์จากไฟล์ข้อมูล ที่ไฟล์ movie-recommend.py ใช้ทดสอบการแนะนำภาพยนต์ โดยบรรทัดที่ 4 จะเป็นการใช้ pickle โหลดค่าของรายชื่อของภาพยนต์ (movies) และผลการคำนวณ Cosine Similarity (cosine_overview) จากไฟล์ movies.p สำหรับการใช้แนะนำภาพยนต์ในบรรทัดที่ 18 ที่สามารถเปลี่ยนชื่อภาพยนต์ได้ (อาจจะลองเปลี่ยนเป็น Toy Story หรือ The Godfather เพื่อทดสอบได้ครับ โดยชื่อที่ใช้ต้องมีอยู่ในข้อมูลรายชื่อภาพยนต์นะครับ)

เรียกคำสั่งด้านล่าง เพื่อได้รับการแนะนำภาพยนต์

$ python movie-recommend.pyYour Recommendations for the Movie Die Hard are:
Die Hard: With a Vengeance
Die Hard 2
Hot Shots! Part Deux
Death Before Dishonor
You Can Count on Me
--------------

เริ่มการทำงานของ API

สั่ง start API ด้วยคำสั่ง

$ python line-movie-api.py

ทดสอบจากการ deploy จากเครื่องของตนเองก่อนด้วย ngrok เปิด Command Prompt หรือ Terminal และให้เปลี่ยนตำแหน่งไปที่ Nrgok.exe จากนั้นสั่งคำสั่งต่อไปนี้

$ ngrok http 8000

นำ Forwarding url ของ ngrok ด้านบนไปใส่ไว้ที่ webhook ของ Line Channel ตามด้านล่าง และต่อท้ายด้วย /callback

ทดสอบ Webhook URL ด้วยการกดปุ่ม Verify ถ้าขึ้นว่าเป็น Success แปลว่าสำเร็จ

ทดสอบผ่าน LINE จะได้ผลลัพธ์ของการแนะนำภาพยนต์ตามด้านล่าง โดยให้พิมพ์ข้อความส่งไปว่า movies แล้วจะมี Carousel โผล่ขึ้นมาเพื่อให้เลือกภาพยนต์ครับ เมื่อเลือกเสร็จก็จะมีรายการภาพยนต์ที่แนะนำแสดงขึ้นมาครับ หรือจะพิมพ์ชื่อภาพยนต์ไปก็ได้ ถ้ามีอยู่ในข้อมูลจะส่งรายชื่อภาพยนต์ที่แนะนำมาครับ

อธิบาย Source Code ของ API

API ไฟล์ line-movie-api.py เป็นการนำตัวอย่าง flask-kitchensink จาก line-bot-sdk-python (link ด้านล่าง) มาปรับแก้และเพิ่มเติมนะครับ

เพิ่มเติมในส่วนของการใช้ pickle ค่ารายชื่อของภาพยนต์ (movies) และผลการคำนวณ Cosine Similarity (cosine_overview) จากไฟล์ movies.p

handle_text_message คือส่วนของการรองรับข้อความที่ส่งมายัง Bot ของ LINE นะครับ

ถ้าส่งมาเป็นข้อความว่า movies จะตอบกลับเป็น Carousel ที่มีรูปของภาพยนต์ที่สามารถเลือกได้อยู่นะครับ โดยจะฝัง PostbackAction ไว้เพื่อให้ handle_postback เป็นตัวจัดการ event ใหนำชื่อของภาพยนต์มาใช้เพื่อทำการแนะนำภาพยนต์ที่มีเนื้อหาใกล้เคียงกันครับ หรือถ้าส่งข้อความอื่นมา จะนำข้อความนั้นมาเป็นชื่อภาพยนต์เพื่อแนะนำครับ

handle_postback เป็นตัวจัดการ event จากการนำชื่อของภาพยนต์ที่ส่งมาจาก code ด้านบน มาใช้เพื่อทำการแนะนำภาพยนต์ที่มีเนื้อหาใกล้เคียงกันด้วยฟังค์ชัน get_recommendations ครับ

เตรียมนำ API ขึ้น Heroku Cloud

ติดตั้ง software ที่จำเป็นดังนี้ครับ ติดตั้งเสร็จแล้ว restart ซักครั้งด้วยนะครับ

ใช้ Docker นำ API ขึ้น Heroku Cloud

build Image ตามคำสั่งด้านล่าง โดยระบุชื่อของ Docker Image ว่าเป็น line-movie-api

$ docker build --tag line-movie-api:latest .

run Container จาก Image เพื่อเป็นการทดลอง deploy ภายในเครื่องคอมเราเองก่อน โดยให้ forward port 8000 จากเครื่องของเราไปยัง port เดียวกันภายใน Container

$ docker run -p 8000:8000 -d --name line-movie-api line-movie-api

ใช้ Heroku CLI เพื่อ login

$ heroku login
$ heroku container:login

สร้าง Application บน Heroku โดยตั้งชื่อว่า line-movie-api (ให้ตั้งชื่อใหม่ด้วยนะครับ)

$ heroku create line-movie-api

deploy API ขึ้นไปที่ Application line-movie-api (ใช้ชื่อเดียวกับที่ตั้งไว้ด้านบน) บน Heroku Cloud ด้วยการ push และ release ตามคำสั่งด้านล่าง

$ heroku container:push web -a line-movie-api
$ heroku container:release web -a line-movie-api

นำ URL https://line-movie-api.herokuapp.com/callback โดยเปลี่ยน line-movie-api เป็นชื่อ Application ที่ตั้งไว้ด้านบน ใส่ไว้ที่ webhook ของ Line Channel ตามด้านล่าง

สามารถดู log ได้จากคำสั่งนี้นะครับ (เปลี่ยนชื่อ line-movie-api ด้วยนะครับ)

$ heroku logs --tail -a line-movie-api

ทดสอบผ่าน LINE อีกครั้งนะครับ ถึงตรงนี้ถ้าติดตรงใหนหลังไมค์มาถามได้นะครับ แล้วพบกันในบทความหน้าครับ 😄

สำหรับเนื้อหาเกี่ยวกับการใช้งาน Docker และ Heroku สามารถดูเพิ่มเติมได้จากบทความของผมเองนะครับ

บทความโดย อ.ดร.กานต์ ยงศิริวิทย์
วิทยาลัยนวัตกรรมดิจิทัลเทคโนโลยี มหาวิทยาลัยรังสิต

--

--

Karn Yongsiriwit
Karn Yongsiriwit

Written by Karn Yongsiriwit

Lecturer at Digital Innovation Technology, Rangsit University

No responses yet