本文最后更新于 2024-10-12T23:02:42+08:00
箱型图
源码数据在GitHub本文件夹的source下边,对餐饮系统的销售额数据进行处理。采用箱型图检测异常值。
代码中xls文件和代码处于同一个文件夹中.这里计算四分位箱图上下界时采用常数1.5是因为使用
1.5 倍的 IQR
来定义上下限的做法源于经验法则,主要是为了平衡灵敏度与稳健性。一些情况下也有用其他值的,值越大定义的异常值标准越宽松
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 catering_sale = 'catering_sale.xls'; index = 1; %用于后面提取第一列数据 %% 读入数据 [num,txt] = xlsread(catering_sale); %通过xlsread获取到文件中的数字和字符 sales = num(2:end,index); %提取出num中从2到最后的第一列,之前定义了index=1 rows = size(sales,1); % 表示返回矩阵的第一维度也就是行, %% 处理缺失值 nanvalue = find(isnan(sales)); if isempty(nanvalue) disp('没有缺失值!'); else row_ = size(nanvalue,1);%缺失值的行数,即缺失值数量 disp(['缺失值个数为:' num2str(row_) ',缺失率为:' num2str(row_/rows)])%方括号 [] 可以将字符串和通过 num2str 转换为字符串的数值拼接在一起,形成一个完整的输出字符串 end %% 设置箱型图属性 q_ = prctile(sales,[25,75]);%获取百分位数,这里是四分位箱图所需的上四分位和下四分位位置 p25 = q_(1,1);%获取上四分位数 p75 = q_(1,2);%下四分位数 % 四分位距 (IQR):计算方法为 p75 - p25 upper = p75+1.5*(p75-p25);%计算上界,1.5是一个常用的常数,用于定义异常值的边界。 lower = p25-1.5*(p75-p25);%计算下界 upper_indexes = sales(sales>upper);%返回一个逻辑数组,sales中如果大于upper返回true,再取出sales中取true的值 lower_indexes = sales(sales<lower);% 同理 indexes = [upper_indexes;lower_indexes];%upper_indexes 和 lower_indexes 垂直拼接在一起,生成一个新的数组 indexes,其中全为异常的值,确保都是列向量,如果不是可用'转置 indexes =sort(indexes);%对indexes进行排序,返回一个升序 %% 画箱型图 figure hold on;%新图可以叠加在旧图上 boxplot(sales,'whisker',1.5,'outliersize',6); %whisker是指定须的长度,须由IQR决定,IQR是上四分位数与下四分位数之差。 %须指的是延伸至最小非异常值和最大非异常值。outliersize 控制异常值的标记大小,便于突出异常数据点 rows = size(indexes,1);%返回indexes的大小 flag = 0;%用于控制文本标注的位置 for i = 1:rows %遍历所有的异常值 if flag == 0 text(1+0.01,indexes(i,1),num2str(indexes(i,1)));%text用于在指定位置添加文本, %第一个参数是x坐标,后面是y坐标即文本标记在异常值当前所在位置,最后一个参数将数值转换为字符串在图中表示出 flag = 1;%下一次循环换一个位置标注 else text(1-0.017*length(num2str(indexes(i,1))),indexes(i,1),num2str(indexes(i,1))); %根据文本长度计算x坐标,确保不重叠,后面两个参数同理 flag = 0; end end hold off; disp('餐饮销售数据缺失值及异常值检测完成!')
结果如下:
以下是一些修改箱型图外观的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 boxplot(data, 'Colors' , 'r' , 'Widths' , 0.5 , 'Whisker' , 1.5 , ...'Symbol' , 'k*' , 'OutlierSize' , 8 ); set(findobj(h, 'Tag' , 'Box' ), 'Color' , 'b' ); set(findobj(h, 'Tag' , 'Median' ), 'Color' , 'r' , 'LineWidth' , 1.5 ); set(findobj(h, 'Tag' , 'Whisker' ), 'Color' , 'g' , 'LineStyle' , '--' ); set(findobj(h, 'Tag' , 'Outliers' ), 'MarkerEdgeColor' , 'm' ); boxes = findobj(gca, 'Tag' , 'Box' );for j = 1 :length (boxes) patch(get(boxes(j ), 'XData' ), get(boxes(j ), 'YData' ), 'c' , 'FaceAlpha' , 0.5 );end
findobj(gca, 'Tag',
'Box') 会查找当前坐标轴(gca)中所有 Tag 为 'Box' 的对象 findobj
根据对象的 Tag
属性来找到特定的图形元素,例如箱体(Box)、中位数线(Median)、须(Whisker)等。MATLAB
自动为不同的图形元素设置了特定的 Tag
属性,这些属性可以用来查找和修改这些元素。例如:
箱体的 Tag
属性为 'Box'
中位数线的 Tag
属性为 'Median'
须的 Tag
属性为 'Whisker'
异常值的 Tag
属性为 'Outliers'
其中,h 是一个图形对象或对象的句柄(handle)。当使用 boxplot
函数创建箱线图时,可以将返回的句柄赋给变量
h,以便以后对图形的各个元素进行访问和修改。