机器学习基础
1. 什么是机器学习
机器学习(Machine Learning, ML)是人工智能的一个重要分支,它使计算机系统能够通过经验自动改进性能,而无需明确编程。机器学习的核心思想是让计算机从数据中学习模式和规律,并利用这些模式对新数据进行预测或决策。
1.1 机器学习的定义
"机器学习是一种让计算机在没有明确编程的情况下学习的能力。" —— Arthur Samuel (1959)
"如果一个计算机程序在某类任务T上的性能(用P衡量)随着经验E的增加而改善,那么我们说这个程序从经验E中学习了任务T。" —— Tom Mitchell (1997)
1.2 机器学习与传统编程的区别
传统编程:
- 输入:数据 + 程序
- 输出:结果
- 特点:人工编写规则和逻辑
机器学习:
- 输入:数据 + 结果
- 输出:程序(模型)
- 特点:自动发现规律和模式
1.3 机器学习的应用场景
- 推荐系统:电商平台商品推荐、视频平台内容推荐
- 图像识别:人脸识别、医学影像诊断、自动驾驶
- 自然语言处理:机器翻译、情感分析、智能客服
- 金融风控:信用评估、欺诈检测、量化交易
- 医疗健康:疾病诊断、药物发现、个性化治疗
- 工业制造:质量检测、预测性维护、供应链优化
2. 机器学习的分类
2.1 按学习方式分类
2.1.1 监督学习(Supervised Learning)
定义:使用带标签的训练数据来学习输入和输出之间的映射关系。
特点:
- 训练数据包含输入特征和对应的标签
- 目标是学习一个函数,能够对新的输入预测正确的输出
- 可以评估模型的准确性
主要任务类型:
分类(Classification):
- 目标:预测离散的类别标签
- 示例:邮件垃圾分类、图像识别、疾病诊断
- 常用算法:逻辑回归、决策树、随机森林、SVM、神经网络
python
# 分类示例:鸢尾花分类
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 加载数据
iris = load_iris()
X, y = iris.data, iris.target
# 分割数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练模型
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)
# 预测和评估
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"分类准确率: {accuracy:.4f}")回归(Regression):
- 目标:预测连续的数值
- 示例:房价预测、股票价格预测、销量预测
- 常用算法:线性回归、多项式回归、岭回归、支持向量回归
python
# 回归示例:房价预测
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 加载数据
boston = load_boston()
X, y = boston.data, boston.target
# 分割数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练模型
reg = LinearRegression()
reg.fit(X_train, y_train)
# 预测和评估
y_pred = reg.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"均方误差: {mse:.4f}")
print(f"R²得分: {r2:.4f}")2.1.2 无监督学习(Unsupervised Learning)
定义:从没有标签的数据中发现隐藏的模式和结构。
特点:
- 训练数据只有输入特征,没有标签
- 目标是发现数据的内在结构
- 难以直接评估模型性能
主要任务类型:
聚类(Clustering):
- 目标:将相似的数据点分组
- 示例:客户细分、基因分析、图像分割
- 常用算法:K-means、层次聚类、DBSCAN
python
# 聚类示例:客户细分
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# 生成示例数据
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
# K-means聚类
kmeans = KMeans(n_clusters=4, random_state=42)
y_pred = kmeans.fit_predict(X)
# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=y_pred, cmap='viridis')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
c='red', marker='x', s=200, linewidths=3)
plt.title('K-means聚类结果')
plt.show()降维(Dimensionality Reduction):
- 目标:减少数据的维度,保留重要信息
- 示例:数据可视化、特征选择、噪声去除
- 常用算法:PCA、t-SNE、LDA
python
# 降维示例:PCA降维
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
# 加载数据
digits = load_digits()
X = digits.data
# PCA降维
pca = PCA(n_components=2)
X_reduced = pca.fit_transform(X)
# 可视化
plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=digits.target, cmap='tab10')
plt.colorbar(scatter)
plt.title('PCA降维可视化')
plt.xlabel('第一主成分')
plt.ylabel('第二主成分')
plt.show()关联规则挖掘:
- 目标:发现数据项之间的关联关系
- 示例:购物篮分析、网页访问模式
- 常用算法:Apriori、FP-Growth
2.1.3 强化学习(Reinforcement Learning)
定义:通过与环境交互,学习在特定情况下采取何种行动以获得最大奖励。
特点:
- 没有直接的监督信号,只有奖励信号
- 需要在探索和利用之间平衡
- 适用于序列决策问题
应用示例:
- 游戏AI(AlphaGo、Dota2 AI)
- 自动驾驶
- 机器人控制
- 推荐系统优化
python
# 强化学习示例:Q-learning解决迷宫问题
import numpy as np
import random
class QLearningAgent:
def __init__(self, states, actions, learning_rate=0.1, discount_factor=0.9, epsilon=0.1):
self.states = states
self.actions = actions
self.lr = learning_rate
self.gamma = discount_factor
self.epsilon = epsilon
self.q_table = np.zeros((states, actions))
def choose_action(self, state):
if random.uniform(0, 1) < self.epsilon:
return random.choice(range(self.actions)) # 探索
else:
return np.argmax(self.q_table[state]) # 利用
def update_q_table(self, state, action, reward, next_state):
current_q = self.q_table[state, action]
max_next_q = np.max(self.q_table[next_state])
new_q = current_q + self.lr * (reward + self.gamma * max_next_q - current_q)
self.q_table[state, action] = new_q
# 使用示例
agent = QLearningAgent(states=16, actions=4) # 4x4迷宫,4个动作
print("Q-learning智能体已创建")2.2 按算法类型分类
2.2.1 参数化方法
- 特点:假设数据符合特定的概率分布
- 优点:计算效率高,理论基础扎实
- 缺点:可能不适合复杂的非线性关系
- 示例:线性回归、逻辑回归、朴素贝叶斯
2.2.2 非参数化方法
- 特点:不对数据分布做强假设
- 优点:灵活性高,适应性强
- 缺点:计算复杂度较高
- 示例:K近邻、决策树、核方法
2.2.3 集成方法
- 特点:结合多个基础模型的预测结果
- 优点:通常具有更好的泛化能力
- 缺点:模型复杂度高,解释性差
- 示例:随机森林、梯度提升、AdaBoost
3. 机器学习的核心概念
3.1 特征工程
特征工程是机器学习中最重要的环节之一,好的特征往往比复杂的算法更重要。
3.1.1 特征选择
目标:从原始特征中选择最相关的特征子集。
方法:
- 过滤法:基于统计指标选择特征
- 包装法:基于模型性能选择特征
- 嵌入法:在模型训练过程中选择特征
python
# 特征选择示例
from sklearn.feature_selection import SelectKBest, chi2, RFE
from sklearn.ensemble import RandomForestClassifier
# 过滤法:卡方检验
selector = SelectKBest(chi2, k=10)
X_selected = selector.fit_transform(X, y)
# 包装法:递归特征消除
estimator = RandomForestClassifier(n_estimators=100)
rfe = RFE(estimator, n_features_to_select=10)
X_rfe = rfe.fit_transform(X, y)
print(f"原始特征数: {X.shape[1]}")
print(f"选择后特征数: {X_selected.shape[1]}")3.1.2 特征构造
数值特征处理:
python
# 数值特征处理示例
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
# 标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 归一化
normalizer = MinMaxScaler()
X_normalized = normalizer.fit_transform(X)
# 鲁棒缩放
robust_scaler = RobustScaler()
X_robust = robust_scaler.fit_transform(X)类别特征处理:
python
# 类别特征处理示例
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
import pandas as pd
# 标签编码
le = LabelEncoder()
categorical_encoded = le.fit_transform(categorical_data)
# 独热编码
ohe = OneHotEncoder(sparse=False)
categorical_onehot = ohe.fit_transform(categorical_data.reshape(-1, 1))
# 使用pandas进行独热编码
df_encoded = pd.get_dummies(df, columns=['category_column'])3.2 模型评估
3.2.1 分类问题评估指标
混淆矩阵:
python
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
# 计算混淆矩阵
cm = confusion_matrix(y_test, y_pred)
# 可视化混淆矩阵
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('混淆矩阵')
plt.ylabel('真实标签')
plt.xlabel('预测标签')
plt.show()
# 详细分类报告
print(classification_report(y_test, y_pred))主要指标:
- 准确率(Accuracy):正确预测的比例
- 精确率(Precision):预测为正例中实际为正例的比例
- 召回率(Recall):实际正例中被正确预测的比例
- F1分数:精确率和召回率的调和平均数
python
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred, average='weighted')
recall = recall_score(y_test, y_pred, average='weighted')
f1 = f1_score(y_test, y_pred, average='weighted')
print(f"准确率: {accuracy:.4f}")
print(f"精确率: {precision:.4f}")
print(f"召回率: {recall:.4f}")
print(f"F1分数: {f1:.4f}")3.2.2 回归问题评估指标
python
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np
# 主要回归指标
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"平均绝对误差 (MAE): {mae:.4f}")
print(f"均方误差 (MSE): {mse:.4f}")
print(f"均方根误差 (RMSE): {rmse:.4f}")
print(f"决定系数 (R²): {r2:.4f}")3.3 交叉验证
交叉验证是评估模型泛化能力的重要方法。
python
from sklearn.model_selection import cross_val_score, StratifiedKFold
# K折交叉验证
cv_scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
print(f"交叉验证得分: {cv_scores}")
print(f"平均得分: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})")
# 分层K折交叉验证(适用于不平衡数据)
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
stratified_scores = cross_val_score(clf, X, y, cv=skf, scoring='accuracy')
print(f"分层交叉验证得分: {stratified_scores.mean():.4f}")3.4 过拟合与欠拟合
3.4.1 概念理解
过拟合(Overfitting):
- 模型在训练数据上表现很好,但在测试数据上表现较差
- 模型过于复杂,学习了训练数据中的噪声
欠拟合(Underfitting):
- 模型在训练数据和测试数据上都表现较差
- 模型过于简单,无法捕捉数据中的模式
3.4.2 诊断方法
python
# 学习曲线诊断
from sklearn.model_selection import learning_curve
def plot_learning_curve(estimator, X, y, title="学习曲线"):
train_sizes, train_scores, val_scores = learning_curve(
estimator, X, y, cv=5, n_jobs=-1,
train_sizes=np.linspace(0.1, 1.0, 10))
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
val_mean = np.mean(val_scores, axis=1)
val_std = np.std(val_scores, axis=1)
plt.figure(figsize=(10, 6))
plt.plot(train_sizes, train_mean, 'o-', color='blue', label='训练得分')
plt.fill_between(train_sizes, train_mean - train_std, train_mean + train_std, alpha=0.1, color='blue')
plt.plot(train_sizes, val_mean, 'o-', color='red', label='验证得分')
plt.fill_between(train_sizes, val_mean - val_std, val_mean + val_std, alpha=0.1, color='red')
plt.xlabel('训练样本数')
plt.ylabel('得分')
plt.title(title)
plt.legend()
plt.grid(True)
plt.show()
# 使用示例
plot_learning_curve(RandomForestClassifier(), X, y)3.4.3 解决方法
解决过拟合:
- 增加训练数据
- 特征选择
- 正则化
- 早停法
- 集成方法
python
# 正则化示例:岭回归
from sklearn.linear_model import Ridge, RidgeCV
# 岭回归(L2正则化)
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
# 交叉验证选择最佳alpha
ridge_cv = RidgeCV(alphas=[0.1, 1.0, 10.0, 100.0], cv=5)
ridge_cv.fit(X_train, y_train)
print(f"最佳alpha: {ridge_cv.alpha_}")解决欠拟合:
- 增加模型复杂度
- 添加更多特征
- 减少正则化强度
- 使用更复杂的算法
4. 常用机器学习算法
4.1 线性模型
4.1.1 线性回归
python
# 线性回归实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
class SimpleLinearRegression:
def __init__(self):
self.slope = None
self.intercept = None
def fit(self, X, y):
# 计算斜率和截距
n = len(X)
self.slope = (n * np.sum(X * y) - np.sum(X) * np.sum(y)) / (n * np.sum(X**2) - (np.sum(X))**2)
self.intercept = (np.sum(y) - self.slope * np.sum(X)) / n
def predict(self, X):
return self.slope * X + self.intercept
# 使用示例
X = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])
model = SimpleLinearRegression()
model.fit(X, y)
predictions = model.predict(X)
plt.scatter(X, y, color='blue', label='实际值')
plt.plot(X, predictions, color='red', label='预测值')
plt.legend()
plt.title('简单线性回归')
plt.show()4.1.2 逻辑回归
python
# 逻辑回归示例
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
# 生成二分类数据
X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0,
n_informative=2, n_clusters_per_class=1, random_state=42)
# 训练逻辑回归模型
log_reg = LogisticRegression()
log_reg.fit(X, y)
# 可视化决策边界
def plot_decision_boundary(X, y, model, title="决策边界"):
plt.figure(figsize=(10, 8))
# 创建网格
h = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
# 预测网格点
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策边界
plt.contourf(xx, yy, Z, alpha=0.8, cmap=plt.cm.RdYlBu)
scatter = plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.RdYlBu, edgecolors='black')
plt.colorbar(scatter)
plt.title(title)
plt.show()
plot_decision_boundary(X, y, log_reg, "逻辑回归决策边界")4.2 树模型
4.2.1 决策树
python
# 决策树示例
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.datasets import load_iris
# 加载数据
iris = load_iris()
X, y = iris.data[:, [2, 3]], iris.target # 只使用两个特征便于可视化
# 训练决策树
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(X, y)
# 可视化决策树
plt.figure(figsize=(15, 10))
plot_tree(dt, feature_names=['花瓣长度', '花瓣宽度'],
class_names=iris.target_names, filled=True, rounded=True)
plt.title('鸢尾花分类决策树')
plt.show()
# 特征重要性
feature_importance = dt.feature_importances_
print("特征重要性:")
for i, importance in enumerate(feature_importance):
print(f"特征 {i}: {importance:.4f}")4.2.2 随机森林
python
# 随机森林示例
from sklearn.ensemble import RandomForestClassifier
# 训练随机森林
rf = RandomForestClassifier(n_estimators=100, max_depth=3, random_state=42)
rf.fit(X_train, y_train)
# 预测和评估
y_pred_rf = rf.predict(X_test)
accuracy_rf = accuracy_score(y_test, y_pred_rf)
print(f"随机森林准确率: {accuracy_rf:.4f}")
# 特征重要性
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(10, 6))
plt.title("特征重要性排序")
plt.bar(range(len(importances)), importances[indices])
plt.xticks(range(len(importances)), [f"特征 {i}" for i in indices])
plt.show()4.3 支持向量机
python
# SVM示例
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
# 数据标准化(SVM对特征尺度敏感)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 训练SVM模型
svm_linear = SVC(kernel='linear', random_state=42)
svm_rbf = SVC(kernel='rbf', random_state=42)
svm_linear.fit(X_train_scaled, y_train)
svm_rbf.fit(X_train_scaled, y_train)
# 比较不同核函数的性能
y_pred_linear = svm_linear.predict(X_test_scaled)
y_pred_rbf = svm_rbf.predict(X_test_scaled)
print(f"线性核SVM准确率: {accuracy_score(y_test, y_pred_linear):.4f}")
print(f"RBF核SVM准确率: {accuracy_score(y_test, y_pred_rbf):.4f}")4.4 K近邻算法
python
# KNN示例
from sklearn.neighbors import KNeighborsClassifier
# 不同k值的性能比较
k_values = range(1, 21)
accuracies = []
for k in k_values:
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
accuracies.append(accuracy_score(y_test, y_pred))
# 可视化k值对性能的影响
plt.figure(figsize=(10, 6))
plt.plot(k_values, accuracies, 'bo-')
plt.xlabel('k值')
plt.ylabel('准确率')
plt.title('KNN算法中k值对性能的影响')
plt.grid(True)
plt.show()
# 选择最佳k值
best_k = k_values[np.argmax(accuracies)]
print(f"最佳k值: {best_k}, 对应准确率: {max(accuracies):.4f}")5. 机器学习项目流程
5.1 问题定义
- 明确业务目标:确定要解决的具体问题
- 确定问题类型:分类、回归、聚类等
- 定义成功指标:准确率、召回率、业务指标等
- 评估可行性:数据可用性、技术难度、资源需求
5.2 数据收集与探索
python
# 数据探索示例
import pandas as pd
import seaborn as sns
# 加载数据
df = pd.read_csv('data.csv')
# 基本信息
print("数据基本信息:")
print(df.info())
print("\n数据描述统计:")
print(df.describe())
# 缺失值检查
print("\n缺失值统计:")
print(df.isnull().sum())
# 数据分布可视化
plt.figure(figsize=(15, 10))
for i, column in enumerate(df.select_dtypes(include=[np.number]).columns):
plt.subplot(2, 3, i+1)
plt.hist(df[column], bins=30, alpha=0.7)
plt.title(f'{column} 分布')
plt.xlabel(column)
plt.ylabel('频次')
plt.tight_layout()
plt.show()
# 相关性分析
plt.figure(figsize=(10, 8))
correlation_matrix = df.corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('特征相关性热力图')
plt.show()5.3 数据预处理
python
# 完整的数据预处理流程
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.impute import SimpleImputer
class DataPreprocessor:
def __init__(self):
self.scalers = {}
self.encoders = {}
self.imputers = {}
def fit_transform(self, df):
df_processed = df.copy()
# 处理数值特征
numeric_columns = df.select_dtypes(include=[np.number]).columns
for col in numeric_columns:
# 处理缺失值
imputer = SimpleImputer(strategy='median')
df_processed[col] = imputer.fit_transform(df_processed[[col]]).ravel()
self.imputers[col] = imputer
# 标准化
scaler = StandardScaler()
df_processed[col] = scaler.fit_transform(df_processed[[col]]).ravel()
self.scalers[col] = scaler
# 处理类别特征
categorical_columns = df.select_dtypes(include=['object']).columns
for col in categorical_columns:
# 处理缺失值
df_processed[col].fillna(df_processed[col].mode()[0], inplace=True)
# 标签编码
encoder = LabelEncoder()
df_processed[col] = encoder.fit_transform(df_processed[col])
self.encoders[col] = encoder
return df_processed
def transform(self, df):
df_processed = df.copy()
# 应用已训练的预处理器
for col in df.select_dtypes(include=[np.number]).columns:
if col in self.imputers:
df_processed[col] = self.imputers[col].transform(df_processed[[col]]).ravel()
if col in self.scalers:
df_processed[col] = self.scalers[col].transform(df_processed[[col]]).ravel()
for col in df.select_dtypes(include=['object']).columns:
if col in self.encoders:
df_processed[col].fillna(df_processed[col].mode()[0], inplace=True)
df_processed[col] = self.encoders[col].transform(df_processed[col])
return df_processed
# 使用示例
preprocessor = DataPreprocessor()
df_processed = preprocessor.fit_transform(df)5.4 模型选择与训练
python
# 多模型比较
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
# 定义多个模型
models = {
'Logistic Regression': LogisticRegression(random_state=42),
'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
'SVM': SVC(random_state=42),
'Gradient Boosting': GradientBoostingClassifier(random_state=42)
}
# 比较模型性能
results = {}
for name, model in models.items():
cv_scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')
results[name] = {
'mean': cv_scores.mean(),
'std': cv_scores.std()
}
print(f"{name}: {cv_scores.mean():.4f} (+/- {cv_scores.std() * 2:.4f})")
# 选择最佳模型
best_model_name = max(results, key=lambda x: results[x]['mean'])
best_model = models[best_model_name]
print(f"\n最佳模型: {best_model_name}")5.5 超参数调优
python
# 网格搜索调优
from sklearn.model_selection import GridSearchCV
# 定义参数网格
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 7, None],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# 网格搜索
rf = RandomForestClassifier(random_state=42)
grid_search = GridSearchCV(rf, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid_search.fit(X_train, y_train)
print(f"最佳参数: {grid_search.best_params_}")
print(f"最佳得分: {grid_search.best_score_:.4f}")
# 使用最佳模型
best_rf = grid_search.best_estimator_5.6 模型评估与部署
python
# 最终模型评估
final_predictions = best_rf.predict(X_test)
final_accuracy = accuracy_score(y_test, final_predictions)
print(f"最终测试准确率: {final_accuracy:.4f}")
print("\n详细分类报告:")
print(classification_report(y_test, final_predictions))
# 模型保存
import joblib
# 保存模型
joblib.dump(best_rf, 'best_model.pkl')
joblib.dump(preprocessor, 'preprocessor.pkl')
# 加载模型
loaded_model = joblib.load('best_model.pkl')
loaded_preprocessor = joblib.load('preprocessor.pkl')
print("模型已保存并可以重新加载使用")6. 实际应用案例
6.1 客户流失预测
python
# 客户流失预测完整案例
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, roc_auc_score, roc_curve
# 模拟客户数据
np.random.seed(42)
n_customers = 1000
data = {
'age': np.random.randint(18, 80, n_customers),
'tenure': np.random.randint(1, 60, n_customers),
'monthly_charges': np.random.uniform(20, 120, n_customers),
'total_charges': np.random.uniform(100, 8000, n_customers),
'contract_type': np.random.choice(['Month-to-month', 'One year', 'Two year'], n_customers),
'payment_method': np.random.choice(['Electronic check', 'Mailed check', 'Bank transfer', 'Credit card'], n_customers),
'internet_service': np.random.choice(['DSL', 'Fiber optic', 'No'], n_customers),
}
# 创建目标变量(流失标签)
churn_probability = (
0.1 +
0.3 * (data['contract_type'] == 'Month-to-month') +
0.2 * (data['monthly_charges'] > 80) +
0.1 * (data['tenure'] < 12) +
0.1 * (data['payment_method'] == 'Electronic check')
)
data['churn'] = np.random.binomial(1, churn_probability, n_customers)
df = pd.DataFrame(data)
# 数据预处理
df_encoded = pd.get_dummies(df, columns=['contract_type', 'payment_method', 'internet_service'])
# 分离特征和目标
X = df_encoded.drop('churn', axis=1)
y = df_encoded['churn']
# 分割数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# 训练模型
rf_churn = RandomForestClassifier(n_estimators=100, random_state=42)
rf_churn.fit(X_train, y_train)
# 预测和评估
y_pred = rf_churn.predict(X_test)
y_pred_proba = rf_churn.predict_proba(X_test)[:, 1]
print("客户流失预测结果:")
print(classification_report(y_test, y_pred))
print(f"AUC得分: {roc_auc_score(y_test, y_pred_proba):.4f}")
# ROC曲线
fpr, tpr, _ = roc_curve(y_test, y_pred_proba)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, label=f'ROC曲线 (AUC = {roc_auc_score(y_test, y_pred_proba):.4f})')
plt.plot([0, 1], [0, 1], 'k--', label='随机分类器')
plt.xlabel('假正率')
plt.ylabel('真正率')
plt.title('ROC曲线 - 客户流失预测')
plt.legend()
plt.show()
# 特征重要性分析
feature_importance = pd.DataFrame({
'feature': X.columns,
'importance': rf_churn.feature_importances_
}).sort_values('importance', ascending=False)
plt.figure(figsize=(10, 6))
plt.barh(feature_importance['feature'][:10], feature_importance['importance'][:10])
plt.xlabel('重要性')
plt.title('客户流失预测 - 前10个重要特征')
plt.gca().invert_yaxis()
plt.show()6.2 房价预测
python
# 房价预测案例
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_absolute_error, mean_squared_error
# 模拟房价数据
np.random.seed(42)
n_houses = 1000
house_data = {
'area': np.random.uniform(50, 300, n_houses),
'bedrooms': np.random.randint(1, 6, n_houses),
'bathrooms': np.random.randint(1, 4, n_houses),
'age': np.random.randint(0, 50, n_houses),
'location_score': np.random.uniform(1, 10, n_houses),
'garage': np.random.choice([0, 1], n_houses),
}
# 创建房价(基于特征的线性组合加噪声)
price = (
house_data['area'] * 1000 +
house_data['bedrooms'] * 5000 +
house_data['bathrooms'] * 8000 +
(50 - house_data['age']) * 500 +
house_data['location_score'] * 10000 +
house_data['garage'] * 15000 +
np.random.normal(0, 20000, n_houses)
)
house_data['price'] = np.maximum(price, 50000) # 确保价格为正
df_house = pd.DataFrame(house_data)
# 数据分割
X_house = df_house.drop('price', axis=1)
y_house = df_house['price']
X_train_house, X_test_house, y_train_house, y_test_house = train_test_split(
X_house, y_house, test_size=0.2, random_state=42
)
# 训练梯度提升回归模型
gbr = GradientBoostingRegressor(n_estimators=100, random_state=42)
gbr.fit(X_train_house, y_train_house)
# 预测和评估
y_pred_house = gbr.predict(X_test_house)
mae = mean_absolute_error(y_test_house, y_pred_house)
mse = mean_squared_error(y_test_house, y_pred_house)
rmse = np.sqrt(mse)
print("房价预测结果:")
print(f"平均绝对误差: ${mae:,.2f}")
print(f"均方根误差: ${rmse:,.2f}")
# 预测vs实际值散点图
plt.figure(figsize=(10, 8))
plt.scatter(y_test_house, y_pred_house, alpha=0.6)
plt.plot([y_test_house.min(), y_test_house.max()],
[y_test_house.min(), y_test_house.max()], 'r--', lw=2)
plt.xlabel('实际房价')
plt.ylabel('预测房价')
plt.title('房价预测:实际值 vs 预测值')
plt.show()
# 残差分析
residuals = y_test_house - y_pred_house
plt.figure(figsize=(10, 6))
plt.scatter(y_pred_house, residuals, alpha=0.6)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('预测房价')
plt.ylabel('残差')
plt.title('残差分析')
plt.show()7. 最佳实践与建议
7.1 数据质量
- 数据收集:确保数据的代表性和完整性
- 数据清洗:处理缺失值、异常值和重复数据
- 数据验证:检查数据的一致性和合理性
- 数据更新:建立数据更新机制,保持数据的时效性
7.2 特征工程
- 领域知识:结合业务理解创建有意义的特征
- 特征选择:去除冗余和无关特征
- 特征变换:标准化、归一化、对数变换等
- 特征组合:创建交互特征和多项式特征
7.3 模型选择
- 简单优先:从简单模型开始,逐步增加复杂度
- 多模型比较:尝试不同类型的算法
- 集成方法:结合多个模型的优势
- 领域适配:选择适合特定领域的算法
7.4 模型评估
- 多指标评估:不要只关注单一指标
- 交叉验证:使用适当的验证策略
- 业务指标:关注对业务有意义的指标
- 模型解释:理解模型的决策过程
7.5 部署与监控
- 模型版本管理:跟踪模型的版本和变更
- 性能监控:持续监控模型在生产环境中的表现
- 数据漂移检测:监控输入数据的分布变化
- 模型更新:建立模型重训练和更新机制
