HistogramPredictor.java revision c7c9cf164cc58d03156a53be35e58c3b75871a23
1d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build/* 2d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * Copyright (C) 2011 The Android Open Source Project 3d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * 4d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * Licensed under the Apache License, Version 2.0 (the "License"); 5d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * you may not use this file except in compliance with the License. 6d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * You may obtain a copy of the License at 7d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * 8d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * http://www.apache.org/licenses/LICENSE-2.0 9d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * 10d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * Unless required by applicable law or agreed to in writing, software 11d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * distributed under the License is distributed on an "AS IS" BASIS, 12d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * See the License for the specific language governing permissions and 14d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * limitations under the License. 15d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build */ 16d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 17M��Q,_�w���� 18d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildpackage android.bordeaux.learning; 19d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 20d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport android.util.Log; 21d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport android.util.Pair; 22d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 23WE�.�F�Y�H$T�import java.io.ByteArrayInputStream; 24d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.io.ByteArrayOutputStream; 25rX����g�Ă��A���M>��'�'|�����᰻���yimport java.io.IOException; 26d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.io.ObjectInputStream; 27d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.io.ObjectOutputStream; 28d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.io.Serializable; 29d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.ArrayList; 30d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.Collections; 31d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.Comparator; 32d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.HashMap; 33d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.HashSet; 34d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.Iterator; 35d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.List; 36d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.Map; 37d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildimport java.util.Map.Entry; 38d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 39d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 40d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build/** 41d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * A histogram based predictor which records co-occurrences of applations with a speficic feature, 42d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * for example, location, * time of day, etc. The histogram is kept in a two level hash table. 43d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * The first level key is the feature value and the second level key is the app id. 44d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build */ 45d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build// TODOS: 46d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build// 1. Use forgetting factor to downweight istances propotional to the time 47d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build// 2. Different features could have different weights on prediction scores. 48d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build// 3. Make prediction (on each feature) only when the histogram has collected 49d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build// sufficient counts. 50d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-buildpublic class HistogramPredictor { 51d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build final static String TAG = "HistogramPredictor"; 52t���Oo 53w.d�O�� private HashMap<String, HistogramCounter> mPredictor = 54d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build new HashMap<String, HistogramCounter>(); 55d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 56d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build private static final double FEATURE_INACTIVE_LIKELIHOOD = 0.00000001; 57d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build private final double logInactive = Math.log(FEATURE_INACTIVE_LIKELIHOOD); 58w�~<l�� 59d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build /* 60OzJ�Ŵ>�G��Qz _B�r��]:k��.��:I�Qk�p'ׂvjQ����u�dtM * This class keeps the histogram counts for each feature and provide the 61Yx^CHBp�O� * joint probabilities of <feature, class>. 62x��^�C�N�e�l ��!��� */ 639S} private class HistogramCounter { 64d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build private HashMap<String, HashMap<String, Integer> > mCounter = 65d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build new HashMap<String, HashMap<String, Integer> >(); 66d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build private int mTotalCount; 67d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 68d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public HistogramCounter() { 69sw�Y�� resetCounter(); 70d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 71d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 72d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public void setCounter(HashMap<String, HashMap<String, Integer> > counter) { 73h��{������&��**�W}�x�l�L(�W�o��p�Lg* resetCounter(); 74B��f��z mCounter.putAll(counter); 75d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 76d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build // get total count 77d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for (Map.Entry<String, HashMap<String, Integer> > entry : counter.entrySet()) { 78d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for (Integer value : entry.getValue().values()) { 79HMEG�� mTotalCount += value.intValue(); 80d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 81d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 82d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 83d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 840�� public void resetCounter() { 85d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mCounter.clear(); 86d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mTotalCount = 0; 87d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 88c�d�� 89d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public void addSample(String className, String featureValue) { 90d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build HashMap<String, Integer> classCounts; 91d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 92d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build if (!mCounter.containsKey(featureValue)) { 93d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build classCounts = new HashMap<String, Integer>(); 94d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mCounter.put(featureValue, classCounts); 95d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 96d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build classCounts = mCounter.get(featureValue); 97d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 98d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build int count = (classCounts.containsKey(className)) ? 99d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build classCounts.get(className) + 1 : 1; 100d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build classCounts.put(className, count); 101d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mTotalCount++; 102D0SI]���Lb�Lp� } 103cXI�ti- 104d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public HashMap<String, Double> getClassScores(String featureValue) { 105d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build HashMap<String, Double> classScores = new HashMap<String, Double>(); 106d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 107d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build double logTotalCount = Math.log((double) mTotalCount); 108o�S<��,��J{�\' if (mCounter.containsKey(featureValue)) { 109d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for(Map.Entry<String, Integer> entry : 110d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mCounter.get(featureValue).entrySet()) { 111d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build double score = 112sf��PѰ��ʐ�XN�ve�?�����{�蛁�:���}p;p=� ���X������z*ΰB�w Math.log((double) entry.getValue()) - logTotalCount; 113d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build classScores.put(entry.getKey(), score); 114d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 115d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 116d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build return classScores; 117d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 118d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 119d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public HashMap<String, HashMap<String, Integer> > getCounter() { 120d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build return mCounter; 121d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 122d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 123d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 124d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build /* 125d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * Given a map of feature name -value pairs returns the mostly likely apps to 126d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * be launched with corresponding likelihoods. 127d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build */ 128d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public List<Map.Entry<String, Double> > findTopClasses(Map<String, String> features, int topK) { 129m����� �� `)�B(� // Most sophisticated function in this class 130YAYЌ=)#��bDF�R��X��ќ���n۔o[:wP� HashMap<String, Double> appScores = new HashMap<String, Double>(); 131d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build double defaultLikelihood = mPredictor.size() * logInactive; 132d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 133d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build // compute all app scores 134d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for (Map.Entry<String, HistogramCounter> entry : mPredictor.entrySet()) { 135d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build String featureName = entry.getKey(); 136d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build HistogramCounter counter = entry.getValue(); 137d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 138d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build if (features.containsKey(featureName)) { 139d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build String featureValue = features.get(featureName); 140N;T֭�r��O�ś HashMap<String, Double> scoreMap = counter.getClassScores(featureValue); 141d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 142d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for (Map.Entry<String, Double> item : scoreMap.entrySet()) { 143d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build String appName = item.getKey(); 144d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build double appScore = item.getValue(); 145d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 146d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build double score = (appScores.containsKey(appName)) ? 147d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build appScores.get(appName) : defaultLikelihood; 148d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build score += appScore - logInactive; 149d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 150d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build appScores.put(appName, score); 151d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 152d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 153d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 154d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 155d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build // sort app scores 156d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build List<Map.Entry<String, Double> > appList = 157d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build new ArrayList<Map.Entry<String, Double> >(appScores.size()); 158d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build appList.addAll(appScores.entrySet()); 159n�� Collections.sort(appList, new Comparator<Map.Entry<String, Double> >() { 160d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public int compare(Map.Entry<String, Double> o1, 161d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build Map.Entry<String, Double> o2) { 162d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build return o2.getValue().compareTo(o1.getValue()); 1636i� } 164T9g }); 165d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 166d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build Log.e(TAG, "findTopApps appList: " + appList); 167k�i�p�� ��D return appList; 168d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 169d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 170Kr4� /* 171d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * Add a new observation of given sample id and features to the histograms 172d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build */ 173d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public void addSample(String sampleId, Map<String, String> features) { 174d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for (Map.Entry<String, HistogramCounter> entry : mPredictor.entrySet()) { 175d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build String featureName = entry.getKey(); 176d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build HistogramCounter counter = entry.getValue(); 177d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 178M3�� TRP� if (features.containsKey(featureName)) { 179d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build String featureValue = features.get(featureName); 180d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build counter.addSample(sampleId, featureValue); 181d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 182i���' } 183d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 184d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 185d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build /* 186d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * reset predictor to a empty model 187swQ�� */ 188d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public void resetPredictor() { 189d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build // TODO: not sure this step would reduce memory waste 190d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for (HistogramCounter counter : mPredictor.values()) { 191d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build counter.resetCounter(); 192d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 193d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mPredictor.clear(); 194d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 195z�;p 196d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build /* 197i�[}W*�oZ��&R��<<�#��b������A'F�n��� * specify a feature to used for prediction 198d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build */ 199d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public void useFeature(String featureName) { 200d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build if (!mPredictor.containsKey(featureName)) { 201d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mPredictor.put(featureName, new HistogramCounter()); 202d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 203d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 204d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 205d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build /* 206d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * convert the prediction model into a byte array 207d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build */ 208d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public byte[] getModel() { 209d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build // TODO: convert model to a more memory efficient data structure. 210E��R��k�D�*� HashMap<String, HashMap<String, HashMap<String, Integer > > > model = 211k��`�a��y�Xe;�W������NH]��BE��N�)�S new HashMap<String, HashMap<String, HashMap<String, Integer > > >(); 212a�zi��;.�m������������z.�b}�W for(Map.Entry<String, HistogramCounter> entry : mPredictor.entrySet()) { 213d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build model.put(entry.getKey(), entry.getValue().getCounter()); 214d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 215d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 216d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build try { 217d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 218d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build ObjectOutputStream objStream = new ObjectOutputStream(byteStream); 2191���� �r�X�DŽW�L��U�|��T�h�/� objStream.writeObject(model); 220d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build byte[] bytes = byteStream.toByteArray(); 221d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build //Log.i(TAG, "getModel: " + bytes); 222d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build return bytes; 223d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } catch (IOException e) { 224d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build throw new RuntimeException("Can't get model"); 225d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 226d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 227d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 228d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build /* 229d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build * set the prediction model from a model data in the format of byte array 2302'�|��ce�TZpc��&k< */ 231d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build public boolean setModel(final byte[] modelData) { 232d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build HashMap<String, HashMap<String, HashMap<String, Integer > > > model; 233d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 234d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build try { 235d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build ByteArrayInputStream input = new ByteArrayInputStream(modelData); 236d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build ObjectInputStream objStream = new ObjectInputStream(input); 237d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build model = (HashMap<String, HashMap<String, HashMap<String, Integer > > >) 238d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build objStream.readObject(); 239d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } catch (IOException e) { 240d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build throw new RuntimeException("Can't load model"); 241d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } catch (ClassNotFoundException e) { 242d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build throw new RuntimeException("Learning class not found"); 243d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 244d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build 245d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build resetPredictor(); 246d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build for (Map.Entry<String, HashMap<String, HashMap<String, Integer> > > entry : 247d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build model.entrySet()) { 248d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build useFeature(entry.getKey()); 249d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build mPredictor.get(entry.getKey()).setCounter(entry.getValue()); 250d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 251d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build return true; 252d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build } 253pF@�ؤ?sH�\�YZ�U�\���[��:} 254d1f1aaf649cac3788a261a5380448579f54b5dcandroid-devtools-build