14

유사한 프로젝트를 찾지 못했기 때문에 clojure에 베이지안 네트워크를 구축하고 싶습니다.Clojure DAG (베이지안 네트워크)

나는 BN에 관한 많은 이론을 연구했지만 여전히 네트워크 구현 방법을 볼 수 없다. (나는 사람들이 "전문가"라고 부르는 것이 아니라 기능 프로그래밍을위한 것이 아니다.).

나는 BN이 DAG와 많은 확률 테이블 (각 노드 당 하나)에 불과하다는 것을 알고 있지만, 이제 DAG를 구현하는 방법이 없다.

첫 번째 아이디어는 몇 개의 작은지도 (DAG 노드)가있는 거대한 세트 (DAG) 였고 모든지도에는 이름 (아마도 a : 키)이 있어야했습니다. 확률 테이블 (다른지도?) 부모 및 마침내 -descendant의 벡터.

이제 부모와 비상수 (두 벡터에 넣어야하는)의 참조를 구현하는 방법을 알지 못합니다. 포인터가 완벽해야하지만 clojure가 부족하다고 생각합니다. 벡터에 다른 노드의 이름을 넣을 수는 있지만 느려질 것입니다. 그렇습니까?

저는 벡터 대신에 더 많은 집합을 사용할 수 있다고 생각했습니다. 이렇게하면 노드의 자손을 더 빨리 찾을 수 있습니다.

다른 노드에서 여전히 참조가 필요한 확률 테이블과 비슷한 문제입니다.

마지막으로 나는 BN (데이터로 시작하는 네트워크 구축)을 배우고 싶습니다. 즉, 확률 테이블, 에지 및 노드 모두를으로 변경한다는 것을 의미합니다.

변경 가능한 유형을 사용해야합니까 아니면 복잡성을 증가시켜야합니까?

+0

[SO 질문] [1] 당신을 도울 수 있습니다. [1] : http : // stackoverflow.com/questions/3127890/clojure-or-scheme-bayesian-classification-libraries/3128224 # 3128224 – Ankur

+1

Chas Emerick은 베이지안 네트워크에 관한 이야기를하고 있습니다. (http://blip.tv/clojure/chas-emerick-modeling-the -world-probabilistically-using-bayesian-networks-in-clojure-5961126)에 ClojureConj를 주었다. 거기에 몇 가지 질문에 대답 할만한 유용한 정보가있었습니다. – jszakmeister

+0

... https://www.youtube.com/watch?v=xoSFcSqo1jQ – Thumbnail

답변

0

노드 맵에 의해 색인이 생성되는 여러 맵을 가질 수도 있습니다 : 하나는 확률 테이블, 하나는 부모 테이블, 다른 하나는 비 (非) 자손을위한 맵입니다. BN 전문가는 아닙니다. 어떻게 사용합니까? 부모 테이블에서 다시 계산할 수있는 것처럼 느껴진다.^W relation^W map).

1

완전한 대답은 아니지만 여기서는 wikipedia article의 예제 네트워크에 대한 인코딩이 가능합니다. 각 노드는 이름, 후계자 (어린이)의 목록과 확률 테이블이 있습니다 또한

(defn node [name children fn] 
    {:name name :children children :table fn}) 

을, 여기에 참/거짓 확률을 구축하기위한 작은 도우미 기능은 다음과 같습니다

;; builds a true/false probability map 
(defn tf [true-prob] #(if % true-prob (- 1.0 true-prob))) 

위의 함수가 반환은 true 값 (false 값)이 주어지면 X=true 이벤트의 확률을 반환합니다 (우리가 인코딩하는 X 확률 변수의 경우).

네트워크가 DAG이기 때문에 순환 참조를 신경 쓸 필요없이 노드를 서로 직접 참조 할 수 있습니다 (언급 한 포인터와 똑같이).

(let [gw (node "grass wet" [] (fn [& {:keys [sprinkler rain]}] 
          (tf (cond (and sprinkler rain) 0.99 
             sprinkler 0.9 
             rain 0.8 
             :else 0.0)))) 

    sk (node "sprinkler" [gw] 
      (fn [& {:keys [rain]}] (tf (if rain 0.01 0.4)))) 

    rn (node "rain" [sk gw] 
      (constantly (tf 0.2)))] 

    (def dag {:nodes {:grass-wet gw :sprinkler sk :rain rn} 
     :joint (fn [g s r] 
       (* 
        (((:table gw) :sprinkler s :rain r) g) 
        (((:table sk) :rain r) s) 
        (((:table rn)) r)))})) 

각 노드의 확률 테이블이 부모 노드의 상태의 함수로 주어진 및 truefalse 값에 대한 확률을 반환 : 우리는 단지 위상 순서로 그래프를 구축 할 수 있습니다.예를 들어,

((:table (:grass-wet dag)) :sprinkler true :rain false) 

은 ... {:true 0.9, :false 0.09999999999999998}를 반환합니다.

P(G,S,R) = P(G|S,R).P(S|R).P(R) 

그리고 ((:joint dag) true true true) 복귀 0.0019800000000000004 :

얻어진 조인트 함수는이 식에 따른 확률을 결합한다. 실제로 ((:table <x>) <args>)에 의해 반환 된 각 값은 확률 변수의 상태를 알고 확률을 반환하는 if 주변의 클로저입니다. 각각의 클로저를 각각의 true/false 값으로 호출하여 적절한 확률을 추출하고 곱합니다. 나는 관절 기능은 그래프를 통과하여 계산해야한다고 생각하기 때문에 여기에

, 나는 (매크로가 일반적인 경우에, 도움을 줄 수) 약간 부정하고있다. 이것은 또한 노드의 상태에 관해서는 좀 더 지저분한 것으로 느껴진다. 사실은 틀림없이 거짓 일 필요가 없다. 일반적으로 일반적인 경우 맵을 사용할 것이다. 일반적으로

1

는 BN의 공동 분포를 계산하는 방법은

prod(P(node | parents of node)) 

이를 실현하려, 각 노드가

  • 노드 이름
  • 을 포함 노드의 목록이 필요하다 부모 목록
  • 확률 표
  • 어린이 목록

확률 테이블 어쩌면 각 행의 값이 부모 구성에 대응하고, 각 열은 노드 값에 대응 될 때 평탄 처리하는 쉬운 것이다. 이것은 레코드를 사용하여 모든 값을 보유한다고 가정합니다. 노드의 값은 노드 내에 포함될 수도 있습니다.

부모가없는 노드는 행이 하나뿐입니다. 당신은 정말 아이의 목록이 필요하지만 쉽게 정렬 위상 만들 수있는 필요하지 않습니다 = 테이블 [행 안부]

|

각 행

는 P (부모 노드) 후 정상화해야한다. DAG는 토폴로지별로 정렬 할 수 있어야합니다.

가장 큰 문제는 확률 테이블에서 세포의 수가 발생은 부모와 자기의 모든 차원의 제품입니다. 행 매핑을 사용하는 스파 스 테이블을 사용하여 C++에서이 문제를 처리했습니다. DAG의 쿼리

다른 물질 및이를 수행하기위한 최선의 방법은, 크기에 의존하고 있는지 대략 응답이 충분하다. 여기서 그들을 감당할 여지가 충분하지 않습니다. 머피와 베이 즈 인터넷 도구 상자에 대한 검색

나는 약간의 작업으로, 당신은 자신의 롤 수 있으며, 특별히 구현을 찾고 실현하지만, 도움이 될 수 있습니다.

관련 문제