3. Scikit-learn 实践应用


文档摘要

Scikit-learn 实践应用 Scikit-learn 实践应用详解 引言 Scikit-learn (也称为 ) 是 Python 中最受欢迎和强大的机器学习库之一。它建立在 NumPy, SciPy 和 matplotlib 之上,提供了丰富的工具和算法,用于分类、回归、聚类、降维、模型选择和预处理等任务。Scikit-learn 以其简洁的 API、完善的文档和广泛的应用场景,成为了机器学习实践者的首选工具。 1. 数据预处理:为模型构建坚实基础 在机器学习项目中,数据预处理是至关重要的第一步。原始数据往往包含噪声、缺失值、不一致的格式等问题,直接使用这些数据训练模型往往会导致模型性能下降甚至失效。

3. Scikit-learn 实践应用

Scikit-learn 实践应用详解

引言

Scikit-learn (也称为 sklearn) 是 Python 中最受欢迎和强大的机器学习库之一。它建立在 NumPy, SciPy 和 matplotlib 之上,提供了丰富的工具和算法,用于分类、回归、聚类、降维、模型选择和预处理等任务。Scikit-learn 以其简洁的 API、完善的文档和广泛的应用场景,成为了机器学习实践者的首选工具。

1. 数据预处理:为模型构建坚实基础

在机器学习项目中,数据预处理是至关重要的第一步。原始数据往往包含噪声、缺失值、不一致的格式等问题,直接使用这些数据训练模型往往会导致模型性能下降甚至失效。Scikit-learn 提供了丰富的预处理工具,帮助我们清洗和转换数据,使其更适合机器学习模型的训练。

1.1 数据标准化与归一化

数据标准化(Standardization)和归一化(Normalization)是常用的数据缩放技术,旨在将不同特征的数据缩放到相似的范围,避免某些特征因数值过大而主导模型训练,从而提高模型的稳定性和收敛速度。

  • 标准化 (StandardScaler): 将数据转换为均值为 0,标准差为 1 的分布。
from sklearn.preprocessing import StandardScaler import numpy as np # 示例数据 data = np.array([[1, 2], [3, 4], [5, 6]]) # 初始化 StandardScaler scaler = StandardScaler() # 拟合数据并进行转换 scaled_data = scaler.fit_transform(data) print("原始数据:\n", data) print("标准化后的数据:\n", scaled_data)

代码详解:

  1. from sklearn.preprocessing import StandardScaler: 导入 StandardScaler 类。

  2. data = np.array([[1, 2], [3, 4], [5, 6]]): 创建一个 NumPy 数组作为示例数据,包含两个特征。

  3. scaler = StandardScaler(): 初始化 StandardScaler 对象。

  4. scaled_data = scaler.fit_transform(data): fit_transform() 方法先拟合数据(计算均值和标准差),然后使用计算出的均值和标准差对数据进行标准化转换。

  5. print(...): 打印原始数据和标准化后的数据,观察数据变化。

  • 归一化 (MinMaxScaler): 将数据缩放到指定的范围,通常是 [0, 1] 或 [-1, 1]。
from sklearn.preprocessing import MinMaxScaler # 示例数据 (与上方相同) data = np.array([[1, 2], [3, 4], [5, 6]]) # 初始化 MinMaxScaler min_max_scaler = MinMaxScaler() # 拟合数据并进行转换 normalized_data = min_max_scaler.fit_transform(data) print("原始数据:\n", data) print("归一化后的数据:\n", normalized_data)

代码详解:

代码结构与 StandardScaler 类似,只是将 StandardScaler 替换为 MinMaxScalerMinMaxScaler 会将数据缩放到 [0, 1] 范围内。

1.2 独热编码 (OneHotEncoder)

独热编码用于处理类别型特征。它将类别型特征转换为数值型,为每个类别创建一个新的二进制特征列,如果样本属于该类别,则对应列的值为 1,否则为 0。

