2024年11月2日 星期六

[文章轉貼] 超詳細匯總,十大數據處理技巧! !

文章轉自微信公眾號:機器學習與人工智慧AI 

文章原始連結:https://mp.weixin.qq.com/s/Pi0-7rNLMSHhc7jmNH217g


今天帶給大家的是十大屬於處理技巧,牽涉到的有:

  1. 缺失值處理(Handling Missing Values)
  2. 數據標準化(Data Normalization)
  3. 資料歸一化(Data Scaling)
  4. 類別編碼(Categorical Encoding)
  5. 資料降維(Dimensionality Reduction)
  6. 資料去重(Removing Duplicates)
  7. 資料分箱(Data Binning)
  8. 特徵選擇(Feature Selection)
  9. 資料變換(Data Transformation)
  10. 資料平衡處理(Handling Imbalanced Data)

具體原理和使用方式,下面跟大家一起聊聊~

1. 缺失值處理(Handling Missing Values)

介紹

在現實資料集中,缺失值的存在是普遍現象。直接包含缺失值的資料會使機器學習模型無法有效訓練,因此常見的缺失值處理方法包括刪除缺失值、平均值插補、中位數插補、眾數插補以及基於迴歸模型的插補等。

核心點

  • 刪除法:直接去掉含有缺失值的行或列。
  • 插補法:使用平均數、中位數、眾數或迴歸模型來填補缺失值。

原理

假設我們有一個特徵 ,其中存在一些缺失值。最簡單的插補方式是用平均值來取代缺失值。假設缺失值為 ,則平均值插補的公式為:

可以類似地用中位數或眾數來插補。

核心公式

均值插補:

程式碼範例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.impute import SimpleImputer

# 创建虚拟数据集
np.random.seed(0)
data = {'A': [12, np.nan, 45],
        'B': [np.nan, 2345],
        'C': [123, np.nan, 5],
        'D': [12, np.nan, np.nan, 5]}

df = pd.DataFrame(data)

# 使用均值插补
imputer = SimpleImputer(strategy='mean')
df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

# 绘制原始数据和填补后的数据对比
fig, ax = plt.subplots(figsize=(106))

# 原始数据
ax.scatter(range(len(df)), df['A'], color='red', label='A: Original', marker='o')
ax.scatter(range(len(df)), df['B'], color='blue', label='B: Original', marker='x')

# 插补后的数据
ax.scatter(range(len(df_imputed)), df_imputed['A'], color='green', label='A: Imputed', marker='s')
ax.scatter(range(len(df_imputed)), df_imputed['B'], color='orange', label='B: Imputed', marker='d')

# 设置图例和标题
ax.legend()
ax.set_title('Original vs Imputed Data (Mean Imputation)')
ax.set_xlabel('Index')
ax.set_ylabel('Value')

plt.show()

图片

紅色和藍色點表示原始資料中的特徵A 和B,包含了一些缺失值。

綠色和橘色點表示經過均值插補後的數據,可以看到缺失值被合理填補。

2. 資料標準化(Data Normalization)

介紹

資料標準化是將特徵值轉換到同一量綱,使得每個特徵的平均值為0,標準差為1。標準化有助於距離測量模型(如KNN、SVM)的收斂,並使模型不因不同尺度的特徵而偏向某些特徵。

核心點

  • 目標:讓每個特徵都有相同的平均數和標準差,消除尺度不同所帶來的影響。
  • 應用場景:適用於梯度下降演算法、距離度量類別演算法等。

原理

標準化的過程是將每個特徵值減去該特徵的平均值,再除以該特徵的標準差,使得每個特徵轉換後的平均值為0,變異數為1。

核心公式

假設  是一個特徵,標準化的公式為:

其中, 是平均值, 是標準差。

均值 

標準差 

程式碼範例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler

# 创建虚拟数据集
np.random.seed(42)
data = np.random.randint(1100, size=(102))
df = pd.DataFrame(data, columns=['Feature1''Feature2'])

# 标准化处理
scaler = StandardScaler()
df_scaled = pd.DataFrame(scaler.fit_transform(df), columns=df.columns)

# 绘制原始数据与标准化后的数据对比
fig, ax = plt.subplots(figsize=(106))

