1984e52f31d596840cfa51b1238e1c43d2e1918f8saberian/* 2984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * Copyright (C) 2012 The Android Open Source Project 3984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * 4984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * Licensed under the Apache License, Version 2.0 (the "License"); 5f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin * you my not use this file except in compliance with the License. 6984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * You may obtain a copy of the License at 7984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * 8984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * http://www.apache.org/licenses/LICENSE-2.0 9984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * 10984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * Unless required by applicable law or agreed to in writing, software 11984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * distributed under the License is distributed on an "AS IS" BASIS, 12984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * See the License for the specific language governing permissions and 14984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * limitations under the License. 15984e52f31d596840cfa51b1238e1c43d2e1918f8saberian */ 16984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 17984e52f31d596840cfa51b1238e1c43d2e1918f8saberianpackage android.bordeaux.services; 18984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 19984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport android.os.IBinder; 20984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport android.util.Log; 21984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.util.HashMap; 22984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.util.ArrayList; 23f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Linimport java.util.List; 24984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.util.Map; 25984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.util.HashSet; 26984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.util.Iterator; 27984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.io.Serializable; 28984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.io.*; 29984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport java.lang.Boolean; 30984e52f31d596840cfa51b1238e1c43d2e1918f8saberianimport android.bordeaux.services.FeatureAssembly; 31f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Linimport android.bordeaux.learning.HistogramPredictor; 32984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 33984e52f31d596840cfa51b1238e1c43d2e1918f8saberian/** 34984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * This is interface to implement Prediction based on histogram that 35984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * uses predictor_histogram from learnerning section 36984e52f31d596840cfa51b1238e1c43d2e1918f8saberian */ 37984e52f31d596840cfa51b1238e1c43d2e1918f8saberianpublic class Predictor extends IPredictor.Stub 38984e52f31d596840cfa51b1238e1c43d2e1918f8saberian implements IBordeauxLearner { 39984e52f31d596840cfa51b1238e1c43d2e1918f8saberian private final String TAG = "Predictor"; 40f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin private ModelChangeCallback modelChangeCallback = null; 41f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin 42f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin private FeatureAssembly mFeatureAssembly = new FeatureAssembly(); 43f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin 4447c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin public static final String SET_FEATURE = "SetFeature"; 4547c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin public static final String SET_PAIRED_FEATURES = "SetPairedFeatures"; 4647c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin public static final String FEATURE_SEPARATOR = ":"; 4747c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin public static final String USE_HISTORY = "UseHistory"; 4847c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin public static final String PREVIOUS_SAMPLE = "PreviousSample"; 49c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin 50c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin private boolean mUseHistory = false; 51c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin private long mHistorySpan = 0; 52c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin private String mPrevSample; 53c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin private long mPrevSampleTime; 54984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 5547c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin // TODO: blacklist should be set outside Bordeaux service! 5647c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin private static final String[] APP_BLACKLIST = { 5747c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.android.contacts", 5847c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.android.chrome", 5947c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.android.providers.downloads.ui", 6047c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.android.settings", 6147c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.android.vending", 6247c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.android.mms", 6347c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.google.android.gm", 6447c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.google.android.gallery3d", 6547c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin "com.google.android.apps.googlevoice", 6647c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin }; 6747c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin 6847c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin private HistogramPredictor mPredictor = new HistogramPredictor(APP_BLACKLIST); 6947c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin 7047c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin 71984e52f31d596840cfa51b1238e1c43d2e1918f8saberian /** 72984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * Reset the Predictor 73984e52f31d596840cfa51b1238e1c43d2e1918f8saberian */ 74f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin public void resetPredictor(){ 75f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin mPredictor.resetPredictor(); 76f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin 77984e52f31d596840cfa51b1238e1c43d2e1918f8saberian if (modelChangeCallback != null) { 78984e52f31d596840cfa51b1238e1c43d2e1918f8saberian modelChangeCallback.modelChanged(this); 79984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 80984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 81984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 82984e52f31d596840cfa51b1238e1c43d2e1918f8saberian /** 83984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * Input is a sampleName e.g.action name. This input is then augmented with requested build-in 84984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * features such as time and location to create sampleFeatures. The sampleFeatures is then 85984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * pushed to the histogram 86984e52f31d596840cfa51b1238e1c43d2e1918f8saberian */ 87984e52f31d596840cfa51b1238e1c43d2e1918f8saberian public void pushNewSample(String sampleName) { 88c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin Map<String, String> sampleFeatures = getSampleFeatures(); 8947c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin Log.i(TAG, "pushNewSample " + sampleName + ": " + sampleFeatures); 90f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin 91c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin // TODO: move to the end of the function? 92c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin mPrevSample = sampleName; 93c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin mPrevSampleTime = System.currentTimeMillis(); 94c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin 95f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin mPredictor.addSample(sampleName, sampleFeatures); 96984e52f31d596840cfa51b1238e1c43d2e1918f8saberian if (modelChangeCallback != null) { 97984e52f31d596840cfa51b1238e1c43d2e1918f8saberian modelChangeCallback.modelChanged(this); 98984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 99984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 100984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 101c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin private Map<String, String> getSampleFeatures() { 102c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin Map<String, String> sampleFeatures = mFeatureAssembly.getFeatureMap(); 103c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin long currTime = System.currentTimeMillis(); 104c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin 105c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin if (mUseHistory && mPrevSample != null && 106c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin ((currTime - mPrevSampleTime) < mHistorySpan)) { 107c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin sampleFeatures.put(PREVIOUS_SAMPLE, mPrevSample); 108c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin } 109c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin 110c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin return sampleFeatures; 111c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin } 112f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin 113f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin // TODO: getTopK samples instead get scord for debugging only 114984e52f31d596840cfa51b1238e1c43d2e1918f8saberian /** 115984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * return probabilty of an exmple using the histogram 116984e52f31d596840cfa51b1238e1c43d2e1918f8saberian */ 117f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin public List<StringFloat> getTopCandidates(int topK) { 118c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin Map<String, String> features = getSampleFeatures(); 119f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin List<Map.Entry<String, Double> > topApps = mPredictor.findTopClasses(features, topK); 120f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin 121f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin int listSize = topApps.size(); 12247c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin ArrayList<StringFloat> result = new ArrayList<StringFloat>(listSize); 123f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin for (int i = 0; i < listSize; ++i) { 124f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin Map.Entry<String, Double> entry = topApps.get(i); 125f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin result.add(new StringFloat(entry.getKey(), entry.getValue().floatValue())); 126f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin } 127f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin return result; 128984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 129984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 130984e52f31d596840cfa51b1238e1c43d2e1918f8saberian /** 131984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * Set parameters for 1) using History in probability estimations e.g. consider the last event 132984e52f31d596840cfa51b1238e1c43d2e1918f8saberian * and 2) featureAssembly e.g. time and location. 133984e52f31d596840cfa51b1238e1c43d2e1918f8saberian */ 134f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin public boolean setPredictorParameter(String key, String value) { 13547c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin Log.i(TAG, "setParameter : " + key + ", " + value); 136f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin boolean result = true; 137f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin if (key.equals(SET_FEATURE)) { 138f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin result = mFeatureAssembly.registerFeature(value); 13947c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin if (!result) { 140f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin Log.e(TAG,"Setting on feauture: " + value + " which is not available"); 141984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 14247c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin } else if (key.equals(SET_PAIRED_FEATURES)) { 14347c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin String[] features = value.split(FEATURE_SEPARATOR); 14447c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin result = mFeatureAssembly.registerFeaturePair(features); 14547c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin if (!result) { 14647c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin Log.e(TAG,"Setting feauture pair: " + value + " is not valid"); 14747c0dc05cde9e9d9cc57e1393429006bf8b23b32Ruei-sung Lin } 148c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin } else if (key.equals(USE_HISTORY)) { 149c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin mUseHistory = true; 150c7c9cf164cc58d03156a53be35e58c3b75871a23Ruei-sung Lin mHistorySpan = Long.valueOf(value); 151f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin } else { 152f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin Log.e(TAG,"Setting parameter " + key + " with " + value + " is not valid"); 153984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 154f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin return result; 155984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 156984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 157984e52f31d596840cfa51b1238e1c43d2e1918f8saberian // Beginning of the IBordeauxLearner Interface implementation 158984e52f31d596840cfa51b1238e1c43d2e1918f8saberian public byte [] getModel() { 159f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin return mPredictor.getModel(); 160984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 161984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 162984e52f31d596840cfa51b1238e1c43d2e1918f8saberian public boolean setModel(final byte [] modelData) { 163f0f78449e8ab7d63894964c54b6ef390ca9ce044Ruei-sung Lin return mPredictor.setModel(modelData); 164984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 165984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 166984e52f31d596840cfa51b1238e1c43d2e1918f8saberian public IBinder getBinder() { 167984e52f31d596840cfa51b1238e1c43d2e1918f8saberian return this; 168984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 169984e52f31d596840cfa51b1238e1c43d2e1918f8saberian 170984e52f31d596840cfa51b1238e1c43d2e1918f8saberian public void setModelChangeCallback(ModelChangeCallback callback) { 171984e52f31d596840cfa51b1238e1c43d2e1918f8saberian modelChangeCallback = callback; 172984e52f31d596840cfa51b1238e1c43d2e1918f8saberian } 173984e52f31d596840cfa51b1238e1c43d2e1918f8saberian // End of IBordeauxLearner Interface implemenation 174984e52f31d596840cfa51b1238e1c43d2e1918f8saberian} 175