from sklearn.preprocessing import OneHotEncoder # 示例类别型数据 categorical_data = np.array([['red'], ['blue'], ['green'], ['red']]) # 初始化 OneHotEncoder encoder = OneHotEncoder() # 拟合数据并进行转换 one_hot_encoded_data = encoder.fit_transform(categorical_data).toarray() print("原始类别型数据:\n", categorical_data) print("独热编码后的数据:\n", one_hot_encoded_data) print("类别名称:", encoder.categories_)

代码详解:

  1. from sklearn.preprocessing import OneHotEncoder: 导入 OneHotEncoder 类。

  2. categorical_data = np.array([['red'], ['blue'], ['green'], ['red']]): 创建一个 NumPy 数组作为示例类别型数据。

  3. encoder = OneHotEncoder(): 初始化 OneHotEncoder 对象。

  4. one_hot_encoded_data = encoder.fit_transform(categorical_data).toarray(): fit_transform() 方法拟合数据(识别所有类别),然后进行独热编码转换。.toarray() 将稀疏矩阵转换为 NumPy 数组。

  5. print(...): 打印原始数据、独热编码后的数据和类别名称。encoder.categories_ 属性可以查看编码器识别出的类别。

1.3 缺失值处理 (SimpleImputer)

实际数据中经常存在缺失值。SimpleImputer 类提供了多种策略来填充缺失值,例如使用均值、中位数、众数或常数。

from sklearn.impute import SimpleImputer import numpy as np # 示例数据,包含缺失值 (NaN) data_with_missing = np.array([[1, np.nan, 3], [4, 5, np.nan], [np.nan, 8, 9]]) # 使用均值填充缺失值 imputer_mean = SimpleImputer(strategy='mean') data_imputed_mean = imputer_mean.fit_transform(data_with_missing) print("使用均值填充后的数据:\n", data_imputed_mean) # 使用中位数填充缺失值 imputer_median = SimpleImputer(strategy='median') data_imputed_median = imputer_median.fit_transform(data_with_missing) print("使用中位数填充后的数据:\n", data_imputed_median) # 使用常数填充缺失值 (例如,用 0 填充) imputer_constant = SimpleImputer(strategy='constant', fill_value=0) data_imputed_constant = imputer_constant.fit_transform(data_with_missing) print("使用常数 (0) 填充后的数据:\n", data_imputed_constant)

代码详解:

  1. from sklearn.impute import SimpleImputer: 导入 SimpleImputer 类。

  2. data_with_missing = ...: 创建包含 np.nan (Not a Number) 的示例数据,表示缺失值。

  3. imputer_mean = SimpleImputer(strategy='mean'): 初始化 SimpleImputer 对象,设置 strategy='mean' 表示使用均值填充。

  4. data_imputed_mean = imputer_mean.fit_transform(data_with_missing): 拟合数据并进行缺失值填充。

  5. 类似地,创建 imputer_medianimputer_constant 对象,分别使用中位数和常数填充缺失值。

  6. print(...): 打印填充后的数据,比较不同填充策略的效果。

2. 模型选择:找到最合适的算法

Scikit-learn 提供了大量的机器学习算法,涵盖分类、回归、聚类、降维等多个领域。模型选择的关键在于根据实际问题的特点和数据特性,选择最合适的算法。

2.1 分类模型

分类模型用于预测样本所属的类别。Scikit-learn 提供了多种分类算法,例如:

  • 逻辑回归 (Logistic Regression): 线性模型,用于二分类和多分类问题。

  • 支持向量机 (Support Vector Machine, SVM): 强大的分类器,在高维空间中表现良好。

  • 决策树 (Decision Tree): 基于树结构的分类器,易于理解和解释。

  • 随机森林 (Random Forest): 集成学习算法,由多个决策树组成,具有较高的准确率和鲁棒性。

  • K 近邻 (K-Nearest Neighbors, KNN): 基于实例的学习算法,根据邻近样本的类别进行预测。

示例:使用逻辑回归进行分类

我们使用 Scikit-learn 内置的 iris 数据集进行演示,这是一个经典的多分类数据集,包含三种鸢尾花 (setosa, versicolor, virginica) 的特征数据。

