【零基础学AI】第9讲:机器学习概述

本节课你将学到

  • 理解什么是机器学习,以及它与传统编程的区别
  • 掌握监督学习、无监督学习的基本概念
  • 使用scikit-learn完成你的第一个机器学习项目
  • 构建一个完整的iris花朵分类器

开始之前

环境要求

  • Python 3.8+
  • Jupyter Notebook 或任何Python IDE

需要安装的包

pip install scikit-learn pandas matplotlib seaborn

前置知识

  • 基本的Python语法(第1-8讲已覆盖)
  • NumPy和Pandas基础操作

核心概念

什么是机器学习?

想象一下教小孩认识动物的过程:

传统编程方式
我们写一本详细的规则书:

  • “如果有四条腿,会汪汪叫,尾巴会摆 → 这是狗”
  • “如果有翅膀,会飞,有羽毛 → 这是鸟”

机器学习方式
我们给孩子看1000张动物照片,每张都告诉他这是什么,然后让孩子自己总结规律。

这就是机器学习的核心:让计算机从数据中自动学习规律,而不是我们手工编写规则

机器学习的三大类型

1. 监督学习(Supervised Learning)

特点:有"标准答案"的学习
举例

  • 给1000封邮件,每封都标注了"垃圾邮件"或"正常邮件"
  • 让机器学会如何识别新邮件

常见任务

  • 分类:判断邮件是否为垃圾邮件
  • 回归:预测房价
2. 无监督学习(Unsupervised Learning)

特点:没有"标准答案",让机器自己发现规律
举例

  • 给1000个客户的购买记录
  • 让机器自己发现客户可以分为几类

常见任务

  • 聚类:客户分群
  • 降维:数据压缩
3. 强化学习(Reinforcement Learning)

特点:通过试错学习,有奖惩机制
举例:训练游戏AI,赢了有奖励,输了有惩罚

代码实战

今天我们用经典的iris(鸢尾花)数据集来体验机器学习。这个数据集包含150朵花的数据,每朵花有4个特征,属于3个品种之一。

第一步:导入库和数据

# 导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
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, classification_report

# 设置中文字体(避免图表中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

print("库导入成功!开始机器学习之旅 ")

第二步:加载和探索数据

# 加载iris数据集
# 这是sklearn自带的经典数据集,非常适合学习
iris = load_iris()

# 将数据转换为DataFrame,方便查看
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = iris.target

# 添加花朵品种名称(比数字更容易理解)
species_names = {0: 'setosa', 1: 'versicolor', 2: 'virginica'}
df['species_name'] = df['species'].map(species_names)

print("数据加载完成!")
print(f"数据形状: {df.shape}")  # 显示数据维度
print("\n前5行数据:")
print(df.head())

print("\n数据基本信息:")
print(df.info())

第三步:数据可视化探索

# 查看每个品种的花朵数量
print("各品种花朵数量:")
print(df['species_name'].value_counts())

# 创建特征分布图
plt.figure(figsize=(12, 8))

# 绘制4个特征的分布
for i, feature in enumerate(iris.feature_names):
    plt.subplot(2, 2, i+1)
    # 按品种分别绘制直方图
    for species in df['species_name'].unique():
        data = df[df['species_name'] == species][feature]
        plt.hist(data, alpha=0.7, label=species, bins=20)
    
    plt.xlabel(feature)
    plt.ylabel('频次')
    plt.title(f'{feature} 分布')
    plt.legend()

plt.tight_layout()
plt.show()

print(" 观察发现:不同品种的花朵在各特征上确实有差异,这为分类提供了基础")

第四步:准备训练数据

# 准备特征和标签
# X是特征(花朵的4个测量值),y是标签(花朵品种)
X = iris.data
y = iris.target

print("特征矩阵形状:", X.shape)  # (150, 4) - 150朵花,每朵4个特征
print("标签数组形状:", y.shape)  # (150,) - 150个标签

