charles-river-analytics / figaro

Figaro Programming Language and Core Libraries
Other
756 stars 151 forks source link

stateful sampling #749

Closed gfrison closed 5 years ago

gfrison commented 5 years ago

Hello,

I'm just taking a look to the framework for a possible adoption in a use case. Specifically, I need to do sampling over a Bayesian graph which brings states along inquiries. What I'm wondering is how Figaro can handle state machines for handling stateful messaging protocols. .observe() may impose a value over an element, but how can I actually keep track of specific parameters given by the environment when a sample is generated?

Thank you

AliOC commented 5 years ago

Hi Giancarlo,

I’m sorry, I don’t really understand your question. Are you saying that there are some environmental parameters that influence the generation of a sample? If so, it would make sense to include explicit variables in the model to represent the parameters and have those variables influence the other variables in the graph. Is this on the right track?

Thanks,

Avi

From: Giancarlo Frison notifications@github.com Reply-To: p2t2/figaro reply@reply.github.com Date: Wednesday, January 9, 2019 at 10:42 AM To: p2t2/figaro figaro@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: [p2t2/figaro] stateful sampling (#749)

Hello,

I'm just taking a look to the framework for a possible adoption in a use case. Specifically, I need to do sampling over a Bayesian graph which brings states along inquiries. What I'm wondering is how Figaro can handle state machines for handling stateful messaging protocols. .observe() may impose a value over an element, but how can I actually keep track of specific parameters given by the environment when a sample is generated?

Thank you

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/p2t2/figaro/issues/749, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AFJD0tpivEtbAcN9a__hdnLgHsii7IrJks5vBg3WgaJpZM4Z3vbe.

gfrison commented 5 years ago

Hello!

I would like to create a model in Figaro which take an input and returns an output based on probabilistic rules I implemented. This model should make inferences not only on the given input, but also previous inputs. I'm interested in sampling from a model, which reacts on a given input and its history. For example, let's take a share price in a stock market. I'd provide inputs like the return of investments on that company likewise any other information required, and the model will infer some prices as output. Some parameters would be affected by also past values of inputs, that's why I'm wondering how can I managed those entities in Figaro. You may say that's the realm of machine learning by using LSTM or RNN, but I want to create a hand-crafted model for that. Is that possible in Figaro? Could you please point me to an example? That would be great.

Thank you,

cadet354 commented 5 years ago

Is it modeling dynamic system? https://livebook.manning.com/#!/book/practical-probabilistic-programming/chapter-8/

apfeffer commented 5 years ago

Giancarlo,

As the other poster suggested, it sound like you want to build a dynamic model. There is a section on dynamic models in the tutorial, or you could read the chapter of my book that the other poster pointed to.

Thanks,

Avi

From: Giancarlo Frison notifications@github.com Reply-To: p2t2/figaro reply@reply.github.com Date: Monday, January 14, 2019 at 5:17 AM To: p2t2/figaro figaro@noreply.github.com Cc: Subscribed subscribed@noreply.github.com Subject: Re: [p2t2/figaro] stateful sampling (#749)

Hello!

I would like to create a model in Figaro which take an input and returns an output based on probabilistic rules I implemented. This model should make inferences not only on the given input, but also previous inputs. I'm interested in sampling from a model, which reacts on a given input and its history. For example, let's take a share price in a stock market. I'd provide inputs like the return of investments on that company likewise any other information required, and the model will infer some prices as output. Some parameters would be affected by also past values of inputs, that's why I'm wondering how can I managed those entities in Figaro. You may say that's the realm of machine learning by using LSTM or RNN, but I want to create a hand-crafted model for that. Is that possible in Figaro? Could you please point me to an example? That would be great.

Thank you,

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/p2t2/figaro/issues/749#issuecomment-453956121, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AFJkdx7L4Vj5BIClW8ii72CnMrYD9-A9ks5vDFlRgaJpZM4Z3vbe.

gfrison commented 5 years ago

Hello,

I tried with some dumb examples with ParticleFilter but I don't get the expected results. For example:

  val cpd = (action:Boolean)=>action match {
    case true => Flip(.9)
    case false => Flip(.1)
  }
  val transition = (prev: Universe) => {
    val act = prev.get[Boolean]("server")
    val curr = Universe.createNew()
    Chain(act, cpd)("client", curr)
    Apply(act, (actt: Boolean) => actt)("server", curr)
    curr
  }

  def main(args: Array[String]): Unit = {
    val initial = Universe.createNew()
    Uniform(true, false)("server", initial)
    Uniform(true, false)("client", initial)
    val pf = ParticleFilter(initial, transition, 100)
    pf.start()
    pf.advanceTime()
    println("probability client=true:" + pf.currentProbability("client", true))
    pf.advanceTime(List(NamedEvidence("server", Observation(true))))
    println("probability client=true after [true] observation:" + pf.currentProbability("client", true))
    pf.advanceTime(List(NamedEvidence("server", Observation(false))))
    println("probability client=true after [false] observation:" + pf.currentProbability("client", true))
    pf.kill()
  }

I get the following:

probability client=true:0.5
probability client=true after [true] observation:0.94
probability client=true after [false] observation:0.89

It seems that first observation is correctly set, but it misses the second one. I expect, by setting the "server" observation to false, to obtain a "client=true" probability close to 0.1, but it is not. What I am doing wrong? Could you please suggest me how to change variables in the universe?

Thank you,

gfrison commented 5 years ago

after few changes I got it running:

  val action2happy = (action: ServerAct) => action match {
    case ServerAct.veryCheap => Flip(.9)
    case _ => Flip(.1)
  }
  val happy2action: Boolean => Element[ServerAct] = (state: Boolean) => state match {
    case true => Constant(ServerAct.veryCheap)
    case _ => Uniform(ServerAct.values.filter(s => s != ServerAct.veryCheap): _*)
  }
  val transition = (prev: Universe) => {
    val act: Element[ServerAct] = prev.get[ServerAct]("stimulus")
    val curr = Universe.createNew()
    val nc: Element[Boolean] = Chain(act, action2happy)("happy", curr)
    Chain(nc, happy2action)("stimulus", curr)
    curr
  }

  def main(args: Array[String]): Unit = {
    val initial = Universe.createNew()
    Uniform(ServerAct.values: _*)("stimulus", initial)
    Uniform(true, false)("happy", initial)
    val pf = ParticleFilter(initial, transition, 100)
    pf.start()
    pf.advanceTime()
    println("probability happy=true:" + pf.currentProbability("happy", true))
    pf.advanceTime(List(NamedEvidence("stimulus", Observation(ServerAct.veryCheap))))
    println("probability happy=true after [veryCheap] stimulus: " + pf.currentProbability("happy", true))
    pf.advanceTime(List(NamedEvidence("stimulus", Observation(ServerAct.veryFast))))
    println("probability happy=true after [veryFast] stimulus: " + pf.currentProbability("happy", true))
    pf.kill()
  }

but... My purpose is to have a dynamic Bayesian network that react on external time-serie events. In this case to make it working (being happy after veryCheap event, and unhappy after veryFast) I have to counter-deducting the cause (the stimulus) from what actually I want in output ('happy'). How can I avoid the happy2action function, which set the stimulus according to what the stimulus has caused? It seems like a dog-tail chasing. I suppose I'm not using the proper paradigm for modelling an indefinitely sequence of time-serie events. What do you think?

apfeffer commented 5 years ago

Hi Giancarlo,

If you want the system to respond to an external signal, you need to create an explicit variable to model that signal and then set the value of the signal as evidence. To do this, you use NamedEvidence. The advanceTime method of ParticleFilter takes a NamedEvidence as argument.

Does this help?

Avi

From: Giancarlo Frison notifications@github.com Reply-To: p2t2/figaro reply@reply.github.com Date: Tuesday, February 5, 2019 at 5:10 AM To: p2t2/figaro figaro@noreply.github.com Cc: Avi Pfeffer apfeffer@cra.com, Comment comment@noreply.github.com Subject: Re: [p2t2/figaro] stateful sampling (#749)

after few changes I got it running:

val action2happy = (action: ServerAct) => action match {

case ServerAct.veryCheap => Flip(.9)

case _ => Flip(.1)

}

val happy2action: Boolean => Element[ServerAct] = (state: Boolean) => state match {

case true => Constant(ServerAct.veryCheap)

case _ => Uniform(ServerAct.values.filter(s => s != ServerAct.veryCheap): _*)

}

val transition = (prev: Universe) => {

val act: Element[ServerAct] = prev.get[ServerAct]("stimulus")

val curr = Universe.createNew()

val nc: Element[Boolean] = Chain(act, action2happy)("happy", curr)

Chain(nc, happy2action)("stimulus", curr)

curr

}

def main(args: Array[String]): Unit = {

val initial = Universe.createNew()

Uniform(ServerAct.values: _*)("stimulus", initial)

Uniform(true, false)("happy", initial)

val pf = ParticleFilter(initial, transition, 100)

pf.start()

pf.advanceTime()

println("probability happy=true:" + pf.currentProbability("happy", true))

pf.advanceTime(List(NamedEvidence("stimulus", Observation(ServerAct.veryCheap))))

println("probability happy=true after [veryCheap] stimulus: " + pf.currentProbability("happy", true))

pf.advanceTime(List(NamedEvidence("stimulus", Observation(ServerAct.veryFast))))

println("probability happy=true after [veryFast] stimulus: " + pf.currentProbability("happy", true))

pf.kill()

}

but... My purpose is to have a dynamic Bayesian network that react on external time-serie events. In this case to make it working (being happy after veryCheap event, and unhappy after veryFast) I have to counter-deducting the cause (the stimulus) from what actually I want in output ('happy'). How can I avoid the happy2action function, which set the stimulus according to what the stimulus has caused? It seems like a dog-tail chasing. I suppose I'm not using the proper paradigm for modelling an indefinitely sequence of time-serie events. What do you think?

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/p2t2/figaro/issues/749#issuecomment-460581483, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AFJkd4zY8j-8htWLqhoayXbk5qzChQiXks5vKViZgaJpZM4Z3vbe.

gfrison commented 5 years ago

if I set a named reference with advanceTime(List(NamedReference("x",...), I don't find in the Universe => Universe function when I invoke Universe.get("x"). Is there a way to get it through Universe.get?