西姆蘭吉特·辛格
一、介紹
????????歡迎來到“機器學習終極指南”的第二部分。在第一部分中,我們討論了探索性數據分析 (EDA),這是機器學習管道中的關鍵步驟。在這一部分中,我們將深入研究特征工程,這是機器學習過程的另一個重要方面。
????????特征工程是將原始數據轉換為有意義的特征的過程,機器學習算法可以使用這些特征進行準確的預測。它涉及選擇、提取和轉換特征以增強模型的性能。良好的特征工程會對模型的準確性產生巨大影響,而糟糕的特征工程會導致性能不佳。
圖例.1 — 特征工程
????????在本指南中,我們將介紹特征工程中常用的一系列技術。我們將從特征選擇和提取開始,這涉及識別數據中最重要的特征。然后,我們將繼續對分類變量進行編碼,這是處理非數值數據時必不可少的步驟。我們還將介紹縮放和歸一化、創建新特征、處理不平衡數據、處理偏度和峰度、處理稀有類別、處理時間序列數據、特征轉換、獨熱編碼、計數和頻率編碼、分箱、分組和文本預處理。
????????在本指南結束時,您將全面了解特征工程技術以及如何使用它們來提高機器學習模型的性能。讓我們開始吧!
目錄
- 特征選擇和提取
- 編碼分類變量
- 縮放和規范化
- 創建新功能
- 處理不平衡的數據
- 處理偏度和峰度
- 處理稀有類別
- 處理時間序列數據
- 文本預處理
二、特征選擇和提取
????????特征選擇和提取是機器學習的重要組成部分,涉及從數據集中選擇最相關的特征以提高模型的準確性和效率。在這里,我們將討論一些流行的功能選擇和提取方法,以及 Python 代碼片段。
2.1. 主成分分析 (PCA):PCA?
????????是一種降維技術,它通過查找一組捕獲數據中最大方差的新特征來減少數據集中的特征數量。新要素稱為主成分,彼此正交,可用于重建原始數據集。
????????讓我們看看如何使用scikit-learn對數據集執行PCA:
from sklearn.decomposition import PCA# create a PCA object
pca = PCA(n_components=2)# fit and transform the data
X_pca = pca.fit_transform(X)# calculate the explained variance ratio
print("Explained variance ratio:", pca.explained_variance_ratio_)
????????在這里,我們創建一個 PCA 對象并指定要提取的組件數。然后,我們擬合并轉換數據以獲得新的特征集。最后,我們計算解釋的方差比率,以確定每個主成分捕獲的數據方差量。
2. 2 線性判別分析(LDA):
????????LDA是一種監督學習技術,用于分類問題中的特征提取。它的工作原理是查找一組新的特征,以最大程度地分離數據中的類。
????????讓我們看看如何使用scikit-learn對數據集執行LDA:
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis# create an LDA object
lda = LinearDiscriminantAnalysis(n_components=1)# fit and transform the data
X_lda = lda.fit_transform(X, y)
????????在這里,我們創建一個 LDA 對象并指定我們要提取的組件數。然后,我們擬合并轉換數據以獲得新的特征集。
????????3.?相關性分析:相關性分析用于識別數據集中特征之間的相關性。可以從數據集中移除彼此高度相關的要素,因為它們提供了冗余信息。
????????讓我們看看如何使用熊貓對數據集執行相關性分析:
import pandas as pd# calculate the correlation matrix
corr_matrix = df.corr()# select highly correlated features
high_corr = corr_matrix[abs(corr_matrix) > 0.8]# drop highly correlated features
df = df.drop(high_corr.columns, axis=1)
????????在這里,我們使用熊貓計算相關矩陣并選擇高度相關的特征。然后,我們使用該方法從數據集中刪除高度相關的特征。drop
圖2 — 特征選擇措施
????????4. 遞歸特征消除(RFE):RFE是一種通過遞歸考慮越來越小的特征子集來選擇特征的方法。在每次迭代中,都會根據其余特征對模型進行訓練,并對每個特征的重要性進行排名。然后消除最不重要的特征,并重復該過程,直到獲得所需數量的特征。
????????下面是使用 RFE 進行要素選擇的示例:
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_bostondata = load_boston()
X, y = data.data, data.targetmodel = LinearRegression()
rfe = RFE(model, n_features_to_select=5)
rfe.fit(X, y)selected_features = data.feature_names[rfe.support_]
print(selected_features)
????????5. 基于樹的方法:決策樹和隨機森林是用于此目的的流行的基于樹的方法。在這些方法中,基于對預測目標變量最重要的特征創建樹結構。每個特征的重要性是通過根據該特征拆分數據而導致的雜質減少來計算的。
????????在決策樹中,選擇信息增益最高的特征作為根節點,并根據該特征拆分數據。此過程以遞歸方式重復,直到滿足停止條件,例如最大樹深度或每片葉子的最小樣本數。
在隨機森林中,使用特征和數據的隨機子集構建多個決策樹。每個特征的重要性計算為所有樹木中雜質的平均減少量。這有助于減少模型的方差并提高其泛化性。
from sklearn.ensemble import RandomForestRegressor# Load the data
X, y = load_data()# Create a random forest regressor
rf = RandomForestRegressor(n_estimators=100, random_state=42)# Fit the model
rf.fit(X, y)# Get feature importances
importances = rf.feature_importances_# Print feature importances
for feature, importance in zip(X.columns, importances):print(feature, importance)
????????基于樹的方法也可用于特征提取。在這種情況下,我們可以根據樹的決策邊界提取新特征。例如,我們可以將決策樹的葉節點用作新的二進制特征,指示數據點是否屬于特征空間的該區域。
????????6. 包裝方法:這是一種特征選擇方法,其中模型在不同的特征子集上進行訓練和評估。針對每個特征子集測量模型的性能,并根據模型的性能選擇最佳子集。
????????下面是如何在scikit-learn中使用遞歸特征消除(RFE)和支持向量機(SVM)分類器實現包裝器方法的示例:
from sklearn.svm import SVC
from sklearn.feature_selection import RFE
from sklearn.datasets import load_iris# load the iris dataset
data = load_iris()
X = data.data
y = data.target# create an SVM classifier
svm = SVC(kernel='linear')# create a feature selector using RFE with SVM
selector = RFE(svm, n_features_to_select=2)# fit the selector to the data
selector.fit(X, y)# print the selected features
print(selector.support_)
print(selector.ranking_)
????????在此示例中,我們首先加載鳶尾花數據集并將其拆分為特征 (X) 和目標 (y)。然后我們創建一個帶有線性內核的 SVM 分類器。然后,我們使用 RFE 和 SVM 創建一個特征選擇器,并將其擬合到數據中。最后,我們使用選擇器的 and 屬性打印所選特征。support_
ranking_
????????前向選擇:?前向選擇是一種包裝方法,它涉及一次迭代地向模型添加一個特征,直到模型的性能停止提高。以下是它在Python中的工作方式:
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.linear_model import LinearRegression# Load the dataset
X, y = load_dataset()# Initialize the feature selector
selector = SequentialFeatureSelector(LinearRegression(), n_features_to_select=5, direction='forward')# Fit the feature selector
selector.fit(X, y)# Print the selected features
print(selector.support_)
????????在上面的代碼中,我們首先加載數據集,然后使用線性回歸模型和指定我們要選擇的特征數量的參數n_features_to_select初始化 SequentialFeatureSelector 對象。然后,我們將選擇器擬合到數據集上并打印所選特征。
????????向后淘汰:?向后消除是一種包裝器方法,它涉及一次從模型中迭代刪除一個特征,直到模型的性能停止提高。以下是它在Python中的工作方式:
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.linear_model import LinearRegression# Load the dataset
X, y = load_dataset()# Initialize the feature selector
selector = SequentialFeatureSelector(LinearRegression(), n_features_to_select=5, direction='backward')# Fit the feature selector
selector.fit(X, y)# Print the selected features
print(selector.support_)
????????在上面的代碼中,我們使用線性回歸模型和參數 direction='backward' 初始化 SequentialFeatureSelector 對象以執行向后消除。然后,我們將選擇器擬合到數據集上并打印所選特征。
????????詳盡搜索:?窮舉搜索是一種過濾方法,涉及評估所有可能的特征子集并根據評分標準選擇最佳子集。以下是它在Python中的工作方式:
from itertools import combinations
from sklearn.metrics import r2_score
from sklearn.linear_model import LinearRegression# Load the dataset
X, y = load_dataset()# Initialize variables
best_score = -float('inf')
best_features = None# Loop over all possible subsets of features
for k in range(1, len(X.columns) + 1):for subset in combinations(X.columns, k):# Train a linear regression modelX_subset = X[list(subset)]model = LinearRegression().fit(X_subset, y)# Compute the R2 scorescore = r2_score(y, model.predict(X_subset))# Update the best subset of featuresif score > best_score:best_score = scorebest_features = subset# Print the best subset of features
print(best_features)
????????在上面的代碼中,我們首先加載數據集,然后使用 itertools.combination 函數遍歷所有可能的特征子集。對于每個子集,我們訓練線性回歸模型并計算 R2 分數。然后,我們根據最高 R2 分數更新最佳特征子集并打印所選特征。
????????7.?嵌入式方法:這些方法涉及選擇特征作為模型訓練過程的一部分。示例包括套索回歸和嶺回歸,它們為損失函數添加懲罰項以鼓勵稀疏特征選擇。
????????套索回歸:?套索回歸還向損失函數添加了一個懲罰項,但它使用模型系數的絕對值而不是平方。這導致了更積極的特征選擇過程,因為某些系數可以精確地設置為零。套索回歸在處理高維數據時特別有用,因為它可以有效地減少模型中使用的特征數量。
from sklearn.linear_model import Lasso
from sklearn.datasets import load_boston
from sklearn.preprocessing import StandardScalerdata = load_boston()
X = data.data
y = data.target# Standardize the features
scaler = StandardScaler()
X = scaler.fit_transform(X)# Fit the Lasso model
lasso = Lasso(alpha=0.1)
lasso.fit(X, y)# Get the coefficients
coefficients = lasso.coef_
????????嶺回歸:?嶺回歸為損失函數添加一個懲罰項,鼓勵模型選擇對預測目標變量更重要的較小特征集。懲罰項與模型系數大小的平方成正比,因此它傾向于將系數縮小到零,而不將它們精確地設置為零。
from sklearn.linear_model import Ridge
from sklearn.datasets import load_boston
from sklearn.preprocessing import StandardScalerdata = load_boston()
X = data.data
y = data.target# Standardize the features
scaler = StandardScaler()
X = scaler.fit_transform(X)# Fit the Ridge model
ridge = Ridge(alpha=0.1)
ridge.fit(X, y)# Get the coefficients
coefficients = ridge.coef_
????????在這兩種情況下,正則化參數控制懲罰項的強度。較高的 alpha 值將導致要素選擇更稀疏。alpha
2.3 編碼分類變量
????????編碼分類變量是特征工程中的關鍵步驟,涉及將分類變量轉換為機器學習算法可以理解的數字形式。以下是用于編碼分類變量的一些常用技術:
1.?獨熱編碼:
????????獨熱編碼是一種將分類變量轉換為一組二進制特征的技術,其中每個特征對應于原始變量中的唯一類別。在此技術中,為每個類別創建一個新的二進制列,如果類別存在,則值設置為 1,如果不存在,則設置為 0。
????????下面是一個使用熊貓庫的示例:
import pandas as pd# create a sample dataframe
df = pd.DataFrame({'color': ['red', 'blue', 'green', 'red', 'yellow', 'blue']
})# apply one-hot encoding
one_hot_encoded = pd.get_dummies(df['color'])
print(one_hot_encoded)
2. 標簽編碼:
????????標簽編碼是一種為原始變量中的每個類別分配唯一數值的技術。在此技術中,為每個類別分配一個數字標簽,其中標簽是根據變量中類別的順序分配的。
????????下面是一個使用 scikit-learn 庫的示例:
from sklearn.preprocessing import LabelEncoder# create a sample dataframe
df = pd.DataFrame({'color': ['red', 'blue', 'green', 'red', 'yellow', 'blue']
})# apply label encoding
label_encoder = LabelEncoder()
df['color_encoded'] = label_encoder.fit_transform(df['color'])
print(df)
圖 3 — 編碼數據
????????3. 序數編碼:
????????序號編碼是一種根據原始變量中每個類別的順序或等級為其分配數值的技術。在此技術中,類別根據特定條件進行排序,并根據類別在順序中的位置分配數值。
????????下面是使用 category_encoders 庫的示例:
import category_encoders as ce# create a sample dataframe
df = pd.DataFrame({'size': ['S', 'M', 'L', 'XL', 'M', 'S']
})# apply ordinal encoding
ordinal_encoder = ce.OrdinalEncoder(cols=['size'], order=['S', 'M', 'L', 'XL'])
df = ordinal_encoder.fit_transform(df)
print(df)
三、縮放和規范化
????????縮放和規范化是特征工程中的重要步驟,可確保特征具有相似的比例和相似的范圍。這有助于提高某些機器學習算法的性能,并使優化過程更快。下面是用于縮放和規范化的一些常用技術:
????????1. 標準化:標準化對特征進行縮放,使其具有零均值和單位方差。這是通過從每個值中減去平均值,然后將其除以標準差來完成的。結果值的平均值為 <>,標準差為 <>。
????????以下是使用scikit-learn進行標準化的示例:
from sklearn.preprocessing import StandardScaler# Create a StandardScaler object
scaler = StandardScaler()# Fit and transform the data
X_scaled = scaler.fit_transform(X)
????????2. 最小-最大縮放:最小-最大縮放將要素縮放到固定范圍,通常在 0 到 1 之間。這是通過從每個值中減去最小值,然后除以范圍來完成的。
????????以下是使用 scikit-learn 進行最小-最大縮放的示例:
from sklearn.preprocessing import MinMaxScaler# Create a MinMaxScaler object
scaler = MinMaxScaler()# Fit and transform the data
X_scaled = scaler.fit_transform(X)
圖例.4 — 標準化和規范化
????????3. 穩健縮放:穩健縮放類似于標準化,但它使用中位數和四分位數范圍而不是平均值和標準偏差。這使得它對數據中的異常值更加可靠。
????????下面是一個使用 scikit-learn 進行健壯擴展的示例:
from sklearn.preprocessing import RobustScaler# Create a RobustScaler object
scaler = RobustScaler()# Fit and transform the data
X_scaled = scaler.fit_transform(X)
????????4. 歸一化:歸一化將每個觀測值縮放為具有單位范數,這意味著每個特征值的平方和為 1。這對于某些需要對所有樣本具有相似比例的算法非常有用。
????????下面是一個使用 scikit-learn 進行規范化的示例:
from sklearn.preprocessing import Normalizer# Create a Normalizer object
scaler = Normalizer()# Fit and transform the data
X_scaled = scaler.fit_transform(X)
四、創建新要素
????????創建新特征是特征工程中的重要步驟,涉及從現有數據創建新變量或列。這有助于捕獲特征之間的復雜關系并提高模型的準確性。
????????以下是創建新要素的一些技術:
????????1. 交互特征:通過將兩個或多個現有特征相乘來創建交互特征。這有助于捕獲要素的聯合效應并發現數據中的新模式。例如,如果我們有兩個特征,“年齡”和“收入”,我們可以通過將這兩個特征相乘來創建一個名為“age_income”的新交互特征。
????????以下是在 Python 中使用 Pandas 創建交互功能的示例:
import pandas as pd# create a sample data frame
data = pd.DataFrame({'age': [25, 30, 35],'income': [50000, 60000, 70000]})# create a new interaction feature
data['age_income'] = data['age'] * data['income']# display the updated data frame
print(data)
????????2. 多項式特征:多項式特征是通過將現有特征提高到更高的冪來創建的。這有助于捕獲特征之間的非線性關系并提高模型的精度。例如,如果我們有一個特征“age”,我們可以通過對這個特征進行平方來創建一個名為“age_squared”的新多項式特征。
????????以下是在Python中使用Scikit-learn創建多項式特征的示例:
from sklearn.preprocessing import PolynomialFeatures
import numpy as np# create a sample data set
X = np.array([[1, 2],[3, 4]])# create polynomial features up to degree 2
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)# display the updated feature matrix
print(X_poly)
????????3. 分箱:分箱涉及將連續值分組為離散類別。這有助于捕獲非線性關系并減少數據中異常值的影響。例如,如果我們有一個特征“age”,我們可以通過將年齡分組為不同的類別(例如“0-18”、“18-25”、“25-35”、“35-50”和“50+”)來創建一個名為“age_group”的新分箱特征。
????????以下是在 Python 中使用 Pandas 創建分箱功能的示例:
import pandas as pd# create a sample data frame
data = pd.DataFrame({'age': [20, 25, 30, 35, 40, 45, 50, 55]})# create bins for different age groups
bins = [0, 18, 25, 35, 50, float('inf')]
labels = ['0-18', '18-25', '25-35', '35-50', '50+']
data['age_group'] = pd.cut(data['age'], bins=bins, labels=labels)# display the updated data frame
print(data)
五、處理不平衡數據
????????處理不平衡的數據是機器學習的一個重要方面。不平衡數據是指目標變量的分布不均勻,并且與另一個類相比,一個類的代表性不足。這可能導致模型中偏向多數類,并且模型在少數類上的表現可能很差。處理不平衡數據的一些技術是:
????????1. 上采樣:上采樣涉及通過對現有樣本進行替換重新采樣,為少數類創建更多樣本。這可以使用模塊中的函數來完成。resample
sklearn.utils
from sklearn.utils import resample# Upsample minority class
X_upsampled, y_upsampled = resample(X_minority, y_minority, replace=True, n_samples=len(X_majority), random_state=42)
????????2. 縮減采樣:縮減采樣涉及從多數類中刪除一些樣本以平衡分布。這可以使用模塊中的函數來完成。resample
sklearn.utils
from sklearn.utils import resample# Downsample majority class
X_downsampled, y_downsampled = resample(X_majority, y_majority, replace=False, n_samples=len(X_minority), random_state=42)
圖 4 — 欠采樣和過采樣
????????3. 合成少數過采樣技術 (SMOTE):SMOTE 涉及基于現有樣本為少數類創建合成樣本。這可以使用模塊中的函數來完成。SMOTE
imblearn.over_sampling
from imblearn.over_sampling import SMOTE# Use SMOTE to upsample minority class
sm = SMOTE(random_state=42)
X_resampled, y_resampled = sm.fit_resample(X, y)
????????4.?類加權:類加權涉及為模型中的每個類分配一個權重以解決不平衡。這可以使用模型中的參數來完成。class_weight
from sklearn.linear_model import LogisticRegression# Use class weighting to handle imbalance
clf = LogisticRegression(class_weight='balanced', random_state=42)
clf.fit(X_train, y_train)
????????5. 異常檢測:異常檢測涉及識別數據中的異常值并將其刪除。這可以使用模塊中的函數來完成。異常檢測可識別數據集中明顯偏離預期或正常行為的罕見事件或觀測值。對于不平衡數據,其中一個類中的觀測值數量遠低于另一個類,則異常檢測可用于識別少數類中的罕見觀測值并將其標記為異常。這有助于平衡數據集并提高機器學習模型的性能。IsolationForest
sklearn.ensemble
????????在不平衡數據中進行異常檢測的一種常見方法是使用無監督學習技術,例如聚類,其中少數類觀察根據其相似性聚類為不同的組。少數類中不屬于任何這些聚類的觀測值可以標記為異常。
????????另一種方法是使用監督學習技術,例如單類分類,其中模型在多數類數據上訓練以學習數據的正常行為。然后,明顯偏離學習正常行為的少數類觀察結果被標記為異常。
from sklearn.ensemble import IsolationForest# Use anomaly detection to handle imbalance
clf = IsolationForest(random_state=42)
clf.fit(X_train)
X_train = X_train[clf.predict(X_train) == 1]
y_train = y_train[clf.predict(X_train) == 1]
????????6. 成本敏感學習:成本敏感學習涉及為模型中的每種類型的錯誤分配不同的成本以解釋不平衡。這可以使用模型中的參數來完成。sample_weight
from sklearn.tree import DecisionTreeClassifier# Use cost-sensitive learning to handle imbalance
clf = DecisionTreeClassifier(random_state=42)
clf.fit(X_train, y_train, sample_weight=class_weights)