# 原始数据
ax.scatter(range(len(df)), df['Feature1'], color='red', label='Feature1: Original', marker='o')
ax.scatter(range(len(df)), df['Feature2'], color='blue', label='Feature2: Original', marker='x')

# 标准化后的数据
ax.scatter(range(len(df_scaled)), df_scaled['Feature1'], color='green', label='Feature1: Scaled', marker='s')
ax.scatter(range(len(df_scaled)), df_scaled['Feature2'], color='orange', label='Feature2: Scaled', marker='d')

# 设置图例和标题
ax.legend()
ax.set_title('Original vs Scaled Data (Standardization)')
ax.set_xlabel('Index')
ax.set_ylabel('Value')

plt.show()

图片

紅色和藍色點表示原始資料的兩個特徵,特徵值範圍較大。

綠色和橘色點表示標準化後的數據,特徵值縮放至平均值為0,變異數為1。

3. 資料歸一化(Data Scaling)

介紹

資料歸一化是將特徵縮放到一個固定的範圍內,通常為[0, 1]。這在神經網路或距離度量類模型中尤其重要,因為模型可能對特徵的量綱差異非常敏感。

核心點

  • 目標:將特徵值縮放到同一範圍內,消除不同特徵之間量級差異對模型的影響。
  • 應用場景:適用於神經網路、KNN 等對量綱敏感的演算法。

原理

歸一化將特徵按比例縮放到特定區間(如[0, 1])。最常見的方法是min-max scaling,它根據每個特徵的最小值和最大值進行縮放。

核心公式

假設特徵 ,歸一化的公式為:

其中, 和  分別是特徵的最小值和最大值。

程式碼範例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler

# 创建虚拟数据集
data = np.random.randint(1100, size=(102))
df = pd.DataFrame(data, columns=['Feature1''Feature2'])

# 归一化处理
scaler = MinMaxScaler()
df_scaled = pd.DataFrame(scaler.fit_transform(df), columns=df.columns)

# 绘制原始数据与归一化后的数据对比
fig, ax = plt.subplots(figsize=(106))

# 原始数据
ax.scatter(range(len(df)), df['Feature1'], color='red', label='Feature1: Original', marker='o')
ax.scatter(range(len(df)), df['Feature2'], color='blue', label='Feature2: Original', marker='x')

# 归一化后的数据


ax.scatter(range(len(df_scaled)), df_scaled['Feature1'], color='green', label='Feature1: Scaled', marker='s')
ax.scatter(range(len(df_scaled)), df_scaled['Feature2'], color='orange', label='Feature2: Scaled', marker='d')

# 设置图例和标题
ax.legend()
ax.set_title('Original vs Scaled Data (Normalization)')
ax.set_xlabel('Index')
ax.set_ylabel('Value')

plt.show()

图片

紅色和藍色點表示原始數據,數據的範圍較廣。

綠色和橘色點表示歸一化後的數據,數據範圍被縮放至[0, 1]。

4. 類別編碼(Categorical Encoding)

介紹

在處理類別資料時,常用的編碼方法包括標籤編碼和獨熱編碼。獨熱編碼(One-Hot Encoding)是將類別資料轉換為二進位向量的過程。

核心點

  • 目標:將類別型特徵轉換為數值型特徵,適用於大多數機器學習模型。
  • 應用場景:常用於迴歸和分類任務中對離散變數的處理。

原理

假設類別數據 ,獨熱編碼將每個類別  轉換為一個長度為  的向量,其中只有第  位為1,其餘為0。

核心公式

獨熱編碼公式

其中, 的位置對應類別  的索引。

程式碼範例

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import OneHotEncoder

# 创建虚拟数据集
data = {'Category': ['A''B''C''A''B']}
df = pd.DataFrame(data)

# 独热编码
encoder = OneHotEncoder(sparse=False)
encoded_data = encoder.fit_transform(df[['Category']])
df_encoded = pd.DataFrame(encoded_data, columns=encoder.categories_)

# 可视化原始数据与独热编码后的数据对比
fig, ax = plt.subplots(figsize=(84))

ax.matshow(encoded_data, cmap='coolwarm')
ax.set_title('One-Hot Encoding Representation')
plt.xlabel('Encoded Categories')
plt.ylabel('Samples')

