images
12/10/2020 07:57 am

Gấu mèo đi làm Data Scientist - Phần 8: Outlier - Anomaly Detection - Part 2

Nếu đã học xác suất thống kê - hay kinh tế lượng trong trường kinh tế hẳn bạn không lạ gì với Gaussian Distribution - Phân phối chuẩn.

Hôm nay Gấu Mèo sẽ đi chi tiết cách phát hiện bất thường bằng phân phối chuẩn. Theo lý thuyết những điểm nằm ngoài vùng 3- sigma là những điểm có xác suất thấp, tức là bất thường.


Thế nhưng làm sao biết được dữ liệu của bạn có phân phối theo Normal distribution hay không ?


“Con người hay hành động theo thói quen nên các action trên web cũng thường theo phân phối chuẩn.” Fat Cat bảo thế với Gấu Mèo


Nghe cũng hợp lý, tuy nhiên cái thời này chém cũng nhiều, tốt nhất cứ phải kiểm tra về dữ liệu đã. Mới mấy hôm trước, khi bắt đầu Covid-19, mấy ông bạn môi giới chứng khoán chém: cứ VN30 mã nào giảm nhiều nhất thì sau này thị trường hồi lại sẽ tăng mạnh nhất. Nghe cũng rất có lý nhưng mà sau khi xem lại dữ liệu đợt khủng hoảng cách đây 10 năm thì thấy sai tè le.


Nhưng kiểm tra như thế nào? Thử với data bán lẻ của một siêu thị nhé:

https://www.kaggle.com/aungpyaeap/supermarket-sales/download


1. Visualize dữ liệu


Cái này dùng khi phân tích một báo cáo đơn lẻ cho nhanh, chứ nếu làm hệ thống thì không làm kiểu này (vì đâu thể nhìn hết dữ liệu hàng trăm nghìn khách hàng). Tuy nhiên ban đầu cứ thử nhìn qua thì cũng dễ chọn phương án làm tiếp hơn.


𝘪𝘮𝘱𝘰𝘳𝘵 𝘱𝘢𝘯𝘥𝘢𝘴 𝘢𝘴 𝘱𝘥

𝘪𝘮𝘱𝘰𝘳𝘵 𝘯𝘶𝘮𝘱𝘺 𝘢𝘴 𝘯𝘱

𝘪𝘮𝘱𝘰𝘳𝘵 𝘮𝘢𝘵𝘱𝘭𝘰𝘵𝘭𝘪𝘣.𝘱𝘺𝘱𝘭𝘰𝘵 𝘢𝘴 𝘱𝘭𝘵

𝘪𝘮𝘱𝘰𝘳𝘵 𝘴𝘦𝘢𝘣𝘰𝘳𝘯 𝘢𝘴 𝘴𝘯𝘴

𝘪𝘮𝘱𝘰𝘳𝘵 𝘮𝘢𝘵𝘱𝘭𝘰𝘵𝘭𝘪𝘣

𝘥𝘧 = 𝘱𝘥.𝘳𝘦𝘢𝘥_𝘦𝘹𝘤𝘦𝘭("𝘚𝘶𝘱𝘦𝘳𝘴𝘵𝘰𝘳𝘦.𝘹𝘭𝘴")

𝘥𝘧['𝘚𝘢𝘭𝘦𝘴'].𝘥𝘦𝘴𝘤𝘳𝘪𝘣𝘦()

𝘥𝘧['𝘚𝘢𝘭𝘦𝘴'].𝘱𝘭𝘰𝘵.𝘩𝘪𝘴𝘵(𝘣𝘪𝘯𝘴=200, 𝘢𝘭𝘱𝘩𝘢=0.5)


Nhìn hình thì chả thấy bell curve đâu cả, dataset còn bị skew(lệch)

Thử xem độ lệnh như thế nào nhé:

𝑝𝑟𝑖𝑛𝑡("𝑆𝑘𝑒𝑤𝑛𝑒𝑠𝑠: %𝑓" % 𝑑𝑓['𝑇𝑜𝑡𝑎𝑙'].𝑠𝑘𝑒𝑤())

𝑝𝑟𝑖𝑛𝑡("𝐾𝑢𝑟𝑡𝑜𝑠𝑖𝑠: %𝑓" % 𝑑𝑓['𝑇𝑜𝑡𝑎𝑙'].𝑘𝑢𝑟𝑡())


Kết quả:


𝑆𝑘𝑒𝑤𝑛𝑒𝑠𝑠: 0.892570

𝐾𝑢𝑟𝑡𝑜𝑠𝑖𝑠: -0.081885


Đấy đời đâu có như là mơ.


Tuy nhiên như đã nói ở trên, không thể nhìn hết từng khách hàng, với cả nếu đưa thành hệ thống tự động thì làm gì có ai ngồi đấy để nhìn.


Thằng em Crazy Puppy đề xuất dùng AI để nhìn ảnh rồi ra kết luận, thế nhưng “pha xử lý này cồng kềnh quá”, bạn có thể đánh giá dữ liệu có theo phân phối chuẩn hay không bằng một vài dòng code.


