Tại sao nên sử dụng K-Means cho dữ liệu chuỗi thời gian? (Phần hai)


Hoàng Trường Phát
1 năm trước
Hữu ích 3 Chia sẻ Viết bình luận 0
Đã xem 9046

Trong " Tại sao nên sử dụng K-Means cho dữ liệu chuỗi thời gian? (Phần một) ", tôi đưa ra một cái nhìn tổng quan về cách sử dụng các hàm thống kê khác nhau và Phân cụm K-Means để phát hiện bất thường cho dữ liệu chuỗi thời gian. Tôi khuyên bạn nên kiểm tra xem nếu bạn không quen thuộc. Trong bài này tôi sẽ chia sẻ:

  1. Một số mã cho thấy cách sử dụng K-Means.
  2. Tại sao bạn không nên sử dụng K-Means để phát hiện dị thường chuỗi thời gian theo ngữ cảnh.

Một số mã hiển thị cách sử dụng

Tôi đang mượn mã và dữ liệu cho phần này từ hướng dẫn của Amid Fish . Hãy nhìn vào nó, nó thật tuyệt vời. Trong ví dụ này, tôi sẽ chỉ cho bạn cách bạn có thể phát hiện sự bất thường trong dữ liệu EKG thông qua phát hiện bất thường theo ngữ cảnh với Phân cụm K-Means. Sự phá vỡ dữ liệu EKG nhịp nhàng là một loại dị thường tập thể nhưng với nó, chúng tôi sẽ phân tích sự bất thường liên quan đến hình dạng (hoặc bối cảnh) của dữ liệu.

Công thức phát hiện bất thường trong dữ liệu EKG bằng K-Means

K-Means sẽ tạo thành cụm. Nhưng bằng cách nào? Dữ liệu chuỗi thời gian không giống như một biểu đồ phân tán đẹp có thể "phân cụm". Cửa sổ dữ liệu của bạn lấy dữ liệu trông như thế này ...

Và biến nó thành một loạt các phân đoạn nhỏ hơn (mỗi phân đoạn có 32 điểm). Chúng thực chất là các bản dịch ngang của nhau. Họ trông như thế này ...

Mỗi phân đoạn cửa sổ được xác định bởi một mảng có kích thước 32.

Sau đó chúng tôi sẽ lấy từng điểm trong mỗi phân đoạn và vẽ đồ thị trong không gian 32 chiều. Tôi thích nghĩ bất cứ điều gì trên 3 chiều là một đám mây mơ hồ. Bạn có thể tưởng tượng rằng chúng ta hiện đang vẽ đồ thị của một đám mây 32 chiều trong một không gian rộng lớn hơn. K-Means sẽ phân cụm các đám mây 32 chiều đó thành các nhóm dựa trên mức độ giống nhau của chúng. Theo cách này, một cụm sẽ đại diện cho các hình dạng khác nhau mà dữ liệu mất.

Một cụm có thể đại diện cho một hàm đa thức thực sự cụ thể. Các cụm cũng có thể đại diện cho một đa thức đơn giản như y = x ^ 3. Loại đường mà mỗi cụm đại diện được xác định bởi kích thước phân khúc của bạn. Kích thước phân khúc của bạn càng nhỏ, bạn sẽ chia dữ liệu chuỗi thời gian của mình thành các phần thành phần - đa thức đơn giản. Bằng cách đặt Seg_len của chúng tôi thành 32, chúng tôi sẽ tạo ra rất nhiều đa thức phức tạp. Ở một mức độ nào đó, số lượng cụm mà chúng tôi chọn thực hiện sẽ xác định mức độ chúng tôi muốn các hệ số cụ thể của đa thức có vấn đề. Nếu chúng ta tạo ra một số lượng nhỏ các cụm, các hệ số sẽ không quan trọng bằng.

Đây là mã để cửa sổ dữ liệu của bạn trông như thế này:

import numpy as np

segment_len = 32
slide_len = 2

segments = []
for start_pos in range(0, len(ekg_data), slide_len):
    end_pos = start_pos + segment_len
     segment = np.copy(ekg_data[start_pos:end_pos])
    # if we're at the end and we've got a truncated segment, drop it
    if len(segment) != segment_len:
        continue
    segments.append(segment)