plt.show()

图片

矩陣圖展示了類別變數透過獨熱編碼轉換為二元矩陣的過程。

5. 資料分箱(Binning)

介紹

資料分箱是一種將連續特徵離散化的方法,透過將數值型資料劃分為多​​個區間,將其轉換為類別型資料。這在處理有序的連續資料時非常有用,能夠減少資料的複雜性,並增強模型的穩定性。

核心點

  • 目標:將連續型變數分成多個類別,減少特徵的噪聲,並簡化特徵分佈。
  • 應用場景:適用於迴歸問題、決策樹模型等,尤其是在特徵資料存在極端值時。

原理

假設特徵  是一個連續變量,分箱的過程是將特徵  劃分為  個區間 ,每個  被映射到某個區間。

可採用等寬分箱或等頻分箱:

  • 等寬分箱:將資料以相等區間長度劃分。
  • 等頻分箱:將資料以相等頻率劃分。

核心公式

等寬分箱公式

其中  和  分別是特徵  的最小值和最大值, 是分箱的數量。

等頻分箱公式:依排序後的數值均勻劃分。

程式碼範例

# 创建虚拟数据集
data = {'Feature': np.random.randint(0100, size=100)}
df = pd.DataFrame(data)

# 等宽分箱
df['Binned'] = pd.cut(df['Feature'], bins=5)

# 等频分箱
df['Binned_freq'] = pd.qcut(df['Feature'], q=5)

# 绘制直方图和分箱后的箱线图
fig, ax = plt.subplots(12, figsize=(146))

# 绘制直方图(原始数据)
ax[0].hist(df['Feature'], bins=20, color='blue', alpha=0.7)
ax[0].set_title('Histogram of Original Data')

# 绘制箱线图(分箱后数据)
df.boxplot(column='Feature', by='Binned', ax=ax[1])
ax[1].set_title('Boxplot of Binned Data (Equal Width)')

plt.suptitle('')
plt.show()

图片

左側的直方圖顯示了原始資料的分佈,特徵值在0-100 範圍內。

右側的箱線圖顯示了等寬分箱後的資料分佈,每個區間內資料的變化範圍較大,但區間劃分明確。

6. 特徵選擇(Feature Selection)

介紹

特徵選擇是從原始特徵集中選擇出最具代表性的部分特徵,去除冗餘的或無關的特徵。常用方法包括過濾法、包裹法和嵌入法。

核心點

  • 目標:減少特徵空間,降低模型複雜性,提高訓練效率,同時減少過度擬合風險。
  • 應用場景:適用於高維度資料集和存在大量無關特徵的任務。

原理

特徵選擇方法可分為以下三類:

  1. 濾波法:透過統計指標(如變異數、相關係數)選擇特徵。
  2. 包裹法:透過模型表現(如遞歸特徵消除,RFE)選擇特徵。
  3. 嵌入法:在模型訓練過程中嵌入特徵選擇,如L1 正規化中的LASSO 迴歸。

核心公式

LASSO 迴歸(嵌入法)的目標是透過引入L1 正規化來選擇特徵,優化目標函數為:

其中, 是正則化強度, 是模型的係數。

當  較大時,某些係數  會被收縮到0,這相當於選擇性地去除了無關特徵。

程式碼範例

import numpy as np
import pandas as pd
from sklearn.datasets import make_regression
from sklearn.linear_model import Lasso
import matplotlib.pyplot as plt

# 创建虚拟数据集
X, y = make_regression(n_samples=100, n_features=10, noise=0.1)

# 使用 LASSO 回归进行特征选择
lasso = Lasso(alpha=0.1)
lasso.fit(X, y)

# 绘制特征重要性图
fig, ax = plt.subplots(figsize=(106))
ax.bar(range(len(lasso.coef_)), lasso.coef_, color='blue')
ax.set_title('Feature Importance (Lasso)')
ax.set_xlabel('Feature Index')
ax.set_ylabel('Coefficient Value')

# 绘制特征值分布图
ax2 = ax.twinx()
ax2.plot(range(len(lasso.coef_)), np.abs(lasso.coef_), 'r--')
ax2.set_ylabel('Absolute Coefficient Value')

