ข้อมูลมีสองแนวโน้ม วิธีแยกเส้นแนวโน้มอิสระ


34

ฉันมีชุดข้อมูลที่ไม่ได้เรียงลำดับ แต่อย่างใดเมื่อมีการวางแผนอย่างชัดเจนมีแนวโน้มที่แตกต่างกันสองอย่าง การถดถอยเชิงเส้นอย่างง่ายจะไม่เพียงพอที่นี่เพราะความแตกต่างที่ชัดเจนระหว่างสองชุด มีวิธีง่าย ๆ ในการรับเส้นแนวโน้มเชิงเส้นที่เป็นอิสระหรือไม่

สำหรับบันทึกที่ฉันใช้ Python และฉันรู้สึกสะดวกสบายกับการเขียนโปรแกรมและการวิเคราะห์ข้อมูลรวมถึงการเรียนรู้ของเครื่อง แต่ยินดีที่จะข้ามไปยัง R หากจำเป็นจริงๆ

ป้อนคำอธิบายรูปภาพที่นี่


6
คำตอบที่ดีที่สุดที่ฉันได้จนถึงคือการพิมพ์นี้บนกระดาษกราฟและใช้ดินสอและไม้บรรทัดและเครื่องคิดเลข ...
jbbiomed

บางทีคุณสามารถคำนวณความลาดชันแบบคู่และจัดกลุ่มให้เป็น "กลุ่มความชัน" ได้ อย่างไรก็ตามสิ่งนี้จะล้มเหลวหากคุณมีแนวโน้มสองขนาน
Thomas Jungblut

1
ฉันไม่ได้มีประสบการณ์ส่วนตัวกับมัน แต่ฉันคิดว่าสถิติจะคุ้มค่าที่จะเช็คเอาท์ สถิติการถดถอยเชิงเส้นที่มีการโต้ตอบสำหรับกลุ่มจะเพียงพอ (เว้นแต่คุณจะบอกว่าคุณมีข้อมูลที่ไม่ได้จัดกลุ่มซึ่งในกรณีที่ค่อนข้างน้อย ... )
Matt Parker

1
น่าเสียดายที่นี่ไม่ใช่ข้อมูลเอฟเฟกต์ แต่เป็นข้อมูลการใช้งานและการใช้งานอย่างชัดเจนจากระบบที่แยกกันสองระบบรวมกันเป็นชุดข้อมูลเดียวกัน ฉันต้องการที่จะสามารถอธิบายรูปแบบการใช้งานทั้งสอง แต่ฉันไม่สามารถย้อนกลับและจำข้อมูลได้เนื่องจากนี่เป็นข้อมูลที่เก็บรวบรวมโดยลูกค้าประมาณ 6 ปี
jbbiomed

2
เพื่อให้แน่ใจว่า: ลูกค้าของคุณไม่มีข้อมูลเพิ่มเติมใด ๆ ที่จะระบุว่าการวัดใดมาจากประชากรใด นี่คือ 100% ของข้อมูลที่คุณหรือลูกค้าของคุณมีหรือสามารถหาได้ นอกจากนี้ในปี 2012 ดูเหมือนว่าการรวบรวมข้อมูลของคุณจะแยกออกจากกันหรือระบบของคุณหนึ่งหรือทั้งสองระบบล้มลงพื้น ทำให้ฉันสงสัยว่าเทรนด์ไลน์เข้าใกล้จุดนั้นมากน้อยแค่ไหน
Wayne

คำตอบ:


30

ในการแก้ปัญหาของคุณแนวทางที่ดีคือกำหนดรูปแบบความน่าจะเป็นที่ตรงกับข้อสมมติเกี่ยวกับชุดข้อมูลของคุณ ในกรณีของคุณคุณอาจต้องการส่วนผสมของตัวแบบการถดถอยเชิงเส้น คุณสามารถสร้างรูปแบบ "การผสมของตัวถอยหลัง" ซึ่งคล้ายกับตัวแบบการผสมแบบเกาส์เซียนโดยเชื่อมโยงจุดข้อมูลที่แตกต่างกับองค์ประกอบการผสมที่แตกต่างกัน

