我将通过一个综合的Python案例来比较神经网络与传统机器学习方法(如逻辑回归、随机森林)在不同场景下的表现,这个案例将涵盖数据生成、模型训练、评估和可视化。

完整案例:信用卡欺诈检测
环境准备和数据生成
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
from sklearn.metrics import confusion_matrix, roc_curve
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import warnings
warnings.filterwarnings('ignore')
# 设置随机种子
np.random.seed(42)
tf.random.set_seed(42)
# 生成模拟的信用卡交易数据
def generate_fraud_data(n_samples=10000, fraud_ratio=0.02):
"""
生成模拟的信用卡交易数据
"""
n_fraud = int(n_samples * fraud_ratio)
n_normal = n_samples - n_fraud
# 正常交易
normal_amounts = np.random.normal(50, 30, n_normal)
normal_amounts = np.abs(normal_amounts) + 1
# 欺诈交易(金额通常较大)
fraud_amounts = np.random.normal(500, 200, n_fraud)
fraud_amounts = np.abs(fraud_amounts)
# 其他特征
normal_features = np.random.normal(0, 1, (n_normal, 20))
fraud_features = np.random.normal(2, 1.5, (n_fraud, 20))
# 组合数据
X = np.vstack([normal_features, fraud_features])
y = np.hstack([np.zeros(n_normal), np.ones(n_fraud)])
amounts = np.hstack([normal_amounts, fraud_amounts])
# 添加一些交易时间特征
transaction_hours = np.random.randint(0, 24, n_samples)
X = np.hstack([X, amounts.reshape(-1, 1), transaction_hours.reshape(-1, 1)])
# 打乱数据
indices = np.random.permutation(n_samples)
X, y = X[indices], y[indices]
return X, y
# 生成数据
X, y = generate_fraud_data()
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
# 标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print(f"训练集大小: {X_train.shape}")
print(f"测试集大小: {X_test.shape}")
print(f"欺诈交易比例: {y.sum()/len(y):.4f}")
传统方法实现
# 逻辑回归
def train_logistic_regression(X_train, y_train, X_test, y_test):
"""训练逻辑回归模型"""
lr_model = LogisticRegression(max_iter=1000, random_state=42)
lr_model.fit(X_train, y_train)
y_pred = lr_model.predict(X_test)
y_pred_proba = lr_model.predict_proba(X_test)[:, 1]
return y_pred, y_pred_proba, lr_model
# 随机森林
def train_random_forest(X_train, y_train, X_test, y_test):
"""训练随机森林模型"""
rf_model = RandomForestClassifier(
n_estimators=100,
max_depth=10,
random_state=42,
n_jobs=-1
)
rf_model.fit(X_train, y_train)
y_pred = rf_model.predict(X_test)
y_pred_proba = rf_model.predict_proba(X_test)[:, 1]
return y_pred, y_pred_proba, rf_model
# 训练传统模型
lr_pred, lr_pred_proba, lr_model = train_logistic_regression(
X_train_scaled, y_train, X_test_scaled, y_test
)
rf_pred, rf_pred_proba, rf_model = train_random_forest(
X_train_scaled, y_train, X_test_scaled, y_test
)
神经网络实现
# 构建神经网络模型
def build_neural_network(input_dim):
"""构建神经网络模型"""
model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(input_dim,)),
layers.Dropout(0.3),
layers.Dense(32, activation='relu'),
layers.Dropout(0.3),
layers.Dense(16, activation='relu'),
layers.Dense(1, activation='sigmoid')
])
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.001),
loss='binary_crossentropy',
metrics=['accuracy', keras.metrics.AUC(name='auc')]
)
return model
# 训练神经网络
def train_neural_network(X_train, y_train, X_test, y_test):
"""训练神经网络模型"""
input_dim = X_train.shape[1]
model = build_neural_network(input_dim)
# 早停和模型检查点
early_stopping = keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=10,
restore_best_weights=True
)
reduce_lr = keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=5,
min_lr=1e-6
)
history = model.fit(
X_train, y_train,
validation_data=(X_test, y_test),
epochs=50,
batch_size=32,
callbacks=[early_stopping, reduce_lr],
verbose=0
)
y_pred = (model.predict(X_test) > 0.5).astype(int)
y_pred_proba = model.predict(X_test).flatten()
return y_pred, y_pred_proba, model, history
# 训练神经网络
nn_pred, nn_pred_proba, nn_model, nn_history = train_neural_network(
X_train_scaled, y_train, X_test_scaled, y_test
)
模型评估函数
def evaluate_models(y_true, predictions_dict):
"""评估多个模型"""
metrics = {}
for name, (y_pred, y_proba) in predictions_dict.items():
metrics[name] = {
'accuracy': accuracy_score(y_true, y_pred),
'precision': precision_score(y_true, y_pred),
'recall': recall_score(y_true, y_pred),
'f1_score': f1_score(y_true, y_pred),
'auc': roc_auc_score(y_true, y_proba)
}
return metrics
# 准备预测结果
predictions = {
'Logistic Regression': (lr_pred, lr_pred_proba),
'Random Forest': (rf_pred, rf_pred_proba),
'Neural Network': (nn_pred, nn_pred_proba)
}
# 评估所有模型
results = evaluate_models(y_test, predictions)
# 显示结果
print("="*60)
print("模型性能对比")
print("="*60)
for model_name, metrics in results.items():
print(f"\n{model_name}:")
print(f" Accuracy: {metrics['accuracy']:.4f}")
print(f" Precision: {metrics['precision']:.4f}")
print(f" Recall: {metrics['recall']:.4f}")
print(f" F1-Score: {metrics['f1_score']:.4f}")
print(f" AUC-ROC: {metrics['auc']:.4f}")
可视化对比
# 创建对比图
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
# 1. 混淆矩阵
for idx, (model_name, (y_pred, _)) in enumerate(predictions.items()):
ax = axes[0, idx]
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', ax=ax, cmap='Blues')
ax.set_title(f'{model_name} - Confusion Matrix')
ax.set_xlabel('Predicted')
ax.set_ylabel('Actual')
# 2. ROC曲线对比
ax = axes[1, 0]
colors = ['blue', 'green', 'red']
for idx, (model_name, (_, y_proba)) in enumerate(predictions.items()):
fpr, tpr, _ = roc_curve(y_test, y_proba)
ax.plot(fpr, tpr, color=colors[idx], label=f'{model_name} (AUC={results[model_name]["auc"]:.3f})')
ax.plot([0, 1], [0, 1], 'k--')
ax.set_xlabel('False Positive Rate')
ax.set_ylabel('True Positive Rate')
ax.set_title('ROC Curves Comparison')
ax.legend()
ax.grid(True)
# 3. 性能柱状图
ax = axes[1, 1]
model_names = list(results.keys())
scores = {
'precision': [results[name]['precision'] for name in model_names],
'recall': [results[name]['recall'] for name in model_names],
'f1_score': [results[name]['f1_score'] for name in model_names],
'auc': [results[name]['auc'] for name in model_names]
}
x = np.arange(len(model_names))
width = 0.2
for i, (metric, values) in enumerate(scores.items()):
ax.bar(x + i*width, values, width, label=metric.capitalize())
ax.set_xlabel('Model')
ax.set_ylabel('Score')
ax.set_title('Model Performance Comparison')
ax.set_xticks(x + width*1.5)
ax.set_xticklabels(model_names, rotation=15)
ax.legend()
ax.grid(True, alpha=0.3)
# 4. 神经网络训练曲线
ax = axes[1, 2]
ax.plot(nn_history.history['loss'], label='Training Loss')
ax.plot(nn_history.history['val_loss'], label='Validation Loss')
ax.set_xlabel('Epoch')
ax.set_ylabel('Loss')
ax.set_title('Neural Network Training')
ax.legend()
ax.grid(True)
# 5. 特征重要性对比
ax = axes[0, 2]
# 使用随机森林的特征重要性
feature_importance = rf_model.feature_importances_
top_features = np.argsort(feature_importance)[-10:]
ax.barh(range(10), feature_importance[top_features])
ax.set_yticks(range(10))
ax.set_yticklabels([f'Feature {i}' for i in top_features])
ax.set_xlabel('Importance')
ax.set_title('Random Forest Feature Importance')
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
扩展实验:非线性数据
# 生成更复杂的数据来展示神经网络的优越性
def generate_complex_data(n_samples=5000):
"""
生成具有复杂非线性关系的数据
"""
X = np.random.uniform(-3, 3, (n_samples, 20))
# 创建复杂的非线性关系
y = np.zeros(n_samples)
# 非线性决策边界
complex_relation = (
np.sin(X[:, 0] * X[:, 1]) +
np.exp(-X[:, 2]**2) * X[:, 3] +
np.abs(X[:, 4] - X[:, 5]) +
(X[:, 6] * X[:, 7] * X[:, 8]) / 10 +
np.log1p(np.abs(X[:, 9]))
)
# 添加噪声
complex_relation += np.random.normal(0, 0.5, n_samples)
# 生成标签
threshold = np.percentile(complex_relation, 80)
y[complex_relation > threshold] = 1
# 标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)
return X, y
# 生成并测试复杂数据
X_complex, y_complex = generate_complex_data()
X_train_c, X_test_c, y_train_c, y_test_c = train_test_split(
X_complex, y_complex, test_size=0.3, random_state=42, stratify=y_complex
)
# 训练模型(比例如前所述,为简化此处只评估部分指标)
print("\n" + "="*60)
print("复杂非线性数据对比")
print("="*60)
# 传统方法
lr_model_c = LogisticRegression(max_iter=1000, random_state=42)
lr_model_c.fit(X_train_c, y_train_c)
lr_pred_c = lr_model_c.predict(X_test_c)
print(f"\n逻辑回归准确率: {accuracy_score(y_test_c, lr_pred_c):.4f}")
rf_model_c = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model_c.fit(X_train_c, y_train_c)
rf_pred_c = rf_model_c.predict(X_test_c)
print(f"随机森林准确率: {accuracy_score(y_test_c, rf_pred_c):.4f}")
# 神经网络
nn_model_c = build_neural_network(X_train_c.shape[1])
early_stopping = keras.callbacks.EarlyStopping(
monitor='val_loss', patience=15, restore_best_weights=True
)
history_c = nn_model_c.fit(
X_train_c, y_train_c,
validation_split=0.2,
epochs=100,
batch_size=32,
callbacks=[early_stopping],
verbose=0
)
nn_pred_c = (nn_model_c.predict(X_test_c) > 0.5).astype(int)
print(f"神经网络准确率: {accuracy_score(y_test_c, nn_pred_c):.4f}")
详细性能总结
# 创建性能对比表格
print("\n" + "="*80)
print("综合性能对比表")
print("="*80)
metrics_df = pd.DataFrame(results).T
print("\n主要评估指标:")
print(metrics_df.round(4))
# 计算相对优势
print("\n" + "="*80)
print("模型相对优势分析")
print("="*80)
best_model = metrics_df['f1_score'].idxmax()
print(f"F1分数最高的模型: {best_model}")
print(f"F1分数: {metrics_df.loc[best_model, 'f1_score']:.4f}")
# 综合评分
metrics_df['综合评分'] = (
metrics_df['accuracy'] +
metrics_df['precision'] +
metrics_df['recall'] +
metrics_df['f1_score'] +
metrics_df['auc']
) / 5
print("\n综合评分排名:")
ranked_models = metrics_df['综合评分'].sort_values(ascending=False)
for model, score in ranked_models.items():
print(f"{model}: {score:.4f}")
# 最终结论
print("\n" + "="*80)
print("quot;)
print("="*80)
conclusions = """
1. 在数据量充足且特征复杂的情况下,神经网络通常表现更好
2. 神经网络能够自动学习特征间的非线性关系
3. 但传统方法在某些场景下仍有优势:
- 计算资源消耗小
- 可解释性强
- 小样本数据表现稳定
- 训练时间短
4. 选择模型时应考虑:
- 数据规模和复杂性
- 计算资源限制
- 模型可解释性需求
- 实时性要求
"""
print(conclusions)
# 保存最佳模型
import joblib
best_model_name = metrics_df['f1_score'].idxmax()
print(f"最佳模型: {best_model_name}")
if best_model_name == "Neural Network":
nn_model.save('best_neural_network_model.h5')
print("神经网络模型已保存")
else:
joblib.dump(rf_model, 'best_rf_model.pkl')
print(f"{best_model_name}模型已保存为 best_model.pkl")
这个综合案例展示了:
-
神经网络的优势:
- 自动特征学习
- 处理非线性关系
- 大数据集表现更好
- 泛化能力强
-
传统方法的优势:
- 训练速度快
- 可解释性强
- 小样本表现稳定
- 资源消耗低
-
选择建议:
- 任务复杂性决定
- 资源限制
- 业务需求
- 部署环境
通过这个案例可以看出,神经网络并非在所有情况下都优于传统方法,需要根据具体场景进行选择,在实际应用中,往往需要结合多种方法才能达到最优效果。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播