在数据分析和机器学习的领域里,数据是基础,异常值的识别则是对基础的细致审查。若一个微小的异常值未被察觉,它可能使一座看似坚固的数据建筑变得岌岌可危,进而影响统计分析和模型训练的结果。这就是一个看似简单却很容易被忽略的问题所在。
数据异常值的影响
数据中的异常值可能悄无声息地影响分析结果。比如,在分析市场销售数据时,若发现某个销售量特别高,这可能是录入数据时出现了错误。如果不加以纠正,就会导致对市场需求的错误估计。这种情况在某个公司的市场分析部门整理全国销量数据时可能会遇到。此外,数据中的异常值还会对训练机器学习模型造成干扰,例如,向垃圾邮件分类模型输入含有异常值的数据,就会降低模型的准确度。因此,在进行任何分析之前,我们都应该对数据异常值给予足够的重视。
异常数值使得统计分析结果难以信赖。以学生成绩分析为例,一旦掺入一个远超或远低于整体水平的分数,平均分便无法准确体现学生的实际学习状况。如果教育工作者据此调整教学策略,那显然是不恰当的。
import pandas as pd
glass = pd.read_csv('glass.csv')
单变量异常值检测
聚焦单一变量是识别异常值的核心方法。在医学研究领域,针对人体指标的数据集中,比如检测“血压”这一指标时,可以借鉴前面提到的“Na”指标的做法,通过绘制箱线图来直观展示。箱线图的上下限之外的散点,很可能就是异常数据点。
在财务报表分析过程中,若某公司特定年度的收入数据与多数数据点存在较大差异,那么这些收入数据便存在疑点。此时,必须对相关业务情况进行复查,以确定是否为新业务取得显著成功,或是统计过程中出现了错误。
import seaborn as sns
sns.pairplot(glass, diag_kws={'color':'red'})
在分析多变量异常值时,必须综合考虑多个属性的结合。比如,在环境监测领域,若要研究空气质量,就必须关注温度、湿度以及污染物浓度等众多因素构成的复合情况。这些因素组合在一起,构成了我们所需要考虑的多变量问题。而在n维空间中,那些与大部分数据点相距较远的数据组合,便被定义为多元异常值。
对城市交通状况的研究涉及多个方面的数据,比如车辆流动数量、行驶速度以及道路拥堵程度等。如果某个时间点的数据在这些因素构成的三维空间中显得格外突出,这或许意味着发生了不寻常的情况,比如交通事故或是道路临时管控等。
统计方法对比
标准偏差检测存在一定不足。例如,在依据“Na”这一变量进行检测时,仅能识别出两条特别的数据,只能揭示出极不寻常的个别点。而在众多数据变化不大但仍有细微起伏的情况下,此方法可能就会遗漏掉一些异常数据。
四分位数间距法更为敏感。它能发现更多的异常数值,比如之前提到的那些不太极端的5个记录。在分析经济趋势时,若数据存在细微波动,IQR方法能更准确地反映出数据的异常状况,而标准差法则可能会忽略这些异常。
机器学习方法应用
孤立森林算法独具特色。该算法沿袭了随机森林的理念,却着重于剔除异常的数据样本。在网络流量监控中,正常的数据流量模式形成了一片健康的数据森林,而那些被孤立的数据点或许正是异常流量的信号,比如突如其来的大规模恶意攻击流量。
图像识别过程中,若特征数据含有异常,孤立森林能识别出这些异常特征,这对提升识别精度大有裨益,能有效防止将异常图像误判为正常。
from sklearn.decomposition import PCA
import plotly.express as px
# Dimensionality reduction to 3 dimensions
pca = PCA(n_components=3)
glass_pca = pca.fit_transform(glass.iloc[:, :-1])
# 3D scatterplot
fig = px.scatter_3d(x=glass_pca[:, 0],
y=glass_pca[:, 1],
z=glass_pca[:, 2],
color=glass.iloc[:, -1])
fig.show()
数据的可视化呈现
Seaborn的pairplot功能非常实用。它能展示数据集中不同字段间的相互关系。例如,在分析员工综合素质时,包括技能、团队协作和效率等,pairplot能让我们清楚地看到各变量间的联系,以及每个变量的分布状况。
其展示的是基于单一变量的分布图,便于直观看出数据是否符合正态分布。通过这样的图表,我们能够迅速识别出那些可能偏离正常分布的数据特性,这有助于我们更有效地查找和处理异常数据。
在您整理工作或学习数据时,是否遇到过数据异常,从而影响了最终结果?欢迎点赞、转发和留言交流。
# Find mean, standard deviation and cut off value
mean = glass["Na"].mean()
std = glass["Na"].std()
cutoff = 3 * std
# Define lower and upper boundaries
lower, upper = mean-cutoff, mean+cutoff
# Define new dataset by masking upper and lower boundaries
new_glass = glass[(glass["Na"] > lower) & (glass["Na"] < upper)]