数据集中异常值与缺失值的处理方法
立即解锁
发布时间: 2025-09-03 00:34:23 阅读量: 2 订阅数: 11 AIGC 


Python探索性数据分析精粹
### 数据集中异常值与缺失值的处理方法
在数据分析过程中,异常值和缺失值是常见的问题,它们可能会影响分析结果的准确性和可靠性。本文将详细介绍识别多元异常值、处理异常值(包括分位数截断、移除和替换)以及识别缺失值的方法,并结合具体代码示例进行说明。
#### 1. 识别多元异常值
识别多元异常值的步骤如下:
1. **使用盒图识别马氏距离异常值**:使用 `seaborn` 中的盒图方法识别马氏距离异常值,盒图中距离超过 4 的为异常值。
2. **移除缺失值**:这是 DBSCAN 算法的要求。DBSCAN 算法有两个关键参数:`epsilon` 和 `minPoints`。
3. **确定最优 `epsilon` 值**:创建 k 距离图,步骤如下:
- 使用 `scikit-learn` 中的 `NearestNeighbors` 类找到数据集中每个数据点与其最近邻的距离。
- 使用 `fit` 方法将最近邻模型拟合到数据集上。
- 使用 `kneighbors` 方法提取每个点与其最近邻的距离以及对应的索引。
- 按升序对距离进行排序,并选择距离数组中第二列的值(第一列对应每个数据点到自身的距离)。
- 使用 `plot` 方法绘制距离图,最优 `epsilon` 值位于图的肘部。
4. **确定最优 `minPoints` 值**:选择至少比变量数量大 1 的值。
5. **创建 DBSCAN 模型**:使用 `scikit-learn` 中的 `DBSCAN` 类,设置 `min_samples` 为 6,`epsilon` 为 1(从 k 距离图的肘部获取)。
6. **提取标签和簇的数量**:使用 `labels_` 属性提取标签,并使用 `len` 和 `set` 函数对标签进行不同计数以提取簇的数量。
7. **保存异常值的索引**:使用 `numpy` 中的 `where` 方法,DBSCAN 中异常值通常标记为 -1。
8. **查看异常值**:注意到马氏距离和 DBSCAN 生成的异常值存在差异,这是因为两种算法使用不同的异常值检测方法,因此需要利用领域知识来确定哪种算法提供的结果最佳。
#### 2. 分位数截断处理异常值
分位数截断是一种处理异常值的技术,包括下限截断和上限截断,即将极端值替换为固定值(分位数)。
- **下限截断**:将小的极端值替换为预定的最小值,如第 10 百分位数的值。
- **上限截断**:将大的极端值替换为预定的最大值,如第 90 百分位数的值。
这些技术适用于极端值可能由测量误差或数据录入错误引起的情况,如果异常值是真实的,这些技术可能会引入偏差。
以下是使用分位数截断处理异常值的具体步骤:
1. **导入相关库**:
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
```
2. **加载数据并选择相关列**:
```python
houseprice_data = pd.read_csv("data/HousingPricesData.csv")
houseprice_data = houseprice_data[['Price', 'Area', 'Room']]
```
3. **查看数据的基本信息**:
```python
houseprice_data.head()
houseprice_data.shape
```
4. **确定分位数阈值**:
```python
floor_thresh = houseprice_data['Price'].quantile(0.10)
cap_thresh = houseprice_data['Price'].quantile(0.90)
print(floor_thresh, cap_thresh)
```
5. **执行分位数截断**:
```python
houseprice_data['Adjusted_Price'] = houseprice_data.loc[:,'Price']
houseprice_data.loc[houseprice_data['Price'] < floor_thresh, 'Adjusted_Price'] = floor_thresh
houseprice_data.loc[houseprice_data['Price'] > cap_thresh, 'Adjusted_Price'] = cap_thresh
```
6. **可视化处理后的数据集**:
```python
plt.figure(figsize = (40,18))
ax = sns.histplot(data= houseprice_data, x= 'Adjusted_Price')
ax.set_xlabel('Adjusted Price in millions', fontsize = 30)
ax.set_title('Outlier Analysis of Adjusted House prices', fontsize = 40)
ax.set_ylabel('Count', fontsize = 30)
plt.xticks(fontsize=30)
plt.yticks(fontsize=30)
```
7. **确定分组分位数阈值**:
```python
houseprice_data['90_perc'] = houseprice_data.groupby('Room')['Price'].transform(lambda x: np.nanpercentile(x,90))
houseprice_data['10_perc'] = houseprice_data.groupby('Room')['Price'].transform(lambda x: np.nanpercentile(x,10))
```
8. **执行分组分位数截断**:
```python
houseprice_data['Group_Adjusted_Price'] = houseprice_data.loc[:,'Price']
houseprice_data.loc[houseprice_data['Price'] < houseprice_data['10_perc'], 'Group_Adjusted_Price'] = houseprice_data['10_perc']
houseprice_data.loc[houseprice_data['Price'] > houseprice_data['90_perc'], 'Group_Adjusted_Price'] = houseprice_data['90_perc']
```
9. **可视化分组处理后的数据集**:
```python
plt.figure(figsize = (40,18))
ax = sns.boxplot(data= houseprice_data, x = 'Room', y= 'Group_Adjusted_Price')
ax.set_xlabel('Room', fontsize = 30)
ax.set_ylabel('Adjusted Price in millions', fontsize = 30)
plt.xticks(fontsize=30)
plt.yticks(fontsize=30)
ax.set_title('Bivariate Outlier Analysis of Adjusted House prices and Rooms', fontsize = 40)
```
#### 3. 移除异常值
移除异常值是一种简单的处理方法,但可能会丢失一
0
0
复制全文
相关推荐










