Dữ liệu có hai xu hướng; Làm thế nào để trích xuất các đường xu hướng độc lập?


34

Tôi có một bộ dữ liệu không được sắp xếp theo bất kỳ cách cụ thể nào nhưng khi được vẽ rõ ràng có hai xu hướng riêng biệt. Hồi quy tuyến tính đơn giản sẽ không thực sự đầy đủ ở đây vì sự phân biệt rõ ràng giữa hai loạt. Có một cách đơn giản để có được hai đường xu hướng tuyến tính độc lập?

Đối với bản ghi tôi đang sử dụng Python và tôi khá thoải mái với việc lập trình và phân tích dữ liệu, bao gồm cả học máy nhưng sẵn sàng chuyển sang R nếu thực sự cần thiết.

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


6
Câu trả lời hay nhất mà tôi có cho đến nay là in nó trên giấy vẽ và sử dụng bút chì, thước kẻ và máy tính ...
jbbiomed

Có lẽ bạn có thể tính toán độ dốc cặp và nhóm chúng thành hai "cụm dốc". Tuy nhiên điều này sẽ thất bại nếu bạn có hai xu hướng song song.
Thomas Jungblut

1
Tôi không có bất kỳ kinh nghiệm cá nhân nào với nó, nhưng tôi nghĩ rằng các số liệu thống kê sẽ đáng để kiểm tra. Theo thống kê, hồi quy tuyến tính với tương tác cho nhóm sẽ là đầy đủ (trừ khi bạn nói rằng bạn có dữ liệu chưa được nhóm, trong trường hợp đó là một chút hairier ...)
Matt Parker

1
Thật không may, đây không phải là dữ liệu hiệu quả mà là dữ liệu sử dụng và sử dụng rõ ràng từ hai hệ thống riêng biệt được trộn lẫn vào cùng một bộ dữ liệu. Tôi muốn có thể mô tả hai mẫu sử dụng, nhưng tôi không thể quay lại và nhớ lại dữ liệu vì điều này thể hiện thông tin có giá trị khoảng 6 năm được thu thập bởi một khách hàng.
jbbiomed

2
Chỉ để đảm bảo: khách hàng của bạn không có bất kỳ dữ liệu bổ sung nào cho biết số đo nào đến từ dân số nào? Đây là 100% dữ liệu mà bạn hoặc khách hàng của bạn có hoặc có thể tìm thấy. Ngoài ra, năm 2012 có vẻ như bộ sưu tập dữ liệu của bạn bị sụp đổ hoặc một hoặc cả hai hệ thống của bạn rơi xuống sàn. Làm cho tôi tự hỏi nếu đường xu hướng đến thời điểm đó quan trọng nhiều.
Wayne

Câu trả lời:


30

Để giải quyết vấn đề của bạn, một cách tiếp cận tốt là xác định mô hình xác suất phù hợp với các giả định về tập dữ liệu của bạn. Trong trường hợp của bạn, bạn có thể muốn một hỗn hợp các mô hình hồi quy tuyến tính. Bạn có thể tạo mô hình "hỗn hợp hồi quy" tương tự như mô hình hỗn hợp gaussian bằng cách liên kết các điểm dữ liệu khác nhau với các thành phần hỗn hợp khác nhau.

Tôi đã bao gồm một số mã để giúp bạn bắt đầu. Mã này thực hiện một thuật toán EM cho một hỗn hợp gồm hai biến hồi quy (nó sẽ tương đối dễ dàng để mở rộng đến các hỗn hợp lớn hơn). Mã dường như khá mạnh mẽ cho các bộ dữ liệu ngẫu nhiên. Tuy nhiên, không giống như hồi quy tuyến tính, các mô hình hỗn hợp có các mục tiêu không lồi, vì vậy đối với một tập dữ liệu thực, bạn có thể cần phải chạy một vài thử nghiệm với các điểm khởi đầu ngẫu nhiên khác nhau.

import numpy as np
import matplotlib.pyplot as plt 
import scipy.linalg as lin

#generate some random data
N=100
x=np.random.rand(N,2)
x[:,1]=1

w=np.random.rand(2,2)
y=np.zeros(N)

n=int(np.random.rand()*N)
y[:n]=np.dot(x[:n,:],w[0,:])+np.random.normal(size=n)*.01
y[n:]=np.dot(x[n:,:],w[1,:])+np.random.normal(size=N-n)*.01


rx=np.ones( (100,2) )
r=np.arange(0,1,.01)
rx[:,0]=r

#plot the random dataset
plt.plot(x[:,0],y,'.b')
plt.plot(r,np.dot(rx,w[0,:]),':k',linewidth=2)
plt.plot(r,np.dot(rx,w[1,:]),':k',linewidth=2)

