Skip to content

Commit

Permalink
python/bllipparser: Add Tree.visualize_nltk()
Browse files Browse the repository at this point in the history
Moved NLTK tree reading and import_maybe to Utility
  • Loading branch information
dmcc committed Aug 30, 2015
1 parent b3658be commit e3cc257
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 25 deletions.
31 changes: 6 additions & 25 deletions python/bllipparser/ParsingShell.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,16 @@
trees will be shown if you have the asciitree package."""
import sys
from cmd import Cmd
import importlib
from os.path import exists

from .RerankingParser import RerankingParser
from .ModelFetcher import list_models

def import_maybe(module_name):
"Import a module and return it if available, otherwise returns None."
try:
return importlib.import_module(module_name)
except ImportError:
return None

try:
import nltk.tree
import nltk.draw.tree
read_nltk_tree = nltk.tree.Tree.parse
have_nltk_tree_drawing = True
except ImportError:
have_nltk_tree_drawing = False
except AttributeError: # handle NLTK API changes
try:
read_nltk_tree = nltk.tree.Tree.fromstring
have_nltk_tree_drawing = True
except AttributeError:
have_nltk_tree_drawing = False
from .Utility import import_maybe, get_nltk_tree_reader_maybe

StanfordDependencies = import_maybe('StanfordDependencies')
asciitree = import_maybe('asciitree')
nltk = import_maybe('nltk')
read_nltk_tree = get_nltk_tree_reader_maybe()

class ParsingShell(Cmd):
def __init__(self, model_dir):
Expand All @@ -68,7 +49,7 @@ def __init__(self, model_dir):

def get_rrp(self, model_dir):
if model_dir is None:
print "Warning: no parsing model specified."
print "Error: no parsing model specified."
print "Specify with: python -mbllipparser /path/to/model/"
print "Or one of these to download and install:"
list_models()
Expand Down Expand Up @@ -105,7 +86,7 @@ def get_rrp(self, model_dir):
def do_visual(self, text):
"""Use reranking parser to parse text. Visualize top parses from
parser and reranker."""
if not have_nltk_tree_drawing:
if not read_nltk_tree:
print "Can't visualize without NLTK installation."
return

Expand Down Expand Up @@ -153,7 +134,7 @@ def do_visualnbest(self, text):
"""Usage: visualnbest [start] stop
Visualizes all parses from start-stop in the n-best list.
Sentence must already be parsed."""
if not have_nltk_tree_drawing:
if not read_nltk_tree:
print "Can't visualize without NLTK installation."
return

Expand Down
12 changes: 12 additions & 0 deletions python/bllipparser/RerankingParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ def dependencies(self):
yield (head, subhead)
else:
tree_to_heads[tree.span()] = tree
def visualize_nltk(self):

This comment has been minimized.

Copy link
@dmcc

dmcc Sep 3, 2015

Author Member

Hmm, in retrospect, I think this should probably just be visualize(self). If other visualization methods appear (could also do asciitree), we can distinguish between them using a new argument (maybe mode='nltk'). Also, this needs a docstring.

from .Utility import get_nltk_tree_reader_maybe
read_nltk_tree = get_nltk_tree_reader_maybe()
if not read_nltk_tree:
raise ValueError("Unable to import nltk tree reading.")
nltk_tree = read_nltk_tree(str(self))
import nltk
nltk.draw.tree.draw_trees(nltk_tree)

#
# properties
Expand Down Expand Up @@ -245,6 +253,10 @@ def sd_tokens(self, sd_converter=None, conversion_kwargs=None):
**conversion_kwargs)
return self._sd_tokens

#
# readers
#

@classmethod
def trees_from_string(this_class, text):
"""Given text containing multiple Penn Treebank trees, returns
Expand Down
24 changes: 24 additions & 0 deletions python/bllipparser/Utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# under the License.

import math
import importlib

# now part of waterworks.Tools
class DeprecatedGetter:
Expand All @@ -37,6 +38,29 @@ def __call__(self, *args, **kwargs):
DeprecationWarning, stacklevel=2)
return self.__value

def import_maybe(module_name):
"Import a module and return it if available, otherwise returns None."
try:
return importlib.import_module(module_name)
except ImportError:
return None

def get_nltk_tree_reader_maybe():
"""Attempts to find the NLTK tree reader for various versions of NLTK.
Returns False if it fails or a function which takes a string and
returns an NLTK tree object otherwise."""
try:
import nltk.tree
import nltk.draw.tree
return nltk.tree.Tree.parse
except ImportError:
return False
except AttributeError: # handle NLTK API changes
try:
return nltk.tree.Tree.fromstring
except AttributeError:
return False

def normalize_logprobs(logprobs, exponent=1):
"""Sum probs stored as log probs in a (more) numerically stable
fashion, see:
Expand Down

0 comments on commit e3cc257

Please sign in to comment.