本文目录导读:
我来为您介绍Python中几种常见的数据归一化方法及案例实现。
数据准备
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
from sklearn.preprocessing import Normalizer
# 创建示例数据
np.random.seed(42)
data = {
'feature1': np.random.randn(100) * 10 + 50, # 均值50,标准差10
'feature2': np.random.randn(100) * 100 + 500, # 均值500,标准差100
'feature3': np.random.uniform(0, 1, 100), # 均匀分布0-1
'feature4': np.random.exponential(2, 100) # 指数分布
}
df = pd.DataFrame(data)
print("原始数据统计描述:")
print(df.describe())
print("\n原始数据前5行:")
print(df.head())
Min-Max归一化(最值归一化)
def min_max_normalization(df):
"""
将数据缩放到[0,1]区间
"""
# 方法1:手动实现
df_min_max = (df - df.min()) / (df.max() - df.min())
# 方法2:使用sklearn
scaler = MinMaxScaler()
df_min_max_sklearn = pd.DataFrame(
scaler.fit_transform(df),
columns=df.columns
)
return df_min_max, df_min_max_sklearn
# 执行归一化
df_min_max, df_min_max_sklearn = min_max_normalization(df)
print("\nMin-Max归一化结果(前5行):")
print(df_min_max.head())
print("\n归一化后数据统计:")
print(df_min_max.describe())
Z-score标准化(标准差标准化)
def z_score_normalization(df):
"""
将数据标准化为均值为0,标准差为1
"""
# 方法1:手动实现
df_zscore = (df - df.mean()) / df.std()
# 方法2:使用sklearn
scaler = StandardScaler()
df_zscore_sklearn = pd.DataFrame(
scaler.fit_transform(df),
columns=df.columns
)
return df_zscore, df_zscore_sklearn
# 执行标准化
df_zscore, df_zscore_sklearn = z_score_normalization(df)
print("\nZ-score标准化结果(前5行):")
print(df_zscore.head())
print("\n标准化后数据统计:")
print(df_zscore.describe())
Robust归一化(鲁棒标准化)
def robust_normalization(df):
"""
使用中位数和四分位数进行标准化,对异常值更鲁棒
"""
# 方法1:手动实现
median = df.median()
q1 = df.quantile(0.25)
q3 = df.quantile(0.75)
iqr = q3 - q1
df_robust = (df - median) / iqr
# 方法2:使用sklearn
scaler = RobustScaler()
df_robust_sklearn = pd.DataFrame(
scaler.fit_transform(df),
columns=df.columns
)
return df_robust, df_robust_sklearn
# 执行鲁棒标准化
df_robust, df_robust_sklearn = robust_normalization(df)
print("\nRobust标准化结果(前5行):")
print(df_robust.head())
print("\n标准化后数据统计:")
print(df_robust.describe())
L2归一化(向量单位归一化)
def l2_normalization(df):
"""
将每个样本向量归一化为单位向量(L2范数=1)
"""
# 方法1:手动实现
l2_norms = np.sqrt((df ** 2).sum(axis=1))
df_l2 = df.div(l2_norms, axis=0)
# 方法2:使用sklearn
normalizer = Normalizer(norm='l2')
df_l2_sklearn = pd.DataFrame(
normalizer.fit_transform(df),
columns=df.columns
)
return df_l2, df_l2_sklearn
# 执行L2归一化
df_l2, df_l2_sklearn = l2_normalization(df)
print("\nL2归一化结果(前5行):")
print(df_l2.head())
print("\n检查L2范数是否为1:")
print(np.sqrt((df_l2 ** 2).sum(axis=1)).head())
可视化对比
def visualize_normalization(original_df, normalized_dfs, titles):
"""
可视化不同归一化方法的效果
"""
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
# 原始数据
axes[0, 0].hist(original_df.values, bins=20, alpha=0.7)
axes[0, 0].set_title('Original Data')
axes[0, 0].set_xlabel('Value')
axes[0, 0].set_ylabel('Frequency')
# 不同归一化方法
for i, (norm_df, title) in enumerate(zip(normalized_dfs, titles)):
row = (i + 1) // 3
col = (i + 1) % 3
axes[row, col].hist(norm_df.values, bins=20, alpha=0.7)
axes[row, col].set_title(title)
axes[row, col].set_xlabel('Value')
axes[row, col].set_ylabel('Frequency')
plt.tight_layout()
plt.show()
# 可视化对比
visualize_normalization(
df,
[df_min_max, df_zscore, df_robust, df_l2],
['Min-Max (0-1)', 'Z-score (0,1)', 'Robust', 'L2 Normalization']
)
实际应用案例:机器学习预处理
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
# 创建分类数据集
np.random.seed(42)
n_samples = 200
X = np.column_stack([
np.random.normal(50, 10, n_samples), # 特征1
np.random.normal(500, 100, n_samples), # 特征2
np.random.uniform(0, 1, n_samples), # 特征3
np.random.exponential(2, n_samples) # 特征4
])
y = (X[:, 0] + X[:, 1] * 0.01 + X[:, 2] * 10 > 60).astype(int)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 比较不同归一化方法对模型性能的影响
normalization_methods = {
'No Normalization': None,
'Min-Max': MinMaxScaler(),
'Z-score': StandardScaler(),
'Robust': RobustScaler()
}
results = {}
for name, scaler in normalization_methods.items():
if scaler is None:
X_train_scaled = X_train
X_test_scaled = X_test
else:
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 使用KNN分类器(对特征缩放敏感)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train_scaled, y_train)
y_pred = knn.predict(X_test_scaled)
accuracy = accuracy_score(y_test, y_pred)
results[name] = accuracy
print(f"{name}: KNN准确率 = {accuracy:.4f}")
# 输出最佳方法
best_method = max(results, key=results.get)
print(f"\n最佳归一化方法: {best_method} (准确率: {results[best_method]:.4f})")
归一化方法选择指南
def suggest_normalization_method(data, has_outliers=False,
distribution_type='unknown'):
"""
根据数据特征推荐合适的归一化方法
"""
suggestions = []
# 检查是否有异常值
if has_outliers:
suggestions.append("RobustScaler (对异常值鲁棒)")
# 检查数据分布
if distribution_type == 'normal':
suggestions.append("StandardScaler (适用于正态分布)")
elif distribution_type == 'uniform':
suggestions.append("MinMaxScaler (适用于均匀分布)")
# 通用建议
if not suggestions:
suggestions = [
"MinMaxScaler (通用,适合神经网络)",
"StandardScaler (适合存在假设的数据)",
"RobustScaler (存在异常值时使用)"
]
print("建议的归一化方法:")
for i, suggestion in enumerate(suggestions, 1):
print(f"{i}. {suggestion}")
return suggestions
# 使用建议函数
print("\n" + "="*50)
print("归一化方法选择建议:")
print("="*50)
suggest_normalization_method(
df,
has_outliers=True,
distribution_type='mixed'
)
不同归一化方法的适用场景:
| 方法 | 适用场景 | 特点 |
|---|---|---|
| Min-Max | 神经网络、需要固定取值范围 | 对异常值敏感 |
| Z-score | 假设数据正态分布 | 保留分布形状 |
| Robust | 存在异常值 | 受异常值影响小 |
| L2归一化 | 文本分类、余弦相似度 | 按样本方向缩放 |
选择建议:
- 神经网络和深度学习:优先使用Min-Max或Z-score
- 存在异常值:使用Robust标准化
- 需要可比性:使用Z-score
- 计算相似度:使用L2归一化
建议根据具体问题和数据特征选择合适的归一化方法,并通过实验验证效果。
标签: Python