Commits

Gary Chambers committed 1049f99

Added numerical and categorical feature classes.

  • Participants
  • Parent commits a86f9d3

Comments (0)

Files changed (3)

src/feature/category.js

+/**
+ * Categorical feature definition
+ *
+ * @class Category
+ * @param {String} key Feature name
+ * @param {Number} weight Weighting to apply to the feature
+ */
+kNN.feature.Category = (function( global, undefined )
+{
+	"use strict";
+
+	var Category;
+
+	Category = function Category( key, weight )
+	{
+		kNN.feature.Feature.call(this, key);
+		this.values = [];
+		this.weight = weight || 1.0;
+	};
+
+	kNN.util.inherit(Category, kNN.feature.Feature);
+
+	/**
+	 * Add category value to internal enum
+	 *
+	 * @method checkValue
+	 * @param {String} value Category label
+	 * @return {Undefined}
+	 */
+	Category.prototype.checkValue = function addValue( value )
+	{
+		var hasValue,
+			i;
+
+		hasValue = false;
+		i = this.values.length;
+
+		while( i-- )
+		{
+			if( this.values[i] === value )
+			{
+				hasValue = true;
+				break;
+			}
+		}
+
+		if( !hasValue )
+		{
+			this.values.push( value );
+		}
+	};
+
+	/**
+	 * Calculates a weighted distance between
+	 * two points for a particular dimension.
+	 * 
+	 * @param {Point} a
+	 * @param {Point} b
+	 * @return {Number}
+	 */
+	Category.prototype.calcDistance = function calcDistance( a, b )
+	{
+		return a.get( key ) === b.get( key ) ?
+			0 : this.weight / this.values.length;
+	};
+
+	return Category;
+})( this );

src/feature/init.js

+/**
+ * Abstract base class for model features.
+ * 
+ * @param {String} key Feature name
+ * @class Feature
+ */
+kNN.feature.Feature = (function( global, undefined )
+{
+	"use strict";
+
+	var Feature;
+
+	Feature = function Feature( key )
+	{
+		this.key = key;
+	};
+
+	/**
+	 * This must be implemented by a subclass,
+	 * or a NotImplementedError will be raised.
+	 * 
+	 * The subclass method will calculate the
+	 * distance between two points for a single
+	 * dimension.
+	 * 
+	 * @param  {Point} a
+	 * @param  {Point} b
+	 * @return {Undefined}
+	 */
+	Feature.prototype.calcDistance = function calcDistance( a, b )
+	{
+		throw {
+			name: "NotImplementedError",
+			message: "Feature#calcDistance must be implemented by a subclass"
+		};
+	};
+
+	return Feature;
+})( this );

src/feature/numerical.js

+/**
+ * Classification feature declaration
+ *
+ * @class Numerical
+ * @param {String} key Feature name
+ */
+kNN.feature.Numerical = (function( global, undefined )
+{
+	"use strict";
+
+	var Numerical;
+
+	Numerical = function Numerical( key )
+	{
+		kNN.feature.Feature.call(this, key);
+		this.minValue = Infinity;
+		this.maxValue = -Infinity;
+	};
+
+	kNN.util.inherit(Numerical, kNN.feature.Feature);
+
+	/**
+	 * Compares a value against feature min
+	 * and max values to determine range
+	 * for normalization
+	 *
+	 * @method checkValue
+	 * @param  {Number} value A numerical value
+	 * @return {Undefined}
+	 */
+	Numerical.prototype.checkValue = function checkValue( value )
+	{
+		if( value < this.minValue )
+		{
+			this.minValue = value;
+		}
+
+		if( value > this.maxValue )
+		{
+			this.maxValue = value;
+		}
+	};
+
+	/**
+	 * Get delta between min and max values
+	 * 
+	 * @method getRange
+	 * @return {Number}
+	 */
+	Numerical.prototype.getRange = function getRange()
+	{
+		return this.maxValue - this.minValue;
+	};
+
+	/**
+	 * Calculates the distance between two
+	 * points for a particular dimension.
+	 *
+	 * The distance is normalised for an
+	 * output value between 0.0 and 1.0
+	 * 
+	 * @param {Point} a
+	 * @param {Point} b
+	 * @return {Number}
+	 */
+	Numerical.prototype.calcDistance = function calcDistance( a, b )
+	{
+		return (a.get( this.key ) - b.get( this.key )) / this.getRange();
+	};
+
+	return Numerical;
+})( this );