/* * JNI_SVM-light - A Java Native Interface for SVM-light * * Copyright (C) 2005 * Tom Crecelius & Martin Theobald * Max-Planck Institute for Computer Science * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package jnisvmlight; /** * A feature vector. Features are dimension-value pairs. This class implements a * simple dictionary data structure to map dimensions onto their values. Note * that for convenience, features do not have be sorted according to their * dimensions at this point. The SVMLightTrainer class has an option for sorting * input vectors prior to training. * * @author Tom Crecelius & Martin Theobald */ public class FeatureVector implements java.io.Serializable { protected int[] m_dims; protected double m_factor; protected double[] m_vals; public FeatureVector(double factor, int[] dims, double[] vals) { this.m_factor = factor; this.m_dims = dims; this.m_vals = vals; } public FeatureVector(int size) { this.m_factor = 1.0; this.m_dims = new int[size]; this.m_vals = new double[size]; } public FeatureVector(int[] dims, double[] vals) { this.m_factor = 1.0; this.m_dims = dims; this.m_vals = vals; } /** * Returns the cosine similarity between two feature vectors. */ public double getCosine(FeatureVector v) { double cosine = 0.0; int dim; double q_i, d_i; for (int i = 0; i < Math.min(this.size(), v.size()); i++) { dim = v.getDimAt(i); q_i = v.getValueAt(dim); d_i = this.getValueAt(dim); cosine += q_i * d_i; } return cosine / (this.getL2Norm() * v.getL2Norm()); } public int getDimAt(int index) { return m_dims[index]; } public double getFactor() { return m_factor; } /** * Returns the linear norm factor of this vector's values (i.e., the sum of * it's values). */ public double getL1Norm() { double sum = 0.0; for (int i = 0; i < m_vals.length; i++) { sum += m_vals[i]; } return sum; } /** * Returns the L2 norm factor of this vector's values. */ public double getL2Norm() { double square_sum = 0.0; for (int i = 0; i < m_vals.length; i++) { square_sum += (m_vals[i] * m_vals[i]); } return Math.sqrt(square_sum); } public double getValueAt(int index) { return m_vals[index]; } /** * Performs a linear normalization to the value 1. */ public void normalizeL1() { normalizeL1(getL1Norm()); } /** * Performs a linear normalization to the given norm value. */ public void normalizeL1(double norm) { for (int i = 0; i < m_vals.length; i++) { if (m_vals[i] > 0) { m_vals[i] /= norm; } } } /** * Performs an L2 normalization to the value 1. */ public void normalizeL2() { double norm = Math.pow(getL2Norm(), 2); for (int i = 0; i < m_vals.length; i++) { m_vals[i] = Math.pow(m_vals[i], 2) / norm; } } public void setFactor(double factor) { this.m_factor = factor; } public void setFeatures(int[] dims, double[] vals) { this.m_dims = dims; this.m_vals = vals; } public int size() { return m_dims.length; } public String toString() { String s = ""; for (int i = 0; i < m_vals.length; i++) { s += "" + m_dims[i] + ":" + m_vals[i] + "" + (i < m_vals.length - 1 ? " " : ""); } return s; } }