# regularization parameter for the regression weights
lam=.01

def em():
    # mixture weights
    rpi=np.zeros( (2) )+.5

    # expected mixture weights for each data point
    pi=np.zeros( (len(x),2) )+.5

    #the regression weights
    w1=np.random.rand(2)
    w2=np.random.rand(2)

    #precision term for the probability of the data under the regression function 
    eta=100

    for _ in xrange(100):
        if 0:
            plt.plot(r,np.dot(rx,w1),'-r',alpha=.5)
            plt.plot(r,np.dot(rx,w2),'-g',alpha=.5)

        #compute lhood for each data point
        err1=y-np.dot(x,w1)
        err2=y-np.dot(x,w2)
        prbs=np.zeros( (len(y),2) )
        prbs[:,0]=-.5*eta*err1**2
        prbs[:,1]=-.5*eta*err2**2

        #compute expected mixture weights
        pi=np.tile(rpi,(len(x),1))*np.exp(prbs)
        pi/=np.tile(np.sum(pi,1),(2,1)).T

        #max with respect to the mixture probabilities
        rpi=np.sum(pi,0)
        rpi/=np.sum(rpi)

        #max with respect to the regression weights
        pi1x=np.tile(pi[:,0],(2,1)).T*x
        xp1=np.dot(pi1x.T,x)+np.eye(2)*lam/eta
        yp1=np.dot(pi1x.T,y)
        w1=lin.solve(xp1,yp1)

        pi2x=np.tile(pi[:,1],(2,1)).T*x
        xp2=np.dot(pi2x.T,x)+np.eye(2)*lam/eta
        yp2=np.dot(pi[:,1]*y,x)
        w2=lin.solve(xp2,yp2)

        #max wrt the precision term
        eta=np.sum(pi)/np.sum(-prbs/eta*pi)

        #objective function - unstable as the pi's become concentrated on a single component
        obj=np.sum(prbs*pi)-np.sum(pi[pi>1e-50]*np.log(pi[pi>1e-50]))+np.sum(pi*np.log(np.tile(rpi,(len(x),1))))+np.log(eta)*np.sum(pi)
        print obj,eta,rpi,w1,w2

        try:
            if np.isnan(obj): break
            if np.abs(obj-oldobj)<1e-2: break
        except:
            pass

        oldobj=obj

    return w1,w2


#run the em algorithm and plot the solution
rw1,rw2=em()
plt.plot(r,np.dot(rx,rw1),'-r')
plt.plot(r,np.dot(rx,rw2),'-g')

plt.show()

25

Ở những nơi khác trong chủ đề này, user1149913 cung cấp lời khuyên tuyệt vời (xác định mô hình xác suất) và mã cho cách tiếp cận mạnh mẽ (ước tính EM). Hai vấn đề vẫn được giải quyết:

  1. Làm thế nào để đối phó với sự khởi hành từ mô hình xác suất (rất rõ ràng trong dữ liệu 2011-2012 và phần nào rõ ràng trong các nhấp nhô của các điểm ít dốc hơn).

  2. Cách xác định các giá trị khởi đầu tốt cho thuật toán EM (hoặc bất kỳ thuật toán nào khác).

Để giải quyết # 2, hãy xem xét sử dụng biến đổi Hough . Đây là một thuật toán phát hiện tính năng, để tìm các tính năng trải dài tuyến tính, có thể được tính toán một cách hiệu quả như một biến đổi Radon .

xyx,ytrong biến đổi Hough. Khi các tính năng trong cốt truyện gốc nằm dọc theo một đường chung hoặc gần đủ với một, thì các tập hợp đường cong mà chúng tạo ra trong biến đổi Hough có xu hướng có một giao điểm chung tương ứng với đường chung đó. Bằng cách tìm ra những điểm có cường độ lớn nhất trong biến đổi Hough, chúng ta có thể đọc được các giải pháp tốt cho vấn đề ban đầu.

Để bắt đầu với những dữ liệu này, trước tiên tôi cắt bỏ các công cụ phụ trợ (trục, dấu tick và nhãn) và để đo tốt các điểm bên ngoài rõ ràng ở phía dưới bên phải và rắc dọc theo trục dưới cùng. (Khi công cụ đó không bị cắt, quy trình vẫn hoạt động tốt, nhưng nó cũng phát hiện các trục, khung, chuỗi tuyến tính của bọ ve, chuỗi tuyến tính của nhãn và thậm chí các điểm nằm lẻ tẻ trên trục dưới cùng!)

img = Import["http://i.stack.imgur.com/SkEm3.png"]
i = ColorNegate[Binarize[img]]
crop2 = ImageCrop[ImageCrop[i, {694, 531}, {Left, Bottom}], {565, 467}, {Right, Top}]

