EM অ্যালগরিদম ম্যানুয়ালি প্রয়োগ করা হয়েছে


20

আমি ই.এম. অ্যালগরিদম নিজে বাস্তবায়ন এবং তারপর ফলাফল এটি তুলনা করতে চান normalmixEMএর mixtoolsপ্যাকেজ। অবশ্যই, যদি তারা উভয়ই একই ফলাফলের দিকে পরিচালিত করে তবে আমি খুশি হব। প্রধান রেফারেন্স হলেন জিওফ্রে ম্যাকল্যাচলান (2000), ফিনিট মিকচার মডেল

আমার দুটি গৌসিয়ানের মিশ্রণ ঘনত্ব রয়েছে, সাধারণ আকারে, লগ-সম্ভাবনা দেওয়া হয় (ম্যাকল্যাচলান পৃষ্ঠা 48):

logLc(Ψ)=i=1gj=1nzij{logπi+logfi(yi;θi)}.
হয় , যদি পর্যবেক্ষণ থেকে ছিল তম উপাদান ঘনত্ব, অন্যথায় । সাধারন বন্টনের ঘনত্ব হয়। , মিশ্রণ অনুপাত, তাই সম্ভাব্যতা হল যে, একটি পর্যবেক্ষণ প্রথম গসিয়ান বন্টন পক্ষ থেকে হয় এবং সম্ভাব্যতা হল যে, একটি পর্যবেক্ষণ দ্বিতীয় গসিয়ান বন্টন থেকে।zij1i0fiππ1π2

ধাপ এখন শর্তসাপেক্ষ প্রত্যাশা হিসাব হল:

Q(Ψ;Ψ(0))=EΨ(0){logLc(|Ψ)|y}.
যা ফলাফল থেকে কিছু ব্যয় ছড়িয়ে পরে (পৃষ্ঠা 49):

τi(yj;Ψ(k))=πi(k)fi(yj;θi(k)f(yj;Ψ(k)=πi(k)fi(yj;θi(k)h=1gπh(k)fh(yj;θh(k))
দুটি গাউসিয়ার ক্ষেত্রে (পৃষ্ঠা )২):

τi(yj;Ψ)=πiϕ(yj;μi,Σi)h=1gπhϕ(yj;μh,Σh)
এম পদক্ষেপ এখন প্রশ্ন (পৃষ্ঠা 49) এর বৃহদায়ন হল:

Q(Ψ;Ψ(k))=i=1gj=1nτi(yj;Ψ(k)){logπi+logfi(yj;θi)}.
এর ফলে (দুটি গাউসিয়ার ক্ষেত্রে) (পৃষ্ঠা ৮২):

μi(k+1)=j=1nτij(k)yjj=1nτij(k)Σi(k+1)=j=1nτij(k)(yjμi(k+1))(yjμi(k+1))Tj=1nτij(k)
এবং আমরা জানি যে (পৃষ্ঠা 50)

πi(k+1)=j=1nτi(yj;Ψ(k))n(i=1,,g).
L(Ψ(k+1))L(Ψ(k)) ছোট না হওয়া পর্যন্ত আমরা E, M পদক্ষেপগুলি পুনরায় বলি

আমি একটি আর কোড লেখার চেষ্টা করেছি (ডেটা এখানে পাওয়া যাবে )।

# EM algorithm manually
# dat is the data

# initial values
pi1       <-  0.5
pi2       <-  0.5
mu1       <- -0.01
mu2       <-  0.01
sigma1    <-  0.01
sigma2    <-  0.02
loglik[1] <-  0
loglik[2] <- sum(pi1*(log(pi1) + log(dnorm(dat,mu1,sigma1)))) + 
             sum(pi2*(log(pi2) + log(dnorm(dat,mu2,sigma2))))

tau1 <- 0
tau2 <- 0
k    <- 1

# loop
while(abs(loglik[k+1]-loglik[k]) >= 0.00001) {

  # E step
  tau1 <- pi1*dnorm(dat,mean=mu1,sd=sigma1)/(pi1*dnorm(x,mean=mu1,sd=sigma1) + 
          pi2*dnorm(dat,mean=mu2,sd=sigma2))
  tau2 <- pi2*dnorm(dat,mean=mu2,sd=sigma2)/(pi1*dnorm(x,mean=mu1,sd=sigma1) + 
          pi2*dnorm(dat,mean=mu2,sd=sigma2))

  # M step
  pi1 <- sum(tau1)/length(dat)
  pi2 <- sum(tau2)/length(dat)

  mu1 <- sum(tau1*x)/sum(tau1)
  mu2 <- sum(tau2*x)/sum(tau2)

  sigma1 <- sum(tau1*(x-mu1)^2)/sum(tau1)
  sigma2 <- sum(tau2*(x-mu2)^2)/sum(tau2)

  loglik[k] <- sum(tau1*(log(pi1) + log(dnorm(x,mu1,sigma1)))) + 
               sum(tau2*(log(pi2) + log(dnorm(x,mu2,sigma2))))
  k         <- k+1
}


# compare
library(mixtools)
gm <- normalmixEM(x, k=2, lambda=c(0.5,0.5), mu=c(-0.01,0.01), sigma=c(0.01,0.02))
gm$lambda
gm$mu
gm$sigma

gm$loglik

অ্যালগরিদম কাজ করছে না, যেহেতু কিছু পর্যবেক্ষণে শূন্য হওয়ার সম্ভাবনা রয়েছে এবং এটির লগইন -Inf। আমার ভুল কোথায়?


সমস্যাটি কোনও পরিসংখ্যানের নয়, বরং একটি সংখ্যাসূচক। আপনার কোডে মেশিনের যথার্থতার চেয়ে কম সম্ভাবনার জন্য আপনার জরুরী অবস্থা যুক্ত করা উচিত।
জনরোস

আপনি কেন খুব সাধারণ উদাহরণ দিয়ে মিক্সটোলস ফাংশনটি কেন খুব সহজেই চেষ্টা করে দেখেন না যা হাত দ্বারা যাচাই করা যায়, প্রথমে কেবল পাঁচ বা দশটি মান এবং দুটি টাইমসারি বলুন। তারপরে, যদি আপনি এটি সেখানে কাজ করে দেখতে পান তবে আপনার কোডটি সাধারণীকরণ করুন এবং প্রতিটি পদক্ষেপে যাচাই করুন।

উত্তর:


17

উত্স কোডে আপনার বেশ কয়েকটি সমস্যা রয়েছে:

  1. @ প্যাট যেমন উল্লেখ করেছেন, আপনার লগ (ডনরম ()) ব্যবহার করা উচিত নয় কারণ এই মানটি অনন্ততায় যেতে পারে। আপনার logmvdnorm ব্যবহার করা উচিত

  2. আপনি যখন যোগফল ব্যবহার করেন , অসীম বা অনুপস্থিত মানগুলি সরাতে সচেতন হন

  3. আপনি ভেরিয়েবল কে লুপিং ভুল, আপনার লগলিক আপডেট করা উচিত [k + 1] তবে আপনি লগলিক আপডেট করেন [কে]

  4. আপনার পদ্ধতি এবং মিক্সটোলগুলির প্রাথমিক মানগুলি পৃথক। আপনি ব্যবহার করছেন আপনার পদ্ধতিতে, কিন্তু ব্যবহার mixtools জন্য (অর্থাত স্ট্যানডার্ড ডেভিয়েশন ম্যানুয়াল mixtools থেকে)।σΣσ

  5. আপনার ডেটা সাধারণ মিশ্রণের মতো দেখায় না (হিস্টোগ্রামটি আমি শেষে প্লট করেছি) দেখুন। এবং মিশ্রণের একটি উপাদানটির খুব ছোট এসডি রয়েছে, তাই আমি নির্বিচারে কিছু চরম নমুনার জন্য সমান হতে এবং সেট করতে একটি লাইন যুক্ত করেছি । কোডটি কাজ করতে পারে তা নিশ্চিত করার জন্য আমি এগুলি যুক্ত করি।τ 2τ1τ2

আমি আপনাকেও আপনার উত্স কোডে সম্পূর্ণ কোডগুলি (যেমন আপনি লগলিক []] প্রবর্তন করার এবং কোডটি সহজেই পড়তে সহজ করার জন্য কোডটি যুক্ত করার পরামর্শ দিচ্ছি।

সর্বোপরি, মিক্সটোল প্যাকেজ প্রবর্তনের জন্য ধন্যবাদ , এবং আমি এগুলি আমার ভবিষ্যতের গবেষণায় ব্যবহার করার পরিকল্পনা করছি।

আমি আপনার রেফারেন্সের জন্য আমার ওয়ার্কিং কোডটিও রেখেছি:

# EM algorithm manually
# dat is the data
setwd("~/Downloads/")
load("datem.Rdata")
x <- dat

# initial values
pi1<-0.5
pi2<-0.5
mu1<--0.01
mu2<-0.01
sigma1<-sqrt(0.01)
sigma2<-sqrt(0.02)
loglik<- rep(NA, 1000)
loglik[1]<-0
loglik[2]<-mysum(pi1*(log(pi1)+log(dnorm(dat,mu1,sigma1))))+mysum(pi2*(log(pi2)+log(dnorm(dat,mu2,sigma2))))

mysum <- function(x) {
  sum(x[is.finite(x)])
}
logdnorm <- function(x, mu, sigma) {
  mysum(sapply(x, function(x) {logdmvnorm(x, mu, sigma)}))  
}
tau1<-0
tau2<-0
#k<-1
k<-2

# loop
while(abs(loglik[k]-loglik[k-1]) >= 0.00001) {
  # E step
  tau1<-pi1*dnorm(dat,mean=mu1,sd=sigma1)/(pi1*dnorm(x,mean=mu1,sd=sigma1)+pi2*dnorm(dat,mean=mu2,sd=sigma2))
  tau2<-pi2*dnorm(dat,mean=mu2,sd=sigma2)/(pi1*dnorm(x,mean=mu1,sd=sigma1)+pi2*dnorm(dat,mean=mu2,sd=sigma2))
  tau1[is.na(tau1)] <- 0.5
  tau2[is.na(tau2)] <- 0.5

  # M step
  pi1<-mysum(tau1)/length(dat)
  pi2<-mysum(tau2)/length(dat)

  mu1<-mysum(tau1*x)/mysum(tau1)
  mu2<-mysum(tau2*x)/mysum(tau2)

  sigma1<-mysum(tau1*(x-mu1)^2)/mysum(tau1)
  sigma2<-mysum(tau2*(x-mu2)^2)/mysum(tau2)

  #  loglik[k]<-sum(tau1*(log(pi1)+log(dnorm(x,mu1,sigma1))))+sum(tau2*(log(pi2)+log(dnorm(x,mu2,sigma2))))
  loglik[k+1]<-mysum(tau1*(log(pi1)+logdnorm(x,mu1,sigma1)))+mysum(tau2*(log(pi2)+logdnorm(x,mu2,sigma2)))
  k<-k+1
}

# compare
library(mixtools)
gm<-normalmixEM(x,k=2,lambda=c(0.5,0.5),mu=c(-0.01,0.01),sigma=c(0.01,0.02))
gm$lambda
	gm$mu
gm$sigma

gm$loglik

Historgram বারলেখ


@ জহএনএক্সডাব্লু আপনার উত্তরটির জন্য ধন্যবাদ, তাই এর অর্থ কি আমার কোডটি ভুল? তাহলে বেসি আইডিয়া কাজ করছে না?
স্ট্যাটিস্টিস্টিয়ান

"আমি আপনাকেও আপনার উত্স কোডে সম্পূর্ণ কোড (যেমন আপনি লগলিক []] প্রবর্তন করার এবং কোডটি সহজেই পড়তে সহজ করার জন্য কোডটি প্রবেশ করার পরামর্শ দিচ্ছি।" আচ্ছা এটা কি আমার কোড? লগলিকটি [] আমি পোস্ট করা কোডে এটি ঘোষিত হিসাবে সংজ্ঞায়িত হয়?
স্ট্যাটিস্টিস্টিয়ান

1
@ স্ট্যাটটিস্টিয়ান ধারণাটি সঠিক, তবে বাস্তবায়নের ত্রুটি রয়েছে। উদাহরণস্বরূপ, আপনি নিম্ন-প্রবাহকে বিবেচনা করেননি। এছাড়াও, আপনি লুপিং ভেরিয়েবল কে বিভ্রান্ত করছেন, আপনি প্রথমে লগলিক সেট করেছেন [1] এবং লগলিক [2], যখন লুপটি প্রবেশ করার পরে আপনি আবার লগলিক সেট করেছেন [1]। এটি করার প্রাকৃতিক উপায় নয়। লগলিক শুরু করার বিষয়ে আমার পরামর্শ [] এর অর্থ কোড loklik <- rep(NA, 100):, এটি লগলিককে প্রাক-বরাদ্দ করবে [1], লগলিক [2] ... লগলিক [100]। আমি এই প্রশ্নটি উত্থাপন করেছি কারণ আপনার মূল কোডটিতে, আমি লগলিকের সঞ্চারিতা পাইনি, সম্ভবত কোডটি আটকানোর সময় কাটা হয়েছে?
zhanxw

যেমন আমি নীচে পোস্ট করেছি: আপনার সহায়তার জন্য ধন্যবাদ, তবে আমি এই বিষয়টি বাদ দিচ্ছি, কারণ এটি আমার পক্ষে অনেক উন্নত।
স্ট্যাটিস্টিস্টিয়ান

ডেটার কোন অংশটি কোন মিশ্রণের সাথে সম্পর্কিত তা নির্ধারণের এখন উপায় আছে?
কার্ডিনাল

2

আপনার .রার ফাইলটি খোলার চেষ্টা করার সময় আমি একটি ত্রুটি পেতে থাকি, তবে এটি কেবল নির্বোধ কিছু করা হতে পারে।

আমি আপনার কোডটিতে কোনও স্পষ্ট ত্রুটি দেখতে পাচ্ছি না। ভাসমান পয়েন্ট যথার্থতার কারণে আপনি জিরো পাচ্ছেন এমন একটি সম্ভাব্য কারণ। মনে রাখবেন, যখন আপনি গণনা করেন , আপনি মূল্যায়ন করছেনf(y;θ)exp(0.5(yμ)2/σ2)μyτ যখন আপনি লগের সম্ভাবনাটি মূল্যায়ন করেন, সমস্যার মুখোমুখি হন - তবে ভাসমান বিন্দু ত্রুটির জন্য, পরিমাণটি ইতিমধ্যে এই পর্যায়ে -Inf হিসাবে মূল্যায়ন করা হয়েছে, সুতরাং এটি সমস্ত বিরতি :)।

যদি সমস্যা হয় তবে কয়েকটি সম্ভাব্য সমাধান রয়েছে:

τ

τlog(f(y|θ))

মূল্যায়ন

log(f(y|θ)τ)

f(y|θ)τ0

  • 0log(0)=0(Inf)=NaN

তবে তাউ দিয়ে আপনি পেলেন

  • log(00)=log(1)=0

00=1

আরেকটি সমাধান হ'ল লগারিদমের ভিতরে জিনিসগুলি প্রসারিত করা। ধরে নেওয়া যাক আপনি প্রাকৃতিক লোগারিদম ব্যবহার করছেন:

τlog(f(y|θ))

=τlog(exp(0.5(yμ)2/σ2)/2πσ2)

=0.5τlog(2πσ2)0.5τ(yμ)2σ2

গাণিতিকভাবে একই, তবে আপনি কোনও বৃহত্তর নেতিবাচক শক্তির গণনা এড়ানোর কারণে ভাসমান পয়েন্টের ত্রুটিগুলির প্রতি আরও স্থিতিশীল হওয়া উচিত। এর অর্থ আপনি বিল্ট ইন আদর্শ মূল্যায়ন ফাংশনটি আর ব্যবহার করতে পারবেন না, তবে এটি যদি সমস্যা না হয় তবে এটি সম্ভবত এটির চেয়ে ভাল উত্তর। উদাহরণস্বরূপ, ধরা যাক আমাদের যেখানে পরিস্থিতি রয়েছে

0.5(yμ)2σ2=0.5402=800

log(exp(800))=log(0)=Inf


mh, সত্যি বলতে: আমি এই জিনিস কাজ করতে যথেষ্ট ভাল না। আমি যা সম্পর্কে আগ্রহী তা হ'ল: আমি কি আমার অ্যালগরিদমের সাথে একই ফলটি মিক্সটোলস প্যাকেজের বাস্তবায়িত সংস্করণ হিসাবে পেতে পারি? তবে আমার দৃষ্টিকোণ থেকে মনে হয় এটি চাঁদ চাইছে। তবে আমি মনে করি আপনি নিজের উত্তরটি চেষ্টা করেছেন, তাই আমি এটি গ্রহণ করব! ধন্যবাদ!
স্ট্যাটিস্টিস্টিয়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.