| package com.yahoo.labs.samoa.learners.classifiers.trees; |
| |
| /* |
| * #%L |
| * SAMOA |
| * %% |
| * Copyright (C) 2013 Yahoo! Inc. |
| * %% |
| * 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. |
| * #L% |
| */ |
| |
| import com.esotericsoftware.kryo.Kryo; |
| import com.esotericsoftware.kryo.Serializer; |
| import com.esotericsoftware.kryo.io.Input; |
| import com.esotericsoftware.kryo.io.Output; |
| |
| import com.yahoo.labs.samoa.core.ContentEvent; |
| |
| /** |
| * Attribute Content Event represents the instances that split vertically based on their attribute |
| * |
| * @author Arinto Murdopo |
| * |
| */ |
| public final class AttributeContentEvent implements ContentEvent { |
| |
| private static final long serialVersionUID = 6652815649846676832L; |
| |
| private final long learningNodeId; |
| private final int obsIndex; |
| private final double attrVal; |
| private final int classVal; |
| private final double weight; |
| private final transient String key; |
| private final boolean isNominal; |
| |
| public AttributeContentEvent() { |
| learningNodeId = -1; |
| obsIndex = -1; |
| attrVal = 0.0; |
| classVal = -1; |
| weight = 0.0; |
| key = ""; |
| isNominal = true; |
| } |
| |
| private AttributeContentEvent(Builder builder) { |
| this.learningNodeId = builder.learningNodeId; |
| this.obsIndex = builder.obsIndex; |
| this.attrVal = builder.attrVal; |
| this.classVal = builder.classVal; |
| this.weight = builder.weight; |
| this.isNominal = builder.isNominal; |
| this.key = builder.key; |
| } |
| |
| @Override |
| public String getKey() { |
| return this.key; |
| } |
| |
| @Override |
| public void setKey(String str) { |
| // do nothing, maybe useful when we want to reuse the object for |
| // serialization/deserialization purpose |
| } |
| |
| @Override |
| public boolean isLastEvent() { |
| return false; |
| } |
| |
| long getLearningNodeId() { |
| return this.learningNodeId; |
| } |
| |
| int getObsIndex() { |
| return this.obsIndex; |
| } |
| |
| int getClassVal() { |
| return this.classVal; |
| } |
| |
| double getAttrVal() { |
| return this.attrVal; |
| } |
| |
| double getWeight() { |
| return this.weight; |
| } |
| |
| boolean isNominal() { |
| return this.isNominal; |
| } |
| |
| static final class Builder { |
| |
| // required parameters |
| private final long learningNodeId; |
| private final int obsIndex; |
| private final String key; |
| |
| // optional parameters |
| private double attrVal = 0.0; |
| private int classVal = 0; |
| private double weight = 0.0; |
| private boolean isNominal = false; |
| |
| Builder(long id, int obsIndex, String key) { |
| this.learningNodeId = id; |
| this.obsIndex = obsIndex; |
| this.key = key; |
| } |
| |
| private Builder(long id, int obsIndex) { |
| this.learningNodeId = id; |
| this.obsIndex = obsIndex; |
| this.key = ""; |
| } |
| |
| Builder attrValue(double val) { |
| this.attrVal = val; |
| return this; |
| } |
| |
| Builder classValue(int val) { |
| this.classVal = val; |
| return this; |
| } |
| |
| Builder weight(double val) { |
| this.weight = val; |
| return this; |
| } |
| |
| Builder isNominal(boolean val) { |
| this.isNominal = val; |
| return this; |
| } |
| |
| AttributeContentEvent build() { |
| return new AttributeContentEvent(this); |
| } |
| } |
| |
| /** |
| * The Kryo serializer class for AttributeContentEvent when executing on top of Storm. This class allow us to change |
| * the precision of the statistics. |
| * |
| * @author Arinto Murdopo |
| * |
| */ |
| public static final class AttributeCESerializer extends Serializer<AttributeContentEvent> { |
| |
| private static double PRECISION = 1000000.0; |
| |
| @Override |
| public void write(Kryo kryo, Output output, AttributeContentEvent event) { |
| output.writeLong(event.learningNodeId, true); |
| output.writeInt(event.obsIndex, true); |
| output.writeDouble(event.attrVal, PRECISION, true); |
| output.writeInt(event.classVal, true); |
| output.writeDouble(event.weight, PRECISION, true); |
| output.writeBoolean(event.isNominal); |
| } |
| |
| @Override |
| public AttributeContentEvent read(Kryo kryo, Input input, |
| Class<AttributeContentEvent> type) { |
| AttributeContentEvent ace = new AttributeContentEvent.Builder(input.readLong(true), input.readInt(true)) |
| .attrValue(input.readDouble(PRECISION, true)) |
| .classValue(input.readInt(true)) |
| .weight(input.readDouble(PRECISION, true)) |
| .isNominal(input.readBoolean()) |
| .build(); |
| return ace; |
| } |
| } |
| |
| /** |
| * The Kryo serializer class for AttributeContentEvent when executing on top of Storm with full precision of the |
| * statistics. |
| * |
| * @author Arinto Murdopo |
| * |
| */ |
| public static final class AttributeCEFullPrecSerializer extends Serializer<AttributeContentEvent> { |
| |
| @Override |
| public void write(Kryo kryo, Output output, AttributeContentEvent event) { |
| output.writeLong(event.learningNodeId, true); |
| output.writeInt(event.obsIndex, true); |
| output.writeDouble(event.attrVal); |
| output.writeInt(event.classVal, true); |
| output.writeDouble(event.weight); |
| output.writeBoolean(event.isNominal); |
| } |
| |
| @Override |
| public AttributeContentEvent read(Kryo kryo, Input input, |
| Class<AttributeContentEvent> type) { |
| AttributeContentEvent ace = new AttributeContentEvent.Builder(input.readLong(true), input.readInt(true)) |
| .attrValue(input.readDouble()) |
| .classValue(input.readInt(true)) |
| .weight(input.readDouble()) |
| .isNominal(input.readBoolean()) |
| .build(); |
| return ace; |
| } |
| |
| } |
| } |