package com.yahoo.labs.samoa.moa.classifiers.core.driftdetection; /* * #%L * SAMOA * %% * Copyright (C) 2013 University of Waikato, Hamilton, New Zealand * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may 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. * #L% */ import com.yahoo.labs.samoa.moa.core.ObjectRepository; import com.yahoo.labs.samoa.moa.tasks.TaskMonitor; /** * Drift detection method based in EDDM method of Manuel Baena et al. * * <p>Early Drift Detection Method. Manuel Baena-Garcia, Jose Del Campo-Avila, * Raúl Fidalgo, Albert Bifet, Ricard Gavalda, Rafael Morales-Bueno. In Fourth * International Workshop on Knowledge Discovery from Data Streams, 2006.</p> * * @author Manuel Baena (mbaena@lcc.uma.es) * @version $Revision: 7 $ */ public class EDDM extends AbstractChangeDetector { /** * */ private static final long serialVersionUID = 140980267062162000L; private static final double FDDM_OUTCONTROL = 0.9; private static final double FDDM_WARNING = 0.95; private static final double FDDM_MINNUMINSTANCES = 30; private double m_numErrors; private int m_minNumErrors = 30; private int m_n; private int m_d; private int m_lastd; private double m_mean; private double m_stdTemp; private double m_m2smax; public EDDM() { resetLearning(); } @Override public void resetLearning() { m_n = 1; m_numErrors = 0; m_d = 0; m_lastd = 0; m_mean = 0.0; m_stdTemp = 0.0; m_m2smax = 0.0; this.estimation = 0.0; } @Override public void input(double prediction) { // prediction must be 1 or 0 // It monitors the error rate // System.out.print(prediction + " " + m_n + " " + probability + " "); if (this.isChangeDetected) { resetLearning(); } this.isChangeDetected = false; m_n++; if (prediction == 1.0) { this.isWarningZone = false; this.delay = 0; m_numErrors += 1; m_lastd = m_d; m_d = m_n - 1; int distance = m_d - m_lastd; double oldmean = m_mean; m_mean = m_mean + ((double) distance - m_mean) / m_numErrors; this.estimation = m_mean; m_stdTemp = m_stdTemp + (distance - m_mean) * (distance - oldmean); double std = Math.sqrt(m_stdTemp / m_numErrors); double m2s = m_mean + 2 * std; if (m2s > m_m2smax) { if (m_n > FDDM_MINNUMINSTANCES) { m_m2smax = m2s; } //m_lastLevel = DDM_INCONTROL_LEVEL; // System.out.print(1 + " "); } else { double p = m2s / m_m2smax; // System.out.print(p + " "); if (m_n > FDDM_MINNUMINSTANCES && m_numErrors > m_minNumErrors && p < FDDM_OUTCONTROL) { //System.out.println(m_mean + ",D"); this.isChangeDetected = true; //resetLearning(); } else { this.isWarningZone = m_n > FDDM_MINNUMINSTANCES && m_numErrors > m_minNumErrors && p < FDDM_WARNING; } } } } @Override public void getDescription(StringBuilder sb, int indent) { // TODO Auto-generated method stub } @Override protected void prepareForUseImpl(TaskMonitor monitor, ObjectRepository repository) { // TODO Auto-generated method stub } }