from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report, confusion_matrix # 加载 iris 数据集 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.3, random_state=42) # 初始化逻辑回归模型 logreg = LogisticRegression(max_iter=1000) # 增加 max_iter 以确保收敛 # 训练模型 logreg.fit(X_train, y_train) # 预测测试集 y_pred = logreg.predict(X_test) # 评估模型 accuracy = accuracy_score(y_test, y_pred) print(f"准确率: {accuracy:.2f}") print("\n分类报告:\n", classification_report(y_test, y_pred)) print("\n混淆矩阵:\n", confusion_matrix(y_test, y_pred))

代码详解:

  1. from sklearn.datasets import load_iris: 导入 load_iris 函数加载数据集。

  2. from sklearn.model_selection import train_test_split: 导入 train_test_split 函数划分数据集。

  3. from sklearn.linear_model import LogisticRegression: 导入 LogisticRegression 类。

  4. from sklearn.metrics import accuracy_score, classification_report, confusion_matrix: 导入评估指标函数。

  5. iris = load_iris(): 加载 iris 数据集。

  6. X, y = iris.data, iris.target: 获取特征数据 X 和目标变量 y

  7. X_train, X_test, y_train, y_test = train_test_split(...): 将数据集划分为训练集和测试集,test_size=0.3 表示测试集占 30%,random_state=42 设置随机种子以保证结果可复现。

  8. logreg = LogisticRegression(max_iter=1000): 初始化逻辑回归模型,max_iter 设置最大迭代次数。

  9. logreg.fit(X_train, y_train): 使用训练集训练模型。

  10. y_pred = logreg.predict(X_test): 使用训练好的模型预测测试集。

  11. accuracy = accuracy_score(y_test, y_pred): 计算准确率。

  12. print(...): 打印准确率、分类报告(包含精确率、召回率、F1-score 等)和混淆矩阵,全面评估模型性能。

2.2 回归模型

回归模型用于预测连续型的目标变量。Scikit-learn 提供了多种回归算法,例如:

  • 线性回归 (Linear Regression): 最基本的回归模型,假设特征与目标变量之间存在线性关系。

  • 岭回归 (Ridge Regression): 带有 L2 正则化的线性回归,可以防止过拟合。

  • Lasso 回归 (Lasso Regression): 带有 L1 正则化的线性回归,可以进行特征选择。

  • 决策树回归 (Decision Tree Regressor): 基于树结构的回归模型。

  • 随机森林回归 (Random Forest Regressor): 集成学习算法,由多个决策树回归器组成。

示例:使用线性回归进行回归

我们使用 Scikit-learn 内置的 boston 房价数据集进行演示。

from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error, r2_score # 加载 boston 数据集 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.3, random_state=42) # 初始化线性回归模型 linreg = LinearRegression() # 训练模型 linreg.fit(X_train, y_train) # 预测测试集 y_pred = linreg.predict(X_test) # 评估模型 mse = mean_squared_error(y_test, y_pred) r2 = r2_score(y_test, y_pred) print(f"均方误差 (MSE): {mse:.2f}") print(f"R 平方值 (R^2): {r2:.2f}")

代码详解:

代码结构与分类示例类似,主要区别在于:

  1. 导入的算法和评估指标不同:LinearRegression 用于回归,mean_squared_errorr2_score 是常用的回归评估指标。

  2. 评估指标解释:

    • 均方误差 (MSE): 预测值与真实值之差的平方的平均值,值越小越好。

    • R 平方值 (R^2): 衡量模型拟合优度的指标,取值范围为 [0, 1],越接近 1 表示模型拟合得越好。

2.3 聚类模型

聚类模型用于将数据样本划分为不同的簇,使得同一簇内的样本彼此相似,不同簇之间的样本差异较大。Scikit-learn 提供了多种聚类算法,例如:

  • K-均值 (K-Means): 经典的聚类算法,将数据划分为 K 个簇。

  • DBSCAN (Density-Based Spatial Clustering of Applications with Noise): 基于密度的聚类算法,可以发现任意形状的簇,并能识别噪声点。

  • 层次聚类 (Agglomerative Clustering): 自底向上的聚类算法,逐步合并簇。

示例:使用 K-Means 进行聚类

我们使用 Scikit-learn 内置的 iris 数据集,忽略其真实标签,进行聚类。

