/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you my 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.List;
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.HistogramPredictor;
/**
* 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 final String TAG = "Predictor";
private ModelChangeCallback modelChangeCallback = null;
private FeatureAssembly mFeatureAssembly = new FeatureAssembly();
public static final String SET_FEATURE = "SetFeature";
public static final String SET_PAIRED_FEATURES = "SetPairedFeatures";
public static final String FEATURE_SEPARATOR = ":";
public static final String USE_HISTORY = "UseHistory";
public static final String PREVIOUS_SAMPLE = "PreviousSample";
private boolean mUseHistory = false;
private long mHistorySpan = 0;
private String mPrevSample;
private long mPrevSampleTime;
// TODO: blacklist should be set outside Bordeaux service!
private static final String[] APP_BLACKLIST = {
"com.android.contacts",
"com.android.chrome",
"com.android.providers.downloads.ui",
"com.android.settings",
"com.android.vending",
"com.android.mms",
"com.google.android.gm",
"com.google.android.gallery3d",
"com.google.android.apps.googlevoice",
};
private HistogramPredictor mPredictor = new HistogramPredictor(APP_BLACKLIST);
/**
* Reset the Predictor
*/
public void resetPredictor(){
mPredictor.resetPredictor();
if (modelChangeCallback != null) {
modelChangeCallback.modelChanged(this);
}
}
/**
* 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) {
Map<String, String> sampleFeatures = getSampleFeatures();
Log.i(TAG, "pushNewSample " + sampleName + ": " + sampleFeatures);
// TODO: move to the end of the function?
mPrevSample = sampleName;
mPrevSampleTime = System.currentTimeMillis();
mPredictor.addSample(sampleName, sampleFeatures);
if (modelChangeCallback != null) {
modelChangeCallback.modelChanged(this);
}
}
private Map<String, String> getSampleFeatures() {
Map<String, String> sampleFeatures = mFeatureAssembly.getFeatureMap();
long currTime = System.currentTimeMillis();
if (mUseHistory && mPrevSample != null &&
((currTime - mPrevSampleTime) < mHistorySpan)) {
sampleFeatures.put(PREVIOUS_SAMPLE, mPrevSample);
}
return sampleFeatures;
}
// TODO: getTopK samples instead get scord for debugging only
/**
* return probabilty of an exmple using the histogram
*/
public List<StringFloat> getTopCandidates(int topK) {
Map<String, String> features = getSampleFeatures();
List<Map.Entry<String, Double> > topApps = mPredictor.findTopClasses(features, topK);
int listSize = topApps.size();
ArrayList<StringFloat> result = new ArrayList<StringFloat>(listSize);
for (int i = 0; i < listSize; ++i) {
Map.Entry<String, Double> entry = topApps.get(i);
result.add(new StringFloat(entry.getKey(), entry.getValue().floatValue()));
}
return result;
}
/**
* 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 key, String value) {
Log.i(TAG, "setParameter : " + key + ", " + value);
boolean result = true;
if (key.equals(SET_FEATURE)) {
result = mFeatureAssembly.registerFeature(value);
if (!result) {
Log.e(TAG,"Setting on feauture: " + value + " which is not available");
}
} else if (key.equals(SET_PAIRED_FEATURES)) {
String[] features = value.split(FEATURE_SEPARATOR);
result = mFeatureAssembly.registerFeaturePair(features);
if (!result) {
Log.e(TAG,"Setting feauture pair: " + value + " is not valid");
}
} else if (key.equals(USE_HISTORY)) {
mUseHistory = true;
mHistorySpan = Long.valueOf(value);
} else {
Log.e(TAG,"Setting parameter " + key + " with " + value + " is not valid");
}
return result;
}
// Beginning of the IBordeauxLearner Interface implementation
public byte [] getModel() {
return mPredictor.getModel();
}
public boolean setModel(final byte [] modelData) {
return mPredictor.setModel(modelData);
}
public IBinder getBinder() {
return this;
}
public void setModelChangeCallback(ModelChangeCallback callback) {
modelChangeCallback = callback;
}
// End of IBordeauxLearner Interface implemenation
}
|