机器学习入门实践:从零开始构建你的第一个预测模型 前言 机器学习正以前所未有的速度改变着我们的世界。从智能推荐系统到自动驾驶汽车,从医疗诊断到金融风控,这项技术已经渗透到各行各业。对于初学者来说,机器学习可能看起来高深莫测,但实际上,通过正确的指导和实践,任何人都可以迈出第一步。
本文将带你从零开始,完成一个完整的机器学习项目。我们将使用经典的鸢尾花数据集,通过Python和Scikit-learn库,构建一个能够准确分类鸢尾花品种的机器学习模型。在这个过程中,你将学习到机器学习的基本流程、核心概念和实用技巧。
环境准备 在开始之前,我们需要准备好开发环境。我推荐使用Anaconda来管理Python环境,它包含了我们所需的大部分科学计算库。
安装步骤 安装Anaconda(从官网下载对应版本) 创建新的虚拟环境:1 2 conda create -n ml-beginner python=3.9 conda activate ml-beginner
安装必要的库:1 pip install numpy pandas matplotlib seaborn scikit-learn jupyter
项目概述:鸢尾花分类 鸢尾花数据集是机器学习领域最经典的数据集之一,包含150个样本,每个样本有4个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)和1个标签(鸢尾花品种:Setosa、Versicolor、Virginica)。
我们的目标是构建一个模型,能够根据花的四个特征准确预测其品种。
🚀 完整实现步骤 第一步:导入必要的库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import accuracy_score, classification_report, confusion_matrixplt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False sns.set_style("whitegrid" )
第二步:加载和探索数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 iris = load_iris() print ("数据集特征名称:" , iris.feature_names)print ("目标类别名称:" , iris.target_names)print ("数据形状:" , iris.data.shape)print ("目标形状:" , iris.target.shape)df = pd.DataFrame(iris.data, columns=iris.feature_names) df['species' ] = iris.target df['species_name' ] = df['species' ].map ({0 : 'setosa' , 1 : 'versicolor' , 2 : 'virginica' }) print ("\n数据前5行:" )print (df.head())print ("\n数据基本信息:" )print (df.info())print ("\n数据统计描述:" )print (df.describe())print ("\n各类别样本数量:" )print (df['species_name' ].value_counts())
第三步:数据可视化分析 理解数据是机器学习项目中至关重要的一步。可视化可以帮助我们发现数据中的模式和关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 fig, axes = plt.subplots(2 , 2 , figsize=(12 , 10 )) for idx, feature in enumerate (iris.feature_names): row, col = divmod (idx, 2 ) axes[row, col].hist(df[feature], bins=20 , alpha=0.7 , color='skyblue' , edgecolor='black' ) axes[row, col].set_title(f'{feature} 分布' ) axes[row, col].set_xlabel(feature) axes[row, col].set_ylabel('频数' ) plt.tight_layout() plt.show() fig, axes = plt.subplots(2 , 2 , figsize=(12 , 10 )) colors = ['red' , 'green' , 'blue' ] for idx, feature in enumerate (iris.feature_names): row, col = divmod (idx, 2 ) for species_idx, species in enumerate (iris.target_names): species_data = df[df['species' ] == species_idx] axes[row, col].scatter(species_data[feature], species_data['species' ], alpha=0.6 , color=colors[species_idx], label=species) axes[row, col].set_title(f'{feature} vs 类别' ) axes[row, col].set_xlabel(feature) axes[row, col].set_ylabel('类别' ) axes[row, col].legend() plt.tight_layout() plt.show() plt.figure(figsize=(10 , 8 )) correlation_matrix = df[iris.feature_names].corr() sns.heatmap(correlation_matrix, annot=True , cmap='coolwarm' , center=0 ) plt.title('特征间相关性热图' ) plt.show()
第四步:数据预处理 数据预处理是机器学习流程中的关键步骤,直接影响模型的性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 X = df[iris.feature_names].values y = df['species' ].values print ("特征数据形状:" , X.shape)print ("目标数据形状:" , y.shape)X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2 , random_state=42 , stratify=y ) print (f"训练集大小: {X_train.shape[0 ]} 个样本" )print (f"测试集大小: {X_test.shape[0 ]} 个样本" )scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) print ("\n标准化后的数据示例(前5行):" )print (X_train_scaled[:5 ])
第五步:构建和训练模型 我们将尝试三种不同的分类算法,比较它们的性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 models = { 'K近邻' : KNeighborsClassifier(n_neighbors=5 ), '决策树' : DecisionTreeClassifier(max_depth=3 , random_state=42 ), '随机森林' : RandomForestClassifier(n_estimators=100 , random_state=42 ) } results = {} for model_name, model in models.items(): print (f"\n正在训练 {model_name} 模型..." ) model.fit(X_train_scaled, y_train) y_train_pred = model.predict(X_train_scaled) y_test_pred = model.predict(X_test_scaled) train_accuracy = accuracy_score(y_train, y_train_pred) test_accuracy = accuracy_score(y_test, y_test_pred) results[model_name] = { 'model' : model, 'train_accuracy' : train_accuracy, 'test_accuracy' : test_accuracy, 'y_test_pred' : y_test_pred } print (f"训练集准确率: {train_accuracy:.4 f} " ) print (f"测试集准确率: {test_accuracy:.4 f} " ) print (f"\n{model_name} 分类报告:" ) print (classification_report(y_test, y_test_pred, target_names=iris.target_names))
第六步:模型评估和比较 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 model_names = list (results.keys()) train_accuracies = [results[name]['train_accuracy' ] for name in model_names] test_accuracies = [results[name]['test_accuracy' ] for name in model_names] x = np.arange(len (model_names)) width = 0.35 fig, ax = plt.subplots(figsize=(10 , 6 )) rects1 = ax.bar(x - width/2 , train_accuracies, width, label='训练集' , color='skyblue' ) rects2 = ax.bar(x + width/2 , test_accuracies, width, label='测试集' , color='lightcoral' ) ax.set_xlabel('模型' ) ax.set_ylabel('准确率' ) ax.set_title('不同模型在训练集和测试集上的表现' ) ax.set_xticks(x) ax.set_xticklabels(model_names) ax.legend() def autolabel (rects ): for rect in rects: height = rect.get_height() ax.annotate(f'{height:.3 f} ' , xy=(rect.get_x() + rect.get_width() / 2 , height), xytext=(0 , 3 ), textcoords="offset points" , ha='center' , va='bottom' ) autolabel(rects1) autolabel(rects2) plt.tight_layout() plt.show() fig, axes = plt.subplots(1 , 3 , figsize=(15 , 5 )) for idx, model_name in enumerate (model_names): cm = confusion_matrix(y_test, results[model_name]['y_test_pred' ]) sns.heatmap(cm, annot=True , fmt='d' , cmap='Blues' , xticklabels=iris.target_names, yticklabels=iris.target_names, ax=axes[idx]) axes[idx].set_title(f'{model_name} 混淆矩阵' ) axes[idx].set_xlabel('预测标签' ) axes[idx].set_ylabel('真实标签' ) plt.tight_layout() plt.show()
第七步:模型优化(以K近邻为例) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 k_values = range (1 , 21 ) train_scores = [] test_scores = [] for k in k_values: knn = KNeighborsClassifier(n_neighbors=k) knn.fit(X_train_scaled, y_train) train_scores.append(knn.score(X_train_scaled, y_train)) test_scores.append(knn.score(X_test_scaled, y_test)) plt.figure(figsize=(10 , 6 )) plt.plot(k_values, train_scores, 'o-' , label='训练集准确率' , color='blue' ) plt.plot(k_values, test_scores, 's-' , label='测试集准确率' , color='red' ) plt.xlabel('K值' ) plt.ylabel('准确率' ) plt.title('K近邻算法中K值对准确率的影响' ) plt.legend() plt.grid(True , alpha=0.3 ) plt.show() optimal_k = k_values[np.argmax(test_scores)] print (f"最优K值: {optimal_k} " )print (f"最优K值对应的测试集准确率: {test_scores[optimal_k-1 ]:.4 f} " )optimal_knn = KNeighborsClassifier(n_neighbors=optimal_k) optimal_knn.fit(X_train_scaled, y_train) def predict_new_sample (features ): """ 预测新样本的类别 参数: features: 列表,包含4个特征值 [花萼长度, 花萼宽度, 花瓣长度, 花瓣宽度] """ features_array = np.array(features).reshape(1 , -1 ) features_scaled = scaler.transform(features_array) prediction = optimal_knn.predict(features_scaled)[0 ] probability = optimal_knn.predict_proba(features_scaled)[0 ] species_name = iris.target_names[prediction] print (f"预测结果: {species_name} " ) print ("\n各类别概率:" ) for i, name in enumerate (iris.target_names): print (f" {name} : {probability[i]:.4 f} " ) return prediction, probability print ("示例预测:" )sample_features = [5.1 , 3.5 , 1.4 , 0.2 ] predict_new_sample(sample_features)
第八步:特征重要性分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 best_model = results['随机森林' ]['model' ] feature_importance = best_model.feature_importances_ importance_df = pd.DataFrame({ '特征' : iris.feature_names, '重要性' : feature_importance }).sort_values('重要性' , ascending=False ) print ("特征重要性排序:" )print (importance_df)plt.figure(figsize=(10 , 6 )) bars = plt.barh(importance_df['特征' ], importance_df['重要性' ], color='teal' ) plt.xlabel('重要性分数' ) plt.title('随机森林特征重要性' ) plt.gca().invert_yaxis() for bar in bars: width = bar.get_width() plt.text(width + 0.01 , bar.get_y() + bar.get_height()/2 , f'{width:.3 f} ' , ha='left' , va='center' ) plt.tight_layout() plt.show()
🚀 关键概念解析 1. 监督学习 vs 无监督学习 本项目属于监督学习,因为我们有明确的标签(鸢尾花品种)来指导模型训练。
2. 过拟合与欠拟合 过拟合:模型在训练集上表现很好,但在测试集上表现差 欠拟合:模型在训练集和测试集上都表现不佳 我们的目标:找到平衡点,使模型具有良好的泛化能力 3. 交叉验证 虽然本文使用了简单的训练集/测试集划分,但在实际项目中,推荐使用交叉验证来更可靠地评估模型性能。
4. 超参数调优 我们演示了如何通过网格搜索找到K近邻算法的最优K值。对于更复杂的模型,可以使用GridSearchCV或RandomizedSearchCV进行自动调优。
实践建议 从简单开始 :不要一开始就尝试最复杂的模型,从简单的模型(如K近邻、逻辑回归)开始,建立基准性能。
理解数据 :花时间探索和理解数据,这通常比盲目尝试不同算法更有效。
迭代改进 :机器学习是一个迭代过程,不断尝试、评估、调整。
记录实验 :记录每次实验的参数、结果和观察,这有助于你理解什么方法有效,什么无效。
关注泛化能力 :最终目标是构建在未见数据上表现良好的模型,而不仅仅是在训练数据上表现好。
✨ 下一步学习方向 完成这个入门项目后,你可以尝试以下方向进一步学习:
尝试其他数据集 :如手写数字识别(MNIST)、波士顿房价预测等探索更复杂的模型 :如支持向量机、神经网络等学习深度学习 :使用TensorFlow或PyTorch构建神经网络参与Kaggle竞赛 :在真实竞赛中应用所学知识学习模型部署 :将训练好的模型部署为Web服务结语 机器学习入门并不难,关键在于动手实践。通过这个完整的项目,你已经掌握了机器学习的基本流程:数据加载、探索分析、预处理、模型训练、评估和优化。这些步骤构成了大多数机器学习项目的基础框架。
记住,每个专家都曾是初学者。持续学习、不断实践,你将在机器学习的道路上越走越远。现在,尝试修改代码中的参数,使用不同的算法,或者应用这个流程到其他数据集上,开始你的机器学习探索之旅吧!
[up主专用,视频内嵌代码贴在这]
零点119官方团队
一站式科技资源平台 | 学生/开发者/极客必备
本文由零点119官方团队原创,转载请注明出处。文章ID: a1f0807a