from sklearn.datasets import load_iris from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score import matplotlib.pyplot as plt # 加载 iris 数据集 iris = load_iris() X = iris.data # 只使用特征数据,忽略标签 # 使用 K-Means 聚类,假设分为 3 簇 kmeans = KMeans(n_clusters=3, random_state=42) kmeans.fit(X) # 获取簇标签 labels = kmeans.labels_ # 评估聚类效果 (轮廓系数) silhouette_avg = silhouette_score(X, labels) print(f"轮廓系数: {silhouette_avg:.2f}") # 可视化聚类结果 (仅适用于低维数据,这里使用前两个特征) plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis') plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red', marker='X', label='Centroids') # 簇中心 plt.title('K-Means Clustering (Iris Dataset)') plt.xlabel('Feature 1') plt.ylabel('Feature 2') plt.legend() plt.show()

代码详解:

  1. from sklearn.cluster import KMeans: 导入 KMeans 类。

  2. from sklearn.metrics import silhouette_score: 导入 silhouette_score 函数评估聚类效果。

  3. X = iris.data: 只使用特征数据 X 进行聚类,忽略真实标签。

  4. kmeans = KMeans(n_clusters=3, random_state=42): 初始化 KMeans 对象,n_clusters=3 表示聚类数为 3,random_state=42 设置随机种子。

  5. kmeans.fit(X): 训练 K-Means 模型。

  6. labels = kmeans.labels_: 获取每个样本的簇标签。

  7. silhouette_avg = silhouette_score(X, labels): 计算轮廓系数,评估聚类效果。轮廓系数取值范围为 [-1, 1],值越接近 1 表示聚类效果越好。

  8. plt.scatter(...): 使用 matplotlib 可视化聚类结果,不同颜色代表不同的簇,红色的 'X' 标记表示簇中心。

3. 模型评估与优化:提升模型性能

模型评估和优化是机器学习流程中不可或缺的环节。评估模型的性能,可以了解模型是否有效,以及在哪些方面需要改进。模型优化则旨在通过调整模型参数、选择更合适的算法或进行特征工程等方法,进一步提升模型性能。

3.1 交叉验证 (Cross-validation)

交叉验证是一种常用的模型评估技术,可以更可靠地评估模型的泛化能力。它将数据集划分为 K 个子集(通常称为折叠),轮流使用其中 K-1 个子集作为训练集,剩余的 1 个子集作为验证集,重复 K 次。最终的模型性能评估结果是 K 次验证结果的平均值。

Scikit-learn 提供了 cross_val_score 函数进行交叉验证。

from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression from sklearn.datasets import load_iris iris = load_iris() X, y = iris.data, iris.target logreg = LogisticRegression(max_iter=1000) # 使用 5 折交叉验证评估逻辑回归模型 scores = cross_val_score(logreg, X, y, cv=5, scoring='accuracy') # cv=5 表示 5 折交叉验证,scoring='accuracy' 指定评估指标为准确率 print("交叉验证得分:", scores) print("平均交叉验证得分:", scores.mean())

代码详解:

  1. from sklearn.model_selection import cross_val_score: 导入 cross_val_score 函数。

  2. scores = cross_val_score(logreg, X, y, cv=5, scoring='accuracy'): 使用 5 折交叉验证评估 logreg 模型,返回每次验证的得分。

  3. print(...): 打印每次验证的得分和平均得分。平均交叉验证得分更可靠地反映了模型的泛化能力。

3.2 网格搜索 (GridSearchCV) 与 超参数调优

机器学习模型通常包含一些超参数,例如逻辑回归的正则化强度、SVM 的核函数类型等。超参数的选择对模型性能有重要影响。网格搜索是一种常用的超参数调优方法。它预先定义一组超参数的候选值,然后遍历所有可能的超参数组合,使用交叉验证评估每种组合的模型性能,最终选择性能最佳的超参数组合。

Scikit-learn 提供了 GridSearchCV 类进行网格搜索。

