文章轉自微信公眾號:機器學習與人工智慧AI
文章原始連結:https://mp.weixin.qq.com/s/Pi0-7rNLMSHhc7jmNH217g
今天帶給大家的是十大屬於處理技巧,牽涉到的有:
缺失值處理(Handling Missing Values) 數據標準化(Data Normalization) 資料歸一化(Data Scaling) 類別編碼(Categorical Encoding) 資料降維(Dimensionality Reduction) 資料去重(Removing Duplicates) 資料分箱(Data Binning) 特徵選擇(Feature Selection) 資料變換(Data Transformation) 資料平衡處理(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': [1, 2, np.nan, 4, 5],
'B': [np.nan, 2, 3, 4, 5],
'C': [1, 2, 3, np.nan, 5],
'D': [1, 2, 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=(10, 6))
# 原始数据
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(1, 100, size=(10, 2))
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=(10, 6))
# 原始数据
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(1, 100, size=(10, 2))
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=(10, 6))
# 原始数据
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=(8, 4))
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(0, 100, 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(1, 2, figsize=(14, 6))
# 绘制直方图(原始数据)
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)
介紹
特徵選擇是從原始特徵集中選擇出最具代表性的部分特徵,去除冗餘的或無關的特徵。常用方法包括過濾法、包裹法和嵌入法。
核心點
目標:減少特徵空間,降低模型複雜性,提高訓練效率,同時減少過度擬合風險。 應用場景:適用於高維度資料集和存在大量無關特徵的任務。
原理
特徵選擇方法可分為以下三類:
濾波法:透過統計指標(如變異數、相關係數)選擇特徵。 包裹法:透過模型表現(如遞歸特徵消除,RFE)選擇特徵。 嵌入法:在模型訓練過程中嵌入特徵選擇,如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=(10, 6))
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(1, 100, size=(50, 2))
df = pd.DataFrame(data, columns=['Feature1', 'Feature2'])
# 特征缩放
scaler = MinMaxScaler()
df_scaled = pd.DataFrame(scaler.fit_transform(df), columns=df.columns)
# 绘制原始数据与缩放后数据对比
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
# 原始数据散点图
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 的過程如下:
中心化資料:對每個特徵減去其平均值,使得資料的平均值為0。 計算協方差矩陣:協方差矩陣描述了特徵之間的線性關係。 計算特徵值和特徵向量:特徵值表示主成分的變異數大小,特徵向量表示主成分的方向。 選擇主成分:選擇特徵值最大的前 個特徵向量作為主成分。 轉換資料:將資料投影到選定的主成分上。
核心公式
協方差矩陣計算:
其中, 是中心化後的資料矩陣。
特徵值和特徵向量:
解特徵方程式:
其中, 是特徵值, 是特徵向量。
數據轉換:
其中, 是選擇的主成分所構成的矩陣。
程式碼範例
from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt
# 创建虚拟数据集
np.random.seed(0)
X = np.random.rand(100, 3) # 100 个样本,3 个特征
# PCA 降维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
# 绘制原始数据和 PCA 降维后的数据
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
# 原始数据的散点图
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)
介紹
特徵工程是創建新的特徵或變換現有特徵的過程,以提高模型的表現。這包括特徵構造、特徵選擇、特徵縮放等。
核心點
目標:透過創造新的特徵或變換特徵,增加模型的預測能力。 應用場景:資料預處理、模型最佳化。
原理
特徵工程的步驟通常包括:
特徵建構:基於現有特徵創造新特徵(如特徵交互作用、組合)。 特徵選擇:選擇對模型最有用的特徵。 特徵轉換:如對數轉換、平方根轉換等,處理特徵的非線性關係。
核心公式
特徵構造範例(如特徵交互作用): 假設有兩個特徵 和 ,新的交互特徵為:
程式碼範例
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(1, 2, figsize=(12, 6))
# 原始特征的散点图
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, [10, 12, 15]])
# 计算 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=(10, 6))
# 数据分布图
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 方法偵測到的異常值,這些點顯著偏離了其他資料點的分佈。