# 数据集分割:训练集用来学习,测试集用来验证效果
# 这就像考试:用练习题学习,用考试题检验
X_train, X_test, y_train, y_test = train_test_split(
    X, y, 
    test_size=0.3,      # 30%用于测试
    random_state=42,    # 固定随机种子,确保结果可重现
    stratify=y          # 保证训练集和测试集中各类别比例相同
)

print(f"\n数据分割完成:")
print(f"训练集: {len(X_train)} 个样本")
print(f"测试集: {len(X_test)} 个样本")

# 检查分割后各类别分布
train_counts = np.bincount(y_train)
test_counts = np.bincount(y_test)
print(f"训练集各类别数量: {train_counts}")
print(f"测试集各类别数量: {test_counts}")

第五步:训练机器学习模型

# 创建随机森林分类器
# 随机森林是一个强大且容易使用的算法,适合初学者
model = RandomForestClassifier(
    n_estimators=100,    # 使用100棵决策树
    random_state=42,     # 固定随机种子
    max_depth=3          # 限制树的深度,防止过拟合
)

print("开始训练模型...")

# 训练模型(这就是"学习"的过程)
model.fit(X_train, y_train)

print("模型训练完成!✅")

# 查看特征重要性(哪个特征对分类最重要)
feature_importance = pd.DataFrame({
    'feature': iris.feature_names,
    'importance': model.feature_importances_
}).sort_values('importance', ascending=False)

print("\n特征重要性排名:")
print(feature_importance)

第六步:模型预测和评估

# 使用训练好的模型进行预测
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"模型准确率: {accuracy:.2%}")

# 详细的分类报告
print("\n详细分类报告:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))

# 预测结果对比
results_df = pd.DataFrame({
    'actual': y_test,
    'predicted': y_pred,
    'actual_name': [iris.target_names[i] for i in y_test],
    'predicted_name': [iris.target_names[i] for i in y_pred]
})

print("\n前10个预测结果:")
print(results_df.head(10))

# 计算预测正确的数量
correct_predictions = (y_test == y_pred).sum()
total_predictions = len(y_test)
print(f"\n预测结果: {correct_predictions}/{total_predictions} 正确")

第七步:可视化结果

# 绘制混淆矩阵
from sklearn.metrics import confusion_matrix

plt.figure(figsize=(8, 6))
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
            xticklabels=iris.target_names, 
            yticklabels=iris.target_names)
plt.title('混淆矩阵')
plt.xlabel('预测结果')
plt.ylabel('实际结果')
plt.show()

print(" 混淆矩阵解读:")
print("- 对角线上的数字:预测正确的数量")
print("- 非对角线数字:预测错误的数量")
print("- 理想情况:只有对角线有数字")

完整项目

# 第9讲:机器学习概述 - iris花朵分类器
# 这是一个完整的机器学习项目,展示从数据到预测的全流程

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
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, classification_report, confusion_matrix

def load_and_explore_data():
    """加载并探索iris数据集"""
    print("=" * 50)
    print(" iris花朵分类器")
    print("=" * 50)
    
    # 加载数据
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns=iris.feature_names)
    df['species'] = iris.target
    
    # 添加品种名称
    species_names = {0: 'setosa', 1: 'versicolor', 2: 'virginica'}
    df['species_name'] = df['species'].map(species_names)
    
    print(" 数据基本信息:")
    print(f"数据形状: {df.shape}")
    print(f"特征数量: {len(iris.feature_names)}")
    print(f"样本数量: {len(df)}")
    print(f"类别数量: {len(iris.target_names)}")
    
    print("\n 各品种分布:")
    print(df['species_name'].value_counts())
    
    print("\n 前5行数据:")
    print(df.head())
    
    return iris, df

def visualize_data(iris, df):
    """可视化数据分布"""
    print("\n 正在生成数据可视化...")
    
    plt.figure(figsize=(15, 10))
    
    # 特征分布图
    for i, feature in enumerate(iris.feature_names):
        plt.subplot(2, 3, i+1)
        for species in df['species_name'].unique():
            data = df[df['species_name'] == species][feature]
            plt.hist(data, alpha=0.7, label=species, bins=15)
        plt.xlabel(feature)
        plt.ylabel('频次')
        plt.title(f'{feature} 分布')
        plt.legend()
    
    # 特征相关性热力图
    plt.subplot(2, 3, 5)
    correlation_matrix = df[iris.feature_names].corr()
    sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
    plt.title('特征相关性')
    
    # 散点图矩阵
    plt.subplot(2, 3, 6)
    # 选择两个最重要的特征进行可视化
    for species in df['species_name'].unique():
        data = df[df['species_name'] == species]
        plt.scatter(data['petal length (cm)'], data['petal width (cm)'], 
                   label=species, alpha=0.7)
    plt.xlabel('花瓣长度 (cm)')
    plt.ylabel('花瓣宽度 (cm)')
    plt.title('花瓣长度 vs 宽度')
    plt.legend()
    
    plt.tight_layout()
    plt.show()

def train_model(iris):
    """训练机器学习模型"""
    print("\n 开始训练机器学习模型...")
    
    # 准备数据
    X = iris.data
    y = iris.target
    
    # 分割数据集
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.3, random_state=42, stratify=y
    )
    
    print(f"✅ 数据分割完成:")
    print(f"   训练集: {len(X_train)} 个样本")
    print(f"   测试集: {len(X_test)} 个样本")
    
    # 创建并训练模型
    model = RandomForestClassifier(
        n_estimators=100,
        random_state=42,
        max_depth=3
    )
    
    # 训练模型
    model.fit(X_train, y_train)
    print("✅ 模型训练完成!")
    
    # 特征重要性
    feature_importance = pd.DataFrame({
        'feature': iris.feature_names,
        'importance': model.feature_importances_
    }).sort_values('importance', ascending=False)
    
    print("\n 特征重要性排名:")
    for idx, row in feature_importance.iterrows():
        print(f"   {row['feature']}: {row['importance']:.3f}")
    
    return model, X_test, y_test

def evaluate_model(model, iris, X_test, y_test):
    """评估模型性能"""
    print("\n 评估模型性能...")
    
    # 预测
    y_pred = model.predict(X_test)
    
    # 计算准确率
    accuracy = accuracy_score(y_test, y_pred)
    print(f" 模型准确率: {accuracy:.2%}")
    
    # 详细报告
    print("\n 详细分类报告:")
    print(classification_report(y_test, y_pred, target_names=iris.target_names))
    
    # 预测结果展示
    results_df = pd.DataFrame({
        'actual': [iris.target_names[i] for i in y_test],
        'predicted': [iris.target_names[i] for i in y_pred],
        'correct': y_test == y_pred
    })
    
    print(f"\n✅ 预测正确数量: {(y_test == y_pred).sum()}/{len(y_test)}")
    print("\n 预测结果样例:")
    print(results_df.head(10))
    
    # 可视化混淆矩阵
    plt.figure(figsize=(8, 6))
    cm = confusion_matrix(y_test, y_pred)
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
                xticklabels=iris.target_names,
                yticklabels=iris.target_names)
    plt.title('混淆矩阵')
    plt.xlabel('预测结果')
    plt.ylabel('实际结果')
    plt.show()
    
    return accuracy

def predict_new_sample(model, iris):
    """预测新样本"""
    print("\n 尝试预测新样本...")
    
    # 创建一个新样本(这里用数据集中的均值作为例子)
    new_sample = np.array([[5.1, 3.5, 1.4, 0.2]])  # setosa的典型特征
    
    # 预测
    prediction = model.predict(new_sample)
    probability = model.predict_proba(new_sample)
    
    print(f" 输入特征: {new_sample[0]}")
    print(f" 预测结果: {iris.target_names[prediction[0]]}")
    print(f" 各类别概率:")
    for i, prob in enumerate(probability[0]):
        print(f"   {iris.target_names[i]}: {prob:.3f}")

def main():
    """主程序"""
    try:
        # 1. 加载和探索数据
        iris, df = load_and_explore_data()
        
        # 2. 数据可视化
        visualize_data(iris, df)
        
        # 3. 训练模型
        model, X_test, y_test = train_model(iris)
        
        # 4. 评估模型
        accuracy = evaluate_model(model, iris, X_test, y_test)
        
        # 5. 预测新样本
        predict_new_sample(model, iris)
        
        print("\n" + "=" * 50)
        print(" 恭喜!你已经完成了第一个机器学习项目!")
        print(f" 最终模型准确率: {accuracy:.2%}")
        print(" 关键收获:")
        print("   1. 理解了监督学习的基本流程")
        print("   2. 学会了数据探索和可视化")
        print("   3. 掌握了模型训练和评估")
        print("   4. 体验了完整的机器学习项目")
        print("=" * 50)
        
    except Exception as e:
        print(f"❌ 运行出错: {e}")
        print(" 检查项目:")
        print("   1. 是否安装了所需的库?")
        print("   2. Python版本是否正确?")

if __name__ == "__main__":
    main()

运行效果

控制台输出

==================================================
 iris花朵分类器
==================================================
 数据基本信息:
数据形状: (150, 4)
特征数量: 4
样本数量: 150
类别数量: 3

 各品种分布:
setosa        50
versicolor    50
virginica     50

 开始训练机器学习模型...
✅ 数据分割完成:
   训练集: 105 个样本
   测试集: 45 个样本
✅ 模型训练完成!

 特征重要性排名:
   petal width (cm): 0.458
   petal length (cm): 0.413
   sepal length (cm): 0.099
   sepal width (cm): 0.030

 评估模型性能...
 模型准确率: 100.00%

✅ 预测正确数量: 45/45

 恭喜!你已经完成了第一个机器学习项目!

生成的可视化图表

  1. 特征分布图:显示不同品种花朵在各特征上的分布差异
  2. 相关性热力图:展示特征之间的相关关系
  3. 混淆矩阵:直观显示预测结果的准确性

常见问题

Q1: 为什么要分训练集和测试集?

**回答:**就像学习考试一样:

  • 训练集 = 练习题(用来学习)
  • 测试集 = 考试题(用来检验真实水平)
    如果用同样的题目练习和考试,就无法知道真实能力了。

Q2: 100%的准确率是不是太好了?

**回答:**iris数据集确实比较简单,各类别区分度很高。在实际项目中:

  • 70-80%准确率:一般水平
  • 80-90%准确率:较好水平
  • 90%以上准确率:很好水平

Q3: 随机森林是什么?

**回答:**想象一下做决定时:

  • 一个人决定:可能有偏见
  • 100个人投票决定:更可靠
    随机森林就是让100棵"决策树"投票,最终结果更准确。

Q4: 特征重要性有什么用?

**回答:**告诉我们哪些特征最有用:

  • 花瓣宽度和长度最重要(45.8% + 41.3%)
  • 花萼特征相对不重要
  • 实际应用中可以重点关注重要特征

课后练习

  1. 修改参数实验

    • 尝试修改test_size为0.2或0.4,观察结果变化
    • 调整随机森林的n_estimators参数
  2. 尝试其他算法

    from sklearn.svm import SVC
    from sklearn.neighbors import KNeighborsClassifier
    
    # 尝试SVM
    svm_model = SVC()
    svm_model.fit(X_train, y_train)
    
  3. 使用自己的数据

    • 收集一些简单的数据(比如身高体重预测性别)
    • 按照同样流程进行分析

下节预告:第10讲我们将学习线性回归,用房价数据预测房屋价值!

你可能感兴趣的:(0基础学AI,人工智能,机器学习,python,numpy,devops,开源)