scikit-learn库用法示例:Python机器学习入门到实践
scikit-learn(简称sklearn)是Python最流行的机器学习库之一,它以简洁的API、丰富的算法实现和完善的文档著称,成为机器学习初学者和从业者的首选工具。无论是分类、回归、聚类还是降维,scikit-learn都能提供高效且易用的解决方案。本文将通过具体示例,从基础概念到实战应用,带你掌握scikit-learn的核心用法,快速入门机器学习。
一、scikit-learn简介与环境准备
1. 为什么选择scikit-learn?
-
算法丰富:涵盖分类、回归、聚类、降维、模型选择等几乎所有经典机器学习算法
-
接口统一:所有算法遵循一致的API设计(
fit()训练、predict()预测),降低学习成本 -
文档完善:拥有详细的官方文档和丰富的示例,便于学习和调试
-
生态兼容:与NumPy、Pandas、Matplotlib无缝集成,形成完整的数据科学工作流
-
轻量高效:专注于机器学习任务,不依赖复杂框架,易于部署
2. 环境搭建
scikit-learn依赖于NumPy和SciPy,建议使用Anaconda环境安装,或通过pip安装:
# 基础安装(包含核心依赖)
pip install scikit-learn
# 完整安装(包含示例数据集和可视化工具)
pip install scikit-learn numpy pandas matplotlib seaborn
验证安装是否成功:
import sklearn
print(f"scikit-learn版本:{sklearn.__version__}") # 输出版本号即表示安装成功
二、核心概念与基本流程
机器学习的核心流程可以概括为:**数据准备→模型训练→评估优化→预测应用**。scikit-learn将这个流程标准化,让开发者可以专注于业务逻辑而非算法细节。
1. 数据表示
在scikit-learn中,数据通常表示为:
-
特征矩阵(X):二维数组(形状为
[n_samples, n_features]),每行是一个样本,每列是一个特征 -
标签向量(y):一维数组(形状为
[n_samples]),存储每个样本的目标值(分类任务为类别,回归任务为连续值)
2. 基本流程示例(以分类任务为例)
# 1. 导入必要的模块
from sklearn.datasets import load_iris # 数据集
from sklearn.model_selection import train_test_split # 划分训练集和测试集
from sklearn.preprocessing import StandardScaler # 特征标准化
from sklearn.ensemble import RandomForestClassifier # 模型
from sklearn.metrics import accuracy_score # 评估指标
# 2. 加载数据
data = load_iris()
X, y = data.data, data.target # 特征矩阵和标签向量
# 3. 数据预处理:划分训练集(80%)和测试集(20%)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42 # random_state确保结果可复现
)
# 4. 特征缩放(部分算法需要,如SVM、KNN)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train) # 训练集拟合并转换
X_test_scaled = scaler.transform(X_test) # 测试集使用相同的缩放规则
# 5. 初始化并训练模型
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train_scaled, y_train) # 传入训练数据和标签
# 6. 模型预测与评估
y_pred = model.predict(X_test_scaled) # 预测测试集
accuracy = accuracy_score(y_test, y_pred) # 计算准确率
print(f"模型准确率:{accuracy:.2f}") # 输出:模型准确率:1.00(鸢尾花数据集较简单)
三、数据预处理:构建高质量特征
数据预处理是机器学习的关键步骤,直接影响模型效果。scikit-learn提供了丰富的预处理工具,涵盖数据清洗、特征转换、特征选择等。
1. 数据标准化与归一化
-
标准化(Standardization):将特征转换为均值为0、标准差为1的分布(适用于正态分布特征)
-
归一化(Normalization):将特征缩放到[0,1]区间(适用于均匀分布特征)
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import numpy as np
# 示例数据
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float64)
# 标准化
scaler = StandardScaler()
data_standardized = scaler.fit_transform(data)
print("标准化后的数据:")
print(data_standardized)
print("均值:", data_standardized.mean(axis=0)) # 接近0
print("标准差:", data_standardized.std(axis=0)) # 接近1
# 归一化
minmax_scaler = MinMaxScaler()
data_normalized = minmax_scaler.fit_transform(data)
print("\n归一化后的数据:")
print(data_normalized) # 所有值在[0,1]区间
2. 处理缺失值
from sklearn.impute import SimpleImputer
import numpy as np
# 含缺失值的数据(NaN表示缺失)
data = np.array([
[1, 2, np.nan],
[4, np.nan, 6],
[7, 8, 9]
])
# 用均值填充缺失值
imputer = SimpleImputer(strategy="mean") # 可选:mean, median, most_frequent, constant
data_imputed = imputer.fit_transform(data)
print("填充缺失值后的数据:")
print(data_imputed)
3. 类别特征编码
机器学习模型通常需要数值输入,对于字符串类型的类别特征(如"红"、"蓝"),需进行编码:
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
import numpy as np
# 示例类别特征
data = np.array(["红", "蓝", "绿", "红", "蓝"]).reshape(-1, 1)
# 标签编码(适用于有序类别,如"低"、"中"、"高")
label_encoder = LabelEncoder()
data_label_encoded = label_encoder.fit_transform(data.ravel()) # 转为0,1,2...
print("标签编码结果:", data_label_encoded)
# 独热编码(适用于无序类别,如颜色、国家)
onehot_encoder = OneHotEncoder(sparse_output=False) # sparse_output=False返回稠密矩阵
data_onehot_encoded = onehot_encoder.fit_transform(data)
print("独热编码结果:")
print(data_onehot_encoded)
# 输出为:
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]
# [1. 0. 0.]
# [0. 1. 0.]]
四、常用机器学习算法示例
1. 分类算法(预测离散标签)
逻辑回归(二分类与多分类)
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 加载乳腺癌数据集(二分类任务)
data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 初始化并训练模型
model = LogisticRegression(max_iter=10000, random_state=42) # 增加迭代次数确保收敛
model.fit(X_train, y_train)
# 预测与评估
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred, target_names=data.target_names))
随机森林(集成学习)
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加载葡萄酒数据集(多分类任务)
data = load_wine()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练随机森林模型
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
model.fit(X_train, y_train)
# 评估
y_pred = model.predict(X_test)
print(f"准确率:{accuracy_score(y_test, y_pred):.2f}")
# 查看特征重要性
importances = model.feature_importances_
for name, importance in zip(data.feature_names, importances):
print(f"{name}: {importance:.3f}")
2. 回归算法(预测连续值)
线性回归
from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# 加载糖尿病数据集(回归任务)
data = load_diabetes()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练线性回归模型
model = LinearRegression()
model.fit(X_train, y_train)
# 预测与评估
y_pred = model.predict(X_test)
print(f"均方误差(MSE):{mean_squared_error(y_test, y_pred):.2f}")
print(f"决定系数(R²):{r2_score(y_test, y_pred):.2f}") # 越接近1越好
随机森林回归
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error
# 加载加州房价数据集
data = fetch_california_housing()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练随机森林回归模型
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 评估
y_pred = model.predict(X_test)
print(f"平均绝对误差(MAE):{mean_absolute_error(y_test, y_pred):.2f}")
3. 聚类算法(无监督学习)
K-Means聚类
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
# 加载鸢尾花数据集
data = load_iris()
X = data.data # 不使用标签,进行无监督聚类
# 训练K-Means模型(假设分为3类)
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10) # n_init确保稳定结果
clusters = kmeans.fit_predict(X)
# 可视化聚类结果(使用前两个特征)
plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap='viridis', label='聚类结果')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
s=300, c='red', marker='X', label='聚类中心')
plt.xlabel(data.feature_names[0])
plt.ylabel(data.feature_names[1])
plt.legend()
plt.show()
4. 降维算法(特征压缩)
PCA主成分分析
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
# 加载手写数字数据集(64维特征)
data = load_digits()
X, y = data.data, data.target
print("原始特征维度:", X.shape[1]) # 输出:64
# 使用PCA降维到2维
pca = PCA(n_components=2) # 保留2个主成分
X_pca = pca.fit_transform(X)
print("降维后特征维度:", X_pca.shape[1]) # 输出:2
# 可视化降维结果
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='tab10', alpha=0.7)
plt.colorbar(label='数字类别')
plt.xlabel('主成分1')
plt.ylabel('主成分2')
plt.title('PCA降维可视化')
plt.show()
# 查看解释方差比
print(f"前2个主成分解释的方差比例:{pca.explained_variance_ratio_.sum():.2f}")
五、实战案例:客户流失预测系统
下面实现一个完整的客户流失预测系统,涵盖数据加载、探索、预处理、模型训练、调参和评估的全流程:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import (accuracy_score, precision_score, recall_score,
f1_score, roc_auc_score, confusion_matrix,
classification_report, roc_curve)
# 1. 数据加载与探索
# 加载数据集(示例使用Kaggle的Telco Customer Churn数据集)
# 实际使用时可从https://www.kaggle.com/datasets/blastchar/telco-customer-churn下载
# 这里使用模拟数据演示
data = pd.DataFrame({
'gender': np.random.choice(['Male', 'Female'], size=1000),
'SeniorCitizen': np.random.choice([0, 1], size=1000),
'Partner': np.random.choice(['Yes', 'No'], size=1000),
'tenure': np.random.randint(1, 73, size=1000),
'MonthlyCharges': np.random.uniform(18, 120, size=1000),
'Contract': np.random.choice(['Month-to-month', 'One year', 'Two year'], size=1000),
'Churn': np.random.choice(['Yes', 'No'], size=1000)
})
# 查看数据基本信息
print("数据集形状:", data.shape)
print("\n前5行数据:")
print(data.head())
# 查看目标变量分布(是否流失)
churn_distribution = data['Churn'].value_counts(normalize=True)
print("\n客户流失比例:")
print(churn_distribution)
# 可视化: tenure与流失的关系
plt.figure(figsize=(10, 6))
sns.boxplot(x='Churn', y='tenure', data=data)
plt.title('客户 tenure 与流失的关系')
plt.show()
# 2. 数据预处理
# 划分特征与目标变量
X = data.drop('Churn', axis=1)
y = (data['Churn'] == 'Yes').astype(int) # 将'Yes'/'No'转为1/0
# 区分数值特征和类别特征
numeric_features = ['tenure', 'MonthlyCharges', 'SeniorCitizen']
categorical_features = ['gender', 'Partner', 'Contract']
# 创建预处理管道:数值特征标准化,类别特征独热编码
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(drop='first'), categorical_features) # drop='first'避免多重共线性
])
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y # stratify确保分层抽样,保持类别比例
)
# 3. 模型训练与超参数调优
# 创建包含预处理和模型的管道
pipeline = Pipeline([
('preprocessor', preprocessor),
('classifier', RandomForestClassifier(random_state=42))
])
# 定义超参数搜索空间
param_grid = {
'classifier__n_estimators': [50, 100, 200],
'classifier__max_depth': [None, 10, 20, 30],
'classifier__min_samples_split': [2, 5, 10]
}
# 网格搜索交叉验证
grid_search = GridSearchCV(
pipeline, param_grid, cv=5, scoring='f1', n_jobs=-1, verbose=1
)
grid_search.fit(X_train, y_train)
print(f"\n最佳超参数:{grid_search.best_params_}")
print(f"最佳交叉验证分数:{grid_search.best_score_:.4f}")
# 4. 模型评估
# 使用最佳模型预测
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
y_pred_proba = best_model.predict_proba(X_test)[:, 1] # 流失的概率
# 计算评估指标
print("\n测试集评估指标:")
print(f"准确率(Accuracy):{accuracy_score(y_test, y_pred):.4f}")
print(f"精确率(Precision):{precision_score(y_test, y_pred):.4f}")
print(f"召回率(Recall):{recall_score(y_test, y_pred):.4f}")
print(f"F1分数:{f1_score(y_test, y_pred):.4f}")
print(f"AUC:{roc_auc_score(y_test, y_pred_proba):.4f}")
# 混淆矩阵
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['未流失', '流失'],
yticklabels=['未流失', '流失'])
plt.xlabel('预测标签')
plt.ylabel('真实标签')
plt.title('混淆矩阵')
plt.show()
# 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--') # 随机猜测的基准线
plt.xlabel('假正例率(FPR)')
plt.ylabel('真正例率(TPR)')
plt.title('ROC曲线')
plt.legend()
plt.show()
# 5. 特征重要性分析
# 提取特征名称(处理后的)
cat_features = list(best_model.named_steps['preprocessor']
.named_transformers_['cat']
.get_feature_names_out(categorical_features))
all_features = numeric_features + cat_features
# 获取特征重要性
importances = best_model.named_steps['classifier'].feature_importances_
feature_importance = pd.DataFrame({
'特征': all_features,
'重要性': importances
}).sort_values(by='重要性', ascending=False)
print("\n特征重要性排序:")
print(feature_importance)
# 可视化特征重要性
plt.figure(figsize=(10, 6))
sns.barplot(x='重要性', y='特征', data=feature_importance)
plt.title('特征重要性')
plt.show()
六、模型选择与调优技巧
1. 交叉验证(避免过拟合)
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
data = load_iris()
X, y = data.data, data.target
model = LogisticRegression(max_iter=1000)
# 5折交叉验证
cv_scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f"各折准确率:{cv_scores}")
print(f"平均准确率:{cv_scores.mean():.2f} ± {cv_scores.std():.2f}")
2. 超参数调优(网格搜索与随机搜索)
from sklearn.model_selection import RandomizedSearchCV
from sklearn.svm import SVC
from scipy.stats import randint, uniform
# 定义参数分布(随机搜索比网格搜索更高效)
param_dist = {
'C': uniform(loc=0, scale=10), # 正则化参数
'kernel': ['linear', 'rbf', 'poly'],
'gamma': uniform(loc=0, scale=1) # 核系数
}
model = SVC()
# 随机搜索(在参数空间中随机采样)
random_search = RandomizedSearchCV(
model, param_dist, n_iter=20, cv=5, scoring='accuracy', random_state=42
)
random_search.fit(X_train, y_train)
print(f"最佳参数:{random_search.best_params_}")
print(f"最佳分数:{random_search.best_score_:.2f}")
3. 模型保存与加载
训练好的模型可以保存到磁盘,便于后续部署:
from sklearn.ensemble import RandomForestClassifier
import joblib # scikit-learn推荐的模型保存工具
# 训练模型
model = RandomForestClassifier()
model.fit(X_train, y_train)
# 保存模型
joblib.dump(model, 'churn_model.pkl')
# 加载模型(部署时使用)
loaded_model = joblib.load('churn_model.pkl')
# 使用加载的模型预测
y_pred = loaded_model.predict(X_test)
七、常用数据集与扩展学习
1. scikit-learn内置数据集
scikit-learn提供了多个小型数据集,方便快速测试算法:
-
load_iris():鸢尾花分类数据集 -
load_breast_cancer():乳腺癌诊断数据集 -
load_diabetes():糖尿病回归数据集 -
load_digits():手写数字识别数据集 -
fetch_california_housing():加州房价数据集
2. 扩展资源
-
官方文档:https://scikit-learn.org/stable/user_guide.html(权威教程)
-
示例库:https://scikit-learn.org/stable/auto_examples/index.html(丰富的代码示例)
-
进阶书籍:《Introduction to Machine Learning with Python》(scikit-learn作者编写)
八、总结
scikit-learn以其简洁的API和丰富的功能,成为机器学习入门和快速原型开发的理想工具。本文从数据预处理、核心算法到实战案例,展示了scikit-learn在分类、回归、聚类和降维等任务中的应用。通过统一的fit()/predict()接口,开发者可以轻松切换不同算法,快速对比效果。
在实际应用中,需注意:
-
数据质量是关键,预处理步骤往往比算法选择更重要
-
避免过拟合,通过交叉验证和正则化提高模型泛化能力
-
结合业务理解选择合适的评估指标(如召回率对欺诈检测更重要)
scikit-learn适合处理中小规模数据集和经典机器学习任务。对于大规模数据或深度学习场景,可结合PySpark MLlib或TensorFlow/PyTorch使用。掌握scikit-learn,将为你的机器学习之旅打下坚实基础,无论是学术研究还是工业应用,都能显著提升开发效率。
更多推荐



所有评论(0)