From: guestwalk Date: Mon, 21 Jan 2013 18:03:19 +0000 (+0000) Subject: Modify Python interface, major changes are: X-Git-Tag: v193~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=77c267a05addffc7640d35662ed581e96e62b988;p=liblinear Modify Python interface, major changes are: + Find local library first. + Change show() to __str__. --- diff --git a/python/README b/python/README index 40fe87d..1c7094c 100644 --- a/python/README +++ b/python/README @@ -118,6 +118,10 @@ LIBLINEAR shared library: val: a float indicates the feature value. + Show the index and the value of a node. + + >>> print(node) + - Function: gen_feature_nodearray(xi [,feature_max=None [,issparse=True]]) Generate a feature vector from a Python list/tuple or a dictionary: @@ -173,7 +177,7 @@ LIBLINEAR shared library: Show values of parameters. - >>> param.show() + >>> print(param) - class model: diff --git a/python/liblinear.py b/python/liblinear.py index 506f118..8db2b88 100644 --- a/python/liblinear.py +++ b/python/liblinear.py @@ -2,21 +2,23 @@ from ctypes import * from ctypes.util import find_library +from os import path import sys -import os -# For unix the prefix 'lib' is not considered. -if find_library('linear'): - liblinear = CDLL(find_library('linear')) -elif find_library('liblinear'): - liblinear = CDLL(find_library('liblinear')) -else: +try: + dirname = path.dirname(path.abspath(__file__)) if sys.platform == 'win32': - liblinear = CDLL(os.path.join(os.path.dirname(__file__),\ - '../windows/liblinear.dll')) + liblinear = CDLL(path.join(dirname, r'..\windows\liblinear.dll')) + else: + liblinear = CDLL(path.join(dirname, '../liblinear.so.1')) +except: +# For unix the prefix 'lib' is not considered. + if find_library('linear'): + liblinear = CDLL(find_library('linear')) + elif find_library('liblinear'): + liblinear = CDLL(find_library('liblinear')) else: - liblinear = CDLL(os.path.join(os.path.dirname(__file__),\ - '../liblinear.so.1')) + raise Exception('LIBLINEAR library not found.') # Construct constants SOLVER_TYPE = ['L2R_LR', 'L2R_L2LOSS_SVC_DUAL', 'L2R_L2LOSS_SVC', 'L2R_L1LOSS_SVC_DUAL',\ @@ -42,6 +44,9 @@ class feature_node(Structure): _types = [c_int, c_double] _fields_ = genFields(_names, _types) + def __str__(self): + return '%d:%g' % (self.index, self.value) + def gen_feature_nodearray(xi, feature_max=None, issparse=True): if isinstance(xi, dict): index_range = xi.keys() @@ -121,11 +126,15 @@ class parameter(Structure): options = '' self.parse_options(options) - def show(self): - attrs = parameter._names + self.__dict__.keys() + def __str__(self): + s = '' + attrs = parameter._names + list(self.__dict__.keys()) values = map(lambda attr: getattr(self, attr), attrs) for attr, val in zip(attrs, values): - print(' %s: %s' % (attr, val)) + s += (' %s: %s\n' % (attr, val)) + s = s.strip() + + return s def set_to_default_values(self): self.solver_type = L2R_L2LOSS_SVC_DUAL @@ -141,7 +150,12 @@ class parameter(Structure): self.print_func = None def parse_options(self, options): - argv = options.split() + if isinstance(options, list): + argv = options + elif isinstance(options, str): + argv = options.split() + else: + raise TypeError("arg 1 should be a list or a str.") self.set_to_default_values() self.print_func = cast(None, PRINT_STRING_FUN) weight_label = [] @@ -261,5 +275,3 @@ fillprototype(liblinear.destroy_param, None, [POINTER(parameter)]) fillprototype(liblinear.check_parameter, c_char_p, [POINTER(problem), POINTER(parameter)]) fillprototype(liblinear.check_probability_model, c_int, [POINTER(model)]) fillprototype(liblinear.set_print_string_function, None, [CFUNCTYPE(None, c_char_p)]) - - diff --git a/python/liblinearutil.py b/python/liblinearutil.py index 1940abe..d63e088 100644 --- a/python/liblinearutil.py +++ b/python/liblinearutil.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +import os, sys +sys.path = [os.path.dirname(os.path.abspath(__file__))] + sys.path from liblinear import * def svm_read_problem(data_file_name): @@ -76,8 +78,8 @@ def evaluations(ty, pv): def train(arg1, arg2=None, arg3=None): """ - train(y, x [, 'options']) -> model | ACC - train(prob, [, 'options']) -> model | ACC + train(y, x [, options]) -> model | ACC + train(prob [, options]) -> model | ACC train(prob, param) -> model | ACC Train a model from data (y, x) or a problem prob using @@ -85,7 +87,7 @@ def train(arg1, arg2=None, arg3=None): If '-v' is specified in 'options' (i.e., cross validation) either accuracy (ACC) or mean-squared error (MSE) is returned. - 'options': + options: -s type : set type of solver (default 1) for multi-class classification 0 -- L2-regularized logistic regression (primal) @@ -158,16 +160,14 @@ def train(arg1, arg2=None, arg3=None): m = liblinear.train(prob, param) m = toPyModel(m) - # If prob is destroyed, data including SVs pointed by m can remain. - m.x_space = prob.x_space return m def predict(y, x, m, options=""): """ - predict(y, x, m [, "options"]) -> (p_labels, p_acc, p_vals) + predict(y, x, m [, options]) -> (p_labels, p_acc, p_vals) Predict data (y, x) with the SVM model m. - "options": + options: -b probability_estimates: whether to output probability estimates, 0 or 1 (default 0); currently for logistic regression only -q quiet mode (no outputs)