ฉันได้รวมรหัสบางอย่างเพื่อให้คุณเริ่มต้น รหัสใช้อัลกอริทึม EM สำหรับการผสมของสอง regressors (มันควรจะค่อนข้างง่ายที่จะขยายไปสู่การผสมขนาดใหญ่) รหัสดูเหมือนจะมีประสิทธิภาพพอสมควรสำหรับชุดข้อมูลแบบสุ่ม อย่างไรก็ตามแตกต่างจากการถดถอยเชิงเส้นแบบจำลองการผสมมีวัตถุประสงค์แบบไม่นูนดังนั้นสำหรับชุดข้อมูลจริงคุณอาจต้องทำการทดลองสองสามครั้งด้วยจุดเริ่มต้นแบบสุ่มที่แตกต่างกัน

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

ที่อื่นในหัวข้อนี้ user1149913 ให้คำแนะนำที่ดี (กำหนดตัวแบบความน่าจะเป็น) และโค้ดสำหรับแนวทางที่มีประสิทธิภาพ (การประมาณค่า EM) ยังคงมีสองประเด็นที่ต้องแก้ไข:

  1. วิธีรับมือกับการออกจากแบบจำลองความน่าจะเป็น (ซึ่งเห็นได้ชัดมากในข้อมูล 2011-2012 และค่อนข้างชัดเจนในการแยกแยะของจุดที่มีความลาดชันน้อยกว่า)

  2. วิธีระบุค่าเริ่มต้นที่ดีสำหรับอัลกอริทึม EM (หรืออัลกอริทึมอื่น ๆ )

ไปยังที่อยู่ที่ 2 พิจารณาการใช้Hough เปลี่ยน นี่คือขั้นตอนวิธีการตรวจสอบคุณลักษณะซึ่งสำหรับการค้นหาเหยียดเชิงเส้นของคุณสมบัติได้มีการคำนวณเป็นเรดอนเปลี่ยน

xYx,Yในการแปลง Hough เมื่อคุณสมบัติในพล็อตดั้งเดิมตกลงไปตามเส้นทั่วไปหรือใกล้พอที่หนึ่งแล้วคอลเลกชันของเส้นโค้งที่พวกเขาสร้างขึ้นในการแปลง Hough มักจะมีจุดตัดร่วมที่สอดคล้องกับบรรทัดทั่วไปนั้น ด้วยการค้นหาจุดที่รุนแรงที่สุดเหล่านี้ในการแปลง Hough เราสามารถอ่านวิธีแก้ปัญหาที่ดีสำหรับปัญหาดั้งเดิม

ในการเริ่มต้นกับข้อมูลเหล่านี้ก่อนอื่นฉันต้องตัดสิ่งเสริม (แกน, เครื่องหมายติ๊กและป้ายกำกับ) ออกและสำหรับการวัดที่ดีให้ตัดจุดที่อยู่ภายนอกที่ด้านล่างขวาและโรยไปตามแกนด้านล่าง (เมื่อสิ่งนั้นไม่ถูกครอบตัดขั้นตอนก็ยังใช้งานได้ดี แต่มันยังตรวจจับแกน, เฟรม, ลำดับเชิงเส้นของเห็บ, ลำดับเชิงเส้นของฉลากและแม้กระทั่งจุดที่วางอยู่บนแกนด้านล่าง!)

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}]

(นี่และรหัสที่เหลืออยู่ในMathematica )

ภาพที่ครอบตัด

ในแต่ละจุดในภาพนี้จะมีช่วงโค้งแคบ ๆ ในการแปลง Hough ซึ่งมองเห็นได้ที่นี่ พวกเขาเป็นคลื่นไซน์:

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

Hough transform

สิ่งนี้ทำให้มองเห็นได้อย่างชัดเจนถึงความรู้สึกที่คำถามนั้นเป็นปัญหาการจัดกลุ่มบรรทัด : การแปลง Hough ช่วยลดปัญหาการจัดกลุ่มจุดซึ่งเราสามารถใช้วิธีการจัดกลุ่มใด ๆ ที่เราชอบ

ในกรณีนี้การจัดกลุ่มมีความชัดเจนว่าการทำโพสต์อย่างง่ายของ Hough transform ที่พอเพียง ในการระบุตำแหน่งที่มีความเข้มมากที่สุดในการแปลงรูปฉันได้เพิ่มความคมชัดและทำให้การแปลงเบลอบนรัศมีประมาณ 1%: นั่นเปรียบได้กับขนาดเส้นผ่าศูนย์กลางของจุดพล็อตในภาพต้นฉบับ

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

การแปลงเบลอ

การกำหนดผลลัพธ์ใหม่ให้แคบลงเหลือสอง blobs เล็ก ๆ ซึ่ง centroids จะระบุจุดที่มีความเข้มมากที่สุดได้อย่างสมเหตุสมผล: สิ่งเหล่านี้ประเมินเส้นที่ติดตั้งไว้

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