plt.show()

图片

藍色的長條圖顯示了每個特徵的係數值,係數為0 的特徵被移除。

紅色虛線顯示了特徵的絕對重要性值,幫助直觀了解哪些特徵對模型的貢獻最大。

7. 特徵縮放(Feature Scaling)

介紹

特徵縮放是將資料按比例縮放到一個範圍內,通常為[0, 1] 或[-1, 1]。縮放後的資料可以加快梯度下降演算法的收斂速度,避免模型被某些尺度較大的特徵所支配。

核心點

  • 目標:平衡各特徵的量綱,避免某些特徵對模型的影響過大。
  • 應用場景:特別適用於基於距離的模型,如KNN、SVM。

原理

特徵縮放與歸一化相似,但更關注的是縮放各特徵到一定範圍而非嚴格的歸一化。

核心公式

常用的特徵縮放公式為Min-Max Scaling:

程式碼範例

from sklearn.preprocessing import MinMaxScaler

# 创建虚拟数据集
data = np.random.randint(1100, size=(502))
df = pd.DataFrame(data, columns=['Feature1''Feature2'])

# 特征缩放
scaler = MinMaxScaler()
df_scaled = pd.DataFrame(scaler.fit_transform(df), columns=df.columns)

# 绘制原始数据与缩放后数据对比
fig, ax = plt.subplots(12, figsize=(126))

# 原始数据散点图
ax[0].scatter(df['Feature1'], df['Feature2'], color='blue', label='Original Data')
ax[0].set_title('Original Data')
ax[0].set_xlabel('Feature 1')
ax[0].set_ylabel('Feature 2')

# 缩放后数据散点图
ax[1].scatter(df_scaled['Feature1'], df_scaled['Feature2'], color='green', label='Scaled Data')
ax[1].set_title('Scaled Data (Min-Max)')
ax[1].set_xlabel('Feature 1')
ax[1].set_ylabel('Feature 2')

plt.show()

图片

左側的散點圖顯示了原始特徵資料的分佈。

右側的散佈圖則展示了經過Min-Max 縮放後的特徵數據,所有數據點都縮放到[0, 1] 的範圍。

8. 主成分分析(Principal Component Analysis, PCA)

介紹

PCA 是一種常用的降維技術,透過線性變換將資料從高維空間映射到低維空間,同時盡可能保留原始資料中的變異數。 PCA 的目標是找到特徵空間中的主成分,這些主成分是資料變異數最大的方向。

核心點

  • 目標:透過線性變換將資料降維到更低的維度,同時保留資料的主要變異性。
  • 應用場景:高維度資料的降維,特徵擷取,資料視覺化。

原理

PCA 的過程如下:

  1. 中心化資料:對每個特徵減去其平均值,使得資料的平均值為0。
  2. 計算協方差矩陣:協方差矩陣描述了特徵之間的線性關係。
  3. 計算特徵值和特徵向量:特徵值表示主成分的變異數大小,特徵向量表示主成分的方向。
  4. 選擇主成分:選擇特徵值最大的前  個特徵向量作為主成分。
  5. 轉換資料:將資料投影到選定的主成分上。

核心公式

協方差矩陣計算

其中, 是中心化後的資料矩陣。

特徵值和特徵向量

解特徵方程式:

其中, 是特徵值, 是特徵向量。

數據轉換

其中, 是選擇的主成分所構成的矩陣。

程式碼範例

from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt

# 创建虚拟数据集
np.random.seed(0)
X = np.random.rand(1003)  # 100 个样本,3 个特征

# PCA 降维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

# 绘制原始数据和 PCA 降维后的数据
fig, ax = plt.subplots(12, figsize=(126))

# 原始数据的散点图
ax[0].scatter(X[:, 0], X[:, 1], c='blue', label='Original Data')
ax[0].set_title('Original Data')
ax[0].set_xlabel('Feature 1')
ax[0].set_ylabel('Feature 2')

# PCA 降维后的散点图
ax[1].scatter(X_pca[:, 0], X_pca[:, 1], c='green', label='PCA Data')
ax[1].set_title('PCA Transformed Data')
ax[1].set_xlabel('Principal Component 1')
ax[1].set_ylabel('Principal Component 2')

