阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 异常检测可视化

异常检测可视化

作者:陈川 阅读数:31245人阅读 分类: ECharts

异常检测可视化的核心需求

异常检测可视化需要直观展示数据中的离群点、异常模式或突变趋势。ECharts作为强大的可视化库,通过丰富的图表类型和交互功能,能够清晰呈现数据异常。关键在于如何选择合适的视觉编码方式,将异常数据与正常数据形成鲜明对比。

基本异常检测图表类型

折线图与面积图

折线图适合展示时间序列数据的异常波动。通过设置阈值线或标记异常点,可以快速识别超出正常范围的数据。

option = {
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [{
    data: [820, 932, 901, 934, 1290, 1330, 1320],
    type: 'line',
    markPoint: {
      data: [
        { type: 'max', name: 'Max' },
        { type: 'min', name: 'Min' }
      ]
    },
    markArea: {
      data: [[
        { yAxis: 800 },
        { yAxis: 950 }
      ]]
    }
  }]
};

散点图与气泡图

散点图能有效展示多维数据中的离群点,通过设置不同颜色或大小区分异常值。

option = {
  xAxis: {},
  yAxis: {},
  series: [{
    symbolSize: 20,
    data: [
      [10.0, 8.04],
      [8.0, 6.95],
      [13.0, 7.58],
      [9.0, 8.81],
      [11.0, 8.33],
      [14.0, 9.96],
      [6.0, 7.24],
      [4.0, 4.26],
      [12.0, 10.84],
      [7.0, 4.82],
      [5.0, 5.68],
      [30.0, 15.0]  // 异常点
    ],
    type: 'scatter',
    itemStyle: {
      color: function(params) {
        return params.data[0] > 20 ? '#ff0000' : '#5470c6';
      }
    }
  }]
};

高级异常检测可视化技术

箱线图与离群点展示

箱线图是展示数据分布和离群点的标准方法,ECharts通过boxplot系列实现。

option = {
  dataset: [{
    source: [
      [850, 740, 900, 1070, 930, 850, 950],
      [960, 940, 960, 940, 880, 800, 850],
      [880, 800, 840, 750, 750, 700, 720],
      [1150, 990, 1000, 1020, 930, 980, 990],
      [890, 810, 810, 820, 800, 770, 750],
      [890, 840, 780, 810, 760, 810, 790],
      [1000, 950, 960, 1000, 1100, 1050, 1000],
      [920, 910, 905, 925, 955, 960, 950]
    ]
  }, {
    transform: {
      type: 'boxplot',
      config: { itemNameFormatter: 'expr {value}' }
    }
  }],
  xAxis: { type: 'category' },
  yAxis: { type: 'value' },
  series: [{
    name: 'boxplot',
    type: 'boxplot',
    datasetIndex: 1,
    itemStyle: {
      color: '#b8c5f2',
      borderColor: '#5470c6'
    },
    emphasis: {
      itemStyle: {
        color: '#5470c6',
        borderColor: '#333'
      }
    }
  }]
};

热力图与矩阵图

热力图适合展示高维数据中的异常模式,通过颜色变化突出异常区域。

option = {
  tooltip: {
    position: 'top'
  },
  grid: {
    height: '50%',
    top: '10%'
  },
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
    splitArea: {
      show: true
    }
  },
  yAxis: {
    type: 'category',
    data: ['Morning', 'Afternoon', 'Evening', 'Night'],
    splitArea: {
      show: true
    }
  },
  visualMap: {
    min: 0,
    max: 10,
    calculable: true,
    orient: 'horizontal',
    left: 'center',
    bottom: '15%'
  },
  series: [{
    name: '异常频率',
    type: 'heatmap',
    data: [
      [0, 0, 5], [1, 0, 7], [2, 0, 3], [3, 0, 5], [4, 0, 2], [5, 0, 1], [6, 0, 0],
      [0, 1, 1], [1, 1, 2], [2, 1, 4], [3, 1, 8], [4, 1, 1], [5, 1, 0], [6, 1, 0],
      [0, 2, 0], [1, 2, 1], [2, 2, 2], [3, 2, 9], [4, 2, 1], [5, 2, 0], [6, 2, 0],
      [0, 3, 0], [1, 3, 1], [2, 3, 1], [3, 3, 10], [4, 3, 2], [5, 3, 0], [6, 3, 0]
    ],
    label: {
      show: true
    },
    emphasis: {
      itemStyle: {
        shadowBlur: 10,
        shadowColor: 'rgba(0, 0, 0, 0.5)'
      }
    }
  }]
};