Phân khúc của chúng tôi sẽ trông như thế này:

Chúng ta cần bình thường hóa các cửa sổ của chúng tôi mặc dù. Sau này khi chúng tôi cố gắng dự đoán dữ liệu mới của chúng tôi thuộc về lớp nào, chúng tôi muốn đầu ra của chúng tôi là một dòng liên tục. Nếu các cụm được xác định bởi các phân đoạn có cửa sổ không bắt đầu bằng 0 và kết thúc bằng 0, chúng sẽ không khớp với nhau khi chúng tôi cố gắng xây dựng lại dữ liệu dự đoán của chúng tôi. Để làm điều này, chúng tôi nhân tất cả các phân đoạn cửa sổ với một chức năng cửa sổ. Chúng tôi lấy từng điểm trong mảng và nhân nó với từng điểm trong một mảng đại diện cho chức năng cửa sổ này:

window_rads = np.linspace(0, np.pi, segment_len)
window = np.sin(window_rads)**2
windowed_segments = []
for segment in segments:
    windowed_segment = np.copy(segment) * window
    windowed_segments.append(windowed_segment)

Bây giờ tất cả các phân khúc của chúng tôi sẽ bắt đầu và kết thúc với giá trị 0.

2. Thời gian để cụm

from sklearn.cluster import KMeans

clusterer = KMeans(n_clusters=150)
clusterer.fit(windowed_segments)

Các trung tâm của cụm của chúng tôi có sẵn từ clusterer.cluster_centers_. Chúng có hình dạng (150, 32). Điều này là do mỗi trung tâm thực sự là một mảng gồm 32 điểm và chúng tôi đã tạo ra 150 cụm.

3. Thời gian tái thiết

Đầu tiên, chúng tôi tạo một mảng 0 dài bằng số liệu bất thường của chúng tôi. (Chúng tôi đã lấy ekg_data của chúng tôi và tạo ra sự bất thường bằng cách chèn một số 0 ekg_data_anomalous[210:215] = 0). Cuối cùng chúng ta sẽ thay thế các số 0 trong mảng tái tạo của chúng ta bằng các trọng tâm dự đoán.

#placeholder reconstruction array 
reconstruction = np.zeros(len(ekg_data_anomalous))

Tiếp theo, chúng ta cần chia dữ liệu bất thường của chúng tôi thành các phân đoạn chồng chéo. Chúng tôi sẽ đưa ra dự đoán dựa trên các phân khúc này.

slide_len = segment_len/2
# slide_len = 16 as opposed to a slide_len = 2. Slide_len = 2 was used to create a lot of horizontal translations to provide K-Means with a lot of data. 

#segments were created from the ekg_data_anomalous dataset from the code above
for segment_n, segment in enumerate(segments):
    # normalize by multiplying our window function to each segment
    segment *= window
    # sklearn uses the euclidean square distance to predict the centroid
    nearest_centroid_idx = clusterer.predict(segment.reshape(1,-1))[0]
    centroids = clusterer.cluster_centers_
    nearest_centroid = np.copy(centroids[nearest_centroid_idx])

    # reconstructed our segments with an overlap equal to the slide_len so the centroids are       
    stitched together perfectly. 
    pos = segment_n * slide_len
    reconstruction[int(pos):int(pos+segment_len)] += nearest_centroid

Cuối cùng, xác định xem chúng tôi có lỗi lớn hơn 2% và âm mưu hay không.

error = reconstruction[0:n_plot_samples] - ekg_data_anomalous[0:n_plot_samples]
error_98th_percentile = np.percentile(error, 98)

4. Cảnh báo

Bây giờ nếu chúng tôi muốn cảnh báo về sự bất thường của mình, tất cả những gì chúng tôi phải làm là đặt ngưỡng 13.1 cho Lỗi Tái thiết của chúng tôi. Bất cứ khi nào nó vượt quá 13.1, chúng tôi đã phát hiện ra sự bất thường.