plt.show()

图片

左側的散點圖顯示了原始資料在前兩個特徵上的分佈。

右側的散點圖展示了通過PCA 降維後的數據,數據被投影到兩個主成分上,特徵維度大大減少但主要的資訊被保留。

9. 特徵工程(Feature Engineering)

介紹

特徵工程是創建新的特徵或變換現有特徵的過程,以提高模型的表現。這包括特徵構造、特徵選擇、特徵縮放等。

核心點

  • 目標:透過創造新的特徵或變換特徵,增加模型的預測能力。
  • 應用場景:資料預處理、模型最佳化。

原理

特徵工程的步驟通常包括:

  1. 特徵建構:基於現有特徵創造新特徵(如特徵交互作用、組合)。
  2. 特徵選擇:選擇對模型最有用的特徵。
  3. 特徵轉換:如對數轉換、平方根轉換等,處理特徵的非線性關係。

核心公式

特徵構造範例(如特徵交互作用): 假設有兩個特徵  和 ,新的交互特徵為:

程式碼範例

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 创建虚拟数据集
data = {'Feature1': np.random.rand(100), 'Feature2': np.random.rand(100)}
df = pd.DataFrame(data)

# 特征工程:构造特征交互
df['Feature_Interaction'] = df['Feature1'] * df['Feature2']

# 绘制特征原始分布和交互特征
fig, ax = plt.subplots(12, figsize=(126))

# 原始特征的散点图
ax[0].scatter(df['Feature1'], df['Feature2'], c='blue', label='Feature1 vs Feature2')
ax[0].set_title('Original Features')
ax[0].set_xlabel('Feature 1')
ax[0].set_ylabel('Feature 2')

# 交互特征的分布图
ax[1].hist(df['Feature_Interaction'], bins=30, color='green', edgecolor='black')
ax[1].set_title('Feature Interaction')
ax[1].set_xlabel('Feature Interaction Value')
ax[1].set_ylabel('Frequency')

plt.show()

图片

左側的散點圖展示了原始兩個特徵的關係。

右側的直方圖展示了新創建的交互特徵的分佈,這種特徵可能捕捉了原始特徵之間的交互資訊。

10. 異常值檢測(Outlier Detection)

介紹

異常值偵測是識別資料集中異常點的過程,這些異常點與其他資料點顯著不同。常用的方法包括Z-score、IQR(四分位數間距)和基於模型的檢測方法。

核心點

  • 目標:辨識和處理那些與大多數資料點顯著不同的異常點。
  • 應用場景:資料清洗、模型提升(移除異常點可能提升模型表現)。

原理

Z-score 方法:計算每個資料點的Z-score,Z-score 超過某個閾值的資料點被視為異常點。

其中, 是平均值, 是標準差。

IQR 方法:計算資料的四分位數間距(IQR),通常取下限為 ,上限為 

核心公式

IQR 計算

異常值下限和上限:

程式碼範例

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from scipy import stats

# 创建虚拟数据集
np.random.seed(0)
data = np.random.normal(loc=0, scale=1, size=100)
data_with_outliers = np.concatenate([data, [101215]])

# 计算 Z-score
z_scores = stats.zscore(data_with_outliers)

# 使用 IQR 方法检测异常值
Q1 = np.percentile(data_with_outliers, 25)
Q3 = np.percentile(data_with_outliers, 75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 绘制数据和异常值检测
fig, ax = plt.subplots(figsize=(106))

# 数据分布图
ax.hist(data_with_outliers, bins=20, color='blue', edgecolor='black', alpha=0.7, label='Data Distribution')

# 标记异常值
outliers = data_with_outliers[(data_with_outliers < lower_bound) | (data_with_outliers > upper_bound)]
ax.scatter(outliers, np.zeros_like(outliers), color='red', marker='x', label='Outliers')

ax.set_title('Outlier Detection')
ax.set_xlabel('Value')
ax.set_ylabel('Frequency')
ax.legend()

plt.show()

图片

直方圖展示了資料的分佈,其中大多數資料點集中在較小的範圍內。

紅色的標記點表示透過IQR 方法偵測到的異常值,這些點顯著偏離了其他資料點的分佈。