2. Statistical Normality Tests bằng python


Chúng ta sẽ giả định dữ liệu theo phân phối chuẩn, và kiểm định xem giả định đấy có đúng không. Hãy thử 1 trong các cách này nhé:


🌱 Shapiro-Wilk Test


# 𝑆ℎ𝑎𝑝𝑖𝑟𝑜-𝑊𝑖𝑙𝑘 𝑇𝑒𝑠𝑡

𝑓𝑟𝑜𝑚 𝑠𝑐𝑖𝑝𝑦.𝑠𝑡𝑎𝑡𝑠 𝑖𝑚𝑝𝑜𝑟𝑡 𝑠ℎ𝑎𝑝𝑖𝑟𝑜

𝑑𝑎𝑡𝑎 = 𝑑𝑓['𝑇𝑜𝑡𝑎𝑙']

# 𝑛𝑜𝑟𝑚𝑎𝑙𝑖𝑡𝑦 𝑡𝑒𝑠𝑡

𝑠𝑡𝑎𝑡, 𝑝 = 𝑠ℎ𝑎𝑝𝑖𝑟𝑜(𝑑𝑎𝑡𝑎)

𝑝𝑟𝑖𝑛𝑡('𝑆𝑡𝑎𝑡𝑖𝑠𝑡𝑖𝑐𝑠=%.3𝑓, 𝑝=%.3𝑓' % (𝑠𝑡𝑎𝑡, 𝑝))

# 𝑖𝑛𝑡𝑒𝑟𝑝𝑟𝑒𝑡

𝑎𝑙𝑝ℎ𝑎 = 0.05

𝑖𝑓 𝑝 > 𝑎𝑙𝑝ℎ𝑎:

𝑝𝑟𝑖𝑛𝑡('𝑆𝑎𝑚𝑝𝑙𝑒 𝑙𝑜𝑜𝑘𝑠 𝐺𝑎𝑢𝑠𝑠𝑖𝑎𝑛 (𝑓𝑎𝑖𝑙 𝑡𝑜 𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)')

𝑒𝑙𝑠𝑒:

𝑝𝑟𝑖𝑛𝑡('𝑆𝑎𝑚𝑝𝑙𝑒 𝑑𝑜𝑒𝑠 𝑛𝑜𝑡 𝑙𝑜𝑜𝑘 𝐺𝑎𝑢𝑠𝑠𝑖𝑎𝑛 (𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)')


Kết quả:


𝑆𝑡𝑎𝑡𝑖𝑠𝑡𝑖𝑐𝑠=0.909, 𝑝=0.000

𝑆𝑎𝑚𝑝𝑙𝑒 𝑑𝑜𝑒𝑠 𝑛𝑜𝑡 𝑙𝑜𝑜𝑘 𝐺𝑎𝑢𝑠𝑠𝑖𝑎𝑛 (𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)


🌱 D'Agostino and Pearson's Test


# 𝐷'𝐴𝑔𝑜𝑠𝑡𝑖𝑛𝑜 𝑎𝑛𝑑 𝑃𝑒𝑎𝑟𝑠𝑜𝑛'𝑠 𝑇𝑒𝑠𝑡

𝑓𝑟𝑜𝑚 𝑠𝑐𝑖𝑝𝑦.𝑠𝑡𝑎𝑡𝑠 𝑖𝑚𝑝𝑜𝑟𝑡 𝑛𝑜𝑟𝑚𝑎𝑙𝑡𝑒𝑠𝑡

𝑑𝑎𝑡𝑎 = 𝑑𝑓['𝑇𝑜𝑡𝑎𝑙']

# 𝑛𝑜𝑟𝑚𝑎𝑙𝑖𝑡𝑦 𝑡𝑒𝑠𝑡

𝑠𝑡𝑎𝑡, 𝑝 = 𝑛𝑜𝑟𝑚𝑎𝑙𝑡𝑒𝑠𝑡(𝑑𝑎𝑡𝑎)

𝑝𝑟𝑖𝑛𝑡('𝑆𝑡𝑎𝑡𝑖𝑠𝑡𝑖𝑐𝑠=%.3𝑓, 𝑝=%.3𝑓' % (𝑠𝑡𝑎𝑡, 𝑝))

# 𝑖𝑛𝑡𝑒𝑟𝑝𝑟𝑒𝑡

𝑎𝑙𝑝ℎ𝑎 = 0.05

𝑖𝑓 𝑝 > 𝑎𝑙𝑝ℎ𝑎:

𝑝𝑟𝑖𝑛𝑡('𝑆𝑎𝑚𝑝𝑙𝑒 𝑙𝑜𝑜𝑘𝑠 𝐺𝑎𝑢𝑠𝑠𝑖𝑎𝑛 (𝑓𝑎𝑖𝑙 𝑡𝑜 𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)')

𝑒𝑙𝑠𝑒:

𝑝𝑟𝑖𝑛𝑡('𝑆𝑎𝑚𝑝𝑙𝑒 𝑑𝑜𝑒𝑠 𝑛𝑜𝑡 𝑙𝑜𝑜𝑘 𝐺𝑎𝑢𝑠𝑠𝑖𝑎𝑛 (𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)')