Bây giờ chúng ta đã dành toàn bộ thời gian để học và hiểu K-Means và ứng dụng của nó trong phát hiện bất thường theo ngữ cảnh, hãy thảo luận về lý do tại sao nó có thể là một ý tưởng tồi để sử dụng nó. Để giúp bạn vượt qua phần này, tôi sẽ cung cấp cho bạn đoạn não ngắn này:

Tại sao bạn không nên sử dụng K-Means cho Phát hiện dị thường theo chuỗi thời gian bối cảnh

Tôi đã học được rất nhiều về những hạn chế của việc sử dụng K-Means từ bài đăng này . Bài đăng đó đi vào rất nhiều chi tiết, nhưng ba nhược điểm chính bao gồm:

1. K-Means chỉ hội tụ trên cực tiểu địa phương để tìm Centroid

Khi K-Means tìm thấy trọng tâm, trước tiên, nó sẽ vẽ 150 "điểm" ngẫu nhiên (trong trường hợp của chúng tôi thực sự là một vật thể 32 chiều, nhưng chúng ta hãy giảm vấn đề này xuống tương tự 2 chiều trong một giây). Nó sử dụng phương trình này để tính khoảng cách giữa tất cả 150 centroid và mọi "điểm" khác. Sau đó, nó sẽ xem xét tất cả các khoảng cách và nhóm các đối tượng lại với nhau dựa trên khoảng cách của chúng. Sklearn tính toán khoảng cách với Chênh lệch Euclide bình phương (điều này nhanh hơn so với chỉ sử dụng chênh lệch Euclide ). Sau đó, nó cập nhật vị trí của tâm dựa trên phương trình này (bạn có thể nghĩ về nó giống như khoảng cách trung bình từ các đối tượng trong một cụm).

Một khi nó không thể được cập nhật nữa, nó xác định rằng điểm đó là trọng tâm. Tuy nhiên, K-Means thực sự không thể "nhìn thấy rừng qua những tán cây". Nếu các trọng tâm được đặt ngẫu nhiên ban đầu ở một vị trí xấu, thì K-Means sẽ không chỉ định một trọng tâm phù hợp. Thay vào đó, nó sẽ hội tụ ở mức tối thiểu cục bộ và cung cấp phân cụm kém. Với cụm nghèo đi kèm dự đoán kém. Để tìm hiểu thêm về cách K-Means tìm thấy centroid, tôi khuyên bạn nên đọc . Nhìn vào đây để tìm hiểu thêm về cách K-Means hội tụ trên cực tiểu địa phương.

2. Mỗi dấu thời gian được truyền dưới dạng thứ nguyên

Làm điều này là tốt nếu các bước thời gian của chúng tôi là thống nhất. Tuy nhiên, hãy tưởng tượng nếu chúng ta sử dụng K-Means trên dữ liệu cảm biến. Giả sử dữ liệu cảm biến của bạn đến trong khoảng thời gian không đều. K-Means thực sự có thể dễ dàng tạo ra các cụm là nguyên mẫu của hành vi chuỗi thời gian cơ bản của bạn.

3. Sử dụng khoảng cách Euclide như một thước đo tương tự có thể gây hiểu nhầm

Chỉ vì một đối tượng gần với một centroid không nhất thiết có nghĩa là nó phải thuộc về cụm đó. Nếu bạn nhìn xung quanh, bạn có thể nhận thấy rằng mọi đối tượng lân cận khác thuộc về một lớp khác. Thay vào đó, bạn có thể xem xét áp dụng KNN bằng cách sử dụng các đối tượng trong cụm được tạo bởi K-Means.

Tôi hy vọng điều này và blog trước giúp bạn trong hành trình phát hiện sự bất thường của bạn. Xin vui lòng cho tôi biết nếu bạn tìm thấy bất cứ điều gì khó hiểu hoặc cảm thấy tự do để yêu cầu tôi giúp đỡ. Bạn có thể truy cập trang cộng đồng InfluxData hoặc tweet cho chúng tôi @InfluxDB.

Hữu ích 3 Chia sẻ Viết bình luận 0
Đã xem 9046