+5

Một ít về AI

Trong công việc, đôi khi bạn muốn đưa thêm một ít AI vào App hay một phần nhỏ Task của mình, hiểu thêm về AI sẽ giúp bạn chủ động hơn.

AI được viết tắt từ artificial intelligence (https://vi.wikipedia.org/wiki/Trí_tuệ_nhân_tạo) có thể hiểu nôm na là khả năng xử lý bằng trí tuệ của bất cứ cái gì bạn tạo ra, bạn có thể tham khảo link phía trước để hiểu rõ thêm về AI.

Vậy đưa AI vào công việc của bạn có phức tạp không, theo mình là không quá phức tạp 😃.

Một App khá đơn giản là đồng hồ báo thức, thông thường tính năng của nó sẽ là cho phép bạn đặt ngày giờ báo thức, ví dụ hàng sáng dậy vào 8h chẳng hạn, nghĩa là đến 8h sáng (giả sử là App chạy trên mobile) sẽ có 1 message thông báo đến giờ dậy đồng thời có 2 option là tắt chuông và 5 phút nữa đổ chuông.

Trong cả tuần sử dụng, bạn luôn tắt chuông mỗi buổi sáng vào lúc 8h, tuy nhiên vào thứ 5 chẳng hạn, bạn ngủ quên và không tắt được chuông, App sẽ đưa ra thông báo nhắc nhở bạn, còn bạn thường xuyên không tắt chuông vào thứ 5, App sẽ không nhắc bạn nữa. Như vậy App đã thông minh lên được 1 tẹo 😃.

Trên đây là ví dụ đơn gỉan về phân tích thói quen người sử dụng, một phần của AI được gọi tên chung là Học máy (machine learning https://vi.wikipedia.org/wiki/Học_máy) Bạn có thể đọc qua link bên cạnh về học máy.

Dữ liệu được thu thập trong trường hợp này khá đơn giản, tạm giả sử là thời điểm ngủ dậy, chu kỳ lặp lại là 1 tuần, tuy nhiên trong thực tế, dữ liệu thu thập được không đơn gỉan như vậy, có thể thu thập qua các ứng dụng được sử dụng hàng ngày như duyệt web, nhắn tin, báo thức ..., chu kỳ được phân tích dưa trên dữ liệu thu thập được. Qúa trình này có thể coi là số hóa thói quen người sử dụng, mức độ chính xác càng cao, chương trình được coi là càng thông minh.

Thói quen của người sử dụng có thể được biểu diễn bởi một biểu đồ hay một mô hình mô phỏng nào đó mang tính lặp lại.

Giả sử ta có dữ liệu với bảng users có trường wake_up dạng date time

create_table "users", force: :cascade do |t|
  t.datetime "wake_up"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

Tại model user ta thêm các scopefunction

class User < ApplicationRecord
  scope :select_rp, -> (max_period) do
    select build_select_rp_sql max_period
  end

  class << self
    def build_select_rp_sql max_period
      (1..max_period).map do |period|
        "CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE \
          DATETIME(users.wake_up, '+#{period} days') = \
            DATETIME(compare_users.wake_up, '+0 days'))) \
              THEN 1 ELSE 0 END AS rp_#{period}"
      end.join ", "
    end

    def max_repetition max_period
      select_rp_attributes = select_rp(max_period).map &:attributes
      (1..max_period).map do |period|
        times = select_rp_attributes.map{|rp| rp["rp_#{period}"]}.sum
        {
          "repeat in #{period} days" => "#{times} times",
          "times" => times
        }
      end.sort_by{|k| k["times"]}.last
    end
  end
end

Tại file seed ta tạo dữ liệu

(0..99).each do |index|
  User.create wake_up: Date.current + index.day + (5 + index % 5).hours
end

Trong console ta thử check hàm max_repetition

2.3.0 :008 > User.max_repetition 10
  User Load (104.8ms)  SELECT CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+1 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_1, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+2 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_2, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+3 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_3, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+4 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_4, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+5 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_5, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+6 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_6, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+7 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_7, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+8 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_8, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+9 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_9, CASE WHEN (EXISTS(SELECT id FROM users compare_users WHERE           DATETIME(users.wake_up, '+10 days') =             DATETIME(compare_users.wake_up, '+0 days')))               THEN 1 ELSE 0 END AS rp_10 FROM "users"
 => {"repeat in 5 days"=>"95 times", "times"=>95} 

Đây la 1 ví dụ tìm ra chu kỳ lặp lại thời điểm thức dậy của 1 user, giờ thức dậy được lưu ở trường wake_up, file seed tạo ra dữ liệu lăp lại trong 5 ngày, có thể thay đổi file seed để kiểm tra kết qủa function.

Cảm ơn và hi vọng bài viết gíup ích trong công việc của bạn.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí