/* * Copyright (C) 2012 The Android Open Source Project * * 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 android.bordeaux.services; import android.os.IBinder; import android.util.Log; import java.util.HashMap; import java.util.ArrayList; import java.util.Map; import java.util.HashSet; import java.util.Iterator; import java.io.Serializable; import java.io.*; import java.lang.Boolean; import android.bordeaux.services.FeatureAssembly; import android.bordeaux.learning.predictorHist; /** * This is interface to implement Prediction based on histogram that * uses predictor_histogram from learnerning section */ public class Predictor extends IPredictor.Stub implements IBordeauxLearner { private ModelChangeCallback modelChangeCallback = null; private final String TAG = "Predictor"; private final String SET_EXPIRE_TIME = "SetExpireTime"; private final String USE_HISTORY = "Use History"; private final String SET_FEATURE = "Set Feature"; private long mExpireTime = 3 * 60; private long mLastSampleTime = 0; private boolean mUseHistoryFlag = false; private final String NEW_START = "New Start"; static public class Model implements Serializable { public HashMap<String, Integer> countHistogram = new HashMap<String, Integer>(); public HashSet<String> usedFeatures = new HashSet<String>(); public int sampleCounts; public boolean useHistoryFlag; public long expireTime; public long lastSampleTime; } private predictorHist mPredictorHist = new predictorHist(); private String mLastSample = NEW_START; public FeatureAssembly mFeatureAssembly = new FeatureAssembly(); /** * Reset the Predictor */ public void ResetPredictor(){ printModel(getPredictionModel()); mPredictorHist.ResetPredictorHist(); mUseHistoryFlag = false; mLastSampleTime = 0; mLastSample = NEW_START; mFeatureAssembly = new FeatureAssembly(); printModel(getPredictionModel()); if (modelChangeCallback != null) { modelChangeCallback.modelChanged(this); } } /** * Augment input string with buildin features such as time, location */ private String buildDataPoint(String sampleName) { String fs = mFeatureAssembly.augmentFeatureInputString(sampleName); if (mUseHistoryFlag) { if (((System.currentTimeMillis()- mLastSampleTime)/1000) > mExpireTime) { mLastSample = NEW_START; } fs = fs + "+" + mLastSample; } return fs; } /** * Input is a sampleName e.g.action name. This input is then augmented with requested build-in * features such as time and location to create sampleFeatures. The sampleFeatures is then * pushed to the histogram */ public void pushNewSample(String sampleName) { String sampleFeatures = buildDataPoint(sampleName); mLastSample = sampleName; mLastSampleTime = System.currentTimeMillis(); mPredictorHist.pushSample(sampleFeatures); if (modelChangeCallback != null) { modelChangeCallback.modelChanged(this); } //printModel(getPredictionModel()); } /** * return probabilty of an exmple using the histogram */ public float getSampleProbability(String sampleName) { String sampleFeatures = buildDataPoint(sampleName); return mPredictorHist.getProbability(sampleFeatures); } /** * Set parameters for 1) using History in probability estimations e.g. consider the last event * and 2) featureAssembly e.g. time and location. */ public boolean setPredictorParameter(String s, String f) { boolean res = false; if (s.equals(USE_HISTORY)) { if (f.equals("true")){ mUseHistoryFlag = true; res = true; } else if (f.equals("false")) { mUseHistoryFlag = false; res = true; } } else if (s.equals(SET_EXPIRE_TIME)) { mExpireTime = Long.valueOf(f); res = true; } else if (s.equals(SET_FEATURE)) { res = mFeatureAssembly.registerFeature(f); } if (!res) Log.e(TAG,"Setting parameter " + s + " with " + f + " is not valid"); return res; } public Model getPredictionModel() { Model m = new Model(); m.countHistogram.putAll(mPredictorHist.getHist()); m.sampleCounts = mPredictorHist.getHistCounts(); m.expireTime = mExpireTime; m.usedFeatures = (HashSet) mFeatureAssembly.getUsedFeatures(); m.useHistoryFlag = mUseHistoryFlag; m.lastSampleTime = mLastSampleTime; return m; } public boolean loadModel(Model m) { //Log.i(TAG,"on loadModel"); //printModel(m); mPredictorHist = new predictorHist(); mPredictorHist.set(m.countHistogram); mExpireTime = m.expireTime; mUseHistoryFlag = m.useHistoryFlag; mLastSampleTime = m.lastSampleTime; mFeatureAssembly = new FeatureAssembly(); boolean res = false; Iterator itr = m.usedFeatures.iterator(); while(itr.hasNext()) { res = res & mFeatureAssembly.registerFeature((String) itr.next()); } return res; } public void printModel(Model m) { Log.i(TAG,"histogram is : " + m.countHistogram.toString()); Log.i(TAG,"number of counts in histogram is : " + m.sampleCounts); Log.i(TAG,"ExpireTime time is : " + m.expireTime); Log.i(TAG,"useHistoryFlag is : " + m.useHistoryFlag); Log.i(TAG,"used features are : " + m.usedFeatures.toString()); } // Beginning of the IBordeauxLearner Interface implementation public byte [] getModel() { Model model = getPredictionModel(); //Log.i(TAG,"on getModel"); printModel(model); try { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); ObjectOutputStream objStream = new ObjectOutputStream(byteStream); objStream.writeObject(model); byte[] bytes = byteStream.toByteArray(); //Log.i(TAG, "getModel: " + bytes); return bytes; } catch (IOException e) { throw new RuntimeException("Can't get model"); } } public boolean setModel(final byte [] modelData) { //Log.i(TAG,"on setModel"); try { ByteArrayInputStream input = new ByteArrayInputStream(modelData); ObjectInputStream objStream = new ObjectInputStream(input); Model model = (Model) objStream.readObject(); boolean res = loadModel(model); //Log.i(TAG, "LoadModel: " + modelData); return res; } catch (IOException e) { throw new RuntimeException("Can't load model"); } catch (ClassNotFoundException e) { throw new RuntimeException("Learning class not found"); } } public IBinder getBinder() { return this; } public void setModelChangeCallback(ModelChangeCallback callback) { modelChangeCallback = callback; } // End of IBordeauxLearner Interface implemenation }