人工智能入门第一天学习指南(Java资深/Python小白适用)

📚 今日学习路径

graph TD
    A[环境准备] --> B[案例:线性回归模型]
    B --> C[数学原理解析]
    C --> D[Python实现]
    D --> E[模型可视化]
    E --> F[扩展思考]

🛠️ 环境配置(Python版)

# 安装必备库
pip install numpy matplotlib

# 验证安装
import numpy as np
import matplotlib.pyplot as plt
print("当前numpy版本:", np.__version__)

🧠 核心案例:单变量线性回归

数据集生成

# 生成训练数据(Java开发者注意:Python不需要显式定义main方法)
np.random.seed(42)
X = 2 * np.random.rand(100, 1) # 生成0-2区间100个数据点
y = 4 + 3 * X + np.random.randn(100, 1) # 真实关系式 + 噪声

# 数据可视化
plt.scatter(X, y)
plt.xlabel("特征X")
plt.ylabel("目标值y")
plt.title("训练数据分布")
plt.show()

在这里插入图片描述

数学原理

在这里插入图片描述

Python实现

class LinearRegression:
    def __init__(self, learning_rate=0.01, n_epochs=100):
        self.lr = learning_rate  # 学习率
        self.epochs = n_epochs  # 迭代次数
        self.theta = None  # 参数向量

    def fit(self, X, y):
        m = X.shape[0]  # X.shape[0]表示X的行数,即样本数量,X.shape[1]表示X的列数.此处m是样本数量
        # 使用np.c_将一个全为1的列向量(形状为(m,1))与输入矩阵X连接起来,得到一个(m,2)的矩阵
        # 目的是为每个样本添加一个偏置项 x0=1,以便模型可以学习偏置参数(即截距项)
        X_b = np.c_[np.ones((m, 1)), X]  # 添加偏置项x0=1
        print(f"X_b={X_b}")
        # 使用 np.random.randn(2, 1) 随机生成一个形状为 (2, 1) 的参数向量 theta
        # 参数向量包含两个部分:偏置项和权重项
        self.theta = np.random.randn(2, 1)  # 随机初始化参数
        print(f"theta={self.theta}")

        for epoch in range(self.epochs):
            # 梯度下降更新参数
            # X_b.dot(self.theta)表示矩阵X_b和参数向量theta的点积,得到预测值
            # X_b.dot(self.theta) - y表示预测值与真实值之间的差值
            # X_b.T.dot(X_b.dot(self.theta) - y) 表示矩阵X_b的转置和差值的点积
            # (1 / m) * X_b.T.dot(X_b.dot(self.theta) - y)表示损失函数的梯度,即损失函数对参数的偏导数
            gradients = (1 / m) * X_b.T.dot(X_b.dot(self.theta) - y)
            # 使用梯度下降法更新参数
            # self.lr * gradients:学习率乘以梯度,表示参数调整的步长
            # self.theta -= ...:从当前参数中减去步长,完成一次参数更新
            self.theta -= self.lr * gradients

            # 每20次打印损失值(类似Java的调试输出)
            if epoch % 20 == 0:
                # X_b.dot(self.theta) - y:预测值与真实值之间的误差
                # np.sum((...) ** 2):计算误差平方和
                # (1 / (2 * m)):将误差平方和除以 2m,得到均方误差(MSE)
                loss = (1 / (2 * m)) * np.sum((X_b.dot(self.theta) - y) ** 2)
                print(f"Epoch {epoch:3d} | Loss: {loss:.4f}")

    def predict(self, X):
        X_b = np.c_[np.ones((len(X), 1)), X]
        return X_b.dot(self.theta)

📊 执行与验证

# 模型训练(注意特征归一化)
model = LinearRegression(learning_rate=0.1, n_epochs=200)
model.fit(X, y)

# 预测新数据
X_new = np.array([[0], [2]])
y_pred = model.predict(X_new)
print("\n模型参数:", model.theta.ravel())

# 可视化结果
plt.plot(X_new, y_pred, "r-", linewidth=2)
plt.plot(X, y, "b.")
plt.axis([0, 2, 0, 15])
plt.show()

在这里插入图片描述

💡 课后思考题

应用题(难度:⭐️)

当梯度下降停止时,以下哪些条件可能被触发?(多选)
A) 损失值变化小于阈值
B) 达到预设最大迭代次数
C) 梯度向量接近零
D) 学习率达到指定值

参考答案:A、B、C
解析:学习率是固定超参数,不会作为停止条件

代码分析题(难度:⭐️⭐️)

下列哪个操作在梯度计算时效率最高?(假设数据量极大)

# 实现1
gradients = (X_b.T @ (X_b @ theta - y)) / m

# 实现2
error = X_b @ theta - y
gradients = np.zeros(2)
for j in range(2):
    gradients[j] = (error * X_b[:, j]).mean()

# 实现3
gradients = []
for j in range(2):
    grad = 0
    for i in range(m):
        grad += (X_b[i] @ theta - y[i]) * X_b[i, j]
    gradients.append(grad/m)

答案分析:实现1最优
原因:基于NumPy的向量化计算比循环快100倍以上(参考Java的流式处理优化原理)

原理探究题(难度:⭐️⭐️⭐️)

若学习率α设置过大,可能导致:________
若α过小,可能引发:________

参考答案:
α过大 → 损失函数震荡不收敛
α过小 → 收敛速度过慢,易陷入局部最优

🚀 阶段总结

对比维度Java开发经验参考Python/AI学习要点
语法差异强类型vs动态类型理解numpy的广播机制
编程范式OOP主导函数式编程与向量化操作的重要性
调试方式IDE单步调试Matplotlib可视化调试
并发处理多线程/线程池数据并行(如Spark MLlib)

📝 附录:标准化开发流程

1. 问题定义 → 2. 数据收集 → 3. 特征工程 → 4. 模型搭建
   ↑                                   ↓
8. 项目部署 ← 7. 超参调优 ← 6. 模型评估 ← 5. 模型训练

🔜 明日学习建议

  • 扩展案例:多元线性回归(类似Java的多维数组处理)
  • 探索Scikit-learn库的使用(对照Java的Weka库)
  • 模型评估指标:MSE、R² score的实现原理

📝 完整案例

import sys

import numpy as np
import matplotlib.pyplot as plt

print(f"当前Python版本为:{sys.version}")  # 当前Python版本为:3.9.21 (main, Dec 11 2024, 16:35:24) [MSC v.1929 64 bit (AMD64)]
print(f"当前numpy版本为:{np.__version__}")  # 当前numpy版本为:1.26.4

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号

# 生成训练数据(Python不需要定义main方法)
np.random.seed(42)

X = 2 * np.random.rand(4, 1)  # 随机生成4个特征值,每个特征值是一个随机数,范围在0到2之间
y = 4 + 3 * X + np.random.randn(4, 1)  # 真实关系式 + 噪音
print(X)
# [[0.74908024]
#  [1.90142861]
#  [1.46398788]
#  [1.19731697]]
print(y)
# [[6.01308734]
#  [9.47014888]
#  [9.97117647]
#  [8.35938563]]
m = X.shape[0]  # X.shape[0]表示X的行数,即样本数量,X.shape[1]表示X的列数.此处m是样本数量
print(m)  # 输出样本数量4
# 生成一个全为1的列向量(形状为(m,1))
print(np.ones((m, 1)))
# [[1.]
#  [1.]
#  [1.]
#  [1.]]
# 使用np.c_将一个全为1的列向量(形状为(m,1))与输入矩阵X连接起来,得到一个(m,2)的矩阵
X_b = np.c_[np.ones((m, 1)), X]
print(X_b)
# [[1. 0.74908024]
#  [1. 1.90142861]
#  [1. 1.46398788]
#  [1. 1.19731697]]

# 矩阵转置
print("X_b.T:", X_b.T)
# X_b.T: [[1.         1.         1.         1.        ]
#  [0.74908024 1.90142861 1.46398788 1.19731697]]

# 矩阵乘法
print(X_b.T.dot(X_b))
# [[4.         5.3118137 ]
#  [5.3118137  7.75338042]]
import sys

import numpy as np
import matplotlib.pyplot as plt

print(f"当前Python版本为:{sys.version}")  # 当前Python版本为:3.9.21 (main, Dec 11 2024, 16:35:24) [MSC v.1929 64 bit (AMD64)]
print(f"当前numpy版本为:{np.__version__}")  # 当前numpy版本为:1.26.4

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号

# 生成训练数据(Python不需要定义main方法)
np.random.seed(42)

X = 2 * np.random.rand(100, 1)  # 随机生成100个特征值,每个特征值是一个随机数,范围在0到2之间
y = 4 + 3 * X + np.random.randn(100, 1)  # 真实关系式 + 噪音

# 数据可视化
plt.scatter(X, y)
plt.xlabel("特征X")
plt.ylabel("目标值y")
plt.title("训练数据分布")
plt.show()


class LinearRegression:
    def __init__(self, learning_rate=0.01, n_epochs=100):
        self.lr = learning_rate  # 学习率
        self.epochs = n_epochs  # 迭代次数
        self.theta = None  # 参数向量

    def fit(self, X, y):
        m = X.shape[0]  # X.shape[0]表示X的行数,即样本数量,X.shape[1]表示X的列数.此处m是样本数量
        # 使用np.c_将一个全为1的列向量(形状为(m,1))与输入矩阵X连接起来,得到一个(m,2)的矩阵
        # 目的是为每个样本添加一个偏置项 x0=1,以便模型可以学习偏置参数(即截距项)
        X_b = np.c_[np.ones((m, 1)), X]  # 添加偏置项x0=1
        print(f"X_b={X_b}")
        # 使用 np.random.randn(2, 1) 随机生成一个形状为 (2, 1) 的参数向量 theta
        # 参数向量包含两个部分:偏置项和权重项
        self.theta = np.random.randn(2, 1)  # 随机初始化参数
        print(f"theta={self.theta}")

        for epoch in range(self.epochs):
            # 梯度下降更新参数
            # X_b.dot(self.theta)表示矩阵X_b和参数向量theta的点积,得到预测值
            # X_b.dot(self.theta) - y表示预测值与真实值之间的差值
            # X_b.T.dot(X_b.dot(self.theta) - y) 表示矩阵X_b的转置和差值的点积
            # (1 / m) * X_b.T.dot(X_b.dot(self.theta) - y)表示损失函数的梯度,即损失函数对参数的偏导数
            gradients = (1 / m) * X_b.T.dot(X_b.dot(self.theta) - y)
            # 使用梯度下降法更新参数
            # self.lr * gradients:学习率乘以梯度,表示参数调整的步长
            # self.theta -= ...:从当前参数中减去步长,完成一次参数更新
            self.theta -= self.lr * gradients

            # 每20次打印损失值(类似Java的调试输出)
            if epoch % 20 == 0:
                # X_b.dot(self.theta) - y:预测值与真实值之间的误差
                # np.sum((...) ** 2):计算误差平方和
                # (1 / (2 * m)):将误差平方和除以 2m,得到均方误差(MSE)
                loss = (1 / (2 * m)) * np.sum((X_b.dot(self.theta) - y) ** 2)
                print(f"Epoch {epoch:3d} | Loss: {loss:.4f}")

    def predict(self, X):
        X_b = np.c_[np.ones((len(X), 1)), X]
        return X_b.dot(self.theta)


# 模型训练(注意特征归一化)
model = LinearRegression(learning_rate=0.1, n_epochs=200)
model.fit(X, y)

# 预测新数据
X_new = np.array([[0], [2]])
y_pred = model.predict(X_new)
print("\n模型参数:", model.theta.ravel())  # 模型参数: [4.01515912 3.10466917]

# 可视化结果
plt.plot(X_new, y_pred, "r-", linewidth=2)
plt.plot(X, y, "b.")
plt.axis([0, 2, 0, 15])
plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lang20150928

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值