0.777

การแปลงแบบไบนาไนซ์ตามเกณฑ์

ด้านซ้ายของภาพสอดคล้องกับทิศทาง 0 องศา (แนวนอน) และเมื่อเรามองจากซ้ายไปขวามุมนั้นจะเพิ่มขึ้นเป็นเส้นตรงเป็น 180 องศา Interpolating ฉันคำนวณว่าสอง blobs อยู่กึ่งกลางที่ 19 และ 57.1 องศาตามลำดับ นอกจากนี้เรายังสามารถอ่านค่าตัดขวางจากตำแหน่งแนวตั้งของ blobs ข้อมูลนี้ให้ผลเริ่มต้นพอดี:

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}

ในลักษณะที่คล้ายกันเราสามารถคำนวณจุดตัดที่สอดคล้องกับความลาดชันเหล่านี้ได้

เส้นติดตั้ง

(เส้นสีแดงตรงกับจุดสีชมพูเล็ก ๆ ในภาพก่อนหน้าและเส้นสีน้ำเงินตรงกับ aqua blob ที่ใหญ่กว่า)

ในระดับที่ยอดเยี่ยมวิธีการนี้จะจัดการกับปัญหาแรกโดยอัตโนมัติ: การเบี่ยงเบนจากการเชิงเส้นทำให้คะแนนของความรุนแรงมากที่สุด แต่โดยทั่วไปแล้วจะไม่เปลี่ยนแปลงมากนัก จุดที่อยู่ไกลออกไปตรงไปตรงมาจะให้เสียงรบกวนในระดับต่ำตลอดการแปลง Hough ซึ่งจะหายไประหว่างขั้นตอนหลังการประมวลผล

ณ จุดนี้เราสามารถจัดเตรียมการประมาณการเหล่านี้เป็นค่าเริ่มต้นสำหรับอัลกอริทึม EM หรือเครื่องมือลดโอกาสที่จะเกิดขึ้น (ซึ่งหากได้รับการประมาณการที่ดี ที่ดีขึ้นแม้ว่าจะมีการใช้ประมาณการถดถอยที่แข็งแกร่งเช่นซ้ำ reweighted น้อยสแควร์ มันสามารถให้น้ำหนักการถดถอยทุกจุด ตุ้มน้ำหนักต่ำหมายถึงจุดที่ไม่ได้อยู่ในบรรทัด ใช้ประโยชน์จากน้ำหนักเหล่านี้หากต้องการเพื่อกำหนดแต่ละจุดให้เป็นแนวที่เหมาะสม จากนั้นเมื่อมีการจำแนกคะแนนคุณสามารถใช้กำลังสองน้อยที่สุดธรรมดา (หรือขั้นตอนการถดถอยอื่น ๆ ) แยกกันในจุดสองกลุ่ม


1
รูปภาพบอกพันคำและคุณมี 5 นี่เป็นงานที่เหลือเชื่อจากกราฟอย่างรวดเร็วที่ฉันทำเพื่อจุดประสงค์ของคำถามนี้! รุ่งโรจน์!
jbbiomed

2
การแปลง Hough ถูกใช้อย่างกว้างขวางในฟิลด์ Computer Vision เพื่อระบุเส้นตรงในรูปภาพ เหตุใดจึงไม่ควรใช้ในสถิติด้วย ;)
Lucas Reis

xY

ใช่. ลองนึกภาพตัวอย่างเช่นจำนวนค่าผิดปกติที่เกี่ยวข้องในการเปรียบเทียบภาพสองภาพเพื่อตรวจสอบว่ามาจากเรื่องเดียวกันหรือไม่ และที่สำคัญที่สุดคือจินตนาการว่าต้องทำในเวลาจริง "ความเร็ว" เป็นปัจจัยที่สำคัญมากใน Computer Vision และไม่สำคัญในสถิติ
Lucas Reis

@RoyalTS ขอบคุณที่ชี้ให้เห็นถึงความจำเป็นในการแก้ไขโค้ดตัวอย่างอันใดอันหนึ่ง เมื่อถึงเวลาที่ฉันพบว่าการเปลี่ยนแปลงที่คุณแนะนำถูกปฏิเสธ (ถูกต้องเพราะมันไม่ถูกต้อง แต่ไม่เป็นไรที่: ฉันรู้สึกขอบคุณที่คุณสังเกตเห็นว่ามีข้อผิดพลาด) ฉันแก้ไขมันโดยลบการอ้างอิงถึงrotationซึ่งถูกตั้งค่าเป็นศูนย์ แต่เดิมแล้วจึงไม่แตกต่างกัน
whuber