交互式异常检测功能

数据刷选与联动

通过brush组件实现异常数据的交互式选择,配合其他图表联动分析。

option = {
  brush: {
    toolbox: ['rect', 'polygon', 'keep', 'clear'],
    xAxisIndex: 0
  },
  toolbox: {
    feature: {
      brush: {
        type: ['rect', 'polygon', 'clear']
      }
    }
  },
  xAxis: {
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {},
  series: [{
    type: 'bar',
    data: [120, 200, 150, 80, 70, 110, 130],
    itemStyle: {
      color: function(params) {
        var colorList = ['#c23531','#2f4554','#61a0a8','#d48265','#91c7ae','#749f83','#ca8622'];
        return params.data > 150 ? '#c23531' : colorList[params.dataIndex];
      }
    }
  }]
};

动态阈值与自适应检测

结合ECharts的数据处理能力,实现动态阈值计算和可视化。

function calculateThreshold(data) {
  const mean = data.reduce((a, b) => a + b) / data.length;
  const std = Math.sqrt(data.reduce((sq, n) => sq + Math.pow(n - mean, 2), 0) / data.length);
  return [mean - 2*std, mean + 2*std];
}

const data = [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42];
const [lower, upper] = calculateThreshold(data);

option = {
  xAxis: {
    type: 'category',
    data: Array.from({length: data.length}, (_, i) => `Day ${i+1}`)
  },
  yAxis: {
    type: 'value'
  },
  series: [{
    data: data,
    type: 'line',
    markArea: {
      silent: true,
      data: [[
        { yAxis: lower },
        { yAxis: upper }
      ]],
      itemStyle: {
        color: 'rgba(135, 206, 235, 0.2)'
      }
    },
    markPoint: {
      data: data.map((value, index) => {
        return (value < lower || value > upper) ? {
          coord: [`Day ${index+1}`, value],
          symbol: 'circle',
          symbolSize: 10,
          itemStyle: {
            color: '#ff0000'
          }
        } : null;
      }).filter(Boolean)
    }
  }]
};

多维异常检测可视化

平行坐标系

平行坐标系适合展示高维数据中的异常模式,通过线条颜色突出异常记录。

option = {
  parallelAxis: [
    {dim: 0, name: 'CPU使用率'},
    {dim: 1, name: '内存使用率'},
    {dim: 2, name: '磁盘IO'},
    {dim: 3, name: '网络流量'},
    {dim: 4, name: '响应时间'}
  ],
  series: {
    type: 'parallel',
    lineStyle: {
      width: 1,
      opacity: 0.5
    },
    data: [
      [80, 70, 65, 50, 120],
      [85, 75, 70, 55, 130],
      [90, 80, 75, 60, 140],
      [95, 85, 80, 65, 150],
      [30, 20, 15, 10, 200],  // 异常记录
      [75, 65, 60, 45, 110],
      [82, 72, 67, 52, 125],
      [88, 78, 73, 58, 135],
      [92, 82, 77, 62, 145],
      [25, 15, 10, 5, 210]   // 异常记录
    ],
    itemStyle: function(params) {
      const data = params.data;
      return {
        color: data[4] > 180 ? '#ff0000' : '#5470c6'
      };
    }
  }
};

雷达图异常模式识别

雷达图适合展示周期性数据或多项指标中的异常模式。

option = {
  radar: {
    indicator: [
      { name: 'CPU', max: 100 },
      { name: '内存', max: 100 },
      { name: '磁盘', max: 100 },
      { name: '网络', max: 100 },
      { name: '响应', max: 200 }
    ],
    radius: '65%'
  },
  series: [{
    type: 'radar',
    data: [
      {
        value: [80, 70, 65, 50, 120],
        name: '正常模式',
        areaStyle: {
          color: 'rgba(84, 112, 198, 0.5)'
        }
      },
      {
        value: [95, 85, 80, 65, 180],
        name: '异常模式',
        areaStyle: {
          color: 'rgba(255, 0, 0, 0.5)'
        }
      }
    ]
  }]
};

实时异常检测可视化

动态数据更新

对于实时数据流,需要动态更新图表以反映最新异常情况。

let data = [];
let now = new Date();

for (let i = 0; i < 100; i++) {
  data.push(randomData());
}

function randomData() {
  now = new Date(+now + 1000);
  const value = Math.random() * 100;
  return {
    name: now.toString(),
    value: [
      now.toLocaleTimeString(),
      value > 90 ? value + 50 : value  // 模拟异常值
    ]
  };
}

option = {
  xAxis: {
    type: 'category',
    boundaryGap: false
  },
  yAxis: {
    type: 'value',
    boundaryGap: [0, '10%']
  },
  series: [{
    type: 'line',
    showSymbol: false,
    data: data,
    markPoint: {
      data: [],
      symbol: 'pin',
      symbolSize: 50,
      label: {
        formatter: function(params) {
          return params.value > 140 ? '异常' : '';
        }
      }
    }
  }]
};

setInterval(function() {
  data.shift();
  const newData = randomData();
  data.push(newData);
  
  if (newData.value[1] > 140) {
    option.series[0].markPoint.data.push({
      coord: [newData.value[0], newData.value[1]],
      itemStyle: { color: '#ff0000' }
    });
  }
  
  myChart.setOption({
    series: [{
      data: data
    }]
  });
}, 1000);

异常事件标记与提示

在时间序列中标记异常事件,并提供详细信息提示。

option = {
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [{
    data: [820, 932, 901, 934, 1290, 1330, 1320],
    type: 'line',
    markPoint: {
      data: [
        {
          coord: ['Fri', 1290],
          value: '异常峰值',
          symbol: 'pin',
          symbolSize: 50,
          itemStyle: {
            color: '#ff0000'
          },
          label: {
            formatter: '异常事件',
            position: 'top'
          }
        },
        {
          coord: ['Sat', 1330],
          value: '最高值',
          symbol: 'pin',
          symbolSize: 50,
          itemStyle: {
            color: '#ff0000'
          },
          label: {
            formatter: '严重异常',
            position: 'top'
          }
        }
      ]
    },
    markLine: {
      data: [
        {
          type: 'average',
          name: '平均值'
        },
        {
          yAxis: 1100,
          name: '阈值线'
        }
      ]
    }
  }],
  tooltip: {
    trigger: 'axis',
    formatter: function(params) {
      const data = params[0].data;
      let tip = `${params[0].axisValue}<br/>`;
      tip += `${params[0].seriesName}: ${data}`;
      
      if (data > 1100) {
        tip += '<br/><span style="color:#ff0000">警告: 超过阈值</span>';
      }
      
      return tip;
    }
  }
};

异常检测可视化的性能优化

大数据量下的渲染策略

当处理大规模数据集时,需要采用降采样或增量渲染技术。

// 降采样函数
function downsample(data, factor) {
  const result = [];
  for (let i = 0; i < data.length; i += factor) {
    const chunk = data.slice(i, i + factor);
    const avg = chunk.reduce((sum, val) => sum + val, 0) / chunk.length;
    result.push(avg);
  }
  return result;
}

// 原始数据
const rawData = Array.from({length: 100000}, () => Math.random() * 100);

// 添加异常点
for (let i = 0; i < 10; i++) {
  const index = Math.floor(Math.random() * rawData.length);
  rawData[index] = 150 + Math.random() * 50;
}

// 降采样
const downsampledData = downsample(rawData, 100);

option = {
  xAxis: {
    type: 'category',
    data: Array.from({length: downsampledData.length}, (_, i) => i)
  },
  yAxis: {
    type: 'value'
  },
  series: [{
    data: downsampledData,
    type: 'line',
    symbol: 'none',
    lineStyle: {
      width: 1
    },
    markPoint: {
      data: downsampledData
        .map((value, index) => (value > 140) ? {coord: [index, value]} : null)
        .filter(Boolean),
      symbol: 'circle',
      symbolSize: 5,
      itemStyle: {
        color: '#ff0000'
      }
    }
  }]
};

WebGL加速渲染

对于极大规模数据,可以使用ECharts的WebGL扩展实现GPU加速。

// 需要引入echarts-gl
const data = new Float32Array(1000000);
for (let i = 0; i < data.length; i++) {
  data[i] = Math.random() * 100;
  if (Math.random() < 0.001) {
    data[i] = 150 + Math.random() * 50; // 添加异常点
  }
}

option = {
  xAxis3D: {
    type: 'value'
  },
  yAxis3D: {
    type: 'value'
  },
  zAxis3D: {
    type: 'value'
  },
  grid3D: {
    viewControl: {
      autoRotate: true
    }
  },
  series:

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