| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| |
| package org.apache.samoa.moa.classifiers.core.driftdetection; |
| |
| import org.apache.samoa.moa.core.ObjectRepository; |
| import org.apache.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 |
| } |
| } |