(Cái này và phần còn lại của mã nằm trong Mathicala .)

Cắt ảnh

Để mỗi dấu chấm trong hình ảnh này tương ứng với một phạm vi đường cong hẹp trong biến đổi Hough, có thể nhìn thấy ở đây. Chúng là sóng hình sin:

hough2 = Radon[crop2, Method -> "Hough"]  // ImageAdjust

Biến đổi

Điều này làm cho biểu hiện trực quan ý nghĩa trong đó câu hỏi là một vấn đề phân cụm dòng : biến đổi Hough giảm nó thành một vấn đề phân cụm điểm , mà chúng ta có thể áp dụng bất kỳ phương pháp phân cụm nào chúng ta muốn.

Trong trường hợp này, việc phân cụm rõ ràng đến mức xử lý hậu kỳ đơn giản của biến đổi Hough được hiệu chỉnh. Để xác định các vị trí có cường độ lớn nhất trong biến đổi, tôi đã tăng độ tương phản và làm mờ biến đổi trên bán kính khoảng 1%: tương đương với đường kính của các điểm cốt truyện trong ảnh gốc.

blur = ImageAdjust[Blur[ImageAdjust[hough2, {1, 0}], 8]]

Biến đổi mờ

Ngưỡng kết quả đã thu hẹp nó thành hai đốm nhỏ có trọng tâm xác định hợp lý các điểm có cường độ lớn nhất: chúng ước tính các đường được trang bị.

comp = MorphologicalComponents[blur, 0.777]) // Colorize

0,777

Biến đổi ngưỡng nhị phân

Phía bên trái của hình ảnh tương ứng với hướng 0 độ (ngang) và, khi chúng ta nhìn từ trái sang phải, góc đó tăng tuyến tính lên 180 độ. Nội suy, tôi tính toán rằng hai đốm màu được tập trung ở 19 và 57,1 độ, tương ứng. Chúng ta cũng có thể đọc ra các phần chặn từ các vị trí thẳng đứng của các đốm màu. Thông tin này mang lại sự phù hợp ban đầu:

width = ImageDimensions[blur][[1]];
slopes =  Module[{x, y, z}, ComponentMeasurements[comp, "Centroid"] /. 
          Rule[x_, {y_, z_}] :>  Round[((y - 1/2)/(width - 1))  180., 0.1]
  ]

{19., 57.1}

Theo cách tương tự, người ta có thể tính toán các phần chặn tương ứng với các độ dốc này, đưa ra các mức khớp này:

Dòng trang bị

(Đường màu đỏ tương ứng với chấm màu hồng nhỏ trong hình trước và đường màu xanh tương ứng với đốm màu nước lớn hơn.)

Ở một mức độ lớn, cách tiếp cận này đã tự động xử lý vấn đề đầu tiên: những sai lệch so với tuyến tính làm mờ đi những điểm có cường độ lớn nhất, nhưng thường không làm thay đổi chúng nhiều. Các điểm ngoại vi thẳng thắn sẽ đóng góp tiếng ồn ở mức độ thấp trong suốt quá trình biến đổi Hough, sẽ biến mất trong quá trình xử lý hậu kỳ.

Tại thời điểm này, người ta có thể cung cấp các ước tính này dưới dạng giá trị bắt đầu cho thuật toán EM hoặc cho bộ giảm thiểu khả năng (được đưa ra ước tính tốt, sẽ hội tụ nhanh chóng). Mặc dù vậy, tốt hơn là sử dụng một công cụ ước lượng hồi quy mạnh mẽ như bình phương tối thiểu lặp lại . Nó có thể cung cấp một trọng số hồi quy cho mọi điểm. Trọng lượng thấp cho thấy một điểm không "thuộc" một dòng. Khai thác các trọng số này, nếu muốn, để gán từng điểm cho dòng thích hợp của nó. Sau đó, khi đã phân loại các điểm, bạn có thể sử dụng các bình phương tối thiểu thông thường (hoặc bất kỳ quy trình hồi quy nào khác) riêng biệt trên hai nhóm điểm.


1
Hình ảnh nói lên hàng ngàn từ và bạn có 5. Đây là công việc đáng kinh ngạc từ một biểu đồ nhanh tôi thực hiện chỉ với mục đích của câu hỏi này! Thanh danh!
jbbiomed

2
Biến đổi Hough được sử dụng rộng rãi trong trường Thị giác máy tính để xác định các đường thẳng trong ảnh. Tại sao nó không nên được sử dụng trong thống kê? ;)
Lucas Reis

Đó là một câu hỏi thú vị, @Lucas. Tuy nhiên, trong nhiều ứng dụng thống kê, có sự bất cân xứng giữaxy

