Phân cụm SOM cho các biến danh nghĩa / vòng tròn


11

Chỉ cần tự hỏi nếu có ai quen thuộc với cụm đầu vào danh nghĩa. Tôi đã xem SOM như một giải pháp nhưng rõ ràng nó chỉ hoạt động với các tính năng số. Có bất kỳ phần mở rộng cho các tính năng phân loại? Cụ thể tôi đã tự hỏi về "Ngày trong tuần" như là một tính năng có thể. Tất nhiên, có thể chuyển đổi nó thành một tính năng số (ví dụ: Mon - Sun tương ứng với số 1-7) tuy nhiên khoảng cách Euclide giữa Mặt trời và Môn (1 & 7) sẽ không giống với khoảng cách từ Thứ Hai đến Thứ Ba (1 & 2 ). Bất kỳ đề xuất hoặc ý tưởng sẽ được nhiều đánh giá cao.


(+1) một câu hỏi rất thú vị
steffen

2
Các biến tuần hoàn được coi là các phần tử của vòng tròn đơn vị trong mặt phẳng phức. Do đó, sẽ rất tự nhiên khi ánh xạ các ngày trong tuần để (giả sử) các điểm , j = 0 , Câu , 6 ; tức là , ( cos ( 0 ) , sin ( 0 ) ) , ( cos ( 2 π / 7 ) , sin ( 2 π / 7điểm kinh nghiệm(2jπTôi/7)j= =0,Giáo dục,6(cos(0),tội(0)) , ... ( cos ( 12 π / 7 ) , tội lỗi ( 12 π / 7 ) ) . (cos(2π/7),tội(2π/7))(cos(12π/7),tội(12π/7))
whuber

1
tôi sẽ phải mã hóa ma trận khoảng cách của riêng tôi sau đó cụ thể cho các biến tuần hoàn? chỉ tự hỏi nếu đã có các thuật toán hiện có cho loại phân cụm này. thx
Michael

@Michael: Tôi tin rằng bạn sẽ muốn chỉ định số liệu khoảng cách của riêng mình phù hợp với ứng dụng của bạn và được xác định trên tất cả các kích thước trong dữ liệu của bạn, không chỉ DOW. Chính thức, để x, y biểu thị các điểm trong không gian dữ liệu của bạn, bạn cần xác định hàm số liệu d (x, y) với các thuộc tính thông thường: d (x, x) = 0, d (x, y) = d (y , x) và d (x, z) <= d (x, y) + d (y, z). Khi bạn đã thực hiện điều đó, việc tạo SOM là cơ học. Thách thức sáng tạo là xác định d () theo cách nắm bắt khái niệm "tương tự" phù hợp với ứng dụng của bạn.
Arthur Nhỏ

Câu trả lời:


7

Lý lịch:

Cách hợp lý nhất để chuyển đổi giờ là thành hai biến xoay qua lại không đồng bộ. Hãy tưởng tượng vị trí của kim giờ của đồng hồ 24 giờ. Vị xtrí dao động qua lại không đồng bộ với yvị trí. Đối với một đồng hồ 24 giờ bạn có thể thực hiện điều này với x=sin(2pi*hour/24), y=cos(2pi*hour/24).

Bạn cần cả hai biến hoặc chuyển động thích hợp qua thời gian bị mất. Điều này là do thực tế là đạo hàm của sin hoặc cos thay đổi theo thời gian trong khi (x,y)vị trí thay đổi trơn tru khi nó di chuyển xung quanh vòng tròn đơn vị.

Cuối cùng, xem xét liệu có đáng để thêm một tính năng thứ ba để theo dõi thời gian tuyến tính, có thể được xây dựng dưới dạng giờ (hoặc phút hoặc giây) từ khi bắt đầu bản ghi đầu tiên hoặc dấu thời gian Unix hoặc một cái gì đó tương tự. Ba tính năng này sau đó cung cấp các proxy cho cả sự tiến triển theo chu kỳ và tuyến tính của thời gian, ví dụ: bạn có thể tạo ra các hiện tượng theo chu kỳ như chu kỳ giấc ngủ trong chuyển động của mọi người và cả sự tăng trưởng tuyến tính như dân số theo thời gian.

Ví dụ về nếu được hoàn thành:

# Enable inline plotting
%matplotlib inline

#Import everything I need...

import numpy as np
import matplotlib as mp

import matplotlib.pyplot as plt
import pandas as pd

# Grab some random times from here: https://www.random.org/clock-times/
# put them into a csv.
from pandas import DataFrame, read_csv
df = read_csv('/Users/angus/Machine_Learning/ipython_notebooks/times.csv',delimiter=':')
df['hourfloat']=df.hour+df.minute/60.0
df['x']=np.sin(2.*np.pi*df.hourfloat/24.)
df['y']=np.cos(2.*np.pi*df.hourfloat/24.)

df

nhập mô tả hình ảnh ở đây

def kmeansshow(k,X):

    from sklearn import cluster
    from matplotlib import pyplot
    import numpy as np

    kmeans = cluster.KMeans(n_clusters=k)
    kmeans.fit(X)

    labels = kmeans.labels_
    centroids = kmeans.cluster_centers_
    #print centroids

    for i in range(k):
        # select only data observations with cluster label == i
        ds = X[np.where(labels==i)]
        # plot the data observations
        pyplot.plot(ds[:,0],ds[:,1],'o')
        # plot the centroids
        lines = pyplot.plot(centroids[i,0],centroids[i,1],'kx')
        # make the centroid x's bigger
        pyplot.setp(lines,ms=15.0)
        pyplot.setp(lines,mew=2.0)
    pyplot.show()
    return centroids

Bây giờ hãy thử xem:

kmeansshow(6,df[['x', 'y']].values)

nhập mô tả hình ảnh ở đây

Bạn chỉ có thể thấy rằng có một số sau nửa đêm bao gồm các cụm màu xanh lá cây trước nửa đêm. Bây giờ, hãy giảm số lượng cụm và chỉ ra rằng trước và sau nửa đêm có thể được kết nối trong một cụm chi tiết hơn:

kmeansshow(3,df[['x', 'y']].values)

nhập mô tả hình ảnh ở đây

Xem cách cụm màu xanh chứa thời gian từ trước và sau nửa đêm được nhóm lại với nhau trong cùng một cụm ...

Bạn có thể làm điều này trong thời gian, hoặc ngày trong tuần, hoặc tuần trong tháng, hoặc ngày trong tháng, hoặc mùa, hoặc bất cứ điều gì.


Hữu ích (+1). Đây là một ứng dụng trong đó đồ thị là hình vuông không thuôn thực sự quan trọng. Tôi không biết phần mềm của bạn nhưng tôi tưởng tượng bạn có thể đặt tỷ lệ khung hình thành 1, cách xa mặc định.
Nick Cox

Đó là sự thật @NickCox. Hoặc bạn chỉ có thể thực hiện chuyển đổi tuyến tính trong đầu ;-)
user1745038

2

Các biến danh nghĩa thông thường được mã hóa giả khi được sử dụng trong SOM (ví dụ: một biến cho 1 cho Thứ Hai 0 không phải Thứ Hai, một biến khác cho Thứ Ba, v.v.).

Bạn có thể kết hợp thông tin bổ sung bằng cách tạo các danh mục kết hợp của các ngày liền kề. Ví dụ: Thứ Hai & Thứ Ba, Thứ Ba & Thứ Tư, v.v. Tuy nhiên, nếu dữ liệu của bạn liên quan đến hành vi của con người, việc sử dụng Ngày trong tuần và Cuối tuần làm danh mục sẽ hữu ích hơn.


2

Đối với các biến danh nghĩa, mã hóa điển hình trong mạng nơ ron hoặc bối cảnh kỹ thuật điện được gọi là "một nóng" - một vectơ của tất cả 0, với một 1 ở vị trí thích hợp cho giá trị của biến. Ví dụ, đối với các ngày trong tuần, có bảy ngày, vì vậy các vectơ nóng của bạn sẽ có chiều dài bảy. Sau đó, Thứ Hai sẽ được biểu diễn dưới dạng [1 0 0 0 0 0 0], Thứ Ba là [0 1 0 0 0 0 0], v.v.

Như Tim gợi ý, cách tiếp cận này có thể được khái quát hóa một cách dễ dàng để bao gồm các vectơ đặc trưng boolean tùy ý, trong đó mỗi vị trí trong vectơ tương ứng với một tính năng quan tâm trong dữ liệu của bạn và vị trí được đặt thành 1 hoặc 0 để chỉ ra sự hiện diện hay vắng mặt của điều đó đặc tính.

Khi bạn có các vectơ nhị phân, khoảng cách Hamming trở thành một số liệu tự nhiên, mặc dù khoảng cách Euclide cũng được sử dụng. Đối với các vectơ nhị phân một nóng, SOM (hoặc hàm xấp xỉ hàm khác) sẽ tự nhiên nội suy giữa 0 và 1 cho mỗi vị trí vectơ. Trong trường hợp này, các vectơ này thường được coi là các tham số của phân phối Boltzmann hoặc softmax trên không gian của biến danh nghĩa; điều trị này cung cấp một cách để sử dụng các vectơ trong một số loại kịch bản phân kỳ KL là tốt.

Biến tuần hoàn là phức tạp hơn nhiều. Như Arthur đã nói trong các nhận xét, bạn cần tự xác định một thước đo khoảng cách kết hợp tính chất tuần hoàn của biến.


1

Giả sử ngày trong tuần (dow) đi từ [0, 6], thay vì chiếu dữ liệu lên một vòng tròn, một tùy chọn khác là sử dụng:

dist = min(abs(dow_diff), 7 - abs(dow_diff))

Để hiểu lý do tại sao, hãy coi dow như một chiếc đồng hồ

  6  0
5      1
4      2
    3

khác nhau giữa 6 và 1 có thể là 6 - 1 = 5 (đi theo chiều kim đồng hồ từ 1 đến 6) hoặc 7 - (6 - 1) = 2. Lấy tối thiểu cả hai tùy chọn nên thực hiện thủ thuật.

Nói chung, bạn có thể sử dụng: min(abs(diff), range - abs(diff))


0

Tôi đã mã hóa thành công các ngày trong tuần (và các tháng trong năm) dưới dạng tuple của (cos, sin) như whuber nhấn mạnh trong bình luận của mình. Hơn khoảng cách sử dụng Euclide.

Đây là một ví dụ về mã trong r:

circularVariable = function(n, r = 4){
 #Transform a circular variable (e.g. Month so the year or day of the week) into two new variables (tuple).
 #n = upper limit of the sequence. E.g. for days of the week this is 7.
 #r =  number of digits to round generated variables.
 #Return
 #
 coord = function(y){
   angle = ((2*pi)/n) *y
   cs = round(cos(angle),r)
   s = round(sin(angle),r)
   c(cs,s)
 }
 do.call("rbind", lapply((0:(n-1)), coord))
}

Khoảng cách Euclide giữa 0 và 6 bằng 0 và 1.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.