smile.feature.DateFeature Maven / Gradle / Ivy
The newest version!
/*******************************************************************************
* Copyright (c) 2010 Haifeng Li
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package smile.feature;
import java.util.Date;
import smile.data.Attribute;
import smile.data.DateAttribute;
import smile.data.NumericAttribute;
/**
* Date/time feature generator. A date attribute is usually represented by a
* long value that is the milliseconds since January 1, 1970, 00:00:00 GMT.
* Such a value is meaningless in data mining in general. One usually extract
* information such as year, month, day, etc. as features in further analysis.
*
* @author Haifeng Li
*/
public class DateFeature implements Feature {
/**
* The types of date/time features.
*/
public static enum Type {
/**
* The year represented by an integer.
*/
YEAR,
/**
* The month represented by an integer from 0 to 11;
* 0 is January, 1 is February, and so forth; thus 11 is December.
*/
MONTH,
/**
* The day of month represented by an integer from 1 to 31 in the usual
* manner.
*/
DAY_OF_MONTH,
/**
* The day of week represented by an integer from 0 to 6;
* 0 is Sunday, 1 is Monday, and so forth; thus 6 is Saturday.
*/
DAY_OF_WEEK,
/**
* The hours represented by an integer from 0 to 23. Thus, the hour
* from midnight to 1 a.m. is hour 0, and the hour from noon to 1 p.m.
* is hour 12.
*/
HOURS,
/**
* The minutes represented by an integer from 0 to 59 in the usual
* manner.
*/
MINUTES,
/**
* The seconds represented by an integer from 0 to 61; the values
* 60 and 61 occur only for leap seconds.
*/
SECONDS,
}
/**
* The variable attributes.
*/
private Attribute[] attributes;
/**
* The attributes of generated binary dummy variables.
*/
private Attribute[] features;
/**
* The types of features to be generated.
*/
private Type[] types;
/**
* A map from feature id to original attribute index.
*/
private int[] map;
/**
* Constructor.
* @param attributes the variable attributes.
* @param types the types of features to be generated.
*/
public DateFeature(Attribute[] attributes, Type[] types) {
this.attributes = attributes;
this.types = types;
int p = 0;
for (Attribute attribute : attributes) {
if (attribute instanceof DateAttribute) {
p += types.length;
}
}
features = new Attribute[p];
map = new int[p];
for (int i = 0, j = 0; j < attributes.length; j++) {
Attribute attribute = attributes[j];
if (attribute instanceof DateAttribute) {
DateAttribute date = (DateAttribute) attribute;
double weight = date.weight;
String name = date.name;
String description = date.description;
for (int k = 0; k < types.length; k++, i++) {
features[i] = new NumericAttribute(name + "_" + types[k], description, weight);
map[i] = j;
}
}
}
}
@Override
public Attribute[] attributes() {
return features;
}
@Override
@SuppressWarnings("deprecation")
public double f(double[] object, int id) {
if (object.length != attributes.length) {
throw new IllegalArgumentException(String.format("Invalide object size %d, expected %d", object.length, attributes.length));
}
if (id < 0 || id >= features.length) {
throw new IllegalArgumentException("Invalide feature id: " + id);
}
Date date = new Date(Double.doubleToLongBits(object[map[id]]));
Type t = types[id % types.length];
switch (t) {
case YEAR:
return 1900 + date.getYear();
case MONTH:
return date.getMonth();
case DAY_OF_MONTH:
return date.getDate();
case DAY_OF_WEEK:
return date.getDay();
case HOURS:
return date.getHours();
case MINUTES:
return date.getMinutes();
case SECONDS:
return date.getSeconds();
}
throw new IllegalStateException("Impossible to reach here.");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy