1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.bordeaux.services; 18 19import android.os.IBinder; 20import android.util.Log; 21import java.util.HashMap; 22import java.util.ArrayList; 23import java.util.Map; 24import java.util.HashSet; 25import java.util.Iterator; 26import java.io.Serializable; 27import java.io.*; 28import java.lang.Boolean; 29import android.bordeaux.services.FeatureAssembly; 30import android.bordeaux.learning.predictorHist; 31 32/** 33 * This is interface to implement Prediction based on histogram that 34 * uses predictor_histogram from learnerning section 35 */ 36public class Predictor extends IPredictor.Stub 37 implements IBordeauxLearner { 38 private ModelChangeCallback modelChangeCallback = null; 39 private final String TAG = "Predictor"; 40 private final String SET_EXPIRE_TIME = "SetExpireTime"; 41 private final String USE_HISTORY = "Use History"; 42 private final String SET_FEATURE = "Set Feature"; 43 private long mExpireTime = 3 * 60; 44 private long mLastSampleTime = 0; 45 private boolean mUseHistoryFlag = false; 46 private final String NEW_START = "New Start"; 47 48 static public class Model implements Serializable { 49 public HashMap<String, Integer> countHistogram = new HashMap<String, Integer>(); 50 public HashSet<String> usedFeatures = new HashSet<String>(); 51 public int sampleCounts; 52 public boolean useHistoryFlag; 53 public long expireTime; 54 public long lastSampleTime; 55 } 56 57 private predictorHist mPredictorHist = new predictorHist(); 58 private String mLastSample = NEW_START; 59 public FeatureAssembly mFeatureAssembly = new FeatureAssembly(); 60 61 /** 62 * Reset the Predictor 63 */ 64 public void ResetPredictor(){ 65 printModel(getPredictionModel()); 66 mPredictorHist.ResetPredictorHist(); 67 mUseHistoryFlag = false; 68 mLastSampleTime = 0; 69 mLastSample = NEW_START; 70 mFeatureAssembly = new FeatureAssembly(); 71 printModel(getPredictionModel()); 72 if (modelChangeCallback != null) { 73 modelChangeCallback.modelChanged(this); 74 } 75 } 76 77 /** 78 * Augment input string with buildin features such as time, location 79 */ 80 private String buildDataPoint(String sampleName) { 81 String fs = mFeatureAssembly.augmentFeatureInputString(sampleName); 82 if (mUseHistoryFlag) { 83 if (((System.currentTimeMillis()- mLastSampleTime)/1000) > mExpireTime) { 84 mLastSample = NEW_START; 85 } 86 fs = fs + "+" + mLastSample; 87 } 88 return fs; 89 } 90 91 /** 92 * Input is a sampleName e.g.action name. This input is then augmented with requested build-in 93 * features such as time and location to create sampleFeatures. The sampleFeatures is then 94 * pushed to the histogram 95 */ 96 public void pushNewSample(String sampleName) { 97 String sampleFeatures = buildDataPoint(sampleName); 98 mLastSample = sampleName; 99 mLastSampleTime = System.currentTimeMillis(); 100 mPredictorHist.pushSample(sampleFeatures); 101 if (modelChangeCallback != null) { 102 modelChangeCallback.modelChanged(this); 103 } 104 //printModel(getPredictionModel()); 105 } 106 107 /** 108 * return probabilty of an exmple using the histogram 109 */ 110 public float getSampleProbability(String sampleName) { 111 String sampleFeatures = buildDataPoint(sampleName); 112 return mPredictorHist.getProbability(sampleFeatures); 113 } 114 115 /** 116 * Set parameters for 1) using History in probability estimations e.g. consider the last event 117 * and 2) featureAssembly e.g. time and location. 118 */ 119 public boolean setPredictorParameter(String s, String f) { 120 boolean res = false; 121 if (s.equals(USE_HISTORY)) { 122 if (f.equals("true")){ 123 mUseHistoryFlag = true; 124 res = true; 125 } 126 else if (f.equals("false")) { 127 mUseHistoryFlag = false; 128 res = true; 129 } 130 } else if (s.equals(SET_EXPIRE_TIME)) { 131 mExpireTime = Long.valueOf(f); 132 res = true; 133 } else if (s.equals(SET_FEATURE)) { 134 res = mFeatureAssembly.registerFeature(f); 135 } 136 if (!res) 137 Log.e(TAG,"Setting parameter " + s + " with " + f + " is not valid"); 138 return res; 139 } 140 141 public Model getPredictionModel() { 142 Model m = new Model(); 143 m.countHistogram.putAll(mPredictorHist.getHist()); 144 m.sampleCounts = mPredictorHist.getHistCounts(); 145 m.expireTime = mExpireTime; 146 m.usedFeatures = (HashSet) mFeatureAssembly.getUsedFeatures(); 147 m.useHistoryFlag = mUseHistoryFlag; 148 m.lastSampleTime = mLastSampleTime; 149 return m; 150 } 151 152 public boolean loadModel(Model m) { 153 //Log.i(TAG,"on loadModel"); 154 //printModel(m); 155 mPredictorHist = new predictorHist(); 156 mPredictorHist.set(m.countHistogram); 157 mExpireTime = m.expireTime; 158 mUseHistoryFlag = m.useHistoryFlag; 159 mLastSampleTime = m.lastSampleTime; 160 mFeatureAssembly = new FeatureAssembly(); 161 boolean res = false; 162 Iterator itr = m.usedFeatures.iterator(); 163 while(itr.hasNext()) { 164 res = res & mFeatureAssembly.registerFeature((String) itr.next()); 165 } 166 return res; 167 } 168 169 public void printModel(Model m) { 170 Log.i(TAG,"histogram is : " + m.countHistogram.toString()); 171 Log.i(TAG,"number of counts in histogram is : " + m.sampleCounts); 172 Log.i(TAG,"ExpireTime time is : " + m.expireTime); 173 Log.i(TAG,"useHistoryFlag is : " + m.useHistoryFlag); 174 Log.i(TAG,"used features are : " + m.usedFeatures.toString()); 175 } 176 177 // Beginning of the IBordeauxLearner Interface implementation 178 public byte [] getModel() { 179 Model model = getPredictionModel(); 180 //Log.i(TAG,"on getModel"); 181 printModel(model); 182 try { 183 ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 184 ObjectOutputStream objStream = new ObjectOutputStream(byteStream); 185 objStream.writeObject(model); 186 byte[] bytes = byteStream.toByteArray(); 187 //Log.i(TAG, "getModel: " + bytes); 188 return bytes; 189 } catch (IOException e) { 190 throw new RuntimeException("Can't get model"); 191 } 192 } 193 194 public boolean setModel(final byte [] modelData) { 195 //Log.i(TAG,"on setModel"); 196 try { 197 ByteArrayInputStream input = new ByteArrayInputStream(modelData); 198 ObjectInputStream objStream = new ObjectInputStream(input); 199 Model model = (Model) objStream.readObject(); 200 boolean res = loadModel(model); 201 //Log.i(TAG, "LoadModel: " + modelData); 202 return res; 203 } catch (IOException e) { 204 throw new RuntimeException("Can't load model"); 205 } catch (ClassNotFoundException e) { 206 throw new RuntimeException("Learning class not found"); 207 } 208 } 209 210 public IBinder getBinder() { 211 return this; 212 } 213 214 public void setModelChangeCallback(ModelChangeCallback callback) { 215 modelChangeCallback = callback; 216 } 217 // End of IBordeauxLearner Interface implemenation 218} 219