Kết quả:


𝑆𝑡𝑎𝑡𝑖𝑠𝑡𝑖𝑐𝑠=101.338, 𝑝=0.000

𝑆𝑎𝑚𝑝𝑙𝑒 𝑑𝑜𝑒𝑠 𝑛𝑜𝑡 𝑙𝑜𝑜𝑘 𝐺𝑎𝑢𝑠𝑠𝑖𝑎𝑛 (𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)


🌱 Anderson-Darling Test


# 𝐴𝑛𝑑𝑒𝑟𝑠𝑜𝑛-𝐷𝑎𝑟𝑙𝑖𝑛𝑔 𝑇𝑒𝑠𝑡

𝑓𝑟𝑜𝑚 𝑛𝑢𝑚𝑝𝑦.𝑟𝑎𝑛𝑑𝑜𝑚 𝑖𝑚𝑝𝑜𝑟𝑡 𝑠𝑒𝑒𝑑

𝑓𝑟𝑜𝑚 𝑠𝑐𝑖𝑝𝑦.𝑠𝑡𝑎𝑡𝑠 𝑖𝑚𝑝𝑜𝑟𝑡 𝑎𝑛𝑑𝑒𝑟𝑠𝑜𝑛

𝑑𝑎𝑡𝑎 = 𝑑𝑓['𝑇𝑜𝑡𝑎𝑙']

# 𝑛𝑜𝑟𝑚𝑎𝑙𝑖𝑡𝑦 𝑡𝑒𝑠𝑡

𝑟𝑒𝑠𝑢𝑙𝑡 = 𝑎𝑛𝑑𝑒𝑟𝑠𝑜𝑛(𝑑𝑎𝑡𝑎)

𝑝𝑟𝑖𝑛𝑡('𝑆𝑡𝑎𝑡𝑖𝑠𝑡𝑖𝑐: %.3𝑓' % 𝑟𝑒𝑠𝑢𝑙𝑡.𝑠𝑡𝑎𝑡𝑖𝑠𝑡𝑖𝑐)

𝑝 = 0

𝑓𝑜𝑟 𝑖 𝑖𝑛 𝑟𝑎𝑛𝑔𝑒(𝑙𝑒𝑛(𝑟𝑒𝑠𝑢𝑙𝑡.𝑐𝑟𝑖𝑡𝑖𝑐𝑎𝑙_𝑣𝑎𝑙𝑢𝑒𝑠)):

𝑠𝑙, 𝑐𝑣 = 𝑟𝑒𝑠𝑢𝑙𝑡.𝑠𝑖𝑔𝑛𝑖𝑓𝑖𝑐𝑎𝑛𝑐𝑒_𝑙𝑒𝑣𝑒𝑙[𝑖], 𝑟𝑒𝑠𝑢𝑙𝑡.𝑐𝑟𝑖𝑡𝑖𝑐𝑎𝑙_𝑣𝑎𝑙𝑢𝑒𝑠[𝑖]

𝑖𝑓 𝑟𝑒𝑠𝑢𝑙𝑡.𝑠𝑡𝑎𝑡𝑖𝑠𝑡𝑖𝑐 < 𝑟𝑒𝑠𝑢𝑙𝑡.𝑐𝑟𝑖𝑡𝑖𝑐𝑎𝑙_𝑣𝑎𝑙𝑢𝑒𝑠[𝑖]:

𝑝𝑟𝑖𝑛𝑡('%.3𝑓: %.3𝑓, 𝑑𝑎𝑡𝑎 𝑙𝑜𝑜𝑘𝑠 𝑛𝑜𝑟𝑚𝑎𝑙 (𝑓𝑎𝑖𝑙 𝑡𝑜 𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)' % (𝑠𝑙, 𝑐𝑣))

𝑒𝑙𝑠𝑒:

𝑝𝑟𝑖𝑛𝑡('%.3𝑓: %.3𝑓, 𝑑𝑎𝑡𝑎 𝑑𝑜𝑒𝑠 𝑛𝑜𝑡 𝑙𝑜𝑜𝑘 𝑛𝑜𝑟𝑚𝑎𝑙 (𝑟𝑒𝑗𝑒𝑐𝑡 𝐻0)' % (𝑠𝑙, 𝑐𝑣))


Kết quả:


Statistic: 28.475

15.000: 0.574, data does not look normal (reject H0)

10.000: 0.653, data does not look normal (reject H0)

5.000: 0.784, data does not look normal (reject H0)

2.500: 0.914, data does not look normal (reject H0)

1.000: 1.088, data does not look normal (reject H0)


Các kết quả giống như khi ta nhìn vào hình vẽ, dữ liệu của chúng ta không theo phân phối chuẩn.


Thế nhưng nó không có nghĩa là hết cách. Gấu Mèo ngay lập tức nghĩ tới: Transform to normal distribution.


Mời các bạn đọc lại bài Gấu mèo đi làm Data Scientist - Phần 8: Outlier - Anomaly Detection - Part 1.


- Tech Zone -


Thư giãn chút nào!!!

Bài viết liên quan