2011-10-20 21:41:38 +08:00
|
|
|
# Optimized inner loop of load_svmlight_file.
|
|
|
|
|
#
|
|
|
|
|
# Authors: Mathieu Blondel <mathieu@mblondel.org>
|
|
|
|
|
# Lars Buitinck <L.J.Buitinck@uva.nl>
|
|
|
|
|
# Olivier Grisel <olivier.grisel@ensta.org>
|
2013-04-30 14:23:46 +08:00
|
|
|
# License: BSD 3 clause
|
2011-10-20 21:41:38 +08:00
|
|
|
|
2014-01-06 04:30:25 +08:00
|
|
|
import array
|
|
|
|
|
from cpython cimport array
|
|
|
|
|
cimport cython
|
2011-10-20 21:41:38 +08:00
|
|
|
from libc.string cimport strchr
|
2014-01-06 04:30:25 +08:00
|
|
|
|
2011-10-20 21:41:38 +08:00
|
|
|
cimport numpy as np
|
|
|
|
|
import numpy as np
|
|
|
|
|
import scipy.sparse as sp
|
|
|
|
|
|
2013-03-19 07:33:07 +08:00
|
|
|
from ..externals.six import b
|
|
|
|
|
|
2013-01-08 01:33:04 +08:00
|
|
|
np.import_array()
|
|
|
|
|
|
2011-11-18 02:22:31 +08:00
|
|
|
|
2011-12-26 16:32:57 +08:00
|
|
|
cdef bytes COMMA = u','.encode('ascii')
|
|
|
|
|
cdef bytes COLON = u':'.encode('ascii')
|
|
|
|
|
|
|
|
|
|
|
2014-01-06 04:30:25 +08:00
|
|
|
@cython.boundscheck(False)
|
|
|
|
|
@cython.wraparound(False)
|
|
|
|
|
def _load_svmlight_file(f, dtype, bint multilabel, bint zero_based,
|
|
|
|
|
bint query_id):
|
|
|
|
|
cdef array.array data, indices, indptr, query
|
2011-10-20 21:41:38 +08:00
|
|
|
cdef bytes line
|
|
|
|
|
cdef char *hash_ptr, *line_cstr
|
2014-01-06 04:30:25 +08:00
|
|
|
cdef int idx, prev_idx
|
2012-09-15 20:24:02 +08:00
|
|
|
cdef Py_ssize_t i
|
2013-03-19 07:33:07 +08:00
|
|
|
cdef bytes qid_prefix = b('qid')
|
|
|
|
|
cdef Py_ssize_t n_features
|
2014-01-06 04:30:25 +08:00
|
|
|
|
|
|
|
|
# Special-case float32 but use float64 for everything else;
|
|
|
|
|
# the Python code will do further conversions.
|
|
|
|
|
if dtype == np.float32:
|
|
|
|
|
data = array.array("f")
|
|
|
|
|
else:
|
|
|
|
|
dtype = np.float64
|
|
|
|
|
data = array.array("d")
|
|
|
|
|
indices = array.array("i")
|
|
|
|
|
indptr = array.array("i", [0])
|
|
|
|
|
query = array.array("i")
|
|
|
|
|
|
2011-12-20 19:41:42 +08:00
|
|
|
if multilabel:
|
|
|
|
|
labels = []
|
|
|
|
|
else:
|
2014-01-06 04:30:25 +08:00
|
|
|
labels = array.array("d")
|
2011-10-20 21:41:38 +08:00
|
|
|
|
|
|
|
|
for line in f:
|
|
|
|
|
# skip comments
|
|
|
|
|
line_cstr = line
|
|
|
|
|
hash_ptr = strchr(line_cstr, '#')
|
2012-09-15 20:24:02 +08:00
|
|
|
if hash_ptr != NULL:
|
|
|
|
|
line = line[:hash_ptr - line_cstr]
|
2011-10-20 21:41:38 +08:00
|
|
|
|
|
|
|
|
line_parts = line.split()
|
|
|
|
|
if len(line_parts) == 0:
|
|
|
|
|
continue
|
|
|
|
|
|
2011-10-27 19:55:14 +08:00
|
|
|
target, features = line_parts[0], line_parts[1:]
|
|
|
|
|
if multilabel:
|
2015-04-10 13:16:43 +08:00
|
|
|
if COLON in target:
|
2015-04-09 21:59:10 +08:00
|
|
|
target, features = [], line_parts[0:]
|
|
|
|
|
else:
|
|
|
|
|
target = [float(y) for y in target.split(COMMA)]
|
2011-10-27 19:55:14 +08:00
|
|
|
target.sort()
|
|
|
|
|
labels.append(tuple(target))
|
|
|
|
|
else:
|
2014-01-06 04:30:25 +08:00
|
|
|
array.resize_smart(labels, len(labels) + 1)
|
|
|
|
|
labels[len(labels) - 1] = float(target)
|
2011-10-20 21:41:38 +08:00
|
|
|
|
2012-08-05 19:34:59 +08:00
|
|
|
prev_idx = -1
|
2012-09-26 18:07:25 +08:00
|
|
|
n_features = len(features)
|
2015-04-09 22:00:10 +08:00
|
|
|
if n_features and features[0].startswith(qid_prefix):
|
|
|
|
|
_, value = features[0].split(COLON, 1)
|
2012-09-28 17:19:01 +08:00
|
|
|
if query_id:
|
2014-01-06 04:30:25 +08:00
|
|
|
array.resize_smart(query, len(query) + 1)
|
|
|
|
|
query[len(query) - 1] = int(value)
|
2015-04-09 22:00:10 +08:00
|
|
|
features.pop(0)
|
2012-09-26 18:07:25 +08:00
|
|
|
n_features -= 1
|
|
|
|
|
|
2015-04-09 22:00:10 +08:00
|
|
|
for i in xrange(0, n_features):
|
|
|
|
|
idx_s, value = features[i].split(COLON, 1)
|
2012-09-15 20:24:02 +08:00
|
|
|
idx = int(idx_s)
|
2012-04-05 03:20:10 +08:00
|
|
|
if idx < 0 or not zero_based and idx == 0:
|
2011-12-21 00:17:31 +08:00
|
|
|
raise ValueError(
|
2012-08-05 19:34:59 +08:00
|
|
|
"Invalid index %d in SVMlight/LibSVM data file." % idx)
|
|
|
|
|
if idx <= prev_idx:
|
2013-03-19 07:33:07 +08:00
|
|
|
raise ValueError("Feature indices in SVMlight/LibSVM data "
|
2012-08-05 19:34:59 +08:00
|
|
|
"file should be sorted and unique.")
|
2011-10-20 21:41:38 +08:00
|
|
|
|
2014-01-06 04:30:25 +08:00
|
|
|
array.resize_smart(indices, len(indices) + 1)
|
|
|
|
|
indices[len(indices) - 1] = idx
|
2011-12-20 19:41:42 +08:00
|
|
|
|
2014-01-06 04:30:25 +08:00
|
|
|
array.resize_smart(data, len(data) + 1)
|
|
|
|
|
data[len(data) - 1] = float(value)
|
|
|
|
|
|
|
|
|
|
prev_idx = idx
|
2012-04-05 03:20:10 +08:00
|
|
|
|
2014-01-06 04:30:25 +08:00
|
|
|
array.resize_smart(indptr, len(indptr) + 1)
|
|
|
|
|
indptr[len(indptr) - 1] = len(data)
|
2012-09-28 17:19:01 +08:00
|
|
|
|
2014-01-06 04:30:25 +08:00
|
|
|
return (dtype, data, indices, indptr, labels, query)
|