接上文:机器学习终极指南:特征工程(01/2)
五、处理不平衡数据
处理不平衡的数据是机器学习的一个重要方面。不平衡数据是指目标变量的分布不均匀,并且与另一个类相比,一个类的代表性不足。这可能导致模型中偏向多数类,并且模型在少数类上的表现可能很差。处理不平衡数据的一些技术是:
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)
六、偏度和峰度处理
偏度和峰度是有助于理解数据分布的统计度量。偏度测量数据中的不对称程度,而峰度测量分布的峰值或平坦程度。
图例.5 — 偏度
偏斜的数据可能会对机器学习模型的性能产生负面影响。因此,处理数据中的偏度非常重要。以下是处理数据偏度的一些技术:
- 对数转换:对数转换可用于减少数据的偏度。它可以应用于正偏斜和负偏斜数据。
- 平方根变换:平方根变换可用于降低数据的偏度。它可以应用于正偏斜数据。
- Box-Cox 变换:Box-Cox 变换是一种更通用的变换方法,可以处理正偏斜和负偏斜数据。它使用参数 lambda 来确定要应用于数据的转换类型。
下面是一些用于演示这些转换的 Python 代码:
import numpy as np
import pandas as pd
from scipy import stats
# Generate some skewed data
data = np.random.gamma(1, 10, 1000)
# Calculate skewness and kurtosis
skewness = stats.skew(data)
kurtosis = stats.kurtosis(data)
print("Skewness:", skewness)
print("Kurtosis:", kurtosis)
# Log transformation
log_data = np.log(data)
log_skewness = stats.skew(log_data)
log_kurtosis = stats.kurtosis(log_data)
print("Log Skewness:", log_skewness)
print("Log Kurtosis:", log_kurtosis)
# Square root transformation
sqrt_data = np.sqrt(data)
sqrt_skewness = stats.skew(sqrt_data)
sqrt_kurtosis = stats.kurtosis(sqrt_data)
print("Sqrt Skewness:", sqrt_skewness)
print("Sqrt Kurtosis:", sqrt_kurtosis)
# Box-Cox transformation
box_cox_data, _ = stats.boxcox(data)
box_cox_skewness = stats.skew(box_cox_data)
box_cox_kurtosis = stats.kurtosis(box_cox_data)
print("Box-Cox Skewness:", box_cox_skewness)
print("Box-Cox Kurtosis:", box_cox_kurtosis)
可以通过应用类似于处理偏度的转换来处理峰度。处理峰度的一些技术包括:
- 对数转换:对数转换也可用于处理数据中的峰度。
- 平方变换:平方变换还可用于处理数据中的峰度。
- Box-Cox 变换:Box-Cox 变换还可用于处理数据中的峰度。
图片.6 — 峰度
下面是一些用于演示这些转换的 Python 代码:
import numpy as np
import pandas as pd
from scipy import stats
# Generate some data with high kurtosis
data = np.random.normal(0, 5, 1000)**3
# Calculate skewness and kurtosis
skewness = stats.skew(data)
kurtosis = stats.kurtosis(data)
print("Skewness:", skewness)
print("Kurtosis:", kurtosis)
# Log transformation
log_data = np.log(data)
log_skewness = stats.skew(log_data)
log_kurtosis = stats.kurtosis(log_data
七、处理稀有类别
处理稀有类别是指处理数据中不经常出现的分类变量中的类别的过程。稀有类别可能会导致机器学习模型中出现问题,因为它们在数据中可能没有足够的表示来准确建模。处理稀有类别的一些技术包括:
- 对稀有类别进行分组: 这涉及将稀有类别分组为单个类别或几个类别。这将减少变量中的类别数并增加稀有类别的表示形式。
- 将稀有类别替换为更常见的类别:这涉及将稀有类别替换为变量中最常见的类别。如果稀有类别对分析不重要,则这可能有效。
- 带有标志的独热编码:这涉及为稀有类别创建新类别并将其标记为稀有。这允许模型以不同于其他类别的方式处理稀有类别。
以下是如何使用泰坦尼克号数据集处理稀有类别的示例:
import pandas as pd
import numpy as np
# load Titanic dataset
titanic = pd.read_csv('titanic.csv')
# view value counts of the 'Embarked' column
print(titanic['Embarked'].value_counts())
# group rare categories into a single category
titanic['Embarked'] = np.where(titanic['Embarked'].isin(['C', 'Q']), titanic['Embarked'], 'R')
# view value counts of the 'Embarked' column after grouping
print(titanic['Embarked'].value_counts())
# replace rare categories with the most common category
titanic['Embarked'] = np.where(titanic['Embarked'].isin(['C', 'Q']), titanic['Embarked'], 'S')
# view value counts of the 'Embarked' column after replacement
print(titanic['Embarked'].value_counts())
# create a new category for rare categories and flag them as rare
titanic['Embarked_R'] = np.where(titanic['Embarked'].isin(['C', 'Q']), 0, 1)
八、处理时间序列数据
处理时间序列数据涉及多种技术,例如数据预处理、特征提取和建模。让我们来看看一些技术以及如何使用 Python 实现它们。
图例.7 — 时间序列数据
1. 数据预处理:时间序列数据通常包含可能影响模型性能的缺失值、异常值和噪声数据。因此,在训练模型之前预处理数据至关重要。数据预处理的一些常见技术包括插补、处理异常值和缩放。
2. 特征提取:特征提取涉及从可用于建模的时间序列数据中提取相关信息。一些流行的特征提取技术包括滚动统计、傅里叶变换和小波变换。
3. 建模:一旦数据经过预处理并提取了特征,就可以将其用于建模。一些流行的时间序列数据模型包括ARIMA:自回归积分移动平均线(ARIMA),LSTM:长短期记忆(LSTM)和Prophet。
让我们看一个如何在 Python 中实现这些技术的示例:
# Import libraries
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from statsmodels.tsa.arima_model import ARIMA
from keras.models import Sequential
from keras.layers import LSTM, Dense
# Load time-series data
data = pd.read_csv('time_series_data.csv')
# Preprocess data
data.fillna(method='ffill', inplace=True)
data = data[(data['date'] > '2020-01-01') & (data['date'] < '2021-12-31')]
data.set_index('date', inplace=True)
scaler = StandardScaler()
data = scaler.fit_transform(data)
# Extract features
rolling_mean = data.rolling(window=7).mean()
fft = np.fft.fft(data)
wavelet = pywt.dwt(data, 'db1')
# Train ARIMA model
model = ARIMA(data, order=(1, 1, 1))
model_fit = model.fit(disp=0)
predictions = model_fit.predict(start='2022-01-01', end='2022-12-31')
# Train LSTM model
X_train, y_train = [], []
for i in range(7, len(data)):
X_train.append(data[i-7:i, 0])
y_train.append(data[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
# Define the LSTM model
model = Sequential()
model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1)))
model.add(Dropout(0.2))
model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=50))
model.add(Dropout(0.2))
model.add(Dense(units=1))
# Compile the model
model.compile(optimizer='adam', loss='mean_squared_error')
# Fit the model to the training data
model.fit(X_train, y_train, epochs=100, batch_size=32)
九、文本预处理
在处理文本数据时,文本预处理是特征工程中的关键步骤。目标是将原始文本转换为可用于机器学习模型的数字表示形式。以下是 Python 中一些常见的文本预处理技术:
- 标记化:这涉及将句子或文档分解为单独的单词或短语。NLTK 库提供了各种分词器,例如单词分词器和句子分词器。
from nltk.tokenize import word_tokenize, sent_tokenize
text = "This is a sample sentence. It contains some words."
words = word_tokenize(text)
sentences = sent_tokenize(text)
print(words)
# Output: ['This', 'is', 'a', 'sample', 'sentence', '.', 'It', 'contains', 'some', 'words', '.']
print(sentences)
# Output: ['This is a sample sentence.', 'It contains some words.']
2.停用词删除:停用词是经常出现的不给文本添加任何含义的单词,例如“a”、“the”、“and”等。删除停用词可以提高文本处理的效率并减小数据的大小。NLTK 库提供了各种语言的停用词列表。
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
filtered_words = [word for word in words if word.casefold() not in stop_words]
print(filtered_words)
# Output: ['sample', 'sentence', '.', 'contains', 'words', '.']
图片.8 — 文本处理
3. 词干提取和词形还原:词干提取和词形还原是用于将单词简化为其基本形式或词根形式的技术。例如,“跑步”、“跑步者”和“跑步”可以简化为词根“跑步”。NLTK 库提供了各种词干分析器和词形还原器。
from nltk.stem import PorterStemmer, WordNetLemmatizer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
stemmed_words = [stemmer.stem(word) for word in filtered_words]
lemmatized_words = [lemmatizer.lemmatize(word) for word in filtered_words]
print(stemmed_words)
# Output: ['sampl', 'sentenc', '.', 'contain', 'word', '.']
print(lemmatized_words)
# Output: ['sample', 'sentence', '.', 'contains', 'word', '.']
4.文本规范化:文本规范化涉及将文本转换为标准化形式,例如将所有文本转换为小写,删除标点符号,将缩写和缩略替换为其完整形式。
import re
def normalize_text(text):
text = text.lower()
text = re.sub(r'[^\w\s]', '', text)
text = re.sub(r'\b(can\'t|won\'t|shouldn\'t)\b', 'not', text)
text = re.sub(r'\b(i\'m|you\'re|he\'s|she\'s|it\'s|we\'re|they\'re)\b', 'be', text)
return text
text = "I can't believe it's not butter!"
normalized_text = normalize_text(text)
print(normalized_text)
# Output: 'i not believe be not butter'
十、结论
总之,特征工程是机器学习过程中的关键步骤,涉及将原始数据转换为机器学习算法可以有效使用的格式。在这篇博文中,我们介绍了特征工程的各种技术,包括特征选择和提取、编码分类变量、缩放和归一化、创建新特征、处理不平衡数据、处理偏度和峰度、处理稀有类别、处理时间序列数据、特征转换和文本预处理。
以下是这篇文章的关键要点:
- 特征选择和提取可以使用统计方法(如 PCA、LDA 和相关分析)以及机器学习方法(如基于树的方法、包装方法和嵌入式方法)来完成。
- 可以使用独热编码、标签编码和计数编码等技术对分类变量进行编码。
- 缩放和规范化可以使用最小-最大缩放、标准缩放和可靠缩放等技术来完成。
- 文本预处理涉及标记化、停用词删除、词干提取和词形还原等技术。