7

I think the question is clear enough. I want to make a hidden Markov model in Python and draw a vizualization model of it. So, it's something like this picture:

model

Is there any module to do that? I've googled it and found nothing.

Community
  • 1
  • 1
user2435611
  • 1,093
  • 1
  • 12
  • 18
  • I never tried this, but I think you should look for graph visualization tools, as an HMM is a directed graph ! you can give a try at networkx for instance http://networkx.github.io/documentation/latest/examples/drawing/index.html. – bendaizer May 31 '13 at 08:25
  • with networkx, are the nodes placed randomly? – user2435611 Jun 04 '13 at 13:41
  • you can specify positions through a dictionary, like in this example : http://networkx.github.io/documentation/latest/examples/drawing/house_with_colors.html – bendaizer Jun 04 '13 at 13:50

3 Answers3

2

The dot package from graphviz is the best I've found. The syntax is simple, simpler than xml.

Charles Pehlivanian
  • 2,083
  • 17
  • 25
0

Though I've never worked with Hidden Markov Models, when I need to visualize a graph (directed, with labels, colors, etc.), I use Gephi, a GUI graph browser/editor and generate the graphs programmatically as GraphML files, which is an XML-based format. Python has good XML-handling tools (in the standard library and lxml). Gephi recognizes some of the <data> sub-elements as positions, colors, and labels for nodes and edges.

Jim Pivarski
  • 5,568
  • 2
  • 35
  • 47
  • Looks like a great software. Could you recommend me a good tutorial to start with? Actually, I'm looking a python module or wrapper to visualize HMM directly from the code because I want to generate it by code. But if there isn't any, I think Gephi is okay. – user2435611 Jun 02 '13 at 16:45
  • For an all-programmatic approach, perhaps you could output to SVG? That would require you to define the placement of the nodes and edges on your own. In this answer: http://stackoverflow.com/questions/16858482/how-to-use-python-to-generate-a-magazine-cover/16867833#16867833 I described a method to build up SVG image-making algorithms in Python. – Jim Pivarski Jun 03 '13 at 14:18
  • rsvg and pysvg, which one is better? – user2435611 Jun 07 '13 at 11:26
  • They do diffent things. rsvg renders SVG (as shown in the example I link to in my previous comment), but pysvg is an XML handling tool that has been specialized for SVG. If you use pysvg to make a graphic, you'll still need something like rsvg (or Inkscape, or a web browser) to view it. Personally, I don't see much point in pysvg--- ElementTree and lxml both make it easy to build up XML documents, and the semantics of SVG are high-level enough to not need an additional layer, unless it were specialized for a particular type of graphic (e.g. Markov model graphs). – Jim Pivarski Jun 07 '13 at 18:19
  • Do you know a good tutorial for rsvg? Just a simple one sufficent enough for creating a HMM visualization. Thanks. :) – user2435611 Jun 08 '13 at 18:50
  • I've never needed to know a lot about rsvg, the renderer. My link above shows everything I've ever done with it--- sending SVG strings to be visualized. In fact, I often don't use rsvg at all and just open the SVG files in a web browser or Preview. For learning how to use SVG itself, I usually read the W3C specification directly--- it's full of examples. http://www.w3.org/TR/SVG/ That, and Google searches. I don't know of a good tutorial, but it's not hard. (You'll mostly be using , , , and markers for the arrow-heads.) – Jim Pivarski Jun 09 '13 at 14:18
0

The Python library pomegranate has good support for Hidden Markov Models. It includes functionality for defining such models, learning it from data, doing inference, and visualizing the transitions graph (as you request here).

Below is example code for defining a model, and plotting the states and transitions. The image output will be like this:

enter image description here

from pomegranate import HiddenMarkovModel, State, DiscreteDistribution
from matplotlib import pyplot as plt

def build_model():

    d1 = DiscreteDistribution({'A' : 0.50, 'B' : 0.50})
    d2 = DiscreteDistribution({'A' : 0.10, 'B' : 0.90})
    d3 = DiscreteDistribution({'A' : 0.90, 'B' : 0.10})

    s1 = State(d1, name="s1")
    s2 = State(d2, name="s2")
    s3 = State(d3, name="s3")

    model = HiddenMarkovModel(name='my model')
    model.add_states(s1, s2, s3)
    model.add_transition(model.start, s1, 1.0)
    model.add_transition(s1, s1, 0.7)
    model.add_transition(s1, s2, 0.3) # s1->s2
    model.add_transition(s2, s2, 0.8)
    
    model.add_transition(s2, s3, 0.0) # no transition from s2 to s3
    model.add_transition(s1, s3, 0.1) # indirect from s1 to s3
    model.add_transition(s3, s1, 0.1) # indirect from s3 to s1
    
    model.add_transition(s3, s3, 0.9)
    model.add_transition(s3, model.end, 0.1)
    model.start.name = 'start'
    model.end.name = 'end'
    model.bake()

    return model

model = build_model()
fig, ax = plt.subplots(1)
model.plot(ax=ax, precision=2)
fig.savefig('model.png')
Jon Nordby
  • 5,494
  • 1
  • 21
  • 50