16b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua/*
26b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Copyright (C) 2012 The Android Open Source Project
36b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
46b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Licensed under the Apache License, Version 2.0 (the "License");
56b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * you may not use this file except in compliance with the License.
66b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * You may obtain a copy of the License at
76b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
86b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *      http://www.apache.org/licenses/LICENSE-2.0
96b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
106b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Unless required by applicable law or agreed to in writing, software
116b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * distributed under the License is distributed on an "AS IS" BASIS,
126b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * See the License for the specific language governing permissions and
146b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * limitations under the License.
156b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua */
166b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
176b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huapackage android.bordeaux.services;
186b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
196b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.bordeaux.services.ILearning_MulticlassPA;
206b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.bordeaux.services.IntFloat;
216b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.content.Context;
226b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.os.RemoteException;
236b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.util.Log;
246b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
256b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.ArrayList;
266b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.List;
276b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.HashMap;
286b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.Map;
296b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
306b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua/** Classifier for the Learning framework.
316b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  For training: call trainOneSample
326b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  For classifying: call classify
336b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  Data is represented as sparse key, value pair. And key is an integer, value
346b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  is a float. Class label(target) for the training data is an integer.
356b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  Note: since the actual classifier is running in a remote the service.
366b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  Sometimes the connection may be lost or not established.
376b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
386b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua */
396b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huapublic class BordeauxClassifier {
406b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    static final String TAG = "BordeauxClassifier";
416b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private Context mContext;
426b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private String mName;
436b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private ILearning_MulticlassPA mClassifier;
446b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private ArrayList<IntFloat> getArrayList(final HashMap<Integer, Float> sample) {
456b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        ArrayList<IntFloat> intfloat_sample = new ArrayList<IntFloat>();
466b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        for (Map.Entry<Integer, Float> x : sample.entrySet()) {
476b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           IntFloat v = new IntFloat();
486b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           v.index = x.getKey();
496b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           v.value = x.getValue();
506b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           intfloat_sample.add(v);
516b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
526b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        return intfloat_sample;
536b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
546b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
556b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private boolean retrieveClassifier() {
566b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (mClassifier == null)
576b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            mClassifier = BordeauxManagerService.getClassifier(mContext, mName);
586b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        // if classifier is not available, return false
596b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (mClassifier == null) {
606b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            Log.i(TAG,"Classifier not available.");
616b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return false;
626b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
636b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        return true;
646b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
656b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
666b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public BordeauxClassifier(Context context) {
676b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mContext = context;
686b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mName = "defaultClassifier";
696b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mClassifier = BordeauxManagerService.getClassifier(context, mName);
706b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
716b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
726b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public BordeauxClassifier(Context context, String name) {
736b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mContext = context;
746b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mName = name;
756b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mClassifier = BordeauxManagerService.getClassifier(context, mName);
766b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
776b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
786b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public boolean update(final HashMap<Integer, Float> sample, int target) {
796b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (!retrieveClassifier())
806b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return false;
816b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        try {
826b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            mClassifier.TrainOneSample(getArrayList(sample), target);
836b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        } catch (RemoteException e) {
846b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            Log.e(TAG,"Exception: training one sample.");
856b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return false;
866b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
876b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        return true;
886b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
896b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
906b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public int classify(final HashMap<Integer, Float> sample) {
916b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        // if classifier is not available return -1 as an indication of fail.
926b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (!retrieveClassifier())
936b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return -1;
946b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        try {
956b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return mClassifier.Classify(getArrayList(sample));
966b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        } catch (RemoteException e) {
976b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            Log.e(TAG,"Exception: classify the sample.");
986b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            // return an invalid number.
996b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            // TODO: throw exception.
1006b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return -1;
1016b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
1026b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
1036b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
104