from sklearn.model_selection import GridSearchCV from sklearn.svm import SVC from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split 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.3, random_state=42) # 定义超参数网格 param_grid = {'C': [0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1], 'kernel': ['rbf']} # 初始化 GridSearchCV 对象 grid_search = GridSearchCV(SVC(), param_grid, cv=5, scoring='accuracy') # 使用 SVC 模型,5 折交叉验证,评估指标为准确率 # 进行网格搜索 grid_search.fit(X_train, y_train) # 最佳模型和最佳参数 best_model = grid_search.best_estimator_ best_params = grid_search.best_params_ print("最佳模型:\n", best_model) print("最佳参数:\n", best_params) # 使用最佳模型评估测试集 y_pred_best = best_model.predict(X_test) accuracy_best = accuracy_score(y_test, y_pred_best) print(f"最佳模型在测试集上的准确率: {accuracy_best:.2f}")

代码详解:

  1. from sklearn.model_selection import GridSearchCV: 导入 GridSearchCV 类。

  2. from sklearn.svm import SVC: 导入 SVC 类(支持向量机分类器)。

  3. param_grid = {'C': [0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1], 'kernel': ['rbf']}: 定义超参数网格,这里针对 SVC 模型,定义了 C (正则化参数)、gamma (核函数参数) 和 kernel (核函数类型) 的候选值。

  4. grid_search = GridSearchCV(SVC(), param_grid, cv=5, scoring='accuracy'): 初始化 GridSearchCV 对象,指定要使用的模型 SVC(),超参数网格 param_grid,交叉验证折数 cv=5,评估指标 scoring='accuracy'

  5. grid_search.fit(X_train, y_train): 进行网格搜索,训练模型并评估不同超参数组合的性能。

  6. best_model = grid_search.best_estimator_: 获取最佳模型(使用最佳超参数训练的模型)。

  7. best_params = grid_search.best_params_: 获取最佳超参数组合。

  8. print(...): 打印最佳模型、最佳参数和最佳模型在测试集上的准确率。

4. Scikit-learn Pipeline:构建高效的机器学习工作流

Scikit-learn Pipeline 允许我们将多个数据处理步骤和模型训练步骤串联起来,形成一个完整的工作流。Pipeline 可以简化代码,提高代码的可读性和可维护性,并避免数据泄露等问题。

from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.datasets import load_iris from sklearn.metrics import accuracy_score # 加载 iris 数据集 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.3, random_state=42) # 创建 Pipeline pipeline = Pipeline([ ('scaler', StandardScaler()), # 数据标准化步骤 ('classifier', LogisticRegression(max_iter=1000)) # 分类器步骤 (逻辑回归) ]) # 训练 Pipeline pipeline.fit(X_train, y_train) # 预测测试集 y_pred = pipeline.predict(X_test) # 评估模型 accuracy = accuracy_score(y_test, y_pred) print(f"Pipeline 模型准确率: {accuracy:.2f}")

代码详解:

  1. from sklearn.pipeline import Pipeline: 导入 Pipeline 类。

  2. pipeline = Pipeline([...]): 创建 Pipeline 对象,传入一个步骤列表。每个步骤是一个元组,包含步骤的名称和 Scikit-learn 转换器或模型对象。

    • ('scaler', StandardScaler()): 第一个步骤命名为 'scaler',使用 StandardScaler 进行数据标准化。

    • ('classifier', LogisticRegression(max_iter=1000)): 第二个步骤命名为 'classifier',使用 LogisticRegression 分类器。

  3. pipeline.fit(X_train, y_train): 训练 Pipeline。fit() 方法会依次调用 Pipeline 中每个步骤的 fit_transform() (对于转换器) 或 fit() (对于最后一个步骤模型) 方法。

  4. y_pred = pipeline.predict(X_test): 预测测试集。predict() 方法会依次调用 Pipeline 中每个步骤的 transform() (对于转换器) 或 predict() (对于最后一个步骤模型) 方法。

结论

Scikit-learn 提供了丰富的工具和算法,可以高效地解决各种机器学习问题。本文通过详细的代码示例和解释,介绍了 Scikit-learn 在数据预处理、模型选择、模型评估和模型优化等方面的实践应用。掌握这些知识,可以帮助读者更好地利用 Scikit-learn 构建强大的机器学习模型,并应用于实际项目中。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U