├── _config.yml ├── .bettercodehub.yml ├── assets ├── ADT.jpg └── ADT-icon.jpg ├── .github └── ISSUE_TEMPLATE │ ├── Custom.md │ ├── Feature_request.md │ └── Bug_report.md ├── src ├── test │ └── java │ │ └── com │ │ └── anomalydetect │ │ ├── IsolationTree │ │ ├── IsolationTreeNodeTest.java │ │ ├── IsolationForestTest.java │ │ └── IsolationTreeToolTest.java │ │ ├── Util │ │ └── MatrixUtilTest.java │ │ ├── BruteForce │ │ ├── AlphabetTreeNodeTest.java │ │ ├── BruteForceToolTest.java │ │ └── HeuristicToolTest.java │ │ ├── LOF │ │ ├── LOFTest.java │ │ └── LOFDetectToolTest.java │ │ ├── Tool │ │ ├── FileToolTest.java │ │ ├── DisplayToolTest.java │ │ ├── DetectToolTest.java │ │ └── MathToolTest.java │ │ ├── ESD │ │ ├── ESDToolTest.java │ │ ├── SESDToolTest.java │ │ └── GrubbsToolTest.java │ │ ├── ReadJson │ │ ├── EventTest.java │ │ ├── ItemsTest.java │ │ └── ItemTest.java │ │ ├── ExponentialMoving │ │ └── HoltWintersToolTest.java │ │ └── Result │ │ └── ResultTest.java └── main │ └── java │ └── com │ └── anomalydetect │ ├── Tool │ ├── MultiDetectTool.java │ ├── DetectTool.java │ ├── DisplayTool.java │ ├── FileTool.java │ └── MathTool.java │ ├── ReadJson │ ├── Datas.java │ ├── Event.java │ ├── Items.java │ ├── Data.java │ └── Item.java │ ├── Wavelet │ └── WaveletTool.java │ ├── IsolationTree │ ├── IsolationTreeNode.java │ ├── IsolationForest.java │ ├── IsolationTreeTool.java │ └── IsolationTree.java │ ├── ESD │ ├── SESDTool.java │ ├── GrubbsTool.java │ └── ESDTool.java │ ├── BruteForce │ ├── Notes.java │ ├── AlphabetTree.java │ ├── AlphabetTreeNode.java │ ├── BruteForceTool.java │ └── HeuristicTool.java │ ├── Result │ └── Result.java │ ├── LOF │ ├── Experiment.java │ ├── LOFDetectTool.java │ ├── readme.md │ └── LOF.java │ ├── Util │ └── MatrixUtil.java │ └── ExponentialMoving │ └── HoltWintersTool.java ├── CONTRIBUTING.md ├── .gitignore ├── LICENSE ├── README.md ├── CODE_OF_CONDUCT.md ├── pom.xml └── data.json /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /.bettercodehub.yml: -------------------------------------------------------------------------------- 1 | component_depth: 6 2 | languages: 3 | - java -------------------------------------------------------------------------------- /assets/ADT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MezereonXP/AnomalyDetectTool/HEAD/assets/ADT.jpg -------------------------------------------------------------------------------- /assets/ADT-icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MezereonXP/AnomalyDetectTool/HEAD/assets/ADT-icon.jpg -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/IsolationTree/IsolationTreeNodeTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.IsolationTree; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | public class IsolationTreeNodeTest { 6 | 7 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 关于贡献代码 2 | 给出主要的流程: 3 | 1. 自己去寻找一些相关的论文 4 | 2. 发现有趣的算法 5 | 3. 提issue, 然后我会判断并且分配任务 6 | 4. 自己编写代码完成之后提PR 7 | 5. review之后并入主分支, 完成贡献 8 | 9 | > 我们的目的是给这个开源社区贡献一点微薄之力, 复现论文中的算法(时序数据异常检测方面), 让其他人可以轻松使用 10 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/IsolationTree/IsolationForestTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.IsolationTree; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | public class IsolationForestTest { 7 | 8 | @Test 9 | public void createForest() { 10 | } 11 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Tool/MultiDetectTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | /** 4 | * 多维度异常检测的接口类 5 | * 6 | * @author mezereon E-mail:mezereonxp@gmail.com 7 | * @since 18-6-26 8 | */ 9 | public interface MultiDetectTool { 10 | 11 | /** 12 | * 对时间序列进行异常检测 13 | */ 14 | void multiTimeSeriesAnalyse(double[][] data, int dimension); 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/Util/MatrixUtilTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Util; 2 | 3 | import org.junit.Test; 4 | 5 | public class MatrixUtilTest { 6 | 7 | @Test 8 | public void getMat() { 9 | double[] num = {1, 2, 3, 4, 5, 6}; 10 | double[][] mat = MatrixUtil.getMat(num, 2, 2, 3); 11 | System.out.println(mat.length); 12 | 13 | } 14 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/BruteForce/AlphabetTreeNodeTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class AlphabetTreeNodeTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @Test 14 | public void isHaveLabel() { 15 | } 16 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | .idea/ 25 | target/ 26 | *.iml 27 | 28 | .DS_Store -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/LOF/LOFTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.LOF; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class LOFTest { 7 | 8 | @Test 9 | public void findKthPoint() { 10 | LOF lof = new LOF(1); 11 | double[][] knn = {{1.0, 2.0}, {3.1, 4.0}}; 12 | double[] x = {1.0, 2.0}; 13 | Assert.assertEquals(lof.findKthPoint(knn, x)[0], 1.0, 0.1); 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Tool/DetectTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | import com.anomalydetect.Result.Result; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 异常检测的接口类 9 | * 10 | * @author mezereon E-mail:mezereonxp@gmail.com 11 | * @since 18-4-12 12 | */ 13 | public interface DetectTool { 14 | 15 | /** 16 | * 对时间序列进行异常检测 17 | */ 18 | void timeSeriesAnalyse(double[] data); 19 | 20 | List getResults(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ReadJson/Datas.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | import java.util.List; 4 | 5 | public class Datas { 6 | 7 | 8 | public List datas; 9 | 10 | public Datas(List datas) { 11 | this.datas = datas; 12 | } 13 | 14 | public List getDatas() { 15 | return datas; 16 | } 17 | 18 | public void setDatas(List datas) { 19 | this.datas = datas; 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/Tool/FileToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.FileNotFoundException; 7 | 8 | public class FileToolTest { 9 | 10 | private static final int LENGTH = 360; 11 | 12 | @Test 13 | public void getData() throws FileNotFoundException { 14 | double[] data = FileTool.getData("data.json"); 15 | Assert.assertEquals(data.length, LENGTH); 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ReadJson/Event.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | /** 4 | * @author mezereon E-mail:mezereonxp@gmail.com 5 | * @since 18-4-12 6 | */ 7 | public class Event { 8 | 9 | private double totalcount; 10 | 11 | public Event(double totalcount) { 12 | this.totalcount = totalcount; 13 | } 14 | 15 | public double getTotal_count() { 16 | return totalcount; 17 | } 18 | 19 | public void setTotal_count(double totalcount) { 20 | this.totalcount = totalcount; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ReadJson/Items.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * JSON中的bean类 7 | * 8 | * @author mezereon E-mail:mezereonxp@gmail.com 9 | * @since 18-4-12 10 | */ 11 | 12 | public class Items { 13 | public List items; 14 | 15 | public Items(List items) { 16 | this.items = items; 17 | } 18 | 19 | public List getItems() { 20 | return items; 21 | } 22 | 23 | public void setItems(List items) { 24 | this.items = items; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Wavelet/WaveletTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Wavelet; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | 6 | import java.util.List; 7 | /** 8 | * Wavelet detect algorithm 9 | * 10 | * @author mezereon E-mail:mezereonxp@gmail.com 11 | * @since 18-4-12 12 | */ 13 | public class WaveletTool implements DetectTool { 14 | 15 | @Override 16 | public void timeSeriesAnalyse(double[] data) { 17 | 18 | } 19 | 20 | @Override 21 | public List getResults() { 22 | return null; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/IsolationTree/IsolationTreeNode.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.IsolationTree; 2 | 3 | public class IsolationTreeNode { 4 | protected Double divdNum;//划分区间的值 5 | protected int size;//当前节点中容纳的值 6 | protected IsolationTreeNode left;//左孩子 7 | protected IsolationTreeNode right;//右孩子 8 | 9 | public IsolationTreeNode(Double divdNum) { 10 | this.divdNum = divdNum; 11 | } 12 | 13 | /** 14 | * 判断是否是外部节点(叶子节点) 15 | * 16 | * @return 17 | */ 18 | public boolean isExtenal() { 19 | return (this.left == null && this.right == null); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/LOF/LOFDetectToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.LOF; 2 | 3 | import com.anomalydetect.Tool.FileTool; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | /** 8 | * Created by Administrator on 2018/4/27. 9 | */ 10 | public class LOFDetectToolTest { 11 | 12 | public double[] testData; 13 | 14 | @Before 15 | public void setUp() throws Exception { 16 | testData = FileTool.getData("data.json"); 17 | } 18 | 19 | @Test 20 | public void timeSeriesAnalyse() throws Exception { 21 | LOFDetectTool lofDetectTool = new LOFDetectTool(200, 20); 22 | lofDetectTool.timeSeriesAnalyse(testData); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/Tool/DisplayToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | import com.anomalydetect.BruteForce.BruteForceTool; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.FileNotFoundException; 8 | 9 | public class DisplayToolTest { 10 | 11 | private double[] data; 12 | 13 | @Before 14 | public void setUp() throws FileNotFoundException { 15 | data = FileTool.getData("data.json"); 16 | } 17 | 18 | @Test 19 | public void showResult() { 20 | BruteForceTool bruteForceTool = new BruteForceTool(10); 21 | bruteForceTool.timeSeriesAnalyse(data); 22 | DisplayTool.showResult(bruteForceTool); 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/ESD/ESDToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ESD; 2 | 3 | import com.anomalydetect.Tool.DisplayTool; 4 | import com.anomalydetect.Tool.FileTool; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.io.FileNotFoundException; 9 | 10 | public class ESDToolTest { 11 | 12 | public double[] testData; 13 | 14 | @Before 15 | public void setUp() throws FileNotFoundException { 16 | testData = FileTool.getData("data.json"); 17 | } 18 | 19 | @Test 20 | public void timeSeriesAnalyse() { 21 | ESDTool esdTool = new ESDTool(10); 22 | esdTool.timeSeriesAnalyse(testData); 23 | DisplayTool.showResult(esdTool); 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/ESD/SESDToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ESD; 2 | 3 | import com.anomalydetect.Tool.DisplayTool; 4 | import com.anomalydetect.Tool.FileTool; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.io.FileNotFoundException; 9 | 10 | public class SESDToolTest { 11 | 12 | public double[] testData; 13 | 14 | @Before 15 | public void setUp() throws FileNotFoundException { 16 | testData = FileTool.getData("data.json"); 17 | } 18 | 19 | @Test 20 | public void timeSeriesAnalyse() { 21 | SESDTool sesdTool = new SESDTool(); 22 | sesdTool.timeSeriesAnalyse(testData); 23 | DisplayTool.showResult(sesdTool); 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/ESD/GrubbsToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ESD; 2 | 3 | import com.anomalydetect.Tool.DisplayTool; 4 | import com.anomalydetect.Tool.FileTool; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.io.FileNotFoundException; 9 | 10 | public class GrubbsToolTest { 11 | 12 | public double[] testData; 13 | 14 | @Before 15 | public void setUp() throws FileNotFoundException { 16 | testData = FileTool.getData("data.json"); 17 | } 18 | 19 | @Test 20 | public void timeSeriesAnalyse() { 21 | GrubbsTool grubbsTool = new GrubbsTool(); 22 | grubbsTool.timeSeriesAnalyse(testData); 23 | DisplayTool.showResult(grubbsTool); 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Tool/DisplayTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | import com.anomalydetect.Result.Result; 4 | 5 | /** 6 | * @program: AnomalyDetectTool 7 | * @description: A tool to display 8 | * @author: mezereonxp Email: mezereonxp@gmail.com 9 | * @create: 2018-05-08 14:43 10 | **/ 11 | public class DisplayTool { 12 | public static void showResult(DetectTool detectTool) { 13 | 14 | for (Result result : detectTool.getResults()) { 15 | System.out.print(result.getIndex() + ", "); 16 | } 17 | System.out.println(); 18 | for (Result result : detectTool.getResults()) { 19 | System.out.print(result.getValue() + ", "); 20 | } 21 | System.out.println(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/BruteForce/BruteForceToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | import com.anomalydetect.Tool.DisplayTool; 4 | import com.anomalydetect.Tool.FileTool; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.io.FileNotFoundException; 9 | 10 | public class BruteForceToolTest { 11 | 12 | private double[] data; 13 | 14 | @Before 15 | public void setUp() throws FileNotFoundException { 16 | data = FileTool.getData("data.json"); 17 | } 18 | 19 | @Test 20 | public void timeSeriesAnalyse() { 21 | BruteForceTool bruteForceTool = new BruteForceTool(10); 22 | bruteForceTool.timeSeriesAnalyse(data); 23 | DisplayTool.showResult(bruteForceTool); 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/BruteForce/HeuristicToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | import com.anomalydetect.Tool.DisplayTool; 4 | import com.anomalydetect.Tool.FileTool; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.io.FileNotFoundException; 9 | 10 | public class HeuristicToolTest { 11 | 12 | private double[] testData; 13 | 14 | @Before 15 | public void setUp() throws FileNotFoundException { 16 | testData = FileTool.getData("data.json"); 17 | } 18 | 19 | @Test 20 | public void timeSeriesAnalyse() { 21 | HeuristicTool heuristicTool = new HeuristicTool(3); 22 | heuristicTool.timeSeriesAnalyse(testData); 23 | DisplayTool.showResult(heuristicTool); 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ReadJson/Data.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | public class Data { 4 | private String caiji_shijian; 5 | private double caiji_zhi; 6 | 7 | public Data() {} 8 | 9 | public Data(String caiji_shijian, double caiji_zhi) { 10 | this.caiji_shijian = caiji_shijian; 11 | this.caiji_zhi = caiji_zhi; 12 | } 13 | 14 | public double getCaiji_zhi() { 15 | return caiji_zhi; 16 | } 17 | 18 | public void setCaiji_zhi(double caiji_zhi) { 19 | this.caiji_zhi = caiji_zhi; 20 | } 21 | 22 | public String getCaiji_shijian() { 23 | return caiji_shijian; 24 | } 25 | 26 | public void setCaiji_shijian(String caiji_shijian) { 27 | this.caiji_shijian = caiji_shijian; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/ReadJson/EventTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class EventTest { 8 | 9 | private Event event; 10 | private static final double VALUE = 1.0; 11 | private static final double NEW_VALUE = 2.0; 12 | private static final double DELTA = 0.0; 13 | 14 | @Before 15 | public void setUp() { 16 | event = new Event(VALUE); 17 | } 18 | 19 | @Test 20 | public void getTotal_count() { 21 | Assert.assertEquals(VALUE, event.getTotal_count(), DELTA); 22 | } 23 | 24 | @Test 25 | public void setTotal_count() { 26 | event.setTotal_count(NEW_VALUE); 27 | Assert.assertEquals(NEW_VALUE, event.getTotal_count(), DELTA); 28 | } 29 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/Tool/DetectToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | import com.anomalydetect.BruteForce.BruteForceTool; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.io.FileNotFoundException; 8 | 9 | public class DetectToolTest { 10 | 11 | private double[] data; 12 | 13 | @Before 14 | public void setUp() throws FileNotFoundException { 15 | data = FileTool.getData("data.json"); 16 | } 17 | 18 | @Test 19 | public void timeSeriesAnalyse() { 20 | BruteForceTool bruteForceTool = new BruteForceTool(10); 21 | bruteForceTool.timeSeriesAnalyse(data); 22 | } 23 | 24 | @Test 25 | public void getResults() { 26 | BruteForceTool bruteForceTool = new BruteForceTool(10); 27 | bruteForceTool.timeSeriesAnalyse(data); 28 | DisplayTool.showResult(bruteForceTool); 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/ExponentialMoving/HoltWintersToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ExponentialMoving; 2 | 3 | import com.anomalydetect.Tool.DisplayTool; 4 | import com.anomalydetect.Tool.FileTool; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | /** 9 | * Created by Administrator on 2018/4/27. 10 | */ 11 | public class HoltWintersToolTest { 12 | 13 | private static final double ALPHA = 0.1; 14 | private static final double STEP = 0.01; 15 | private static final int TIMES = 1000; 16 | 17 | public double[] testData; 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | testData = FileTool.getData("data.json"); 22 | } 23 | 24 | @Test 25 | public void timeSeriesAnalyse() throws Exception { 26 | HoltWintersTool holtWintersTool = new HoltWintersTool(ALPHA, STEP, TIMES); 27 | holtWintersTool.timeSeriesAnalyse(testData); 28 | DisplayTool.showResult(holtWintersTool); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. iOS] 25 | - Browser [e.g. chrome, safari] 26 | - Version [e.g. 22] 27 | 28 | **Smartphone (please complete the following information):** 29 | - Device: [e.g. iPhone6] 30 | - OS: [e.g. iOS8.1] 31 | - Browser [e.g. stock browser, safari] 32 | - Version [e.g. 22] 33 | 34 | **Additional context** 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ReadJson/Item.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | /** 4 | * JSON中的bean类 5 | * 6 | * @author mezereon E-mail:mezereonxp@gmail.com 7 | * @since 18-4-12 8 | */ 9 | public class Item { 10 | 11 | private String tempstamp; 12 | private Event event; 13 | 14 | public Item() { 15 | } 16 | 17 | public Item(String tempstamp) { 18 | this.tempstamp = tempstamp; 19 | } 20 | 21 | public Item(Event event) { 22 | this.event = event; 23 | } 24 | 25 | public Item(String tempstamp, Event event) { 26 | this.tempstamp = tempstamp; 27 | this.event = event; 28 | } 29 | 30 | public String getTempstamp() { 31 | return tempstamp; 32 | } 33 | 34 | public void setTempstamp(String tempstamp) { 35 | this.tempstamp = tempstamp; 36 | } 37 | 38 | public Event getEvent() { 39 | return event; 40 | } 41 | 42 | public void setEvent(Event event) { 43 | this.event = event; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Ke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/Result/ResultTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Result; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class ResultTest { 8 | 9 | public Result result; 10 | public static final int INDEX = 1; 11 | public static final int NEW_INDEX = 2; 12 | public static final double VALUE = 2.0; 13 | public static final double NEW_VALUE = 3.0; 14 | public static final double DELTA = 0.0; 15 | 16 | @Before 17 | public void setUp() { 18 | result = new Result(INDEX, VALUE); 19 | } 20 | 21 | @Test 22 | public void getIndex() { 23 | Assert.assertEquals("Test getIndex of Result", result.getIndex(), INDEX); 24 | } 25 | 26 | @Test 27 | public void setIndex() { 28 | result.setIndex(NEW_INDEX); 29 | Assert.assertEquals("Test setIndex of Result", result.getIndex(), NEW_INDEX); 30 | } 31 | 32 | @Test 33 | public void getValue() { 34 | Assert.assertEquals(VALUE, result.getValue(), DELTA); 35 | } 36 | 37 | @Test 38 | public void setValue() { 39 | result.setValue(NEW_VALUE); 40 | Assert.assertEquals(NEW_VALUE, result.getValue(), DELTA); 41 | } 42 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/Tool/MathToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | /** 8 | * @program: MathToolTest 9 | * @description: To test some useful calculations 10 | * @author: mezereonxp Email: mezereonxp@gmail.com 11 | * @create: 2018-05-03 14:52 12 | **/ 13 | public class MathToolTest { 14 | 15 | private double[] testArray; 16 | private static final double DELTA = 0.000001; 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | testArray = new double[5]; 21 | testArray[0] = 0.0; 22 | testArray[1] = 1.0; 23 | testArray[2] = 2.0; 24 | testArray[3] = 3.0; 25 | testArray[4] = 4.0; 26 | } 27 | 28 | @Test 29 | public void normalize() throws Exception { 30 | Assert.assertEquals(MathTool.normalize(testArray)[1], 0.25, 0.1); 31 | } 32 | 33 | @Test 34 | public void getAverageFromArray() throws Exception { 35 | Assert.assertEquals(MathTool.getAverageFromArray(testArray), 2.0, 0.0); 36 | } 37 | 38 | @Test 39 | public void getStdDeviation() throws Exception { 40 | Assert.assertEquals(MathTool.getStdDeviation(testArray), 1.581138, DELTA); 41 | } 42 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/ReadJson/ItemsTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.ArrayList; 8 | 9 | public class ItemsTest { 10 | 11 | private Items items; 12 | private static final double VALUE = 1.0; 13 | private static final double NEW_VALUE = 2.0; 14 | private static final int SIZE = 1; 15 | private static final int NEW_SIZE = 2; 16 | private static final String TIME_STAMP = "111400000000"; 17 | 18 | @Before 19 | public void setUp() { 20 | ArrayList itemArrayList = new ArrayList(); 21 | itemArrayList.add(new Item(TIME_STAMP, new Event(VALUE))); 22 | items = new Items(itemArrayList); 23 | } 24 | 25 | @Test 26 | public void getItems() { 27 | Assert.assertEquals(items.getItems().size(), SIZE); 28 | } 29 | 30 | @Test 31 | public void setItems() { 32 | ArrayList itemArrayList = new ArrayList(); 33 | itemArrayList.add(new Item(TIME_STAMP, new Event(VALUE))); 34 | itemArrayList.add(new Item(TIME_STAMP, new Event(NEW_VALUE))); 35 | items.setItems(itemArrayList); 36 | Assert.assertEquals(items.getItems().size(), NEW_SIZE); 37 | } 38 | } -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/ReadJson/ItemTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ReadJson; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class ItemTest { 8 | 9 | private static final double VALUE = 1.0; 10 | private static final double NEW_VALUE = 2.0; 11 | private static final double DELTA = 0.0; 12 | private static final int SIZE = 1; 13 | private static final int NEW_SIZE = 2; 14 | private static final String TIME_STAMP = "111400000000"; 15 | private static final String NEW_TIME_STAMP = "111400000001"; 16 | private Item item; 17 | 18 | @Before 19 | public void setUp() { 20 | item = new Item(TIME_STAMP, new Event(VALUE)); 21 | } 22 | 23 | @Test 24 | public void getTempstamp() { 25 | Assert.assertEquals(TIME_STAMP, item.getTempstamp()); 26 | } 27 | 28 | @Test 29 | public void setTempstamp() { 30 | item.setTempstamp(NEW_TIME_STAMP); 31 | Assert.assertEquals(NEW_TIME_STAMP, item.getTempstamp()); 32 | } 33 | 34 | @Test 35 | public void getEvent() { 36 | Assert.assertEquals(VALUE, item.getEvent().getTotal_count(), DELTA); 37 | } 38 | 39 | @Test 40 | public void setEvent() { 41 | item.setEvent(new Event(NEW_VALUE)); 42 | Assert.assertEquals(NEW_VALUE, item.getEvent().getTotal_count(), DELTA); 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ESD/SESDTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ESD; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * @program: AnomalyDetectTool 10 | * @description: Seasonal Extreme Studentized Deviate 11 | * @author: mezereonxp Email: mezereonxp@gmail.com 12 | * @create: 2018-05-07 18:16 13 | **/ 14 | public class SESDTool implements DetectTool { 15 | 16 | private double t;// t统计量 17 | private ArrayList results; 18 | private ESDTool esdTool; 19 | 20 | /** 21 | * constructor 22 | */ 23 | SESDTool() { 24 | esdTool = new ESDTool(1); 25 | } 26 | 27 | public void timeSeriesAnalyse(double[] data) { 28 | esdTool.timeSeriesAnalyse(data); 29 | results = esdTool.getResults(); 30 | } 31 | 32 | public double getT() { 33 | return t; 34 | } 35 | 36 | public void setT(double t) { 37 | this.t = t; 38 | } 39 | 40 | public ArrayList getResults() { 41 | return results; 42 | } 43 | 44 | public void setResults(ArrayList results) { 45 | this.results = results; 46 | } 47 | 48 | public ESDTool getEsdTool() { 49 | return esdTool; 50 | } 51 | 52 | public void setEsdTool(ESDTool esdTool) { 53 | this.esdTool = esdTool; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/BruteForce/Notes.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | /** 4 | * @program: anomaly-detection 5 | * @description: To store the string and counts 6 | * @author: mezereonxp Email: mezereonxp@gmail.com 7 | * @create: 2018-05-11 11:43 8 | **/ 9 | public class Notes { 10 | 11 | private int length; 12 | private char[] data; 13 | private int count = 1; 14 | private int index; 15 | private boolean isVisited = false; 16 | 17 | Notes(int length, char[] d, int position, int index) { 18 | this.length = length; 19 | this.index = index; 20 | data = new char[length]; 21 | for (int i = position; i < position + length; i++) { 22 | data[i - position] = d[i]; 23 | } 24 | } 25 | 26 | public int getLength() { 27 | return length; 28 | } 29 | 30 | public void setLength(int length) { 31 | this.length = length; 32 | } 33 | 34 | public char[] getData() { 35 | return data; 36 | } 37 | 38 | public void setData(char[] data) { 39 | this.data = data; 40 | } 41 | 42 | public int getCount() { 43 | return count; 44 | } 45 | 46 | public void setCount(int count) { 47 | this.count = count; 48 | } 49 | 50 | public int getIndex() { 51 | return index; 52 | } 53 | 54 | public void setIndex(int index) { 55 | this.index = index; 56 | } 57 | 58 | public boolean isVisited() { 59 | return isVisited; 60 | } 61 | 62 | public void setVisited(boolean visited) { 63 | isVisited = visited; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Result/Result.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Result; 2 | 3 | /** 4 | * @program: AnomalyDetectTool 5 | * @description: A class to store result 6 | * @author: mezereonxp Email: mezereonxp@gmail.com 7 | * @create: 2018-05-08 09:56 8 | **/ 9 | public class Result { 10 | private int index; 11 | private double value; 12 | private double[] multiValue; 13 | private Boolean isMuti; 14 | 15 | public Result(int index, double[] multiValue) { 16 | this.index = index; 17 | this.multiValue = multiValue; 18 | this.isMuti = true; 19 | } 20 | 21 | public Result(int index, double value) { 22 | this.index = index; 23 | this.value = value; 24 | this.isMuti = false; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | String result = "Index is " + index + ", value is "; 30 | if (isMuti) { 31 | for (double d : multiValue) { 32 | result += "[ " + d + " ],"; 33 | } 34 | return result; 35 | } else { 36 | return "Index is " + index + ", value is " + value; 37 | } 38 | } 39 | 40 | public int getIndex() { 41 | return index; 42 | } 43 | 44 | public void setIndex(int index) { 45 | this.index = index; 46 | } 47 | 48 | public double getValue() { 49 | return value; 50 | } 51 | 52 | public void setValue(double value) { 53 | this.value = value; 54 | } 55 | 56 | public Boolean getMuti() { 57 | return isMuti; 58 | } 59 | 60 | public void setMuti(Boolean muti) { 61 | isMuti = muti; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/BruteForce/AlphabetTree.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | /** 4 | * @program: anomaly-detection 5 | * @description: The tree to map word 6 | * @author: mezereonxp Email: mezereonxp@gmail.com 7 | * @create: 2018-05-11 14:12 8 | **/ 9 | public class AlphabetTree { 10 | 11 | private AlphabetTreeNode head; 12 | 13 | AlphabetTree(char initChar, int depth, int ways) { 14 | head = new AlphabetTreeNode(false, initChar, true); 15 | } 16 | 17 | public void addNote(Notes note) { 18 | char[] chars = note.getData(); 19 | AlphabetTreeNode temp = head; 20 | int position = 0; 21 | for (char c : chars) { 22 | if (!temp.isHaveLabel(c)) { 23 | temp.getNodeList().add(new AlphabetTreeNode(position == chars.length - 1, c, false)); 24 | } 25 | if (position == chars.length - 1) { 26 | temp.getNodeByLabel(c).getNotes().add(note); 27 | if (temp.getNodeByLabel(c).getNotes().size() > 1) { 28 | temp.increase(c); 29 | } 30 | } 31 | temp = temp.getNodeByLabel(c); 32 | position++; 33 | } 34 | } 35 | 36 | /** 37 | * 给节点加上子节点 38 | * 39 | * @param node 节点 40 | * @param initChar 初始字符 41 | * @param ways 分成几个类别的字符 42 | * @param isLeaf 是否是叶节点 43 | */ 44 | private void addNodes(AlphabetTreeNode node, char initChar, int ways, boolean isLeaf) { 45 | for (int i = 0; i < ways; i++) { 46 | AlphabetTreeNode n = new AlphabetTreeNode(isLeaf, (char) (initChar + i), false); 47 | node.getNodeList().add(n); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/anomalydetect/IsolationTree/IsolationTreeToolTest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.IsolationTree; 2 | 3 | import com.anomalydetect.Tool.DisplayTool; 4 | import com.anomalydetect.Tool.FileTool; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import java.io.FileNotFoundException; 8 | 9 | 10 | 11 | public class IsolationTreeToolTest { 12 | public static int TEST_LENGTH = 100; 13 | public static int TEST_LONG_LENGTH = 4000; 14 | public double[] testData; 15 | public double[] testData2; 16 | public double[] testData3; 17 | 18 | @Before 19 | public void setUp() throws FileNotFoundException { 20 | testData = FileTool.getData("data.json"); 21 | testData2 = new double[TEST_LENGTH]; 22 | for (int i=0; i < TEST_LENGTH; i++) { 23 | testData2[i] = Math.random() - 0.5; 24 | } 25 | testData3 = new double[TEST_LONG_LENGTH]; 26 | for (int i=0; i < TEST_LONG_LENGTH; i++) { 27 | testData3[i] = Math.random() - 0.5; 28 | } 29 | } 30 | 31 | @Test 32 | public void timeSeriesAnalyse() { 33 | System.out.println("Isolation Forest Test is Started ..."); 34 | IsolationTreeTool isolationTreeTool = new IsolationTreeTool(); 35 | isolationTreeTool.timeSeriesAnalyse(testData); 36 | DisplayTool.showResult(isolationTreeTool); 37 | isolationTreeTool.timeSeriesAnalyse(testData2); 38 | DisplayTool.showResult(isolationTreeTool); 39 | System.out.println("Start test repeat value sequence ..."); 40 | for (int i=0; i<100; i++) { 41 | isolationTreeTool.timeSeriesAnalyse(testData3); 42 | } 43 | DisplayTool.showResult(isolationTreeTool); 44 | System.out.println("Isolation Forest Test is Finished"); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Tool/FileTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | import com.anomalydetect.ReadJson.Data; 4 | import com.anomalydetect.ReadJson.Datas; 5 | import com.anomalydetect.ReadJson.Item; 6 | import com.google.gson.Gson; 7 | 8 | import java.io.FileNotFoundException; 9 | import java.io.FileReader; 10 | import java.io.Reader; 11 | 12 | /** 13 | * @author mezereon E-mail:mezereonxp@gmail.com 14 | * @since 18-4-12 15 | */ 16 | public class FileTool { 17 | 18 | /** 19 | * 通过json文件获取时间序列数据 20 | */ 21 | public static double[] getData(String filePath) throws FileNotFoundException { 22 | Gson gson = new Gson(); 23 | Reader reader = new FileReader(filePath); 24 | Item[] items = gson.fromJson(reader, Item[].class); 25 | double[] series = new double[items.length]; 26 | 27 | System.out.println(items.length); 28 | 29 | int i = 0; 30 | for (Item item : items) { 31 | series[i++] = item.getEvent().getTotal_count() / (60 * 60 * 1000); 32 | System.out.print(item.getEvent().getTotal_count() / (60 * 60 * 1000) + ", "); 33 | } 34 | System.out.println(); 35 | return series; 36 | 37 | } 38 | 39 | 40 | /** 41 | * 通过json文件获取时间序列数据 42 | */ 43 | public static double[] getData2(String filePath) throws FileNotFoundException { 44 | Gson gson = new Gson(); 45 | Reader reader = new FileReader(filePath); 46 | Data[] items = gson.fromJson(reader, Data[].class); 47 | double[] series = new double[items.length]; 48 | 49 | System.out.println(items.length); 50 | 51 | int i = 0; 52 | for (Data item : items) { 53 | series[i++] = item.getCaiji_zhi(); 54 | System.out.print(item.getCaiji_zhi() + ", "); 55 | } 56 | System.out.println(); 57 | return series; 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ESD/GrubbsTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ESD; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | import com.anomalydetect.Tool.MathTool; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * @program: GrubbsTool 11 | * @description: Grubbs method to detect anomaly point 12 | * @author: mezereonxp Email: mezereonxp@gmail.com 13 | * @create: 2018-05-03 15:08 14 | **/ 15 | public class GrubbsTool implements DetectTool { 16 | 17 | private double average;// 平均值 18 | private double stdDeviation;// 样本标准差 19 | private double[] G;// 可疑值 20 | private double G_MAX = 3.754;// 100个样本执行概率为99.50%的阈值 21 | private ArrayList results;// 结果集 22 | 23 | public GrubbsTool() { 24 | } 25 | 26 | public GrubbsTool(double g) { 27 | G_MAX = g; 28 | } 29 | 30 | public void timeSeriesAnalyse(double[] data) { 31 | results = new ArrayList(); 32 | average = MathTool.getAverageFromArray(data); 33 | stdDeviation = MathTool.getStdDeviation(data); 34 | G = new double[data.length]; 35 | for (int i = 0; i < data.length; i++) { 36 | G[i] = (data[i] - average) / stdDeviation; 37 | if (G[i] > G_MAX) { 38 | results.add(new Result(i, data[i])); 39 | System.out.println("Anomaly point! value is : " + data[i]); 40 | } 41 | } 42 | } 43 | 44 | public ArrayList getResults() { 45 | return this.results; 46 | } 47 | 48 | public double getAverage() { 49 | return average; 50 | } 51 | 52 | public void setAverage(double average) { 53 | this.average = average; 54 | } 55 | 56 | public double getStdDeviation() { 57 | return stdDeviation; 58 | } 59 | 60 | public void setStdDeviation(double stdDeviation) { 61 | this.stdDeviation = stdDeviation; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/LOF/Experiment.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.LOF; 2 | 3 | import com.anomalydetect.Tool.FileTool; 4 | import com.anomalydetect.Util.MatrixUtil; 5 | 6 | import java.io.FileNotFoundException; 7 | 8 | /** 9 | * @author mezereon E-mail:mezereonxp@gmail.com 10 | * @since 18-4-26 11 | */ 12 | public class Experiment { 13 | 14 | public static final int T = 200; 15 | public static final int L = 50; 16 | 17 | /** 18 | * Test the LOF 19 | * 20 | * @param args 21 | * @throws FileNotFoundException 22 | */ 23 | public static void main(String[] args) throws FileNotFoundException { 24 | 25 | double[] series = FileTool.getData("data.json"); 26 | double[][] mat = MatrixUtil.getMat(series, T, series.length - T - L + 1, L); 27 | double[] test = null; 28 | 29 | double[][] matC = new double[L][series.length - T - L - 1]; 30 | double[][] matT = new double[L][T]; 31 | 32 | matC = MatrixUtil.getMatC(mat, T, series.length - T - L + 1, L); 33 | matT = MatrixUtil.getMatT(mat, T, series.length - T - L + 1, L); 34 | 35 | // MatrixUtil.printMatrix(matC); 36 | // MatrixUtil.printMatrix(matT); 37 | 38 | LOF lof = new LOF(1); 39 | 40 | double[] ncmForC = new double[matC.length]; 41 | double ncmForTest = -1; 42 | 43 | for (int i = 0; i < matC.length; i++) { 44 | ncmForC[i] = lof.getLOF(matT, matC[i]); 45 | } 46 | 47 | double[] scores = new double[series.length / L + 1]; 48 | 49 | System.out.println("-------------------------------"); 50 | test = MatrixUtil.getTestSeries(series, series.length - L - 1, L); 51 | ncmForTest = lof.getLOF(matT, test); 52 | double count = 0; 53 | for (double x : ncmForC) { 54 | if (ncmForTest <= x) { 55 | count++; 56 | } 57 | } 58 | count /= matC.length; 59 | System.out.println(count); 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | --- 4 | # AnomalyDetectTool 5 | 6 | > A tool of detecting anomaly points from data 7 | 8 | 9 | 现在已经传到中央仓库, 可以直接在依赖添加如下代码来使用 10 | ```xml 11 | 12 | com.github.mezereonxp 13 | AnomalyDetectTool 14 | 1.1.1 15 | 16 | ``` 17 | 18 | ### LOF-ICAD 算法的使用 19 | You can use this tool like: 20 | 21 | ```java 22 | testData = FileTool.getData("data.json"); 23 | LOFDetectTool lofDetectTool = new LOFDetectTool(200, 20); 24 | lofDetectTool.timeSeriesAnalyse(testData); 25 | ``` 26 | 27 | 关于其算法细节可以查看我的文章,给出地址: 28 | https://www.jianshu.com/p/ec40dd7b6b37 29 | 30 | 31 | ### 指数平滑模型的使用 32 | You can use this tool like: 33 | ```java 34 | HoltWintersTool holtWintersTool = new HoltWintersTool(ALPHA, STEP, TIMES); 35 | holtWintersTool.timeSeriesAnalyse(testData); 36 | ``` 37 | 38 | 关于其算法细节可以查看我的文章,给出地址: 39 | https://www.jianshu.com/p/a2dbd47b3f1a 40 | 41 | 42 | ### Grubbs模型的使用 43 | You can use this tool like: 44 | ```java 45 | GrubbsTool grubbsTool = new GrubbsTool (G_MAX); 46 | grubbsTool.timeSeriesAnalyse(testData); 47 | ``` 48 | 49 | ### BF模型的使用 50 | You can use this tool like: 51 | ```java 52 | BruteForceTool bruteForceTool = new BruteForceTool(10); 53 | bruteForceTool.timeSeriesAnalyse(data); 54 | ``` 55 | 56 | ### Heuristic模型的使用 57 | You can use this tool like: 58 | ```java 59 | HeuristicTool heuristicTool = new HeuristicTool(3); 60 | heuristicTool.timeSeriesAnalyse(testData); 61 | ``` 62 | 63 | ### Isolation Tree模型的使用 64 | You can use this tool like: 65 | ```java 66 | IsolaitonTool isolationTool = new IsolationTool(); 67 | isolationTreeTool.timeSeriesAnalyse(testData); 68 | ``` 69 | 70 | ### 结果显示工具的使用 71 | You can use this tool like: 72 | ```java 73 | BruteForceTool bruteForceTool = new BruteForceTool(10); 74 | bruteForceTool.timeSeriesAnalyse(data); 75 | DisplayTool.showResult(bruteForceTool); 76 | ``` 77 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/IsolationTree/IsolationForest.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.IsolationTree; 2 | 3 | import com.anomalydetect.Tool.MathTool; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Random; 7 | 8 | public class IsolationForest { 9 | private ArrayList forest;//存放的每一棵树的集合 10 | private int maxTreeNum;//森林中最多容纳树的数量 11 | private int maxTreeHeight;//每一棵树最大的高度 12 | private int subSamplingNum;//随机抽样数目 13 | private int dataLengeth;//数据长度 14 | 15 | public IsolationForest(int maxTreeNum, int maxSampling) { 16 | this.subSamplingNum = maxSampling; 17 | this.maxTreeNum = maxTreeNum; 18 | this.maxTreeHeight = (int) Math.ceil(MathTool.log2(maxSampling)); 19 | this.forest = new ArrayList(maxTreeNum); 20 | } 21 | 22 | /** 23 | * 创建用所给的数据创建孤立森林 24 | * 25 | * @param data 26 | */ 27 | public void createForest(double[] data) { 28 | this.dataLengeth = data.length; 29 | boolean isSample = false; 30 | if (data.length > this.subSamplingNum) { 31 | isSample = true; 32 | } 33 | for (int i = 0; i < maxTreeNum; i++) { 34 | IsolationTree iTree = new IsolationTree(); 35 | if (isSample) { 36 | data = subSampling(data); 37 | } 38 | iTree.create(data, this.maxTreeHeight); 39 | forest.add(iTree); 40 | } 41 | } 42 | 43 | /** 44 | * 从森林中查找数值d 的深度, 返回一个异常分数 45 | * 46 | * @param d 47 | * @return 48 | */ 49 | public double searchForest(double d) { 50 | double hx = 0; 51 | for (IsolationTree tree : this.forest) { 52 | hx += tree.pathLength(d); 53 | } 54 | double cn = 2 * (Math.log(this.dataLengeth - 1.0) + MathTool.EulerConstant) - 2 * (this.dataLengeth - 1) / this.dataLengeth; 55 | return Math.pow(2, -hx / this.maxTreeNum / cn); 56 | } 57 | 58 | /** 59 | * 对数据进行随机抽样 60 | * 61 | * @param data 62 | * @return 63 | */ 64 | private double[] subSampling(double[] data) { 65 | int n = data.length; 66 | double[] sample = new double[this.subSamplingNum]; 67 | for (int i = 0; i < this.subSamplingNum; i++) { 68 | int r = new Random().nextInt(n); 69 | sample[i] = data[r]; 70 | data[r] = data[--n]; 71 | } 72 | return sample; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/IsolationTree/IsolationTreeTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.IsolationTree; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class IsolationTreeTool implements DetectTool { 10 | 11 | private int maxTreeNum = 100; 12 | private int maxSampling = 256; 13 | private double factor = 0.6f; 14 | 15 | private ArrayList results; 16 | private IsolationForest forest; 17 | 18 | public IsolationTreeTool() { 19 | } 20 | 21 | public IsolationTreeTool(int maxTreeNum, int maxSampling) { 22 | this.maxTreeNum = maxTreeNum; 23 | this.maxSampling = maxSampling; 24 | } 25 | 26 | @Override 27 | public void timeSeriesAnalyse(double[] data) { 28 | this.results = new ArrayList(); 29 | if (data.length > maxSampling) { 30 | System.out.println("[IsolationTreeTool]: The MaxSampling is less than the data length!"); 31 | System.out.println("[IsolationTreeTool]: We have changed the MaxSampling to fit the data length!"); 32 | maxSampling = data.length; 33 | } 34 | IsolationForest tempForest = new IsolationForest(maxTreeNum, maxSampling); 35 | tempForest.createForest(data.clone()); 36 | this.forest = tempForest; 37 | cutAnomaly(data, factor); 38 | } 39 | 40 | /** 41 | * 选出所有异常值 42 | * 43 | * @param data 44 | * @param factor 45 | */ 46 | public void cutAnomaly(double[] data, double factor) { 47 | for (int i = 0; i < data.length; i++) { 48 | if (this.forest.searchForest(data[i]) > factor) { 49 | this.results.add(new Result(i, data[i])); 50 | } 51 | } 52 | } 53 | 54 | @Override 55 | public List getResults() { 56 | return results; 57 | } 58 | 59 | public int getMaxSampling() { 60 | return maxSampling; 61 | } 62 | 63 | public void setMaxSampling(int maxSampling) { 64 | this.maxSampling = maxSampling; 65 | } 66 | 67 | public int getMaxTreeNum() { 68 | return maxTreeNum; 69 | } 70 | 71 | public void setMaxTreeNum(int maxTreeNum) { 72 | this.maxTreeNum = maxTreeNum; 73 | } 74 | 75 | public double getFactor() { 76 | return factor; 77 | } 78 | 79 | public void setFactor(double factor) { 80 | this.factor = factor; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/LOF/LOFDetectTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.LOF; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | import com.anomalydetect.Util.MatrixUtil; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * @author mezereon E-mail:mezereonxp@gmail.com 11 | * @since 18-4-26 12 | */ 13 | public class LOFDetectTool implements DetectTool { 14 | 15 | private int T;// 时间序列用来训练的长度 16 | private int L;// 时间序列的所利用的窗口长度 17 | private int K = 1;// LOF算法中的k值, 默认设置为1, 也就是取历史最相似的序列进行预测 18 | private ArrayList results; 19 | 20 | /** 21 | * LOF检测工具的构造方法 22 | * 23 | * @param T 时间序列用来训练的长度 24 | * @param L 时间序列的所利用的窗口长度 25 | */ 26 | public LOFDetectTool(int T, int L) { 27 | this.T = T; 28 | this.L = L; 29 | } 30 | 31 | /** 32 | * 利用LOF进行时间序列分析 33 | * 打印最后一段窗口的异常分数, 越接近1则越异常 34 | */ 35 | public void timeSeriesAnalyse(double[] series) { 36 | 37 | // 利用T和L, 以及时间序列生成测试矩阵 38 | double[][] mat = MatrixUtil.getMat(series, T, series.length - T - L + 1, L); 39 | 40 | //一个窗口大小的测试序列, 默认是原序列中最后窗口大小的序列 41 | double[] test = MatrixUtil.getTestSeries(series, series.length - L, L); 42 | ; 43 | 44 | double[][] matC = MatrixUtil.getMatC(mat, T, series.length - T - L + 1, L); 45 | double[][] matT = MatrixUtil.getMatT(mat, T, series.length - T - L + 1, L); 46 | 47 | LOF lof = new LOF(K); 48 | 49 | double[] ncmForC = new double[matC.length]; 50 | 51 | for (int i = 0; i < matC.length; i++) { 52 | ncmForC[i] = lof.getLOF(matT, matC[i]); 53 | } 54 | 55 | double ncmForTest = lof.getLOF(matT, test); 56 | double count = 0; 57 | for (double x : ncmForC) { 58 | if (ncmForTest <= x) { 59 | count++; 60 | } 61 | } 62 | count /= matC.length; 63 | System.out.println("Anomaly Score is " + count); 64 | } 65 | 66 | public int getT() { 67 | return T; 68 | } 69 | 70 | public void setT(int t) { 71 | T = t; 72 | } 73 | 74 | public int getL() { 75 | return L; 76 | } 77 | 78 | public void setL(int l) { 79 | L = l; 80 | } 81 | 82 | public int getK() { 83 | return K; 84 | } 85 | 86 | public void setK(int k) { 87 | K = k; 88 | } 89 | 90 | public ArrayList getResults() { 91 | return results; 92 | } 93 | 94 | public void setResults(ArrayList results) { 95 | this.results = results; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/BruteForce/AlphabetTreeNode.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @program: anomaly-detection 8 | * @description: A node of AlphabetTree 9 | * @author: mezereonxp Email: mezereonxp@gmail.com 10 | * @create: 2018-05-11 14:13 11 | **/ 12 | public class AlphabetTreeNode { 13 | 14 | private boolean isLeaf; 15 | private boolean isRoot; 16 | private char label; 17 | private List notes; 18 | private List nodeList; 19 | 20 | /** 21 | * Constructor 22 | * 23 | * @param isLeaf 是否是叶子节点 24 | * @param label 所带的label值 25 | * @param isRoot 是否是根节点 26 | */ 27 | AlphabetTreeNode(boolean isLeaf, char label, boolean isRoot) { 28 | this.isLeaf = isLeaf; 29 | this.label = label; 30 | this.isRoot = isRoot; 31 | nodeList = new ArrayList(); 32 | if (isLeaf) { 33 | notes = new ArrayList(); 34 | } 35 | } 36 | 37 | /** 38 | * 判断是否含有label 39 | * 40 | * @param label 41 | * @return 42 | */ 43 | public boolean isHaveLabel(char label) { 44 | return getNodeByLabel(label) != null; 45 | } 46 | 47 | /** 48 | * 通过label获取节点 49 | * 50 | * @param label 51 | * @return 52 | */ 53 | public AlphabetTreeNode getNodeByLabel(char label) { 54 | for (AlphabetTreeNode node : nodeList) { 55 | if (node.label == label) { 56 | return node; 57 | } 58 | } 59 | return null; 60 | } 61 | 62 | public void increase(char label) { 63 | for (Notes notes : getNodeByLabel(label).notes) { 64 | notes.setCount(notes.getCount() + 1); 65 | } 66 | } 67 | 68 | public boolean isRoot() { 69 | return isRoot; 70 | } 71 | 72 | public void setRoot(boolean root) { 73 | isRoot = root; 74 | } 75 | 76 | public List getNodeList() { 77 | return nodeList; 78 | } 79 | 80 | public void setNodeList(List nodeList) { 81 | this.nodeList = nodeList; 82 | } 83 | 84 | public boolean isLeaf() { 85 | return isLeaf; 86 | } 87 | 88 | public void setLeaf(boolean leaf) { 89 | isLeaf = leaf; 90 | } 91 | 92 | public char getLabel() { 93 | return label; 94 | } 95 | 96 | public void setLabel(char label) { 97 | this.label = label; 98 | } 99 | 100 | public List getNotes() { 101 | return notes; 102 | } 103 | 104 | public void setNotes(List notes) { 105 | this.notes = notes; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/BruteForce/BruteForceTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | import com.anomalydetect.Tool.MathTool; 6 | import com.anomalydetect.Tool.MultiDetectTool; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @program: AnomalyDetectTool 13 | * @description: Using Brute Force Algorithm to find anomaly subsequence 14 | * @author: mezereonxp Email: mezereonxp@gmail.com 15 | * @create: 2018-05-10 15:03 16 | **/ 17 | public class BruteForceTool implements DetectTool, MultiDetectTool { 18 | 19 | private ArrayList results; 20 | 21 | private int length; 22 | 23 | public BruteForceTool(int length) { 24 | this.length = length; 25 | } 26 | 27 | public void timeSeriesAnalyse(double[] data) { 28 | results = new ArrayList(); 29 | double bestDist = 0; 30 | int bestLoc = -1; 31 | 32 | for (int p = 0; p < data.length - length + 1; p++) { 33 | double tempDist = Double.MAX_VALUE; 34 | for (int q = 0; q < data.length - length + 1; q++) { 35 | if (Math.abs(p - q) >= length && MathTool.dist(data, p, q, length) < tempDist) { 36 | tempDist = MathTool.dist(data, p, q, length); 37 | } 38 | } 39 | if (tempDist > bestDist) { 40 | bestDist = tempDist; 41 | bestLoc = p; 42 | } 43 | } 44 | results.add(new Result(bestLoc, data[bestLoc])); 45 | } 46 | 47 | @Override 48 | public void multiTimeSeriesAnalyse(double[][] data, int dimension) { 49 | results = new ArrayList(); 50 | double bestDist = 0; 51 | int bestLoc = -1; 52 | 53 | for (int p = 0; p < data.length - length + 1; p++) { 54 | double tempDist = Double.MAX_VALUE; 55 | for (int q = 0; q < data.length - length + 1; q++) { 56 | if (Math.abs(p - q) >= length && MathTool.distForMulti(data, p, q, length, dimension) < tempDist) { 57 | tempDist = MathTool.distForMulti(data, p, q, length, dimension); 58 | } 59 | } 60 | if (tempDist > bestDist) { 61 | bestDist = tempDist; 62 | bestLoc = p; 63 | } 64 | } 65 | results.add(new Result(bestLoc, data[bestLoc])); 66 | } 67 | 68 | public List getResults() { 69 | return results; 70 | } 71 | 72 | public void setResults(ArrayList results) { 73 | this.results = results; 74 | } 75 | 76 | public int getLength() { 77 | return length; 78 | } 79 | 80 | public void setLength(int length) { 81 | this.length = length; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/LOF/readme.md: -------------------------------------------------------------------------------- 1 | 数据的异常检测是一个难题, 面临许多挑战, 其中包括: 2 | - 定义一个正常表现的范围是比较困难的, 异常值和正常值有时候边界并不是特别明显 3 | - 某些恶意行为会伪装成正常值, 难以发现 4 | - 大多数领域的正常行为只能在一段时间内有效, 对于未来的普适性并不是很高 5 | - 对于异常的概念会由于应用的不同而不同 6 | - 缺少带有标记的数据 7 | - 数据的噪声可能有较大的影响 8 | 9 | 分析异常数据有多种方案, 包括: 10 | - 基于分类的手段 11 | - 基于最近邻算法 12 | - 基于聚类 13 | - 基于统计方法 14 | - 基于信息理论 15 | - 基于特征理论 16 | 17 | 我们这次着重介绍的是时序数据的异常检测, 我们来讨论讨论LOF方法, 并且给出相应的代码实现 18 | 19 | ### 1. LOF方法简介 20 | > 该方法源自于论文**Conformalized density- and distance-based anomaly detection in time-series data** 21 | 22 | LOF方法也就是**Local Outlier Factor**的缩写 23 | 首先我们需要引入一些符号: 24 | **k**: 类似于KNN中的k, 代表第k个相邻的 25 | **dist(a,b)**: 表示a和b之间的距离, 可以是几何距离, 也可以是曼哈顿距离等 26 | 27 | LOF方法使用对于第k个邻居的反向平均距离(**Inverted average distance**)来进行一个密度的测量, 我们记作loc_dens 28 | ![密度的测量](https://upload-images.jianshu.io/upload_images/2601951-1691df13ef51485f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 29 | 30 | 同时我们给出其中的reach_dist 31 | ![reach_dist](https://upload-images.jianshu.io/upload_images/2601951-4620910dbe2c0713.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 32 | 其中NN_k(x)是x的第k个近邻, 而reach_dist是为了当x和o彼此靠近的时候减少统计波动 33 | 34 | 我们计算出密度之后, 就要利用该密度和其他近邻的点进行比较, 进而我们就可以计算出异常程度的分数, 记为LOF, 按如下方法进行计算: 35 | ![LOF](https://upload-images.jianshu.io/upload_images/2601951-83613c89decf80a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 36 | 37 | 如果LOF越大则说明异常程度越高 38 | 39 | ### 2. LOF-ICAD方法 40 | 基于LOF方法, 论文给出了一种特征抽取的方法, 进一步提高了精度 41 | 这里直接给出算法的细节: 42 | #### 输入: 43 | - **窗口长度L** 44 | - **合适的训练集合的大小T** 45 | - **修正集合的大小C** 46 | - **时间序列(x1, ... , x(T+C+L-1))** 47 | - **测试的值x(T+C+L)** 48 | - **密度测量NCM** 49 | 50 | #### 输出(异常分数p, 从0到1): 51 | 步骤: 52 | 1. 将时间序列(x1, ... , x(T+C+L-1))映射到矩阵X, 其中矩阵X是L x (T+C)的矩阵 53 | 举个例子, 比如对于时间序列(1, 2, 3, 4, 5, 6), T=2, C=2, L=3 54 | 则生成X矩阵为 55 | 1, 2, 3, 4 56 | 2, 3, 4, 5 57 | 3, 4, 5, 6 58 | 2. 将矩阵X划分成训练矩阵X(T)(L x T大小)以及修正矩阵X(C)(L x C大小) 59 | 如上述例子, X(T)为: 60 | 1, 2 61 | 2, 3 62 | 3, 4 63 | 3. 计算NCM值(α1, ..., αC)对于修正矩阵X(C)的每一行(应该会有L行) 64 | ![NCM](https://upload-images.jianshu.io/upload_images/2601951-d1fed0fc5b5e63cf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 65 | 具体的NCM值的计算也就是LOF的计算方式得到 66 | 4. 对序列最后的x(T+C+L-1)计算NCM值 67 | ![计算序列末尾的NCM](https://upload-images.jianshu.io/upload_images/2601951-b9e0baef2e943745.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 68 | 5. 计算异常程度分数p 69 | ![p的计算](https://upload-images.jianshu.io/upload_images/2601951-d4e8785fdba44866.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 70 | 71 | 如果p的分数特别高, 则异常程度相应地越高 72 | 73 | ### 3. 测试 74 | ![测试序列1](https://upload-images.jianshu.io/upload_images/2601951-8ceddc91c23b7aae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 75 | 对于上图序列计算得到的窗口异常分数为0.007092198 76 | 我们给它加一个峰值 77 | ![测试序列2](https://upload-images.jianshu.io/upload_images/2601951-06a191efe2fd0313.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 78 | 得到的窗口异常分数为0.950354609 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/IsolationTree/IsolationTree.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.IsolationTree; 2 | 3 | import com.anomalydetect.Tool.MathTool; 4 | 5 | import java.util.Arrays; 6 | 7 | public class IsolationTree { 8 | private IsolationTreeNode root;//树的根节点 9 | 10 | /** 11 | * 创建树 12 | * 13 | * @param data 14 | * @param maxHeight 15 | */ 16 | public void create(double[] data, int maxHeight) { 17 | Arrays.sort(data); 18 | root = createByR(data, 0, maxHeight, 0, data.length - 1); 19 | } 20 | 21 | /** 22 | * 通过递归创建树,树的递归体 23 | * 24 | * @param data 25 | * @param currentHeight 26 | * @param maxHeight 27 | * @param start 28 | * @param end 29 | * @return 30 | */ 31 | private IsolationTreeNode createByR(double[] data, int currentHeight, int maxHeight, int start, int end) { 32 | if (start > end) return null; 33 | if (currentHeight == maxHeight || end == start) { 34 | IsolationTreeNode node = new IsolationTreeNode(0.0); 35 | node.size = end - start + 1; 36 | return node; 37 | } 38 | 39 | double min = data[start]; 40 | double max = data[end]; 41 | double divd = min + (max - min) * Math.random(); 42 | int divideIndex; 43 | for (divideIndex = start; divideIndex <= end; divideIndex++) { 44 | if (data[divideIndex] >= divd) { 45 | break; 46 | } 47 | } 48 | if (min == max) { 49 | divideIndex = (start + end) / 2; 50 | } 51 | IsolationTreeNode node = new IsolationTreeNode(divd); 52 | node.left = createByR(data, currentHeight + 1, maxHeight, start, divideIndex - 1); 53 | node.right = createByR(data, currentHeight + 1, maxHeight, divideIndex, end); 54 | return node; 55 | } 56 | 57 | /** 58 | * 从当前树查找 x 的高度 59 | * 60 | * @param x 61 | * @return 62 | */ 63 | public double pathLength(double x) { 64 | return pathLengthM(x, root, 1); 65 | } 66 | 67 | /** 68 | * 通过递归查找值 69 | * 70 | * @param x 71 | * @param node 72 | * @param currHeight 73 | * @return 74 | */ 75 | private double pathLengthM(double x, IsolationTreeNode node, int currHeight) { 76 | if (node.isExtenal()) { 77 | return currHeight + e(node.size); 78 | } 79 | if (x >= node.divdNum) { 80 | return pathLengthM(x, node.right, currHeight + 1); 81 | } else { 82 | return pathLengthM(x, node.left, currHeight + 1); 83 | } 84 | } 85 | 86 | /** 87 | * 对节点的一个标准化,主要作用是放大 n 大于 1 的数,缩小 n 等于 1的数 88 | * 89 | * @param n 90 | * @return 91 | */ 92 | private double e(int n) { 93 | double s = (double) n; 94 | return 2 * (Math.log(s) + MathTool.EulerConstant) + 2 * (s - 1) / s; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Util/MatrixUtil.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Util; 2 | 3 | /** 4 | * Local Outlier Factor 5 | * 6 | * @author mezereon E-mail:mezereonxp@gmail.com 7 | * @since 18-4-12 8 | */ 9 | 10 | public class MatrixUtil { 11 | 12 | public static final String PARA_ERROR_MSG = "Parameters Error"; 13 | 14 | /** 15 | * 利用时间序列获取相应大小的矩阵 16 | * 17 | * @param series 时间序列 18 | * @param T 训练集合长度 19 | * @param C 候选集合长度 20 | * @param L 窗口长度 21 | * @return 返回一个Lx(T*C)的矩阵 22 | */ 23 | public static double[][] getMat(double[] series, int T, int C, int L) { 24 | if (series.length != (T + C + L - 1)) { 25 | System.out.println(PARA_ERROR_MSG); 26 | return null; 27 | } 28 | 29 | double[][] mat = new double[L][T + C]; 30 | for (int i = 0; i < L; i++) { 31 | for (int j = 0; j < T + C; j++) { 32 | mat[i][j] = series[i + j]; 33 | } 34 | } 35 | return mat; 36 | } 37 | 38 | /** 39 | * 利用时间序列数据, 获取所需大小的测试序列 40 | * 41 | * @param series 时间序列数据 42 | * @param begin 计算开始的位置 43 | * @param L 计算的窗口大小 44 | * @return 返回所需大小的测试序列 45 | */ 46 | public static double[] getTestSeries(double[] series, int begin, int L) { 47 | 48 | double[] mat = new double[L]; 49 | for (int i = 0; i < L; i++) { 50 | mat[i] = series[i + begin]; 51 | } 52 | return mat; 53 | } 54 | 55 | /** 56 | * 计算并返回C矩阵 57 | * 58 | * @param m 输入矩阵 59 | * @param T 训练集合长度 60 | * @param C 候选集合长度 61 | * @param L 窗口长度 62 | * @return 返回LOF算法中的C矩阵 63 | */ 64 | public static double[][] getMatC(double[][] m, int T, int C, int L) { 65 | 66 | double[][] mat = new double[C][L]; 67 | for (int i = 0; i < L; i++) { 68 | for (int j = T; j < T + C; j++) { 69 | mat[j - T][i] = m[i][j]; 70 | } 71 | } 72 | return mat; 73 | } 74 | 75 | /** 76 | * 计算并返回测试矩阵 77 | * 78 | * @param m 输入矩阵 79 | * @param T 训练集合长度 80 | * @param C 候选集合长度 81 | * @param L 窗口长度 82 | * @return 测试矩阵 83 | */ 84 | public static double[][] getMatT(double[][] m, int T, int C, int L) { 85 | 86 | double[][] mat = new double[T][L]; 87 | for (int i = 0; i < L; i++) { 88 | for (int j = 0; j < T; j++) { 89 | mat[j][i] = m[i][j]; 90 | } 91 | } 92 | return mat; 93 | } 94 | 95 | /** 96 | * 将矩阵内容打印出来 97 | * 98 | * @param m 矩阵数组 99 | */ 100 | public static void printMatrix(double[][] m) { 101 | for (int i = 0; i < m.length; i++) { 102 | for (int j = 0; j < m[i].length; j++) { 103 | System.out.print(m[i][j] + "\t"); 104 | } 105 | System.out.println(); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/LOF/LOF.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.LOF; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * Local Outlier Factor 7 | * 8 | * @author mezereon E-mail:mezereonxp@gmail.com 9 | * @since 18-4-12 10 | */ 11 | public class LOF { 12 | 13 | private int k; 14 | 15 | public LOF(int k) { 16 | this.k = k; 17 | } 18 | 19 | /** 20 | * 返回异常程度的分数, 越接近1则越异常 21 | * 22 | * @param knn 输入一个时序数据生成的旋转矩阵 23 | * @param x 输入测试的序列 24 | */ 25 | public double getLOF(double[][] knn, double[] x) { 26 | double sum = 0; 27 | for (double[] o : knn) { 28 | sum += getLocDens(knn, o) / getLocDens(knn, x); 29 | } 30 | return sum / k; 31 | } 32 | 33 | /** 34 | * 获取local density 35 | * 36 | * @param knn 输入一个时序数据生成的旋转矩阵 37 | * @param x 输入测试的序列 38 | */ 39 | public double getLocDens(double[][] knn, double[] x) { 40 | double[] nnk = findKthPoint(knn, x); 41 | 42 | double sum = 0; 43 | for (double[] o : knn) { 44 | sum += reachDist(o, x, nnk); 45 | } 46 | return sum / k; 47 | } 48 | 49 | /** 50 | * 找到第k个相似的序列 51 | * 52 | * @param knn 输入一个时序数据生成的旋转矩阵 53 | * @param x 输入测试的序列 54 | */ 55 | public double[] findKthPoint(double[][] knn, double[] x) { 56 | 57 | ArrayList list = new ArrayList(); 58 | for (int i = 0; i < knn.length; i++) { 59 | list.add(knn[i]); 60 | } 61 | int index = 0; 62 | double minDist = dist(knn[0], x); 63 | 64 | for (int i = 0; i < k; i++) { 65 | index = 0; 66 | minDist = dist((double[]) list.get(0), x); 67 | for (int j = 0; j < list.size(); j++) { 68 | if (minDist > dist((double[]) list.get(j), x)) { 69 | minDist = dist((double[]) list.get(j), x); 70 | index = j; 71 | } 72 | } 73 | if (i != k - 1) { 74 | list.remove(index); 75 | } 76 | } 77 | 78 | return (double[]) list.get(index); 79 | } 80 | 81 | /** 82 | * 返回与相似序列的距离比较之下的较大值 83 | * 84 | * @param o 输入序列 85 | * @param x 测试序列 86 | * @param nnk 第k相似的序列 87 | */ 88 | public double reachDist(double[] o, double[] x, double[] nnk) { 89 | return Math.max(dist(o, x), dist(nnk, x)); 90 | } 91 | 92 | /** 93 | * 返回序列之间的欧几里德距离 94 | * 95 | * @param nnk 第k相似的序列 96 | * @param x 测试序列 97 | */ 98 | private double dist(double[] nnk, double[] x) { 99 | 100 | double sum = 0; 101 | for (int i = 0; i < nnk.length; i++) { 102 | sum += (nnk[i] - x[i]) * (nnk[i] - x[i]); 103 | } 104 | 105 | return Math.sqrt(sum); 106 | } 107 | 108 | public int getK() { 109 | return k; 110 | } 111 | 112 | public void setK(int k) { 113 | this.k = k; 114 | } 115 | } -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/Tool/MathTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.Tool; 2 | 3 | /** 4 | * @program: AnomalyDetectTool 5 | * @description: The Tool to do some useful calculations 6 | * @author: mezereonxp Email: mezereonxp@gmail.com 7 | * @create: 2018-04-28 16:38 8 | **/ 9 | public class MathTool { 10 | 11 | private MathTool() { 12 | } 13 | 14 | public static double EulerConstant = 0.57721566490153286060651209; 15 | 16 | /** 17 | * 计算两个长度为n的序列的欧几里德距离并返回 18 | * 19 | * @param data 时间序列数据 20 | * @param p 序列1的开始位置 21 | * @param q 序列2的开始位置 22 | * @param length 序列的长度 23 | * @return 24 | */ 25 | public static double dist(double[] data, int p, int q, int length) { 26 | double dist = 0; 27 | for (int i = 0; i < length; i++) { 28 | dist += Math.pow(data[p + i] - data[q + i], 2); 29 | } 30 | return Math.sqrt(dist); 31 | } 32 | 33 | /** 34 | * 计算两个长度为n的多维度序列的欧几里德距离并返回 35 | * 36 | * @param data 时间序列数据 37 | * @param p 序列1的开始位置 38 | * @param q 序列2的开始位置 39 | * @param length 序列的长度 40 | * @return 41 | */ 42 | public static double distForMulti(double[][] data, int p, int q, int length, int n) { 43 | double dist = 0; 44 | for (int i = 0; i < length; i++) { 45 | for (int j = 0; j < n; j++) { 46 | dist += Math.pow(data[p + i][j] - data[q + i][j], 2); 47 | } 48 | } 49 | return Math.sqrt(dist); 50 | } 51 | 52 | /** 53 | * 正态化 54 | * 55 | * @param data 56 | * @return 57 | */ 58 | public static double[] gassian(double[] data) { 59 | double[] temp = data.clone(); 60 | double avg = getAverageFromArray(data); 61 | double s = getStdDeviation(data); 62 | for (int i = 0; i < data.length; i++) { 63 | temp[i] = (temp[i] - avg) / s; 64 | } 65 | return temp; 66 | } 67 | 68 | /** 69 | * 对传入的数组进行归一化 70 | */ 71 | public static double[] normalize(double[] data) { 72 | double[] temp = data.clone(); 73 | double max = Double.MIN_VALUE; 74 | double min = Double.MAX_VALUE; 75 | for (double n : data) { 76 | if (max < n) { 77 | max = n; 78 | } 79 | if (min > n) { 80 | min = n; 81 | } 82 | } 83 | for (int i = 0; i < data.length; i++) { 84 | temp[i] = (temp[i] - min) / max; 85 | } 86 | return temp; 87 | } 88 | 89 | /** 90 | * 计算double数组的平均值 91 | */ 92 | public static double getAverageFromArray(double[] array) { 93 | double sum = 0; 94 | for (double d : array) { 95 | sum += d; 96 | } 97 | return sum / array.length; 98 | } 99 | 100 | /** 101 | * 计算double数组的标准差 102 | */ 103 | public static double getStdDeviation(double[] array) { 104 | double average = getAverageFromArray(array); 105 | double sum = 0; 106 | for (double d : array) { 107 | sum += Math.pow(d - average, 2); 108 | } 109 | return Math.sqrt(sum / (array.length - 1)); 110 | } 111 | 112 | /** 113 | * 计算以二为底的对数 114 | */ 115 | public static double log2(double value) { 116 | return Math.log(value) / Math.log(2); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ESD/ESDTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ESD; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | import com.anomalydetect.Tool.MathTool; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * @program: AnomalyDetectTool 11 | * @description: Extreme Studentized Deviate 12 | * @author: mezereonxp Email: mezereonxp@gmail.com 13 | * @create: 2018-04-28 11:41 14 | **/ 15 | public class ESDTool implements DetectTool { 16 | 17 | private double average;// 平均值 18 | private double stdDeviation;// 方差 19 | private int K;// 第k个值 20 | private double t;// t统计量 21 | private double[] g;// Grubbs统计量 22 | private ArrayList results; 23 | 24 | ESDTool(int k) { 25 | this.K = k; 26 | this.g = new double[k]; 27 | } 28 | 29 | public void timeSeriesAnalyse(double[] data) { 30 | 31 | initG(data); 32 | this.average = MathTool.getAverageFromArray(data); 33 | this.stdDeviation = MathTool.getStdDeviation(data); 34 | 35 | for (K = 1; K <= data.length; K++) { 36 | ArrayList tempResults = new ArrayList(); 37 | double kValue = this.getKExtremeValue(data, K); 38 | int n = data.length; 39 | int count = 0; 40 | for (int i = 0; i < data.length; i++) { 41 | t = Math.abs(data[i] - average) / (stdDeviation / Math.sqrt(n - K)); 42 | double lambda = (n - K) * t / (Math.sqrt((n - K - 1 + t * t) * (n - K + 1))); 43 | if (lambda < kValue) { 44 | tempResults.add(new Result(i, data[i])); 45 | count++; 46 | } 47 | } 48 | if (count == K) { 49 | results = tempResults; 50 | } 51 | } 52 | 53 | } 54 | 55 | private void initG(double[] data) { 56 | double[] temp = data.clone(); 57 | double tempAvg = MathTool.getAverageFromArray(temp); 58 | double tempS = MathTool.getStdDeviation(temp); 59 | for (int i = 0; i < K; i++) { 60 | 61 | } 62 | 63 | } 64 | 65 | public double getKExtremeValue(double[] data, int k) { 66 | double[] temp = data.clone(); 67 | for (int i = 0; i < data.length; i++) { 68 | temp[i] = Math.abs(temp[i] - average) / stdDeviation; 69 | } 70 | 71 | for (int i = 0; i < k + 1; i++) { 72 | for (int j = i + 1; j < data.length; j++) { 73 | if (temp[i] < temp[j]) { 74 | double c = temp[i]; 75 | temp[i] = temp[j]; 76 | temp[j] = c; 77 | } 78 | } 79 | } 80 | return temp[k - 1]; 81 | } 82 | 83 | public double getAverage() { 84 | return average; 85 | } 86 | 87 | public void setAverage(double average) { 88 | this.average = average; 89 | } 90 | 91 | public double getStdDeviation() { 92 | return stdDeviation; 93 | } 94 | 95 | public void setStdDeviation(double stdDeviation) { 96 | this.stdDeviation = stdDeviation; 97 | } 98 | 99 | public int getK() { 100 | return K; 101 | } 102 | 103 | public void setK(int k) { 104 | K = k; 105 | } 106 | 107 | public double getT() { 108 | return t; 109 | } 110 | 111 | public void setT(double t) { 112 | this.t = t; 113 | } 114 | 115 | public ArrayList getResults() { 116 | return results; 117 | } 118 | 119 | public void setResults(ArrayList results) { 120 | this.results = results; 121 | } 122 | 123 | public double[] getG() { 124 | return g; 125 | } 126 | 127 | public void setG(double[] g) { 128 | this.g = g; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/BruteForce/HeuristicTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.BruteForce; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | import com.anomalydetect.Tool.MathTool; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * @program: anomaly-detection 12 | * @description: An Algorithm to speed up BF 13 | * @author: mezereonxp Email: mezereonxp@gmail.com 14 | * @create: 2018-05-11 11:13 15 | **/ 16 | public class HeuristicTool implements DetectTool { 17 | 18 | private int w;// SAX表达的word的长度 19 | private int a = 3;// 字母表的个数 20 | private List results; 21 | private char initChar = 'a'; 22 | 23 | HeuristicTool(int w) { 24 | this.w = w; 25 | results = new ArrayList(); 26 | } 27 | 28 | @Override 29 | public void timeSeriesAnalyse(double[] data) { 30 | double[] nums = MathTool.gassian(data); 31 | char[] chars = saxConvert(nums); 32 | results = new ArrayList(); 33 | 34 | ArrayList notes = new ArrayList(); 35 | 36 | AlphabetTree tree = new AlphabetTree(initChar, w, a); 37 | for (int i = 0; i < data.length - w + 1; i++) { 38 | Notes n = new Notes(w, chars, i, i); 39 | notes.add(n); 40 | tree.addNote(n); 41 | } 42 | int index = findMinCount(notes); 43 | doTheHeuristicAnalysis(nums, index, w, notes); 44 | 45 | } 46 | 47 | private void doTheHeuristicAnalysis(double[] data, int index, int length, ArrayList notes) { 48 | double bestDist = 0; 49 | int bestLoc = -1; 50 | notes.get(index).setVisited(true); 51 | double tempDist = Double.MAX_VALUE; 52 | for (int q = 0; q < data.length - length + 1; q++) { 53 | if (Math.abs(index - q) >= length && MathTool.dist(data, index, q, length) < tempDist) { 54 | tempDist = MathTool.dist(data, index, q, length); 55 | } 56 | } 57 | if (tempDist > bestDist) { 58 | bestDist = tempDist; 59 | bestLoc = index; 60 | } 61 | 62 | for (int p = 0; p < data.length - length + 1; p++) { 63 | if (!notes.get(p).isVisited()) { 64 | tempDist = Double.MAX_VALUE; 65 | for (int q = 0; q < data.length - length + 1; q++) { 66 | if (Math.abs(p - q) >= length && MathTool.dist(data, p, q, length) < bestDist) { 67 | if (tempDist == Double.MAX_VALUE) { 68 | tempDist = Double.MIN_VALUE; 69 | } 70 | break; 71 | } 72 | if (Math.abs(p - q) >= length && MathTool.dist(data, p, q, length) < tempDist) { 73 | tempDist = MathTool.dist(data, p, q, length); 74 | } 75 | } 76 | if (tempDist > bestDist) { 77 | bestDist = tempDist; 78 | bestLoc = p; 79 | } 80 | } 81 | } 82 | results.add(new Result(bestLoc, data[bestLoc])); 83 | } 84 | 85 | private int findMinCount(ArrayList notes) { 86 | int min = Integer.MAX_VALUE; 87 | int index = 0; 88 | int count = 0; 89 | for (Notes n : notes) { 90 | if (min > n.getCount()) { 91 | min = n.getCount(); 92 | index = count; 93 | } 94 | count++; 95 | } 96 | return index; 97 | } 98 | 99 | /** 100 | * SAX编码 101 | * 102 | * @param data 103 | * @return 104 | */ 105 | private char[] saxConvert(double[] data) { 106 | char[] result = new char[data.length]; 107 | for (int i = 0; i < data.length; i++) { 108 | result[i] = alphabetConvert(data[i]); 109 | } 110 | return result; 111 | } 112 | 113 | /** 114 | * 将正态化后的数字转换成字母 115 | * 116 | * @param datum 117 | * @return 118 | */ 119 | private char alphabetConvert(double datum) { 120 | if (datum >= -0.43 && datum <= 0.43) { 121 | return 'b'; 122 | } else if (datum < -0.43) { 123 | return 'a'; 124 | } else { 125 | return 'c'; 126 | } 127 | } 128 | 129 | @Override 130 | public List getResults() { 131 | return this.results; 132 | } 133 | 134 | public void setResults(List results) { 135 | this.results = results; 136 | } 137 | 138 | public char getInitChar() { 139 | return initChar; 140 | } 141 | 142 | public void setInitChar(char initChar) { 143 | this.initChar = initChar; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## 1. Purpose 4 | 5 | A primary goal of Anomaly Detect Tool is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof). 6 | 7 | This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior. 8 | 9 | We invite all those who participate in Anomaly Detect Tool to help us create safe and positive experiences for everyone. 10 | 11 | ## 2. Open Source Citizenship 12 | 13 | A supplemental goal of this Code of Conduct is to increase open source citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community. 14 | 15 | Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society. 16 | 17 | If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know. 18 | 19 | ## 3. Expected Behavior 20 | 21 | The following behaviors are expected and requested of all community members: 22 | 23 | * Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community. 24 | * Exercise consideration and respect in your speech and actions. 25 | * Attempt collaboration before conflict. 26 | * Refrain from demeaning, discriminatory, or harassing behavior and speech. 27 | * Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential. 28 | * Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations. 29 | 30 | ## 4. Unacceptable Behavior 31 | 32 | The following behaviors are considered harassment and are unacceptable within our community: 33 | 34 | * Violence, threats of violence or violent language directed against another person. 35 | * Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language. 36 | * Posting or displaying sexually explicit or violent material. 37 | * Posting or threatening to post other people’s personally identifying information ("doxing"). 38 | * Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability. 39 | * Inappropriate photography or recording. 40 | * Inappropriate physical contact. You should have someone’s consent before touching them. 41 | * Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances. 42 | * Deliberate intimidation, stalking or following (online or in person). 43 | * Advocating for, or encouraging, any of the above behavior. 44 | * Sustained disruption of community events, including talks and presentations. 45 | 46 | ## 5. Consequences of Unacceptable Behavior 47 | 48 | Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated. 49 | 50 | Anyone asked to stop unacceptable behavior is expected to comply immediately. 51 | 52 | If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event). 53 | 54 | ## 6. Reporting Guidelines 55 | 56 | If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. mezereonxp@gmail.com. 57 | 58 | 59 | 60 | Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress. 61 | 62 | ## 7. Addressing Grievances 63 | 64 | If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify MezereonXP with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies. 65 | 66 | 67 | 68 | ## 8. Scope 69 | 70 | We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues–online and in-person–as well as in all one-on-one communications pertaining to community business. 71 | 72 | This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members. 73 | 74 | ## 9. Contact info 75 | 76 | mezereonxp@gmail.com 77 | 78 | ## 10. License and attribution 79 | 80 | This Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/). 81 | 82 | Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy). 83 | 84 | Retrieved on November 22, 2016 from [http://citizencodeofconduct.org/](http://citizencodeofconduct.org/) 85 | -------------------------------------------------------------------------------- /src/main/java/com/anomalydetect/ExponentialMoving/HoltWintersTool.java: -------------------------------------------------------------------------------- 1 | package com.anomalydetect.ExponentialMoving; 2 | 3 | import com.anomalydetect.Result.Result; 4 | import com.anomalydetect.Tool.DetectTool; 5 | import com.anomalydetect.Tool.FileTool; 6 | 7 | import java.io.FileNotFoundException; 8 | import java.util.ArrayList; 9 | 10 | /** 11 | * 使用二阶指数平滑以及SGD进行自动化参数调整 12 | * 13 | * @author mezereon E-mail:mezereonxp@gmail.com 14 | * @since 18-4-26 15 | */ 16 | public class HoltWintersTool implements DetectTool { 17 | 18 | private double alpha;// 指数平滑的初始参数 19 | private double step;// 步长 20 | private double lastAlpha;// 记录之前的alpha值 21 | private int trainingTimes; 22 | 23 | private double[] s1;// 指数平滑中的s1 24 | private double[] s2;// 指数平滑中的s2 25 | 26 | private double[] ds1;// s1的对应偏导数 27 | private double[] ds2;// s2的对应偏导数 28 | private ArrayList results; 29 | private double THREADHOLD = 0.2; 30 | 31 | /** 32 | * @param alpha 33 | * @param step 34 | * @param trainingTimes 35 | */ 36 | HoltWintersTool(double alpha, double step, int trainingTimes) { 37 | this.alpha = alpha; 38 | this.step = step; 39 | this.trainingTimes = trainingTimes; 40 | } 41 | 42 | /** 43 | * 利用二阶指数平滑对时序数据进行异常检测 44 | */ 45 | public void timeSeriesAnalyse(double[] data) { 46 | results = new ArrayList(); 47 | initial(data.length); 48 | trainModel(data); 49 | testModel(data); 50 | } 51 | 52 | /** 53 | * 根据步长等参数来训练模型 54 | */ 55 | private void trainModel(double[] data) { 56 | int count = 0;// 训练次数计数 57 | //training model 58 | while (count < trainingTimes) { 59 | count++; 60 | s1[0] = getInitialValue(data, 5); 61 | s2[0] = s1[0]; 62 | double sum = 0; 63 | for (int i = 1; i < data.length; i++) { 64 | s1[i] = alpha * data[i - 1] + (1 - alpha) * s1[i - 1]; 65 | s2[i] = alpha * s1[i] + (1 - alpha) * s2[i - 1]; 66 | double A = 2 * s1[i] - s2[i]; 67 | double B = (alpha / (1 - alpha)) * (s1[i] - s2[i]); 68 | // double predict = A + B * 1; 69 | double predict = s2[i]; 70 | if (i == 1) { 71 | ds1[i] = data[i - 1] - s1[i - 1]; 72 | ds2[i] = s1[i] + alpha * ds1[i] - s2[0]; 73 | } else { 74 | ds1[i] = data[i - 1] - ds1[i - 1]; 75 | ds2[i] = s1[i] + alpha * ds1[i] - s2[i - 1] + (1 - alpha) * ds2[i - 1]; 76 | } 77 | sum += Math.pow(predict - data[i], 2); 78 | alpha -= step * ((predict - data[i]) * ds2[i]); 79 | } 80 | if (Math.abs(alpha - lastAlpha) < 1E-8) { 81 | break; 82 | } 83 | lastAlpha = alpha; 84 | System.out.println("MSE is " + sum / (data.length)); 85 | } 86 | } 87 | 88 | /** 89 | * 初始化指数平滑的计算空间 90 | */ 91 | private void initial(int length) { 92 | this.s1 = new double[length]; 93 | this.s2 = new double[length]; 94 | this.ds1 = new double[length]; 95 | this.ds2 = new double[length]; 96 | } 97 | 98 | /** 99 | * 利用已有模型进行测试 100 | */ 101 | private void testModel(double[] data) { 102 | //testing model 103 | s1[0] = getInitialValue(data, 5); 104 | s2[0] = s1[0]; 105 | double sum = 0; 106 | for (int i = 1; i < data.length; i++) { 107 | s1[i] = alpha * data[i - 1] + (1 - alpha) * s1[i - 1]; 108 | s2[i] = alpha * s1[i] + (1 - alpha) * s2[i - 1]; 109 | double A = 2 * s1[i] - s2[i]; 110 | double B = (alpha / (1 - alpha)) * (s1[i] - s2[i]); 111 | // double predict = A + B * 1; 112 | double predict = s2[i]; 113 | if (Math.abs(predict - data[i]) > THREADHOLD) { 114 | results.add(new Result(i, data[i])); 115 | System.out.println(data[i - 1] + "," + data[i] + "--------predict: " + predict); 116 | } 117 | } 118 | } 119 | 120 | public void main(String[] args) throws FileNotFoundException { 121 | double[] data = FileTool.getData("data.json");// 时间序列数据 122 | } 123 | 124 | /** 125 | * 获得初始值, 也就是数组前a个数的平均数 126 | */ 127 | private static double getInitialValue(double[] data, int a) { 128 | 129 | if (data.length <= a) { 130 | System.out.println("Error: data length is not enough"); 131 | return -1; 132 | } 133 | 134 | double sum = 0; 135 | for (int i = 0; i < a; i++) { 136 | sum += data[i]; 137 | } 138 | return sum / a; 139 | } 140 | 141 | public double[] getS1() { 142 | return s1; 143 | } 144 | 145 | public void setS1(double[] s1) { 146 | this.s1 = s1; 147 | } 148 | 149 | public double[] getS2() { 150 | return s2; 151 | } 152 | 153 | public void setS2(double[] s2) { 154 | this.s2 = s2; 155 | } 156 | 157 | public double[] getDs1() { 158 | return ds1; 159 | } 160 | 161 | public void setDs1(double[] ds1) { 162 | this.ds1 = ds1; 163 | } 164 | 165 | public double[] getDs2() { 166 | return ds2; 167 | } 168 | 169 | public void setDs2(double[] ds2) { 170 | this.ds2 = ds2; 171 | } 172 | 173 | public double getAlpha() { 174 | return alpha; 175 | } 176 | 177 | public void setAlpha(double alpha) { 178 | this.alpha = alpha; 179 | } 180 | 181 | public ArrayList getResults() { 182 | return results; 183 | } 184 | 185 | public void setResults(ArrayList results) { 186 | this.results = results; 187 | } 188 | 189 | public double getTHREADHOLD() { 190 | return THREADHOLD; 191 | } 192 | 193 | public void setTHREADHOLD(double THREADHOLD) { 194 | this.THREADHOLD = THREADHOLD; 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.github.mezereonxp 8 | AnomalyDetectTool 9 | 1.1.1 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 3.11.0 16 | 17 | 7 18 | 7 19 | 20 | 21 | 22 | 23 | 24 | AnomalyDetectTool 25 | A tool to detect anomaly points in series data. 26 | https://github.com/MezereonXP/AnomalyDetectTool 27 | 28 | 29 | 30 | The Apache Software License, Version 2.0 31 | http://www.apache.org/licenses/LICENSE-2.0.txt 32 | 33 | 34 | 35 | 36 | https://github.com/MezereonXP/AnomalyDetectTool 37 | https://github.com/MezereonXP/AnomalyDetectTool.git 38 | https://github.com/MezereonXP/AnomalyDetectTool/ 39 | 40 | 41 | 42 | 43 | MezereonXP 44 | mezereonxp@gmail.com 45 | https://github.com/MezereonXP/AnomalyDetectTool 46 | 47 | 48 | 49 | 50 | 51 | release 52 | 53 | 54 | 55 | org.apache.maven.plugins 56 | maven-compiler-plugin 57 | 58 | 1.7 59 | 1.7 60 | 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-source-plugin 66 | 3.2.1 67 | 68 | 69 | package 70 | 71 | jar-no-fork 72 | 73 | 74 | 75 | 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-javadoc-plugin 80 | 3.5.0 81 | 82 | none 83 | UTF-8 84 | 85 | 86 | 87 | package 88 | 89 | jar 90 | 91 | 92 | 93 | 94 | 95 | 96 | org.apache.maven.plugins 97 | maven-gpg-plugin 98 | 3.0.1 99 | 100 | 101 | sign-artifacts 102 | verify 103 | 104 | sign 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | oss 114 | https://oss.sonatype.org/content/repositories/snapshots 115 | 116 | 117 | oss 118 | https://oss.sonatype.org/service/local/staging/deploy/maven2 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | org.junit.jupiter 128 | junit-jupiter-api 129 | 5.9.2 130 | test 131 | 132 | 133 | junit 134 | junit 135 | 4.12 136 | test 137 | 138 | 139 | com.google.code.gson 140 | gson 141 | 2.3.1 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "version": "v1", 4 | "timestamp": "2018-04-12T05:46:00.000+08:00", 5 | "event": { 6 | "totalcount": 123174, 7 | "service_name": "speech-answer" 8 | } 9 | }, 10 | { 11 | "version": "v1", 12 | "timestamp": "2018-04-12T05:47:00.000+08:00", 13 | "event": { 14 | "totalcount": 103523, 15 | "service_name": "speech-answer" 16 | } 17 | }, 18 | { 19 | "version": "v1", 20 | "timestamp": "2018-04-12T05:48:00.000+08:00", 21 | "event": { 22 | "totalcount": 140452, 23 | "service_name": "speech-answer" 24 | } 25 | }, 26 | { 27 | "version": "v1", 28 | "timestamp": "2018-04-12T05:49:00.000+08:00", 29 | "event": { 30 | "totalcount": 133318, 31 | "service_name": "speech-answer" 32 | } 33 | }, 34 | { 35 | "version": "v1", 36 | "timestamp": "2018-04-12T05:50:00.000+08:00", 37 | "event": { 38 | "totalcount": 193644, 39 | "service_name": "speech-answer" 40 | } 41 | }, 42 | { 43 | "version": "v1", 44 | "timestamp": "2018-04-12T05:51:00.000+08:00", 45 | "event": { 46 | "totalcount": 146530, 47 | "service_name": "speech-answer" 48 | } 49 | }, 50 | { 51 | "version": "v1", 52 | "timestamp": "2018-04-12T05:52:00.000+08:00", 53 | "event": { 54 | "totalcount": 164769, 55 | "service_name": "speech-answer" 56 | } 57 | }, 58 | { 59 | "version": "v1", 60 | "timestamp": "2018-04-12T05:53:00.000+08:00", 61 | "event": { 62 | "totalcount": 134880, 63 | "service_name": "speech-answer" 64 | } 65 | }, 66 | { 67 | "version": "v1", 68 | "timestamp": "2018-04-12T05:54:00.000+08:00", 69 | "event": { 70 | "totalcount": 146674, 71 | "service_name": "speech-answer" 72 | } 73 | }, 74 | { 75 | "version": "v1", 76 | "timestamp": "2018-04-12T05:55:00.000+08:00", 77 | "event": { 78 | "totalcount": 156128, 79 | "service_name": "speech-answer" 80 | } 81 | }, 82 | { 83 | "version": "v1", 84 | "timestamp": "2018-04-12T05:56:00.000+08:00", 85 | "event": { 86 | "totalcount": 154668, 87 | "service_name": "speech-answer" 88 | } 89 | }, 90 | { 91 | "version": "v1", 92 | "timestamp": "2018-04-12T05:57:00.000+08:00", 93 | "event": { 94 | "totalcount": 145764, 95 | "service_name": "speech-answer" 96 | } 97 | }, 98 | { 99 | "version": "v1", 100 | "timestamp": "2018-04-12T05:58:00.000+08:00", 101 | "event": { 102 | "totalcount": 151562, 103 | "service_name": "speech-answer" 104 | } 105 | }, 106 | { 107 | "version": "v1", 108 | "timestamp": "2018-04-12T05:59:00.000+08:00", 109 | "event": { 110 | "totalcount": 166089, 111 | "service_name": "speech-answer" 112 | } 113 | }, 114 | { 115 | "version": "v1", 116 | "timestamp": "2018-04-12T06:00:00.000+08:00", 117 | "event": { 118 | "totalcount": 656198, 119 | "service_name": "speech-answer" 120 | } 121 | }, 122 | { 123 | "version": "v1", 124 | "timestamp": "2018-04-12T06:01:00.000+08:00", 125 | "event": { 126 | "totalcount": 320401, 127 | "service_name": "speech-answer" 128 | } 129 | }, 130 | { 131 | "version": "v1", 132 | "timestamp": "2018-04-12T06:02:00.000+08:00", 133 | "event": { 134 | "totalcount": 228963, 135 | "service_name": "speech-answer" 136 | } 137 | }, 138 | { 139 | "version": "v1", 140 | "timestamp": "2018-04-12T06:03:00.000+08:00", 141 | "event": { 142 | "totalcount": 217108, 143 | "service_name": "speech-answer" 144 | } 145 | }, 146 | { 147 | "version": "v1", 148 | "timestamp": "2018-04-12T06:04:00.000+08:00", 149 | "event": { 150 | "totalcount": 232412, 151 | "service_name": "speech-answer" 152 | } 153 | }, 154 | { 155 | "version": "v1", 156 | "timestamp": "2018-04-12T06:05:00.000+08:00", 157 | "event": { 158 | "totalcount": 249936, 159 | "service_name": "speech-answer" 160 | } 161 | }, 162 | { 163 | "version": "v1", 164 | "timestamp": "2018-04-12T06:06:00.000+08:00", 165 | "event": { 166 | "totalcount": 237544, 167 | "service_name": "speech-answer" 168 | } 169 | }, 170 | { 171 | "version": "v1", 172 | "timestamp": "2018-04-12T06:07:00.000+08:00", 173 | "event": { 174 | "totalcount": 213144, 175 | "service_name": "speech-answer" 176 | } 177 | }, 178 | { 179 | "version": "v1", 180 | "timestamp": "2018-04-12T06:08:00.000+08:00", 181 | "event": { 182 | "totalcount": 223461, 183 | "service_name": "speech-answer" 184 | } 185 | }, 186 | { 187 | "version": "v1", 188 | "timestamp": "2018-04-12T06:09:00.000+08:00", 189 | "event": { 190 | "totalcount": 260498, 191 | "service_name": "speech-answer" 192 | } 193 | }, 194 | { 195 | "version": "v1", 196 | "timestamp": "2018-04-12T06:10:00.000+08:00", 197 | "event": { 198 | "totalcount": 397903, 199 | "service_name": "speech-answer" 200 | } 201 | }, 202 | { 203 | "version": "v1", 204 | "timestamp": "2018-04-12T06:11:00.000+08:00", 205 | "event": { 206 | "totalcount": 272659, 207 | "service_name": "speech-answer" 208 | } 209 | }, 210 | { 211 | "version": "v1", 212 | "timestamp": "2018-04-12T06:12:00.000+08:00", 213 | "event": { 214 | "totalcount": 294697, 215 | "service_name": "speech-answer" 216 | } 217 | }, 218 | { 219 | "version": "v1", 220 | "timestamp": "2018-04-12T06:13:00.000+08:00", 221 | "event": { 222 | "totalcount": 294326, 223 | "service_name": "speech-answer" 224 | } 225 | }, 226 | { 227 | "version": "v1", 228 | "timestamp": "2018-04-12T06:14:00.000+08:00", 229 | "event": { 230 | "totalcount": 285802, 231 | "service_name": "speech-answer" 232 | } 233 | }, 234 | { 235 | "version": "v1", 236 | "timestamp": "2018-04-12T06:15:00.000+08:00", 237 | "event": { 238 | "totalcount": 366739, 239 | "service_name": "speech-answer" 240 | } 241 | }, 242 | { 243 | "version": "v1", 244 | "timestamp": "2018-04-12T06:16:00.000+08:00", 245 | "event": { 246 | "totalcount": 324935, 247 | "service_name": "speech-answer" 248 | } 249 | }, 250 | { 251 | "version": "v1", 252 | "timestamp": "2018-04-12T06:17:00.000+08:00", 253 | "event": { 254 | "totalcount": 317081, 255 | "service_name": "speech-answer" 256 | } 257 | }, 258 | { 259 | "version": "v1", 260 | "timestamp": "2018-04-12T06:18:00.000+08:00", 261 | "event": { 262 | "totalcount": 354273, 263 | "service_name": "speech-answer" 264 | } 265 | }, 266 | { 267 | "version": "v1", 268 | "timestamp": "2018-04-12T06:19:00.000+08:00", 269 | "event": { 270 | "totalcount": 348103, 271 | "service_name": "speech-answer" 272 | } 273 | }, 274 | { 275 | "version": "v1", 276 | "timestamp": "2018-04-12T06:20:00.000+08:00", 277 | "event": { 278 | "totalcount": 564462, 279 | "service_name": "speech-answer" 280 | } 281 | }, 282 | { 283 | "version": "v1", 284 | "timestamp": "2018-04-12T06:21:00.000+08:00", 285 | "event": { 286 | "totalcount": 416271, 287 | "service_name": "speech-answer" 288 | } 289 | }, 290 | { 291 | "version": "v1", 292 | "timestamp": "2018-04-12T06:22:00.000+08:00", 293 | "event": { 294 | "totalcount": 403325, 295 | "service_name": "speech-answer" 296 | } 297 | }, 298 | { 299 | "version": "v1", 300 | "timestamp": "2018-04-12T06:23:00.000+08:00", 301 | "event": { 302 | "totalcount": 420906, 303 | "service_name": "speech-answer" 304 | } 305 | }, 306 | { 307 | "version": "v1", 308 | "timestamp": "2018-04-12T06:24:00.000+08:00", 309 | "event": { 310 | "totalcount": 410080, 311 | "service_name": "speech-answer" 312 | } 313 | }, 314 | { 315 | "version": "v1", 316 | "timestamp": "2018-04-12T06:25:00.000+08:00", 317 | "event": { 318 | "totalcount": 424549, 319 | "service_name": "speech-answer" 320 | } 321 | }, 322 | { 323 | "version": "v1", 324 | "timestamp": "2018-04-12T06:26:00.000+08:00", 325 | "event": { 326 | "totalcount": 429180, 327 | "service_name": "speech-answer" 328 | } 329 | }, 330 | { 331 | "version": "v1", 332 | "timestamp": "2018-04-12T06:27:00.000+08:00", 333 | "event": { 334 | "totalcount": 470393, 335 | "service_name": "speech-answer" 336 | } 337 | }, 338 | { 339 | "version": "v1", 340 | "timestamp": "2018-04-12T06:28:00.000+08:00", 341 | "event": { 342 | "totalcount": 440130, 343 | "service_name": "speech-answer" 344 | } 345 | }, 346 | { 347 | "version": "v1", 348 | "timestamp": "2018-04-12T06:29:00.000+08:00", 349 | "event": { 350 | "totalcount": 463974, 351 | "service_name": "speech-answer" 352 | } 353 | }, 354 | { 355 | "version": "v1", 356 | "timestamp": "2018-04-12T06:30:00.000+08:00", 357 | "event": { 358 | "totalcount": 1345913, 359 | "service_name": "speech-answer" 360 | } 361 | }, 362 | { 363 | "version": "v1", 364 | "timestamp": "2018-04-12T06:31:00.000+08:00", 365 | "event": { 366 | "totalcount": 637895, 367 | "service_name": "speech-answer" 368 | } 369 | }, 370 | { 371 | "version": "v1", 372 | "timestamp": "2018-04-12T06:32:00.000+08:00", 373 | "event": { 374 | "totalcount": 645641, 375 | "service_name": "speech-answer" 376 | } 377 | }, 378 | { 379 | "version": "v1", 380 | "timestamp": "2018-04-12T06:33:00.000+08:00", 381 | "event": { 382 | "totalcount": 590331, 383 | "service_name": "speech-answer" 384 | } 385 | }, 386 | { 387 | "version": "v1", 388 | "timestamp": "2018-04-12T06:34:00.000+08:00", 389 | "event": { 390 | "totalcount": 618589, 391 | "service_name": "speech-answer" 392 | } 393 | }, 394 | { 395 | "version": "v1", 396 | "timestamp": "2018-04-12T06:35:00.000+08:00", 397 | "event": { 398 | "totalcount": 680244, 399 | "service_name": "speech-answer" 400 | } 401 | }, 402 | { 403 | "version": "v1", 404 | "timestamp": "2018-04-12T06:36:00.000+08:00", 405 | "event": { 406 | "totalcount": 612542, 407 | "service_name": "speech-answer" 408 | } 409 | }, 410 | { 411 | "version": "v1", 412 | "timestamp": "2018-04-12T06:37:00.000+08:00", 413 | "event": { 414 | "totalcount": 648111, 415 | "service_name": "speech-answer" 416 | } 417 | }, 418 | { 419 | "version": "v1", 420 | "timestamp": "2018-04-12T06:38:00.000+08:00", 421 | "event": { 422 | "totalcount": 634144, 423 | "service_name": "speech-answer" 424 | } 425 | }, 426 | { 427 | "version": "v1", 428 | "timestamp": "2018-04-12T06:39:00.000+08:00", 429 | "event": { 430 | "totalcount": 642376, 431 | "service_name": "speech-answer" 432 | } 433 | }, 434 | { 435 | "version": "v1", 436 | "timestamp": "2018-04-12T06:40:00.000+08:00", 437 | "event": { 438 | "totalcount": 884334, 439 | "service_name": "speech-answer" 440 | } 441 | }, 442 | { 443 | "version": "v1", 444 | "timestamp": "2018-04-12T06:41:00.000+08:00", 445 | "event": { 446 | "totalcount": 769883, 447 | "service_name": "speech-answer" 448 | } 449 | }, 450 | { 451 | "version": "v1", 452 | "timestamp": "2018-04-12T06:42:00.000+08:00", 453 | "event": { 454 | "totalcount": 741764, 455 | "service_name": "speech-answer" 456 | } 457 | }, 458 | { 459 | "version": "v1", 460 | "timestamp": "2018-04-12T06:43:00.000+08:00", 461 | "event": { 462 | "totalcount": 721107, 463 | "service_name": "speech-answer" 464 | } 465 | }, 466 | { 467 | "version": "v1", 468 | "timestamp": "2018-04-12T06:44:00.000+08:00", 469 | "event": { 470 | "totalcount": 710600, 471 | "service_name": "speech-answer" 472 | } 473 | }, 474 | { 475 | "version": "v1", 476 | "timestamp": "2018-04-12T06:45:00.000+08:00", 477 | "event": { 478 | "totalcount": 878345, 479 | "service_name": "speech-answer" 480 | } 481 | }, 482 | { 483 | "version": "v1", 484 | "timestamp": "2018-04-12T06:46:00.000+08:00", 485 | "event": { 486 | "totalcount": 777350, 487 | "service_name": "speech-answer" 488 | } 489 | }, 490 | { 491 | "version": "v1", 492 | "timestamp": "2018-04-12T06:47:00.000+08:00", 493 | "event": { 494 | "totalcount": 769507, 495 | "service_name": "speech-answer" 496 | } 497 | }, 498 | { 499 | "version": "v1", 500 | "timestamp": "2018-04-12T06:48:00.000+08:00", 501 | "event": { 502 | "totalcount": 773675, 503 | "service_name": "speech-answer" 504 | } 505 | }, 506 | { 507 | "version": "v1", 508 | "timestamp": "2018-04-12T06:49:00.000+08:00", 509 | "event": { 510 | "totalcount": 806458, 511 | "service_name": "speech-answer" 512 | } 513 | }, 514 | { 515 | "version": "v1", 516 | "timestamp": "2018-04-12T06:50:00.000+08:00", 517 | "event": { 518 | "totalcount": 1021556, 519 | "service_name": "speech-answer" 520 | } 521 | }, 522 | { 523 | "version": "v1", 524 | "timestamp": "2018-04-12T06:51:00.000+08:00", 525 | "event": { 526 | "totalcount": 938472, 527 | "service_name": "speech-answer" 528 | } 529 | }, 530 | { 531 | "version": "v1", 532 | "timestamp": "2018-04-12T06:52:00.000+08:00", 533 | "event": { 534 | "totalcount": 891072, 535 | "service_name": "speech-answer" 536 | } 537 | }, 538 | { 539 | "version": "v1", 540 | "timestamp": "2018-04-12T06:53:00.000+08:00", 541 | "event": { 542 | "totalcount": 872784, 543 | "service_name": "speech-answer" 544 | } 545 | }, 546 | { 547 | "version": "v1", 548 | "timestamp": "2018-04-12T06:54:00.000+08:00", 549 | "event": { 550 | "totalcount": 879279, 551 | "service_name": "speech-answer" 552 | } 553 | }, 554 | { 555 | "version": "v1", 556 | "timestamp": "2018-04-12T06:55:00.000+08:00", 557 | "event": { 558 | "totalcount": 937294, 559 | "service_name": "speech-answer" 560 | } 561 | }, 562 | { 563 | "version": "v1", 564 | "timestamp": "2018-04-12T06:56:00.000+08:00", 565 | "event": { 566 | "totalcount": 931651, 567 | "service_name": "speech-answer" 568 | } 569 | }, 570 | { 571 | "version": "v1", 572 | "timestamp": "2018-04-12T06:57:00.000+08:00", 573 | "event": { 574 | "totalcount": 1004132, 575 | "service_name": "speech-answer" 576 | } 577 | }, 578 | { 579 | "version": "v1", 580 | "timestamp": "2018-04-12T06:58:00.000+08:00", 581 | "event": { 582 | "totalcount": 928966, 583 | "service_name": "speech-answer" 584 | } 585 | }, 586 | { 587 | "version": "v1", 588 | "timestamp": "2018-04-12T06:59:00.000+08:00", 589 | "event": { 590 | "totalcount": 992164, 591 | "service_name": "speech-answer" 592 | } 593 | }, 594 | { 595 | "version": "v1", 596 | "timestamp": "2018-04-12T07:00:00.000+08:00", 597 | "event": { 598 | "totalcount": 2974619, 599 | "service_name": "speech-answer" 600 | } 601 | }, 602 | { 603 | "version": "v1", 604 | "timestamp": "2018-04-12T07:01:00.000+08:00", 605 | "event": { 606 | "totalcount": 1100375, 607 | "service_name": "speech-answer" 608 | } 609 | }, 610 | { 611 | "version": "v1", 612 | "timestamp": "2018-04-12T07:02:00.000+08:00", 613 | "event": { 614 | "totalcount": 1071206, 615 | "service_name": "speech-answer" 616 | } 617 | }, 618 | { 619 | "version": "v1", 620 | "timestamp": "2018-04-12T07:03:00.000+08:00", 621 | "event": { 622 | "totalcount": 1085910, 623 | "service_name": "speech-answer" 624 | } 625 | }, 626 | { 627 | "version": "v1", 628 | "timestamp": "2018-04-12T07:04:00.000+08:00", 629 | "event": { 630 | "totalcount": 1094914, 631 | "service_name": "speech-answer" 632 | } 633 | }, 634 | { 635 | "version": "v1", 636 | "timestamp": "2018-04-12T07:05:00.000+08:00", 637 | "event": { 638 | "totalcount": 1095554, 639 | "service_name": "speech-answer" 640 | } 641 | }, 642 | { 643 | "version": "v1", 644 | "timestamp": "2018-04-12T07:06:00.000+08:00", 645 | "event": { 646 | "totalcount": 1052601, 647 | "service_name": "speech-answer" 648 | } 649 | }, 650 | { 651 | "version": "v1", 652 | "timestamp": "2018-04-12T07:07:00.000+08:00", 653 | "event": { 654 | "totalcount": 1046062, 655 | "service_name": "speech-answer" 656 | } 657 | }, 658 | { 659 | "version": "v1", 660 | "timestamp": "2018-04-12T07:08:00.000+08:00", 661 | "event": { 662 | "totalcount": 1084888, 663 | "service_name": "speech-answer" 664 | } 665 | }, 666 | { 667 | "version": "v1", 668 | "timestamp": "2018-04-12T07:09:00.000+08:00", 669 | "event": { 670 | "totalcount": 1064083, 671 | "service_name": "speech-answer" 672 | } 673 | }, 674 | { 675 | "version": "v1", 676 | "timestamp": "2018-04-12T07:10:00.000+08:00", 677 | "event": { 678 | "totalcount": 1119549, 679 | "service_name": "speech-answer" 680 | } 681 | }, 682 | { 683 | "version": "v1", 684 | "timestamp": "2018-04-12T07:11:00.000+08:00", 685 | "event": { 686 | "totalcount": 1124720, 687 | "service_name": "speech-answer" 688 | } 689 | }, 690 | { 691 | "version": "v1", 692 | "timestamp": "2018-04-12T07:12:00.000+08:00", 693 | "event": { 694 | "totalcount": 1156945, 695 | "service_name": "speech-answer" 696 | } 697 | }, 698 | { 699 | "version": "v1", 700 | "timestamp": "2018-04-12T07:13:00.000+08:00", 701 | "event": { 702 | "totalcount": 1083529, 703 | "service_name": "speech-answer" 704 | } 705 | }, 706 | { 707 | "version": "v1", 708 | "timestamp": "2018-04-12T07:14:00.000+08:00", 709 | "event": { 710 | "totalcount": 1109267, 711 | "service_name": "speech-answer" 712 | } 713 | }, 714 | { 715 | "version": "v1", 716 | "timestamp": "2018-04-12T07:15:00.000+08:00", 717 | "event": { 718 | "totalcount": 1128682, 719 | "service_name": "speech-answer" 720 | } 721 | }, 722 | { 723 | "version": "v1", 724 | "timestamp": "2018-04-12T07:16:00.000+08:00", 725 | "event": { 726 | "totalcount": 1099047, 727 | "service_name": "speech-answer" 728 | } 729 | }, 730 | { 731 | "version": "v1", 732 | "timestamp": "2018-04-12T07:17:00.000+08:00", 733 | "event": { 734 | "totalcount": 1073643, 735 | "service_name": "speech-answer" 736 | } 737 | }, 738 | { 739 | "version": "v1", 740 | "timestamp": "2018-04-12T07:18:00.000+08:00", 741 | "event": { 742 | "totalcount": 1072359, 743 | "service_name": "speech-answer" 744 | } 745 | }, 746 | { 747 | "version": "v1", 748 | "timestamp": "2018-04-12T07:19:00.000+08:00", 749 | "event": { 750 | "totalcount": 1093462, 751 | "service_name": "speech-answer" 752 | } 753 | }, 754 | { 755 | "version": "v1", 756 | "timestamp": "2018-04-12T07:20:00.000+08:00", 757 | "event": { 758 | "totalcount": 1061425, 759 | "service_name": "speech-answer" 760 | } 761 | }, 762 | { 763 | "version": "v1", 764 | "timestamp": "2018-04-12T07:21:00.000+08:00", 765 | "event": { 766 | "totalcount": 1128351, 767 | "service_name": "speech-answer" 768 | } 769 | }, 770 | { 771 | "version": "v1", 772 | "timestamp": "2018-04-12T07:22:00.000+08:00", 773 | "event": { 774 | "totalcount": 1109060, 775 | "service_name": "speech-answer" 776 | } 777 | }, 778 | { 779 | "version": "v1", 780 | "timestamp": "2018-04-12T07:23:00.000+08:00", 781 | "event": { 782 | "totalcount": 1106922, 783 | "service_name": "speech-answer" 784 | } 785 | }, 786 | { 787 | "version": "v1", 788 | "timestamp": "2018-04-12T07:24:00.000+08:00", 789 | "event": { 790 | "totalcount": 1114160, 791 | "service_name": "speech-answer" 792 | } 793 | }, 794 | { 795 | "version": "v1", 796 | "timestamp": "2018-04-12T07:25:00.000+08:00", 797 | "event": { 798 | "totalcount": 1087984, 799 | "service_name": "speech-answer" 800 | } 801 | }, 802 | { 803 | "version": "v1", 804 | "timestamp": "2018-04-12T07:26:00.000+08:00", 805 | "event": { 806 | "totalcount": 1079574, 807 | "service_name": "speech-answer" 808 | } 809 | }, 810 | { 811 | "version": "v1", 812 | "timestamp": "2018-04-12T07:27:00.000+08:00", 813 | "event": { 814 | "totalcount": 1116186, 815 | "service_name": "speech-answer" 816 | } 817 | }, 818 | { 819 | "version": "v1", 820 | "timestamp": "2018-04-12T07:28:00.000+08:00", 821 | "event": { 822 | "totalcount": 1108380, 823 | "service_name": "speech-answer" 824 | } 825 | }, 826 | { 827 | "version": "v1", 828 | "timestamp": "2018-04-12T07:29:00.000+08:00", 829 | "event": { 830 | "totalcount": 1055320, 831 | "service_name": "speech-answer" 832 | } 833 | }, 834 | { 835 | "version": "v1", 836 | "timestamp": "2018-04-12T07:30:00.000+08:00", 837 | "event": { 838 | "totalcount": 1837748, 839 | "service_name": "speech-answer" 840 | } 841 | }, 842 | { 843 | "version": "v1", 844 | "timestamp": "2018-04-12T07:31:00.000+08:00", 845 | "event": { 846 | "totalcount": 918763, 847 | "service_name": "speech-answer" 848 | } 849 | }, 850 | { 851 | "version": "v1", 852 | "timestamp": "2018-04-12T07:32:00.000+08:00", 853 | "event": { 854 | "totalcount": 811329, 855 | "service_name": "speech-answer" 856 | } 857 | }, 858 | { 859 | "version": "v1", 860 | "timestamp": "2018-04-12T07:33:00.000+08:00", 861 | "event": { 862 | "totalcount": 779123, 863 | "service_name": "speech-answer" 864 | } 865 | }, 866 | { 867 | "version": "v1", 868 | "timestamp": "2018-04-12T07:34:00.000+08:00", 869 | "event": { 870 | "totalcount": 823644, 871 | "service_name": "speech-answer" 872 | } 873 | }, 874 | { 875 | "version": "v1", 876 | "timestamp": "2018-04-12T07:35:00.000+08:00", 877 | "event": { 878 | "totalcount": 881707, 879 | "service_name": "speech-answer" 880 | } 881 | }, 882 | { 883 | "version": "v1", 884 | "timestamp": "2018-04-12T07:36:00.000+08:00", 885 | "event": { 886 | "totalcount": 769047, 887 | "service_name": "speech-answer" 888 | } 889 | }, 890 | { 891 | "version": "v1", 892 | "timestamp": "2018-04-12T07:37:00.000+08:00", 893 | "event": { 894 | "totalcount": 786453, 895 | "service_name": "speech-answer" 896 | } 897 | }, 898 | { 899 | "version": "v1", 900 | "timestamp": "2018-04-12T07:38:00.000+08:00", 901 | "event": { 902 | "totalcount": 721872, 903 | "service_name": "speech-answer" 904 | } 905 | }, 906 | { 907 | "version": "v1", 908 | "timestamp": "2018-04-12T07:39:00.000+08:00", 909 | "event": { 910 | "totalcount": 778123, 911 | "service_name": "speech-answer" 912 | } 913 | }, 914 | { 915 | "version": "v1", 916 | "timestamp": "2018-04-12T07:40:00.000+08:00", 917 | "event": { 918 | "totalcount": 878552, 919 | "service_name": "speech-answer" 920 | } 921 | }, 922 | { 923 | "version": "v1", 924 | "timestamp": "2018-04-12T07:41:00.000+08:00", 925 | "event": { 926 | "totalcount": 711604, 927 | "service_name": "speech-answer" 928 | } 929 | }, 930 | { 931 | "version": "v1", 932 | "timestamp": "2018-04-12T07:42:00.000+08:00", 933 | "event": { 934 | "totalcount": 710765, 935 | "service_name": "speech-answer" 936 | } 937 | }, 938 | { 939 | "version": "v1", 940 | "timestamp": "2018-04-12T07:43:00.000+08:00", 941 | "event": { 942 | "totalcount": 705959, 943 | "service_name": "speech-answer" 944 | } 945 | }, 946 | { 947 | "version": "v1", 948 | "timestamp": "2018-04-12T07:44:00.000+08:00", 949 | "event": { 950 | "totalcount": 718477, 951 | "service_name": "speech-answer" 952 | } 953 | }, 954 | { 955 | "version": "v1", 956 | "timestamp": "2018-04-12T07:45:00.000+08:00", 957 | "event": { 958 | "totalcount": 753015, 959 | "service_name": "speech-answer" 960 | } 961 | }, 962 | { 963 | "version": "v1", 964 | "timestamp": "2018-04-12T07:46:00.000+08:00", 965 | "event": { 966 | "totalcount": 750965, 967 | "service_name": "speech-answer" 968 | } 969 | }, 970 | { 971 | "version": "v1", 972 | "timestamp": "2018-04-12T07:47:00.000+08:00", 973 | "event": { 974 | "totalcount": 943695, 975 | "service_name": "speech-answer" 976 | } 977 | }, 978 | { 979 | "version": "v1", 980 | "timestamp": "2018-04-12T07:48:00.000+08:00", 981 | "event": { 982 | "totalcount": 990167, 983 | "service_name": "speech-answer" 984 | } 985 | }, 986 | { 987 | "version": "v1", 988 | "timestamp": "2018-04-12T07:49:00.000+08:00", 989 | "event": { 990 | "totalcount": 894458, 991 | "service_name": "speech-answer" 992 | } 993 | }, 994 | { 995 | "version": "v1", 996 | "timestamp": "2018-04-12T07:50:00.000+08:00", 997 | "event": { 998 | "totalcount": 981864, 999 | "service_name": "speech-answer" 1000 | } 1001 | }, 1002 | { 1003 | "version": "v1", 1004 | "timestamp": "2018-04-12T07:51:00.000+08:00", 1005 | "event": { 1006 | "totalcount": 913629, 1007 | "service_name": "speech-answer" 1008 | } 1009 | }, 1010 | { 1011 | "version": "v1", 1012 | "timestamp": "2018-04-12T07:52:00.000+08:00", 1013 | "event": { 1014 | "totalcount": 883247, 1015 | "service_name": "speech-answer" 1016 | } 1017 | }, 1018 | { 1019 | "version": "v1", 1020 | "timestamp": "2018-04-12T07:53:00.000+08:00", 1021 | "event": { 1022 | "totalcount": 885857, 1023 | "service_name": "speech-answer" 1024 | } 1025 | }, 1026 | { 1027 | "version": "v1", 1028 | "timestamp": "2018-04-12T07:54:00.000+08:00", 1029 | "event": { 1030 | "totalcount": 902828, 1031 | "service_name": "speech-answer" 1032 | } 1033 | }, 1034 | { 1035 | "version": "v1", 1036 | "timestamp": "2018-04-12T07:55:00.000+08:00", 1037 | "event": { 1038 | "totalcount": 970454, 1039 | "service_name": "speech-answer" 1040 | } 1041 | }, 1042 | { 1043 | "version": "v1", 1044 | "timestamp": "2018-04-12T07:56:00.000+08:00", 1045 | "event": { 1046 | "totalcount": 865593, 1047 | "service_name": "speech-answer" 1048 | } 1049 | }, 1050 | { 1051 | "version": "v1", 1052 | "timestamp": "2018-04-12T07:57:00.000+08:00", 1053 | "event": { 1054 | "totalcount": 703807, 1055 | "service_name": "speech-answer" 1056 | } 1057 | }, 1058 | { 1059 | "version": "v1", 1060 | "timestamp": "2018-04-12T07:58:00.000+08:00", 1061 | "event": { 1062 | "totalcount": 591837, 1063 | "service_name": "speech-answer" 1064 | } 1065 | }, 1066 | { 1067 | "version": "v1", 1068 | "timestamp": "2018-04-12T07:59:00.000+08:00", 1069 | "event": { 1070 | "totalcount": 601962, 1071 | "service_name": "speech-answer" 1072 | } 1073 | }, 1074 | { 1075 | "version": "v1", 1076 | "timestamp": "2018-04-12T08:00:00.000+08:00", 1077 | "event": { 1078 | "totalcount": 1282898, 1079 | "service_name": "speech-answer" 1080 | } 1081 | }, 1082 | { 1083 | "version": "v1", 1084 | "timestamp": "2018-04-12T08:01:00.000+08:00", 1085 | "event": { 1086 | "totalcount": 690942, 1087 | "service_name": "speech-answer" 1088 | } 1089 | }, 1090 | { 1091 | "version": "v1", 1092 | "timestamp": "2018-04-12T08:02:00.000+08:00", 1093 | "event": { 1094 | "totalcount": 629026, 1095 | "service_name": "speech-answer" 1096 | } 1097 | }, 1098 | { 1099 | "version": "v1", 1100 | "timestamp": "2018-04-12T08:03:00.000+08:00", 1101 | "event": { 1102 | "totalcount": 666758, 1103 | "service_name": "speech-answer" 1104 | } 1105 | }, 1106 | { 1107 | "version": "v1", 1108 | "timestamp": "2018-04-12T08:04:00.000+08:00", 1109 | "event": { 1110 | "totalcount": 624904, 1111 | "service_name": "speech-answer" 1112 | } 1113 | }, 1114 | { 1115 | "version": "v1", 1116 | "timestamp": "2018-04-12T08:05:00.000+08:00", 1117 | "event": { 1118 | "totalcount": 584023, 1119 | "service_name": "speech-answer" 1120 | } 1121 | }, 1122 | { 1123 | "version": "v1", 1124 | "timestamp": "2018-04-12T08:06:00.000+08:00", 1125 | "event": { 1126 | "totalcount": 564510, 1127 | "service_name": "speech-answer" 1128 | } 1129 | }, 1130 | { 1131 | "version": "v1", 1132 | "timestamp": "2018-04-12T08:07:00.000+08:00", 1133 | "event": { 1134 | "totalcount": 560259, 1135 | "service_name": "speech-answer" 1136 | } 1137 | }, 1138 | { 1139 | "version": "v1", 1140 | "timestamp": "2018-04-12T08:08:00.000+08:00", 1141 | "event": { 1142 | "totalcount": 555071, 1143 | "service_name": "speech-answer" 1144 | } 1145 | }, 1146 | { 1147 | "version": "v1", 1148 | "timestamp": "2018-04-12T08:09:00.000+08:00", 1149 | "event": { 1150 | "totalcount": 596111, 1151 | "service_name": "speech-answer" 1152 | } 1153 | }, 1154 | { 1155 | "version": "v1", 1156 | "timestamp": "2018-04-12T08:10:00.000+08:00", 1157 | "event": { 1158 | "totalcount": 613108, 1159 | "service_name": "speech-answer" 1160 | } 1161 | }, 1162 | { 1163 | "version": "v1", 1164 | "timestamp": "2018-04-12T08:11:00.000+08:00", 1165 | "event": { 1166 | "totalcount": 555967, 1167 | "service_name": "speech-answer" 1168 | } 1169 | }, 1170 | { 1171 | "version": "v1", 1172 | "timestamp": "2018-04-12T08:12:00.000+08:00", 1173 | "event": { 1174 | "totalcount": 551716, 1175 | "service_name": "speech-answer" 1176 | } 1177 | }, 1178 | { 1179 | "version": "v1", 1180 | "timestamp": "2018-04-12T08:13:00.000+08:00", 1181 | "event": { 1182 | "totalcount": 562365, 1183 | "service_name": "speech-answer" 1184 | } 1185 | }, 1186 | { 1187 | "version": "v1", 1188 | "timestamp": "2018-04-12T08:14:00.000+08:00", 1189 | "event": { 1190 | "totalcount": 520117, 1191 | "service_name": "speech-answer" 1192 | } 1193 | }, 1194 | { 1195 | "version": "v1", 1196 | "timestamp": "2018-04-12T08:15:00.000+08:00", 1197 | "event": { 1198 | "totalcount": 545613, 1199 | "service_name": "speech-answer" 1200 | } 1201 | }, 1202 | { 1203 | "version": "v1", 1204 | "timestamp": "2018-04-12T08:16:00.000+08:00", 1205 | "event": { 1206 | "totalcount": 530870, 1207 | "service_name": "speech-answer" 1208 | } 1209 | }, 1210 | { 1211 | "version": "v1", 1212 | "timestamp": "2018-04-12T08:17:00.000+08:00", 1213 | "event": { 1214 | "totalcount": 550342, 1215 | "service_name": "speech-answer" 1216 | } 1217 | }, 1218 | { 1219 | "version": "v1", 1220 | "timestamp": "2018-04-12T08:18:00.000+08:00", 1221 | "event": { 1222 | "totalcount": 520800, 1223 | "service_name": "speech-answer" 1224 | } 1225 | }, 1226 | { 1227 | "version": "v1", 1228 | "timestamp": "2018-04-12T08:19:00.000+08:00", 1229 | "event": { 1230 | "totalcount": 525258, 1231 | "service_name": "speech-answer" 1232 | } 1233 | }, 1234 | { 1235 | "version": "v1", 1236 | "timestamp": "2018-04-12T08:20:00.000+08:00", 1237 | "event": { 1238 | "totalcount": 523897, 1239 | "service_name": "speech-answer" 1240 | } 1241 | }, 1242 | { 1243 | "version": "v1", 1244 | "timestamp": "2018-04-12T08:21:00.000+08:00", 1245 | "event": { 1246 | "totalcount": 503641, 1247 | "service_name": "speech-answer" 1248 | } 1249 | }, 1250 | { 1251 | "version": "v1", 1252 | "timestamp": "2018-04-12T08:22:00.000+08:00", 1253 | "event": { 1254 | "totalcount": 462139, 1255 | "service_name": "speech-answer" 1256 | } 1257 | }, 1258 | { 1259 | "version": "v1", 1260 | "timestamp": "2018-04-12T08:23:00.000+08:00", 1261 | "event": { 1262 | "totalcount": 647399, 1263 | "service_name": "speech-answer" 1264 | } 1265 | }, 1266 | { 1267 | "version": "v1", 1268 | "timestamp": "2018-04-12T08:24:00.000+08:00", 1269 | "event": { 1270 | "totalcount": 675372, 1271 | "service_name": "speech-answer" 1272 | } 1273 | }, 1274 | { 1275 | "version": "v1", 1276 | "timestamp": "2018-04-12T08:25:00.000+08:00", 1277 | "event": { 1278 | "totalcount": 649454, 1279 | "service_name": "speech-answer" 1280 | } 1281 | }, 1282 | { 1283 | "version": "v1", 1284 | "timestamp": "2018-04-12T08:26:00.000+08:00", 1285 | "event": { 1286 | "totalcount": 673255, 1287 | "service_name": "speech-answer" 1288 | } 1289 | }, 1290 | { 1291 | "version": "v1", 1292 | "timestamp": "2018-04-12T08:27:00.000+08:00", 1293 | "event": { 1294 | "totalcount": 668938, 1295 | "service_name": "speech-answer" 1296 | } 1297 | }, 1298 | { 1299 | "version": "v1", 1300 | "timestamp": "2018-04-12T08:28:00.000+08:00", 1301 | "event": { 1302 | "totalcount": 676199, 1303 | "service_name": "speech-answer" 1304 | } 1305 | }, 1306 | { 1307 | "version": "v1", 1308 | "timestamp": "2018-04-12T08:29:00.000+08:00", 1309 | "event": { 1310 | "totalcount": 665197, 1311 | "service_name": "speech-answer" 1312 | } 1313 | }, 1314 | { 1315 | "version": "v1", 1316 | "timestamp": "2018-04-12T08:30:00.000+08:00", 1317 | "event": { 1318 | "totalcount": 842160, 1319 | "service_name": "speech-answer" 1320 | } 1321 | }, 1322 | { 1323 | "version": "v1", 1324 | "timestamp": "2018-04-12T08:31:00.000+08:00", 1325 | "event": { 1326 | "totalcount": 767248, 1327 | "service_name": "speech-answer" 1328 | } 1329 | }, 1330 | { 1331 | "version": "v1", 1332 | "timestamp": "2018-04-12T08:32:00.000+08:00", 1333 | "event": { 1334 | "totalcount": 671975, 1335 | "service_name": "speech-answer" 1336 | } 1337 | }, 1338 | { 1339 | "version": "v1", 1340 | "timestamp": "2018-04-12T08:33:00.000+08:00", 1341 | "event": { 1342 | "totalcount": 649545, 1343 | "service_name": "speech-answer" 1344 | } 1345 | }, 1346 | { 1347 | "version": "v1", 1348 | "timestamp": "2018-04-12T08:34:00.000+08:00", 1349 | "event": { 1350 | "totalcount": 610557, 1351 | "service_name": "speech-answer" 1352 | } 1353 | }, 1354 | { 1355 | "version": "v1", 1356 | "timestamp": "2018-04-12T08:35:00.000+08:00", 1357 | "event": { 1358 | "totalcount": 642381, 1359 | "service_name": "speech-answer" 1360 | } 1361 | }, 1362 | { 1363 | "version": "v1", 1364 | "timestamp": "2018-04-12T08:36:00.000+08:00", 1365 | "event": { 1366 | "totalcount": 654186, 1367 | "service_name": "speech-answer" 1368 | } 1369 | }, 1370 | { 1371 | "version": "v1", 1372 | "timestamp": "2018-04-12T08:37:00.000+08:00", 1373 | "event": { 1374 | "totalcount": 632144, 1375 | "service_name": "speech-answer" 1376 | } 1377 | }, 1378 | { 1379 | "version": "v1", 1380 | "timestamp": "2018-04-12T08:38:00.000+08:00", 1381 | "event": { 1382 | "totalcount": 653207, 1383 | "service_name": "speech-answer" 1384 | } 1385 | }, 1386 | { 1387 | "version": "v1", 1388 | "timestamp": "2018-04-12T08:39:00.000+08:00", 1389 | "event": { 1390 | "totalcount": 635880, 1391 | "service_name": "speech-answer" 1392 | } 1393 | }, 1394 | { 1395 | "version": "v1", 1396 | "timestamp": "2018-04-12T08:40:00.000+08:00", 1397 | "event": { 1398 | "totalcount": 668097, 1399 | "service_name": "speech-answer" 1400 | } 1401 | }, 1402 | { 1403 | "version": "v1", 1404 | "timestamp": "2018-04-12T08:41:00.000+08:00", 1405 | "event": { 1406 | "totalcount": 615056, 1407 | "service_name": "speech-answer" 1408 | } 1409 | }, 1410 | { 1411 | "version": "v1", 1412 | "timestamp": "2018-04-12T08:42:00.000+08:00", 1413 | "event": { 1414 | "totalcount": 647165, 1415 | "service_name": "speech-answer" 1416 | } 1417 | }, 1418 | { 1419 | "version": "v1", 1420 | "timestamp": "2018-04-12T08:43:00.000+08:00", 1421 | "event": { 1422 | "totalcount": 638594, 1423 | "service_name": "speech-answer" 1424 | } 1425 | }, 1426 | { 1427 | "version": "v1", 1428 | "timestamp": "2018-04-12T08:44:00.000+08:00", 1429 | "event": { 1430 | "totalcount": 648385, 1431 | "service_name": "speech-answer" 1432 | } 1433 | }, 1434 | { 1435 | "version": "v1", 1436 | "timestamp": "2018-04-12T08:45:00.000+08:00", 1437 | "event": { 1438 | "totalcount": 607711, 1439 | "service_name": "speech-answer" 1440 | } 1441 | }, 1442 | { 1443 | "version": "v1", 1444 | "timestamp": "2018-04-12T08:46:00.000+08:00", 1445 | "event": { 1446 | "totalcount": 602923, 1447 | "service_name": "speech-answer" 1448 | } 1449 | }, 1450 | { 1451 | "version": "v1", 1452 | "timestamp": "2018-04-12T08:47:00.000+08:00", 1453 | "event": { 1454 | "totalcount": 661149, 1455 | "service_name": "speech-answer" 1456 | } 1457 | }, 1458 | { 1459 | "version": "v1", 1460 | "timestamp": "2018-04-12T08:48:00.000+08:00", 1461 | "event": { 1462 | "totalcount": 620870, 1463 | "service_name": "speech-answer" 1464 | } 1465 | }, 1466 | { 1467 | "version": "v1", 1468 | "timestamp": "2018-04-12T08:49:00.000+08:00", 1469 | "event": { 1470 | "totalcount": 634732, 1471 | "service_name": "speech-answer" 1472 | } 1473 | }, 1474 | { 1475 | "version": "v1", 1476 | "timestamp": "2018-04-12T08:50:00.000+08:00", 1477 | "event": { 1478 | "totalcount": 610281, 1479 | "service_name": "speech-answer" 1480 | } 1481 | }, 1482 | { 1483 | "version": "v1", 1484 | "timestamp": "2018-04-12T08:51:00.000+08:00", 1485 | "event": { 1486 | "totalcount": 555782, 1487 | "service_name": "speech-answer" 1488 | } 1489 | }, 1490 | { 1491 | "version": "v1", 1492 | "timestamp": "2018-04-12T08:52:00.000+08:00", 1493 | "event": { 1494 | "totalcount": 646354, 1495 | "service_name": "speech-answer" 1496 | } 1497 | }, 1498 | { 1499 | "version": "v1", 1500 | "timestamp": "2018-04-12T08:53:00.000+08:00", 1501 | "event": { 1502 | "totalcount": 598530, 1503 | "service_name": "speech-answer" 1504 | } 1505 | }, 1506 | { 1507 | "version": "v1", 1508 | "timestamp": "2018-04-12T08:54:00.000+08:00", 1509 | "event": { 1510 | "totalcount": 587126, 1511 | "service_name": "speech-answer" 1512 | } 1513 | }, 1514 | { 1515 | "version": "v1", 1516 | "timestamp": "2018-04-12T08:55:00.000+08:00", 1517 | "event": { 1518 | "totalcount": 595150, 1519 | "service_name": "speech-answer" 1520 | } 1521 | }, 1522 | { 1523 | "version": "v1", 1524 | "timestamp": "2018-04-12T08:56:00.000+08:00", 1525 | "event": { 1526 | "totalcount": 577478, 1527 | "service_name": "speech-answer" 1528 | } 1529 | }, 1530 | { 1531 | "version": "v1", 1532 | "timestamp": "2018-04-12T08:57:00.000+08:00", 1533 | "event": { 1534 | "totalcount": 554572, 1535 | "service_name": "speech-answer" 1536 | } 1537 | }, 1538 | { 1539 | "version": "v1", 1540 | "timestamp": "2018-04-12T08:58:00.000+08:00", 1541 | "event": { 1542 | "totalcount": 578223, 1543 | "service_name": "speech-answer" 1544 | } 1545 | }, 1546 | { 1547 | "version": "v1", 1548 | "timestamp": "2018-04-12T08:59:00.000+08:00", 1549 | "event": { 1550 | "totalcount": 617255, 1551 | "service_name": "speech-answer" 1552 | } 1553 | }, 1554 | { 1555 | "version": "v1", 1556 | "timestamp": "2018-04-12T09:00:00.000+08:00", 1557 | "event": { 1558 | "totalcount": 698833, 1559 | "service_name": "speech-answer" 1560 | } 1561 | }, 1562 | { 1563 | "version": "v1", 1564 | "timestamp": "2018-04-12T09:01:00.000+08:00", 1565 | "event": { 1566 | "totalcount": 620654, 1567 | "service_name": "speech-answer" 1568 | } 1569 | }, 1570 | { 1571 | "version": "v1", 1572 | "timestamp": "2018-04-12T09:02:00.000+08:00", 1573 | "event": { 1574 | "totalcount": 647894, 1575 | "service_name": "speech-answer" 1576 | } 1577 | }, 1578 | { 1579 | "version": "v1", 1580 | "timestamp": "2018-04-12T09:03:00.000+08:00", 1581 | "event": { 1582 | "totalcount": 580583, 1583 | "service_name": "speech-answer" 1584 | } 1585 | }, 1586 | { 1587 | "version": "v1", 1588 | "timestamp": "2018-04-12T09:04:00.000+08:00", 1589 | "event": { 1590 | "totalcount": 578972, 1591 | "service_name": "speech-answer" 1592 | } 1593 | }, 1594 | { 1595 | "version": "v1", 1596 | "timestamp": "2018-04-12T09:05:00.000+08:00", 1597 | "event": { 1598 | "totalcount": 631518, 1599 | "service_name": "speech-answer" 1600 | } 1601 | }, 1602 | { 1603 | "version": "v1", 1604 | "timestamp": "2018-04-12T09:06:00.000+08:00", 1605 | "event": { 1606 | "totalcount": 575109, 1607 | "service_name": "speech-answer" 1608 | } 1609 | }, 1610 | { 1611 | "version": "v1", 1612 | "timestamp": "2018-04-12T09:07:00.000+08:00", 1613 | "event": { 1614 | "totalcount": 595095, 1615 | "service_name": "speech-answer" 1616 | } 1617 | }, 1618 | { 1619 | "version": "v1", 1620 | "timestamp": "2018-04-12T09:08:00.000+08:00", 1621 | "event": { 1622 | "totalcount": 548506, 1623 | "service_name": "speech-answer" 1624 | } 1625 | }, 1626 | { 1627 | "version": "v1", 1628 | "timestamp": "2018-04-12T09:09:00.000+08:00", 1629 | "event": { 1630 | "totalcount": 509985, 1631 | "service_name": "speech-answer" 1632 | } 1633 | }, 1634 | { 1635 | "version": "v1", 1636 | "timestamp": "2018-04-12T09:10:00.000+08:00", 1637 | "event": { 1638 | "totalcount": 491109, 1639 | "service_name": "speech-answer" 1640 | } 1641 | }, 1642 | { 1643 | "version": "v1", 1644 | "timestamp": "2018-04-12T09:11:00.000+08:00", 1645 | "event": { 1646 | "totalcount": 477574, 1647 | "service_name": "speech-answer" 1648 | } 1649 | }, 1650 | { 1651 | "version": "v1", 1652 | "timestamp": "2018-04-12T09:12:00.000+08:00", 1653 | "event": { 1654 | "totalcount": 469718, 1655 | "service_name": "speech-answer" 1656 | } 1657 | }, 1658 | { 1659 | "version": "v1", 1660 | "timestamp": "2018-04-12T09:13:00.000+08:00", 1661 | "event": { 1662 | "totalcount": 489585, 1663 | "service_name": "speech-answer" 1664 | } 1665 | }, 1666 | { 1667 | "version": "v1", 1668 | "timestamp": "2018-04-12T09:14:00.000+08:00", 1669 | "event": { 1670 | "totalcount": 474605, 1671 | "service_name": "speech-answer" 1672 | } 1673 | }, 1674 | { 1675 | "version": "v1", 1676 | "timestamp": "2018-04-12T09:15:00.000+08:00", 1677 | "event": { 1678 | "totalcount": 483017, 1679 | "service_name": "speech-answer" 1680 | } 1681 | }, 1682 | { 1683 | "version": "v1", 1684 | "timestamp": "2018-04-12T09:16:00.000+08:00", 1685 | "event": { 1686 | "totalcount": 497214, 1687 | "service_name": "speech-answer" 1688 | } 1689 | }, 1690 | { 1691 | "version": "v1", 1692 | "timestamp": "2018-04-12T09:17:00.000+08:00", 1693 | "event": { 1694 | "totalcount": 500613, 1695 | "service_name": "speech-answer" 1696 | } 1697 | }, 1698 | { 1699 | "version": "v1", 1700 | "timestamp": "2018-04-12T09:18:00.000+08:00", 1701 | "event": { 1702 | "totalcount": 521732, 1703 | "service_name": "speech-answer" 1704 | } 1705 | }, 1706 | { 1707 | "version": "v1", 1708 | "timestamp": "2018-04-12T09:19:00.000+08:00", 1709 | "event": { 1710 | "totalcount": 516754, 1711 | "service_name": "speech-answer" 1712 | } 1713 | }, 1714 | { 1715 | "version": "v1", 1716 | "timestamp": "2018-04-12T09:20:00.000+08:00", 1717 | "event": { 1718 | "totalcount": 505025, 1719 | "service_name": "speech-answer" 1720 | } 1721 | }, 1722 | { 1723 | "version": "v1", 1724 | "timestamp": "2018-04-12T09:21:00.000+08:00", 1725 | "event": { 1726 | "totalcount": 531070, 1727 | "service_name": "speech-answer" 1728 | } 1729 | }, 1730 | { 1731 | "version": "v1", 1732 | "timestamp": "2018-04-12T09:22:00.000+08:00", 1733 | "event": { 1734 | "totalcount": 519789, 1735 | "service_name": "speech-answer" 1736 | } 1737 | }, 1738 | { 1739 | "version": "v1", 1740 | "timestamp": "2018-04-12T09:23:00.000+08:00", 1741 | "event": { 1742 | "totalcount": 527441, 1743 | "service_name": "speech-answer" 1744 | } 1745 | }, 1746 | { 1747 | "version": "v1", 1748 | "timestamp": "2018-04-12T09:24:00.000+08:00", 1749 | "event": { 1750 | "totalcount": 491059, 1751 | "service_name": "speech-answer" 1752 | } 1753 | }, 1754 | { 1755 | "version": "v1", 1756 | "timestamp": "2018-04-12T09:25:00.000+08:00", 1757 | "event": { 1758 | "totalcount": 470573, 1759 | "service_name": "speech-answer" 1760 | } 1761 | }, 1762 | { 1763 | "version": "v1", 1764 | "timestamp": "2018-04-12T09:26:00.000+08:00", 1765 | "event": { 1766 | "totalcount": 468111, 1767 | "service_name": "speech-answer" 1768 | } 1769 | }, 1770 | { 1771 | "version": "v1", 1772 | "timestamp": "2018-04-12T09:27:00.000+08:00", 1773 | "event": { 1774 | "totalcount": 470580, 1775 | "service_name": "speech-answer" 1776 | } 1777 | }, 1778 | { 1779 | "version": "v1", 1780 | "timestamp": "2018-04-12T09:28:00.000+08:00", 1781 | "event": { 1782 | "totalcount": 528361, 1783 | "service_name": "speech-answer" 1784 | } 1785 | }, 1786 | { 1787 | "version": "v1", 1788 | "timestamp": "2018-04-12T09:29:00.000+08:00", 1789 | "event": { 1790 | "totalcount": 490741, 1791 | "service_name": "speech-answer" 1792 | } 1793 | }, 1794 | { 1795 | "version": "v1", 1796 | "timestamp": "2018-04-12T09:30:00.000+08:00", 1797 | "event": { 1798 | "totalcount": 551793, 1799 | "service_name": "speech-answer" 1800 | } 1801 | }, 1802 | { 1803 | "version": "v1", 1804 | "timestamp": "2018-04-12T09:31:00.000+08:00", 1805 | "event": { 1806 | "totalcount": 507580, 1807 | "service_name": "speech-answer" 1808 | } 1809 | }, 1810 | { 1811 | "version": "v1", 1812 | "timestamp": "2018-04-12T09:32:00.000+08:00", 1813 | "event": { 1814 | "totalcount": 499880, 1815 | "service_name": "speech-answer" 1816 | } 1817 | }, 1818 | { 1819 | "version": "v1", 1820 | "timestamp": "2018-04-12T09:33:00.000+08:00", 1821 | "event": { 1822 | "totalcount": 486999, 1823 | "service_name": "speech-answer" 1824 | } 1825 | }, 1826 | { 1827 | "version": "v1", 1828 | "timestamp": "2018-04-12T09:34:00.000+08:00", 1829 | "event": { 1830 | "totalcount": 458232, 1831 | "service_name": "speech-answer" 1832 | } 1833 | }, 1834 | { 1835 | "version": "v1", 1836 | "timestamp": "2018-04-12T09:35:00.000+08:00", 1837 | "event": { 1838 | "totalcount": 510132, 1839 | "service_name": "speech-answer" 1840 | } 1841 | }, 1842 | { 1843 | "version": "v1", 1844 | "timestamp": "2018-04-12T09:36:00.000+08:00", 1845 | "event": { 1846 | "totalcount": 459163, 1847 | "service_name": "speech-answer" 1848 | } 1849 | }, 1850 | { 1851 | "version": "v1", 1852 | "timestamp": "2018-04-12T09:37:00.000+08:00", 1853 | "event": { 1854 | "totalcount": 446629, 1855 | "service_name": "speech-answer" 1856 | } 1857 | }, 1858 | { 1859 | "version": "v1", 1860 | "timestamp": "2018-04-12T09:38:00.000+08:00", 1861 | "event": { 1862 | "totalcount": 483310, 1863 | "service_name": "speech-answer" 1864 | } 1865 | }, 1866 | { 1867 | "version": "v1", 1868 | "timestamp": "2018-04-12T09:39:00.000+08:00", 1869 | "event": { 1870 | "totalcount": 488393, 1871 | "service_name": "speech-answer" 1872 | } 1873 | }, 1874 | { 1875 | "version": "v1", 1876 | "timestamp": "2018-04-12T09:40:00.000+08:00", 1877 | "event": { 1878 | "totalcount": 480662, 1879 | "service_name": "speech-answer" 1880 | } 1881 | }, 1882 | { 1883 | "version": "v1", 1884 | "timestamp": "2018-04-12T09:41:00.000+08:00", 1885 | "event": { 1886 | "totalcount": 485355, 1887 | "service_name": "speech-answer" 1888 | } 1889 | }, 1890 | { 1891 | "version": "v1", 1892 | "timestamp": "2018-04-12T09:42:00.000+08:00", 1893 | "event": { 1894 | "totalcount": 475921, 1895 | "service_name": "speech-answer" 1896 | } 1897 | }, 1898 | { 1899 | "version": "v1", 1900 | "timestamp": "2018-04-12T09:43:00.000+08:00", 1901 | "event": { 1902 | "totalcount": 439775, 1903 | "service_name": "speech-answer" 1904 | } 1905 | }, 1906 | { 1907 | "version": "v1", 1908 | "timestamp": "2018-04-12T09:44:00.000+08:00", 1909 | "event": { 1910 | "totalcount": 458388, 1911 | "service_name": "speech-answer" 1912 | } 1913 | }, 1914 | { 1915 | "version": "v1", 1916 | "timestamp": "2018-04-12T09:45:00.000+08:00", 1917 | "event": { 1918 | "totalcount": 496414, 1919 | "service_name": "speech-answer" 1920 | } 1921 | }, 1922 | { 1923 | "version": "v1", 1924 | "timestamp": "2018-04-12T09:46:00.000+08:00", 1925 | "event": { 1926 | "totalcount": 513723, 1927 | "service_name": "speech-answer" 1928 | } 1929 | }, 1930 | { 1931 | "version": "v1", 1932 | "timestamp": "2018-04-12T09:47:00.000+08:00", 1933 | "event": { 1934 | "totalcount": 511171, 1935 | "service_name": "speech-answer" 1936 | } 1937 | }, 1938 | { 1939 | "version": "v1", 1940 | "timestamp": "2018-04-12T09:48:00.000+08:00", 1941 | "event": { 1942 | "totalcount": 506352, 1943 | "service_name": "speech-answer" 1944 | } 1945 | }, 1946 | { 1947 | "version": "v1", 1948 | "timestamp": "2018-04-12T09:49:00.000+08:00", 1949 | "event": { 1950 | "totalcount": 503312, 1951 | "service_name": "speech-answer" 1952 | } 1953 | }, 1954 | { 1955 | "version": "v1", 1956 | "timestamp": "2018-04-12T09:50:00.000+08:00", 1957 | "event": { 1958 | "totalcount": 461216, 1959 | "service_name": "speech-answer" 1960 | } 1961 | }, 1962 | { 1963 | "version": "v1", 1964 | "timestamp": "2018-04-12T09:51:00.000+08:00", 1965 | "event": { 1966 | "totalcount": 451850, 1967 | "service_name": "speech-answer" 1968 | } 1969 | }, 1970 | { 1971 | "version": "v1", 1972 | "timestamp": "2018-04-12T09:52:00.000+08:00", 1973 | "event": { 1974 | "totalcount": 474631, 1975 | "service_name": "speech-answer" 1976 | } 1977 | }, 1978 | { 1979 | "version": "v1", 1980 | "timestamp": "2018-04-12T09:53:00.000+08:00", 1981 | "event": { 1982 | "totalcount": 454353, 1983 | "service_name": "speech-answer" 1984 | } 1985 | }, 1986 | { 1987 | "version": "v1", 1988 | "timestamp": "2018-04-12T09:54:00.000+08:00", 1989 | "event": { 1990 | "totalcount": 476603, 1991 | "service_name": "speech-answer" 1992 | } 1993 | }, 1994 | { 1995 | "version": "v1", 1996 | "timestamp": "2018-04-12T09:55:00.000+08:00", 1997 | "event": { 1998 | "totalcount": 511717, 1999 | "service_name": "speech-answer" 2000 | } 2001 | }, 2002 | { 2003 | "version": "v1", 2004 | "timestamp": "2018-04-12T09:56:00.000+08:00", 2005 | "event": { 2006 | "totalcount": 446015, 2007 | "service_name": "speech-answer" 2008 | } 2009 | }, 2010 | { 2011 | "version": "v1", 2012 | "timestamp": "2018-04-12T09:57:00.000+08:00", 2013 | "event": { 2014 | "totalcount": 491309, 2015 | "service_name": "speech-answer" 2016 | } 2017 | }, 2018 | { 2019 | "version": "v1", 2020 | "timestamp": "2018-04-12T09:58:00.000+08:00", 2021 | "event": { 2022 | "totalcount": 492750, 2023 | "service_name": "speech-answer" 2024 | } 2025 | }, 2026 | { 2027 | "version": "v1", 2028 | "timestamp": "2018-04-12T09:59:00.000+08:00", 2029 | "event": { 2030 | "totalcount": 452942, 2031 | "service_name": "speech-answer" 2032 | } 2033 | }, 2034 | { 2035 | "version": "v1", 2036 | "timestamp": "2018-04-12T10:00:00.000+08:00", 2037 | "event": { 2038 | "totalcount": 474968, 2039 | "service_name": "speech-answer" 2040 | } 2041 | }, 2042 | { 2043 | "version": "v1", 2044 | "timestamp": "2018-04-12T10:01:00.000+08:00", 2045 | "event": { 2046 | "totalcount": 449940, 2047 | "service_name": "speech-answer" 2048 | } 2049 | }, 2050 | { 2051 | "version": "v1", 2052 | "timestamp": "2018-04-12T10:02:00.000+08:00", 2053 | "event": { 2054 | "totalcount": 500986, 2055 | "service_name": "speech-answer" 2056 | } 2057 | }, 2058 | { 2059 | "version": "v1", 2060 | "timestamp": "2018-04-12T10:03:00.000+08:00", 2061 | "event": { 2062 | "totalcount": 478267, 2063 | "service_name": "speech-answer" 2064 | } 2065 | }, 2066 | { 2067 | "version": "v1", 2068 | "timestamp": "2018-04-12T10:04:00.000+08:00", 2069 | "event": { 2070 | "totalcount": 482410, 2071 | "service_name": "speech-answer" 2072 | } 2073 | }, 2074 | { 2075 | "version": "v1", 2076 | "timestamp": "2018-04-12T10:05:00.000+08:00", 2077 | "event": { 2078 | "totalcount": 483400, 2079 | "service_name": "speech-answer" 2080 | } 2081 | }, 2082 | { 2083 | "version": "v1", 2084 | "timestamp": "2018-04-12T10:06:00.000+08:00", 2085 | "event": { 2086 | "totalcount": 511018, 2087 | "service_name": "speech-answer" 2088 | } 2089 | }, 2090 | { 2091 | "version": "v1", 2092 | "timestamp": "2018-04-12T10:07:00.000+08:00", 2093 | "event": { 2094 | "totalcount": 485560, 2095 | "service_name": "speech-answer" 2096 | } 2097 | }, 2098 | { 2099 | "version": "v1", 2100 | "timestamp": "2018-04-12T10:08:00.000+08:00", 2101 | "event": { 2102 | "totalcount": 448076, 2103 | "service_name": "speech-answer" 2104 | } 2105 | }, 2106 | { 2107 | "version": "v1", 2108 | "timestamp": "2018-04-12T10:09:00.000+08:00", 2109 | "event": { 2110 | "totalcount": 490571, 2111 | "service_name": "speech-answer" 2112 | } 2113 | }, 2114 | { 2115 | "version": "v1", 2116 | "timestamp": "2018-04-12T10:10:00.000+08:00", 2117 | "event": { 2118 | "totalcount": 476502, 2119 | "service_name": "speech-answer" 2120 | } 2121 | }, 2122 | { 2123 | "version": "v1", 2124 | "timestamp": "2018-04-12T10:11:00.000+08:00", 2125 | "event": { 2126 | "totalcount": 442564, 2127 | "service_name": "speech-answer" 2128 | } 2129 | }, 2130 | { 2131 | "version": "v1", 2132 | "timestamp": "2018-04-12T10:12:00.000+08:00", 2133 | "event": { 2134 | "totalcount": 468422, 2135 | "service_name": "speech-answer" 2136 | } 2137 | }, 2138 | { 2139 | "version": "v1", 2140 | "timestamp": "2018-04-12T10:13:00.000+08:00", 2141 | "event": { 2142 | "totalcount": 452079, 2143 | "service_name": "speech-answer" 2144 | } 2145 | }, 2146 | { 2147 | "version": "v1", 2148 | "timestamp": "2018-04-12T10:14:00.000+08:00", 2149 | "event": { 2150 | "totalcount": 462774, 2151 | "service_name": "speech-answer" 2152 | } 2153 | }, 2154 | { 2155 | "version": "v1", 2156 | "timestamp": "2018-04-12T10:15:00.000+08:00", 2157 | "event": { 2158 | "totalcount": 499556, 2159 | "service_name": "speech-answer" 2160 | } 2161 | }, 2162 | { 2163 | "version": "v1", 2164 | "timestamp": "2018-04-12T10:16:00.000+08:00", 2165 | "event": { 2166 | "totalcount": 535136, 2167 | "service_name": "speech-answer" 2168 | } 2169 | }, 2170 | { 2171 | "version": "v1", 2172 | "timestamp": "2018-04-12T10:17:00.000+08:00", 2173 | "event": { 2174 | "totalcount": 459204, 2175 | "service_name": "speech-answer" 2176 | } 2177 | }, 2178 | { 2179 | "version": "v1", 2180 | "timestamp": "2018-04-12T10:18:00.000+08:00", 2181 | "event": { 2182 | "totalcount": 469022, 2183 | "service_name": "speech-answer" 2184 | } 2185 | }, 2186 | { 2187 | "version": "v1", 2188 | "timestamp": "2018-04-12T10:19:00.000+08:00", 2189 | "event": { 2190 | "totalcount": 451692, 2191 | "service_name": "speech-answer" 2192 | } 2193 | }, 2194 | { 2195 | "version": "v1", 2196 | "timestamp": "2018-04-12T10:20:00.000+08:00", 2197 | "event": { 2198 | "totalcount": 477846, 2199 | "service_name": "speech-answer" 2200 | } 2201 | }, 2202 | { 2203 | "version": "v1", 2204 | "timestamp": "2018-04-12T10:21:00.000+08:00", 2205 | "event": { 2206 | "totalcount": 556378, 2207 | "service_name": "speech-answer" 2208 | } 2209 | }, 2210 | { 2211 | "version": "v1", 2212 | "timestamp": "2018-04-12T10:22:00.000+08:00", 2213 | "event": { 2214 | "totalcount": 456116, 2215 | "service_name": "speech-answer" 2216 | } 2217 | }, 2218 | { 2219 | "version": "v1", 2220 | "timestamp": "2018-04-12T10:23:00.000+08:00", 2221 | "event": { 2222 | "totalcount": 526618, 2223 | "service_name": "speech-answer" 2224 | } 2225 | }, 2226 | { 2227 | "version": "v1", 2228 | "timestamp": "2018-04-12T10:24:00.000+08:00", 2229 | "event": { 2230 | "totalcount": 491514, 2231 | "service_name": "speech-answer" 2232 | } 2233 | }, 2234 | { 2235 | "version": "v1", 2236 | "timestamp": "2018-04-12T10:25:00.000+08:00", 2237 | "event": { 2238 | "totalcount": 439994, 2239 | "service_name": "speech-answer" 2240 | } 2241 | }, 2242 | { 2243 | "version": "v1", 2244 | "timestamp": "2018-04-12T10:26:00.000+08:00", 2245 | "event": { 2246 | "totalcount": 508221, 2247 | "service_name": "speech-answer" 2248 | } 2249 | }, 2250 | { 2251 | "version": "v1", 2252 | "timestamp": "2018-04-12T10:27:00.000+08:00", 2253 | "event": { 2254 | "totalcount": 485240, 2255 | "service_name": "speech-answer" 2256 | } 2257 | }, 2258 | { 2259 | "version": "v1", 2260 | "timestamp": "2018-04-12T10:28:00.000+08:00", 2261 | "event": { 2262 | "totalcount": 450765, 2263 | "service_name": "speech-answer" 2264 | } 2265 | }, 2266 | { 2267 | "version": "v1", 2268 | "timestamp": "2018-04-12T10:29:00.000+08:00", 2269 | "event": { 2270 | "totalcount": 490251, 2271 | "service_name": "speech-answer" 2272 | } 2273 | }, 2274 | { 2275 | "version": "v1", 2276 | "timestamp": "2018-04-12T10:30:00.000+08:00", 2277 | "event": { 2278 | "totalcount": 493457, 2279 | "service_name": "speech-answer" 2280 | } 2281 | }, 2282 | { 2283 | "version": "v1", 2284 | "timestamp": "2018-04-12T10:31:00.000+08:00", 2285 | "event": { 2286 | "totalcount": 481613, 2287 | "service_name": "speech-answer" 2288 | } 2289 | }, 2290 | { 2291 | "version": "v1", 2292 | "timestamp": "2018-04-12T10:32:00.000+08:00", 2293 | "event": { 2294 | "totalcount": 455018, 2295 | "service_name": "speech-answer" 2296 | } 2297 | }, 2298 | { 2299 | "version": "v1", 2300 | "timestamp": "2018-04-12T10:33:00.000+08:00", 2301 | "event": { 2302 | "totalcount": 470336, 2303 | "service_name": "speech-answer" 2304 | } 2305 | }, 2306 | { 2307 | "version": "v1", 2308 | "timestamp": "2018-04-12T10:34:00.000+08:00", 2309 | "event": { 2310 | "totalcount": 486501, 2311 | "service_name": "speech-answer" 2312 | } 2313 | }, 2314 | { 2315 | "version": "v1", 2316 | "timestamp": "2018-04-12T10:35:00.000+08:00", 2317 | "event": { 2318 | "totalcount": 496890, 2319 | "service_name": "speech-answer" 2320 | } 2321 | }, 2322 | { 2323 | "version": "v1", 2324 | "timestamp": "2018-04-12T10:36:00.000+08:00", 2325 | "event": { 2326 | "totalcount": 482944, 2327 | "service_name": "speech-answer" 2328 | } 2329 | }, 2330 | { 2331 | "version": "v1", 2332 | "timestamp": "2018-04-12T10:37:00.000+08:00", 2333 | "event": { 2334 | "totalcount": 483962, 2335 | "service_name": "speech-answer" 2336 | } 2337 | }, 2338 | { 2339 | "version": "v1", 2340 | "timestamp": "2018-04-12T10:38:00.000+08:00", 2341 | "event": { 2342 | "totalcount": 449323, 2343 | "service_name": "speech-answer" 2344 | } 2345 | }, 2346 | { 2347 | "version": "v1", 2348 | "timestamp": "2018-04-12T10:39:00.000+08:00", 2349 | "event": { 2350 | "totalcount": 467325, 2351 | "service_name": "speech-answer" 2352 | } 2353 | }, 2354 | { 2355 | "version": "v1", 2356 | "timestamp": "2018-04-12T10:40:00.000+08:00", 2357 | "event": { 2358 | "totalcount": 450635, 2359 | "service_name": "speech-answer" 2360 | } 2361 | }, 2362 | { 2363 | "version": "v1", 2364 | "timestamp": "2018-04-12T10:41:00.000+08:00", 2365 | "event": { 2366 | "totalcount": 441343, 2367 | "service_name": "speech-answer" 2368 | } 2369 | }, 2370 | { 2371 | "version": "v1", 2372 | "timestamp": "2018-04-12T10:42:00.000+08:00", 2373 | "event": { 2374 | "totalcount": 462958, 2375 | "service_name": "speech-answer" 2376 | } 2377 | }, 2378 | { 2379 | "version": "v1", 2380 | "timestamp": "2018-04-12T10:43:00.000+08:00", 2381 | "event": { 2382 | "totalcount": 451135, 2383 | "service_name": "speech-answer" 2384 | } 2385 | }, 2386 | { 2387 | "version": "v1", 2388 | "timestamp": "2018-04-12T10:44:00.000+08:00", 2389 | "event": { 2390 | "totalcount": 509190, 2391 | "service_name": "speech-answer" 2392 | } 2393 | }, 2394 | { 2395 | "version": "v1", 2396 | "timestamp": "2018-04-12T10:45:00.000+08:00", 2397 | "event": { 2398 | "totalcount": 466754, 2399 | "service_name": "speech-answer" 2400 | } 2401 | }, 2402 | { 2403 | "version": "v1", 2404 | "timestamp": "2018-04-12T10:46:00.000+08:00", 2405 | "event": { 2406 | "totalcount": 496323, 2407 | "service_name": "speech-answer" 2408 | } 2409 | }, 2410 | { 2411 | "version": "v1", 2412 | "timestamp": "2018-04-12T10:47:00.000+08:00", 2413 | "event": { 2414 | "totalcount": 470714, 2415 | "service_name": "speech-answer" 2416 | } 2417 | }, 2418 | { 2419 | "version": "v1", 2420 | "timestamp": "2018-04-12T10:48:00.000+08:00", 2421 | "event": { 2422 | "totalcount": 474458, 2423 | "service_name": "speech-answer" 2424 | } 2425 | }, 2426 | { 2427 | "version": "v1", 2428 | "timestamp": "2018-04-12T10:49:00.000+08:00", 2429 | "event": { 2430 | "totalcount": 445083, 2431 | "service_name": "speech-answer" 2432 | } 2433 | }, 2434 | { 2435 | "version": "v1", 2436 | "timestamp": "2018-04-12T10:50:00.000+08:00", 2437 | "event": { 2438 | "totalcount": 467130, 2439 | "service_name": "speech-answer" 2440 | } 2441 | }, 2442 | { 2443 | "version": "v1", 2444 | "timestamp": "2018-04-12T10:51:00.000+08:00", 2445 | "event": { 2446 | "totalcount": 468489, 2447 | "service_name": "speech-answer" 2448 | } 2449 | }, 2450 | { 2451 | "version": "v1", 2452 | "timestamp": "2018-04-12T10:52:00.000+08:00", 2453 | "event": { 2454 | "totalcount": 492184, 2455 | "service_name": "speech-answer" 2456 | } 2457 | }, 2458 | { 2459 | "version": "v1", 2460 | "timestamp": "2018-04-12T10:53:00.000+08:00", 2461 | "event": { 2462 | "totalcount": 466083, 2463 | "service_name": "speech-answer" 2464 | } 2465 | }, 2466 | { 2467 | "version": "v1", 2468 | "timestamp": "2018-04-12T10:54:00.000+08:00", 2469 | "event": { 2470 | "totalcount": 475517, 2471 | "service_name": "speech-answer" 2472 | } 2473 | }, 2474 | { 2475 | "version": "v1", 2476 | "timestamp": "2018-04-12T10:55:00.000+08:00", 2477 | "event": { 2478 | "totalcount": 451940, 2479 | "service_name": "speech-answer" 2480 | } 2481 | }, 2482 | { 2483 | "version": "v1", 2484 | "timestamp": "2018-04-12T10:56:00.000+08:00", 2485 | "event": { 2486 | "totalcount": 472688, 2487 | "service_name": "speech-answer" 2488 | } 2489 | }, 2490 | { 2491 | "version": "v1", 2492 | "timestamp": "2018-04-12T10:57:00.000+08:00", 2493 | "event": { 2494 | "totalcount": 527693, 2495 | "service_name": "speech-answer" 2496 | } 2497 | }, 2498 | { 2499 | "version": "v1", 2500 | "timestamp": "2018-04-12T10:58:00.000+08:00", 2501 | "event": { 2502 | "totalcount": 496487, 2503 | "service_name": "speech-answer" 2504 | } 2505 | }, 2506 | { 2507 | "version": "v1", 2508 | "timestamp": "2018-04-12T10:59:00.000+08:00", 2509 | "event": { 2510 | "totalcount": 455830, 2511 | "service_name": "speech-answer" 2512 | } 2513 | }, 2514 | { 2515 | "version": "v1", 2516 | "timestamp": "2018-04-12T11:00:00.000+08:00", 2517 | "event": { 2518 | "totalcount": 510859, 2519 | "service_name": "speech-answer" 2520 | } 2521 | }, 2522 | { 2523 | "version": "v1", 2524 | "timestamp": "2018-04-12T11:01:00.000+08:00", 2525 | "event": { 2526 | "totalcount": 501934, 2527 | "service_name": "speech-answer" 2528 | } 2529 | }, 2530 | { 2531 | "version": "v1", 2532 | "timestamp": "2018-04-12T11:02:00.000+08:00", 2533 | "event": { 2534 | "totalcount": 498683, 2535 | "service_name": "speech-answer" 2536 | } 2537 | }, 2538 | { 2539 | "version": "v1", 2540 | "timestamp": "2018-04-12T11:03:00.000+08:00", 2541 | "event": { 2542 | "totalcount": 504499, 2543 | "service_name": "speech-answer" 2544 | } 2545 | }, 2546 | { 2547 | "version": "v1", 2548 | "timestamp": "2018-04-12T11:04:00.000+08:00", 2549 | "event": { 2550 | "totalcount": 542108, 2551 | "service_name": "speech-answer" 2552 | } 2553 | }, 2554 | { 2555 | "version": "v1", 2556 | "timestamp": "2018-04-12T11:05:00.000+08:00", 2557 | "event": { 2558 | "totalcount": 457375, 2559 | "service_name": "speech-answer" 2560 | } 2561 | }, 2562 | { 2563 | "version": "v1", 2564 | "timestamp": "2018-04-12T11:06:00.000+08:00", 2565 | "event": { 2566 | "totalcount": 491864, 2567 | "service_name": "speech-answer" 2568 | } 2569 | }, 2570 | { 2571 | "version": "v1", 2572 | "timestamp": "2018-04-12T11:07:00.000+08:00", 2573 | "event": { 2574 | "totalcount": 501793, 2575 | "service_name": "speech-answer" 2576 | } 2577 | }, 2578 | { 2579 | "version": "v1", 2580 | "timestamp": "2018-04-12T11:08:00.000+08:00", 2581 | "event": { 2582 | "totalcount": 478308, 2583 | "service_name": "speech-answer" 2584 | } 2585 | }, 2586 | { 2587 | "version": "v1", 2588 | "timestamp": "2018-04-12T11:09:00.000+08:00", 2589 | "event": { 2590 | "totalcount": 472963, 2591 | "service_name": "speech-answer" 2592 | } 2593 | }, 2594 | { 2595 | "version": "v1", 2596 | "timestamp": "2018-04-12T11:10:00.000+08:00", 2597 | "event": { 2598 | "totalcount": 501734, 2599 | "service_name": "speech-answer" 2600 | } 2601 | }, 2602 | { 2603 | "version": "v1", 2604 | "timestamp": "2018-04-12T11:11:00.000+08:00", 2605 | "event": { 2606 | "totalcount": 472242, 2607 | "service_name": "speech-answer" 2608 | } 2609 | }, 2610 | { 2611 | "version": "v1", 2612 | "timestamp": "2018-04-12T11:12:00.000+08:00", 2613 | "event": { 2614 | "totalcount": 475272, 2615 | "service_name": "speech-answer" 2616 | } 2617 | }, 2618 | { 2619 | "version": "v1", 2620 | "timestamp": "2018-04-12T11:13:00.000+08:00", 2621 | "event": { 2622 | "totalcount": 519392, 2623 | "service_name": "speech-answer" 2624 | } 2625 | }, 2626 | { 2627 | "version": "v1", 2628 | "timestamp": "2018-04-12T11:14:00.000+08:00", 2629 | "event": { 2630 | "totalcount": 477919, 2631 | "service_name": "speech-answer" 2632 | } 2633 | }, 2634 | { 2635 | "version": "v1", 2636 | "timestamp": "2018-04-12T11:15:00.000+08:00", 2637 | "event": { 2638 | "totalcount": 543527, 2639 | "service_name": "speech-answer" 2640 | } 2641 | }, 2642 | { 2643 | "version": "v1", 2644 | "timestamp": "2018-04-12T11:16:00.000+08:00", 2645 | "event": { 2646 | "totalcount": 537722, 2647 | "service_name": "speech-answer" 2648 | } 2649 | }, 2650 | { 2651 | "version": "v1", 2652 | "timestamp": "2018-04-12T11:17:00.000+08:00", 2653 | "event": { 2654 | "totalcount": 563549, 2655 | "service_name": "speech-answer" 2656 | } 2657 | }, 2658 | { 2659 | "version": "v1", 2660 | "timestamp": "2018-04-12T11:18:00.000+08:00", 2661 | "event": { 2662 | "totalcount": 504338, 2663 | "service_name": "speech-answer" 2664 | } 2665 | }, 2666 | { 2667 | "version": "v1", 2668 | "timestamp": "2018-04-12T11:19:00.000+08:00", 2669 | "event": { 2670 | "totalcount": 520553, 2671 | "service_name": "speech-answer" 2672 | } 2673 | }, 2674 | { 2675 | "version": "v1", 2676 | "timestamp": "2018-04-12T11:20:00.000+08:00", 2677 | "event": { 2678 | "totalcount": 528766, 2679 | "service_name": "speech-answer" 2680 | } 2681 | }, 2682 | { 2683 | "version": "v1", 2684 | "timestamp": "2018-04-12T11:21:00.000+08:00", 2685 | "event": { 2686 | "totalcount": 509946, 2687 | "service_name": "speech-answer" 2688 | } 2689 | }, 2690 | { 2691 | "version": "v1", 2692 | "timestamp": "2018-04-12T11:22:00.000+08:00", 2693 | "event": { 2694 | "totalcount": 536685, 2695 | "service_name": "speech-answer" 2696 | } 2697 | }, 2698 | { 2699 | "version": "v1", 2700 | "timestamp": "2018-04-12T11:23:00.000+08:00", 2701 | "event": { 2702 | "totalcount": 533619, 2703 | "service_name": "speech-answer" 2704 | } 2705 | }, 2706 | { 2707 | "version": "v1", 2708 | "timestamp": "2018-04-12T11:24:00.000+08:00", 2709 | "event": { 2710 | "totalcount": 516169, 2711 | "service_name": "speech-answer" 2712 | } 2713 | }, 2714 | { 2715 | "version": "v1", 2716 | "timestamp": "2018-04-12T11:25:00.000+08:00", 2717 | "event": { 2718 | "totalcount": 489772, 2719 | "service_name": "speech-answer" 2720 | } 2721 | }, 2722 | { 2723 | "version": "v1", 2724 | "timestamp": "2018-04-12T11:26:00.000+08:00", 2725 | "event": { 2726 | "totalcount": 499067, 2727 | "service_name": "speech-answer" 2728 | } 2729 | }, 2730 | { 2731 | "version": "v1", 2732 | "timestamp": "2018-04-12T11:27:00.000+08:00", 2733 | "event": { 2734 | "totalcount": 486875, 2735 | "service_name": "speech-answer" 2736 | } 2737 | }, 2738 | { 2739 | "version": "v1", 2740 | "timestamp": "2018-04-12T11:28:00.000+08:00", 2741 | "event": { 2742 | "totalcount": 516651, 2743 | "service_name": "speech-answer" 2744 | } 2745 | }, 2746 | { 2747 | "version": "v1", 2748 | "timestamp": "2018-04-12T11:29:00.000+08:00", 2749 | "event": { 2750 | "totalcount": 527652, 2751 | "service_name": "speech-answer" 2752 | } 2753 | }, 2754 | { 2755 | "version": "v1", 2756 | "timestamp": "2018-04-12T11:30:00.000+08:00", 2757 | "event": { 2758 | "totalcount": 560308, 2759 | "service_name": "speech-answer" 2760 | } 2761 | }, 2762 | { 2763 | "version": "v1", 2764 | "timestamp": "2018-04-12T11:31:00.000+08:00", 2765 | "event": { 2766 | "totalcount": 533145, 2767 | "service_name": "speech-answer" 2768 | } 2769 | }, 2770 | { 2771 | "version": "v1", 2772 | "timestamp": "2018-04-12T11:32:00.000+08:00", 2773 | "event": { 2774 | "totalcount": 549783, 2775 | "service_name": "speech-answer" 2776 | } 2777 | }, 2778 | { 2779 | "version": "v1", 2780 | "timestamp": "2018-04-12T11:33:00.000+08:00", 2781 | "event": { 2782 | "totalcount": 546869, 2783 | "service_name": "speech-answer" 2784 | } 2785 | }, 2786 | { 2787 | "version": "v1", 2788 | "timestamp": "2018-04-12T11:34:00.000+08:00", 2789 | "event": { 2790 | "totalcount": 572395, 2791 | "service_name": "speech-answer" 2792 | } 2793 | }, 2794 | { 2795 | "version": "v1", 2796 | "timestamp": "2018-04-12T11:35:00.000+08:00", 2797 | "event": { 2798 | "totalcount": 561408, 2799 | "service_name": "speech-answer" 2800 | } 2801 | }, 2802 | { 2803 | "version": "v1", 2804 | "timestamp": "2018-04-12T11:36:00.000+08:00", 2805 | "event": { 2806 | "totalcount": 548161, 2807 | "service_name": "speech-answer" 2808 | } 2809 | }, 2810 | { 2811 | "version": "v1", 2812 | "timestamp": "2018-04-12T11:37:00.000+08:00", 2813 | "event": { 2814 | "totalcount": 562829, 2815 | "service_name": "speech-answer" 2816 | } 2817 | }, 2818 | { 2819 | "version": "v1", 2820 | "timestamp": "2018-04-12T11:38:00.000+08:00", 2821 | "event": { 2822 | "totalcount": 1533983, 2823 | "service_name": "speech-answer" 2824 | } 2825 | }, 2826 | { 2827 | "version": "v1", 2828 | "timestamp": "2018-04-12T11:39:00.000+08:00", 2829 | "event": { 2830 | "totalcount": 547461, 2831 | "service_name": "speech-answer" 2832 | } 2833 | }, 2834 | { 2835 | "version": "v1", 2836 | "timestamp": "2018-04-12T11:40:00.000+08:00", 2837 | "event": { 2838 | "totalcount": 539811, 2839 | "service_name": "speech-answer" 2840 | } 2841 | }, 2842 | { 2843 | "version": "v1", 2844 | "timestamp": "2018-04-12T11:41:00.000+08:00", 2845 | "event": { 2846 | "totalcount": 594859, 2847 | "service_name": "speech-answer" 2848 | } 2849 | }, 2850 | { 2851 | "version": "v1", 2852 | "timestamp": "2018-04-12T11:42:00.000+08:00", 2853 | "event": { 2854 | "totalcount": 528444, 2855 | "service_name": "speech-answer" 2856 | } 2857 | }, 2858 | { 2859 | "version": "v1", 2860 | "timestamp": "2018-04-12T11:43:00.000+08:00", 2861 | "event": { 2862 | "totalcount": 567467, 2863 | "service_name": "speech-answer" 2864 | } 2865 | }, 2866 | { 2867 | "version": "v1", 2868 | "timestamp": "2018-04-12T11:44:00.000+08:00", 2869 | "event": { 2870 | "totalcount": 559429, 2871 | "service_name": "speech-answer" 2872 | } 2873 | }, 2874 | { 2875 | "version": "v1", 2876 | "timestamp": "2018-04-12T11:45:00.000+08:00", 2877 | "event": { 2878 | "totalcount": 600705, 2879 | "service_name": "speech-answer" 2880 | } 2881 | } 2882 | ] --------------------------------------------------------------------------------