15

ผมพบว่าคำถามนี้เชื่อมโยงในคำถามอื่น ฉันจริง ๆ แล้วการวิจัยเชิงวิชาการเกี่ยวกับปัญหาแบบนี้ โปรดตรวจสอบคำตอบที่เหมาะสม"Least สแควร์รูต"? วิธีการกระชับที่มีหลายขั้นตอนสำหรับรายละเอียดเพิ่มเติม

วิธีการแปลง Hough ของ Whuber เป็นวิธีแก้ปัญหาที่ดีมากสำหรับสถานการณ์ง่าย ๆ ตามที่คุณให้ ฉันทำงานกับสถานการณ์ที่มีข้อมูลที่ซับซ้อนมากขึ้นเช่นนี้

ปัญหาการเชื่อมโยงข้อมูล - ชุดข้อมูลลูกอม

ผู้เขียนร่วมของฉันและฉันแสดงว่านี่เป็นปัญหา "การเชื่อมโยงข้อมูล" เมื่อคุณพยายามที่จะแก้ปัญหาโดยทั่วไปปัญหาหลักคือ combinatorial เนื่องจากจำนวนชุดข้อมูลที่เป็นไปได้แทน

เราได้ตีพิมพ์ "การรวมกันของกระบวนการแบบเกาส์สำหรับปัญหาการเชื่อมโยงข้อมูล " ซึ่งเราเข้าหาปัญหาทั่วไปของเส้นโค้ง N ด้วยเทคนิคการวนซ้ำซึ่งให้ผลลัพธ์ที่ดีมาก คุณสามารถค้นหารหัส Matlab ที่เชื่อมโยงในกระดาษ

[Update] การใช้งานหลามของเทคนิค OMGP ที่สามารถพบได้ในห้องสมุด GPClust

ฉันมีบทความอื่นที่เราผ่อนคลายปัญหาเพื่อให้ได้ปัญหาการเพิ่มประสิทธิภาพนูน แต่มันยังไม่ได้รับการตีพิมพ์ มันมีความเฉพาะสำหรับ 2 เส้นโค้งดังนั้นมันจึงทำงานได้อย่างสมบูรณ์บนข้อมูลของคุณ แจ้งให้เราทราบหากคุณสนใจ


1
ฉันเสียใจที่เห็นว่าสองปีที่ผ่านมาไม่มีใครได้ยกระดับการตอบกลับดั้งเดิมและมีค่านี้ ในระหว่างนี้คุณได้รับเอกสารฉบับสุดท้ายที่ได้รับการยอมรับหรือไม่
whuber

1
กระดาษได้รับการยอมรับแน่นอนเพียงไม่กี่เดือนที่ผ่านมา คุณสามารถดาวน์โหลดได้ที่นี่gtas.unican.es/pub/378 นี่เป็นปัญหาที่ค่อนข้างหายาก (ซึ่งอาจอธิบายถึงการขาดความนิยม) แต่เราก็ยังหาแอพพลิเคชั่นที่น่าสนใจ ดูการทดลองที่ท้ายกระดาษถ้าคุณชอบ
Steven

2

user1149913 มีคำตอบที่ยอดเยี่ยม (+1) แต่สำหรับฉันแล้วการรวบรวมข้อมูลของคุณแตกสลายในปลายปี 2011 ดังนั้นคุณต้องตัดส่วนนั้นออกจากข้อมูลของคุณ เริ่มต้นค่าสัมประสิทธิ์เพื่อดูว่าคุณได้รับอะไร

วิธีหนึ่งที่ตรงไปตรงมาในการทำสิ่งต่าง ๆ คือการแยกข้อมูลของคุณออกเป็นสองชุดด้วยตาแล้วใช้เทคนิคโมเดลเชิงเส้นที่คุณคุ้นเคย ใน R มันจะเป็นlmฟังก์ชั่น

หรือพอดีสองเส้นด้วยตา ใน R คุณจะใช้ablineทำสิ่งนี้

ข้อมูลกระเพื่อม, มีค่าผิดปกติ, และแยกออกจากกันในตอนท้าย, ด้วยตาเปล่ามีสองเส้นที่ชัดเจนพอสมควร, ดังนั้นฉันไม่แน่ใจว่าวิธีการที่มีค่านั้นจะคุ้มค่าหรือไม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.