Vâng. Ví dụ, hãy tưởng tượng số lượng ngoại lệ liên quan đến việc so sánh hai hình ảnh để phát hiện nếu chúng đến từ cùng một chủ đề. Và, trên hết, hãy tưởng tượng phải làm điều đó trong thời gian thực. "Tốc độ" là một yếu tố rất quan trọng trong Thị giác máy tính và không quá quan trọng trong Thống kê.
Lucas Reis

@RoyaltyTS Cảm ơn bạn đã chỉ ra sự cần thiết phải sửa một trong các đoạn mã. Vào thời điểm tôi tìm thấy thay đổi được đề xuất của bạn, nó đã bị từ chối (chính xác, bởi vì nó không hoàn toàn đúng, nhưng đừng bận tâm rằng: Tôi rất biết ơn bạn đã nhận thấy có lỗi). Tôi đã sửa nó bằng cách xóa tham chiếu đến rotation, được đặt thành 0 ban đầu và do đó không có sự khác biệt.
whuber

15

Tôi tìm thấy câu hỏi này liên kết trên một câu hỏi khác . Tôi thực sự đã làm nghiên cứu học thuật về loại vấn đề này. Vui lòng kiểm tra câu trả lời của tôi "Ít nhất căn bậc hai"? Một phương pháp phù hợp với nhiều cực tiểu để biết thêm chi tiết.

Cách tiếp cận dựa trên biến đổi Hough của Whuber là một giải pháp rất tốt cho các kịch bản đơn giản như cách bạn đưa ra. Tôi đã làm việc trên các kịch bản với dữ liệu phức tạp hơn, chẳng hạn như:

vấn đề liên kết dữ liệu - tập dữ liệu kẹo

Các đồng tác giả của tôi và tôi đã ký hiệu đây là một vấn đề "liên kết dữ liệu". Khi bạn cố gắng giải quyết nó, vấn đề chính thường là sự kết hợp do số lượng kết hợp dữ liệu có thể có theo cấp số nhân.

Chúng tôi có một ấn phẩm " Các hỗn hợp chồng chéo của các quy trình Gaussian cho vấn đề liên kết dữ liệu " khi chúng tôi tiếp cận vấn đề chung về các đường cong N bằng một kỹ thuật lặp, cho kết quả rất tốt. Bạn có thể tìm thấy mã Matlab được liên kết trong bài báo.

[Cập nhật] Có thể tìm thấy triển khai Python của kỹ thuật OMGP trong thư viện GPClust .

Tôi có một bài báo khác, nơi chúng tôi giải quyết vấn đề để có được một vấn đề tối ưu hóa lồi, nhưng nó chưa được chấp nhận để xuất bản. Nó là cụ thể cho 2 đường cong, vì vậy nó sẽ hoạt động hoàn hảo trên dữ liệu của bạn. Hãy cho tôi biết nếu bạn quan tâm.


1
Tôi buồn khi thấy rằng hơn hai năm qua, không ai khác đã đưa ra câu trả lời nguyên bản và có giá trị này. Trong khi đó, giấy cuối cùng bạn đề cập có được chấp nhận không?
whuber

1
Bài báo đã thực sự được chấp nhận, chỉ một vài tháng trước. Bạn có thể tải xuống tại đây gtas.unican.es/pub/378 . Đây thực sự là một vấn đề khá hiếm gặp (có thể giải thích sự thiếu phổ biến của nó), nhưng chúng tôi vẫn tìm được một số ứng dụng thú vị. Có một cái nhìn vào các thí nghiệm ở cuối bài nếu bạn thích.
Steven

2

user1149913 có một câu trả lời tuyệt vời (+1), nhưng theo tôi thì bộ sưu tập dữ liệu của bạn đã bị hỏng vào cuối năm 2011, vì vậy bạn phải cắt bỏ phần dữ liệu đó, và sau đó vẫn chạy mọi thứ một vài lần với các ngẫu nhiên khác nhau bắt đầu hệ số để xem những gì bạn nhận được.

Một cách đơn giản để thực hiện mọi việc sẽ là tách dữ liệu của bạn thành hai bộ bằng mắt, sau đó sử dụng bất kỳ kỹ thuật mô hình tuyến tính nào bạn đã sử dụng. Trong R, nó sẽ là lmhàm.

Hoặc phù hợp với hai dòng bằng mắt. Trong R bạn sẽ sử dụng ablineđể làm điều này.

Dữ liệu bị xáo trộn, có các ngoại lệ và cuối cùng bị phân tách, nhưng bằng mắt có hai dòng khá rõ ràng, vì vậy tôi không chắc một phương pháp ưa thích nào đáng giá.

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.