文章轉自微信公眾號:機器學習與人工智慧AI
文章原始連結:https://mp.weixin.qq.com/s/Pi0-7rNLMSHhc7jmNH217g
今天帶給大家的是十大屬於處理技巧,牽涉到的有:
缺失值處理(Handling Missing Values) 數據標準化(Data Normalization) 類別編碼(Categorical Encoding) 資料降維(Dimensionality Reduction) 資料去重(Removing Duplicates) 資料變換(Data Transformation) 資料平衡處理(Handling Imbalanced Data) 具體原理和使用方式,下面跟大家一起聊聊~
1. 缺失值處理(Handling Missing Values) 介紹 在現實資料集中,缺失值的存在是普遍現象。直接包含缺失值的資料會使機器學習模型無法有效訓練,因此常見的缺失值處理方法包括刪除缺失值、平均值插補、中位數插補、眾數插補以及基於迴歸模型的插補等。
核心點 插補法 :使用平均數、中位數、眾數或迴歸模型來填補缺失值。 原理 假設我們有一個特徵 ,其中存在一些缺失值。最簡單的插補方式是用平均值來取代缺失值。假設缺失值為 ,則平均值插補的公式為:
可以類似地用中位數或眾數來插補。
核心公式 均值插補:
程式碼範例 import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom 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 npimport pandas as pdimport matplotlib.pyplot as pltfrom 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 npimport pandas as pdimport matplotlib.pyplot as pltfrom 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 pdimport matplotlib.pyplot as pltfrom 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 npimport pandas as pdfrom sklearn.datasets import make_regressionfrom sklearn.linear_model import Lassoimport 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 PCAimport numpy as npimport 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 pdimport numpy as npimport 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 pdimport numpy as npimport matplotlib.pyplot as pltfrom 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 方法偵測到的異常值,這些點顯著偏離了其他資料點的分佈。