前言
Python 是用来做 AI 人工智能 的 , 不适合开发 Web 网站
为什么?
答 : 因为生态
Python 拥有全球最丰富、最成熟的 AI/ML 专用库,无需从零写算法,直接调用封装好的高性能接口即可:
| 领域 | 核心库 | 核心能力 |
|---|---|---|
| 机器学习 | Scikit-learn | 封装了所有经典算法(线性回归、决策树、SVM、聚类等),一行代码就能训练模型 |
| 深度学习 | TensorFlow / PyTorch | 工业级深度学习框架,支持 GPU/TPU 加速,覆盖计算机视觉、NLP、大模型开发 |
| 数据处理 | NumPy / Pandas | 高效处理矩阵 / 表格数据(AI 开发 80% 时间在处理数据),性能接近 C 语言 |
| 数据可视化 | Matplotlib / Seaborn | 快速绘制模型结果、数据分布,直观分析效果 |
| 大模型开发 | LangChain / Transformers | 基于 HuggingFace 生态,快速搭建大模型应用(问答、摘要、多模态) |
目录
如果你实在想开发 Web 应用 , 选择哪个 框架 好呢?
下面我来介绍一下
⚠️ : 排名不分先后顺序 !
Python Web 框架
一、主流 Web 框架分类
Python Web 框架主要分两类,核心区别是「是否包含全栈功能」:
| 类型 | 特点 | 代表框架 |
|---|---|---|
| 全栈框架(Full-Stack) | 内置模板引擎、ORM、表单验证、会话管理等全套功能,开箱即用 | Django、Web2py |
| 微框架(Micro-Framework) | 轻量、极简,只实现核心的路由 / 请求响应,其他功能需靠第三方库扩展 | Flask、FastAPI、Bottle |
二、核心框架详细介绍
1. Django(全栈王者)
核心特点
- 大而全:遵循「电池已内置」(Batteries Included)理念,内置 ORM、Admin 后台、表单验证、用户认证、缓存、国际化等所有 Web 开发需要的功能。
- MTV 架构:对应 MVC(Model - 模型 / 数据、Template - 模板 / 视图、View - 视图 / 控制器),逻辑清晰,适合大型项目。
- 严格的规范:强制使用 RESTful 路由、统一的配置风格,团队协作成本低。
适用场景
- 大型 / 复杂 Web 应用(电商、内容管理系统、企业后台、社交平台)。
- 追求开发效率、不想重复造轮子的场景。
核心优势
- 自带 Admin 后台:几行代码就能生成完整的后台管理界面,快速管理数据库。
- ORM 强大:无需写 SQL 即可操作数据库,支持 MySQL、PostgreSQL、SQLite 等。
- 生态丰富:第三方插件(Django REST Framework、Django Celery)覆盖所有需求。
入门示例(快速创建一个页面)
# 1. 安装:pip install django
# 2. 创建项目:django-admin startproject mysite
# 3. 创建应用:cd mysite && python manage.py startapp myapp
# 4. 在 myapp/views.py 中写视图
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello Django!")
# 5. 在 mysite/urls.py 配置路由
from django.urls import path
from myapp.views import hello
urlpatterns = [
path('hello/', hello),
]
# 6. 启动服务:python manage.py runserver
# 访问 http://127.0.0.1:8000/hello/ 即可看到结果
2. Flask(轻量灵活)
核心特点
- 极简主义:核心代码不足万行,只包含路由、请求响应、模板引擎(Jinja2)三个核心功能。
- 高度灵活:没有强制规范,可自由选择数据库、认证方式、缓存等第三方库。
- 扩展丰富:通过 Flask-SQLAlchemy(ORM)、Flask-Login(用户认证)等扩展可实现全栈功能。
适用场景
- 小型应用、个人项目、API 接口、原型开发。
- 追求灵活定制、不想被框架束缚的场景。
核心优势
- 学习成本极低:新手半小时可上手开发。
- 轻量无依赖:部署简单,资源占用少。
- 社区活跃:几乎所有需求都有对应的扩展。
入门示例
# 1. 安装:pip install flask
# 2. 创建 app.py
from flask import Flask
app = Flask(__name__)
@app.route('/hello')
def hello():
return "Hello Flask!"
if __name__ == '__main__':
app.run(debug=True) # debug=True 支持热更新
# 运行:python app.py,访问 http://127.0.0.1:5000/hello
3. FastAPI(高性能 API 首选)
核心特点
- 异步支持:基于 Starlette(异步框架)和 Pydantic(数据验证),性能接近 Node.js/Go。
- 自动生成文档:写代码时加类型注解,自动生成 Swagger/ReDoc 接口文档,无需手动写。
- 强类型验证:基于 Pydantic 做请求参数 / 响应数据验证,减少调试成本。
- 兼容 OpenAPI:符合 RESTful 规范,适合前后端分离、微服务。
适用场景
- 高性能 API 接口、微服务、前后端分离项目。
- 需要异步处理(如并发请求、IO 密集型任务)的场景。
核心优势
- 速度快:性能远超 Flask/Django,是 Python 中最快的 Web 框架之一。
- 易用性:语法接近 Flask,学习成本低,同时支持同步 / 异步代码。
- 现代化:原生支持 JSON、Form 数据、文件上传、WebSocket。
入门示例
# 1. 安装:pip install fastapi uvicorn
# 2. 创建 main.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# 定义请求数据模型
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
@app.get("/hello")
def read_root():
return {"message": "Hello FastAPI!"}
@app.post("/items/{item_id}")
def create_item(item_id: int, item: Item):
return {"item_id": item_id, "item_name": item.name, "price": item.price}
# 运行:uvicorn main:app --reload
# 访问 http://127.0.0.1:8000/docs 可看到自动生成的接口文档
4. 其他常用框架(补充)
| 框架 | 核心特点 | 适用场景 |
|---|---|---|
| Bottle | 超轻量(单文件),无依赖,无需安装额外库 | 小型脚本、嵌入式 Web 应用 |
| Tornado | 异步非阻塞,原生支持 WebSocket,高性能 | 实时应用(聊天、直播、推送) |
| Web2py | 全栈、自带数据库 / 后台 / 部署工具,零配置 | 快速开发、低维护成本的小型项目 |
| Sanic | 异步、高性能,语法接近 Flask | 高并发 API、IO 密集型服务 |
三、框架选择建议
| 需求场景 | 推荐框架 |
|---|---|
| 大型企业应用、内容管理系统 | Django |
| 小型 API、原型开发、个人项目 | Flask |
| 高性能 API、微服务、异步场景 | FastAPI |
| 实时应用(WebSocket) | Tornado/FastAPI |
| 超轻量、嵌入式应用 | Bottle |
总结
- Django:全栈、规范、高效,适合大型项目,新手也能快速上手(自带功能多,无需踩坑)。
- Flask:轻量、灵活,适合小项目 / API,学习成本最低,是新手入门首选。
- FastAPI:现代、高性能、自动生成文档,适合前后端分离 / 微服务,是当前最热门的 API 框架。
下面讲一下 数据处理 NumPy / Pandas
NumPy & Pandas 零基础数据处理教程
数据处理是 Python 数据分析/AI 开发的核心环节,NumPy 负责高效处理数值型数组(矩阵),Pandas 基于 NumPy 构建,专注于结构化数据(表格/行列)处理。本教程从基础语法到实战案例,带你掌握 80% 日常数据处理场景的用法。
一、前置准备
1.1 安装依赖
# 安装 NumPy + Pandas
pip install numpy pandas
# 验证安装
import numpy as np
import pandas as pd
print(f"NumPy 版本:{np.__version__}")
print(f"Pandas 版本:{pd.__version__}")
1.2 核心定位
| 工具 | 核心优势 | 适用场景 |
|---|---|---|
| NumPy | 高性能数组运算、广播机制 | 数值计算、矩阵操作、AI 数据预处理 |
| Pandas | 行列索引、缺失值处理、分组 | 表格数据清洗、统计分析、数据可视化 |
二、NumPy 核心教程
2.1 数组(ndarray)基础
NumPy 的核心是 ndarray 数组,比 Python 列表更高效(底层 C 实现)。
2.1.1 创建数组
import numpy as np
# 1. 从列表创建
arr1 = np.array([1, 2, 3, 4, 5]) # 一维数组
arr2 = np.array([[1, 2], [3, 4]]) # 二维数组(矩阵)
# 2. 快速创建特殊数组
arr_zero = np.zeros((2, 3)) # 全0数组 (2行3列)
arr_one = np.ones((3, 2)) # 全1数组
arr_range = np.arange(0, 10, 2) # 步长2的序列:[0 2 4 6 8]
arr_linspace = np.linspace(0, 1, 5) # 0-1均分5个数:[0. 0.25 0.5 0.75 1. ]
arr_random = np.random.rand(2, 2) # 0-1随机数数组
arr_eye = np.eye(3) # 3阶单位矩阵
# 查看数组属性
print("数组维度:", arr2.ndim) # 2
print("数组形状:", arr2.shape) # (2, 2)
print("数组元素类型:", arr2.dtype) # int64
print("数组元素个数:", arr2.size) # 4
2.1.2 数组索引与切片
arr = np.array([[1,2,3], [4,5,6], [7,8,9]])
# 1. 索引(行优先)
print(arr[0]) # 第一行:[1 2 3]
print(arr[0, 1]) # 第一行第二列:2
print(arr[:, 1]) # 所有行的第二列:[2 5 8]
# 2. 切片(左闭右开)
print(arr[0:2, 1:3]) # 前两行、后两列:[[2 3],[5 6]]
# 3. 布尔索引(筛选)
arr_bool = arr[arr > 5] # 筛选大于5的元素:[6 7 8 9]
2.2 数组运算(核心优势)
NumPy 支持向量化运算,无需循环,效率提升百倍。
a = np.array([1,2,3])
b = np.array([4,5,6])
# 1. 元素级运算
print(a + b) # [5 7 9]
print(a * b) # [4 10 18]
print(a **2) # [1 4 9]
print(a > 2) # [False False True]
# 2. 矩阵运算
mat1 = np.array([[1,2],[3,4]])
mat2 = np.array([[5,6],[7,8]])
print(np.dot(mat1, mat2)) # 矩阵乘法:[[19 22],[43 50]]
print(mat1 @ mat2) # 等价于dot,Python 3.5+支持
# 3. 聚合运算
arr = np.array([[1,2,3],[4,5,6]])
print(np.sum(arr)) # 总和:21
print(np.mean(arr)) # 均值:3.5
print(np.max(arr)) # 最大值:6
print(np.sum(arr, axis=0)) # 按列求和:[5 7 9]
print(np.sum(arr, axis=1)) # 按行求和:[6 15]
2.3 数组变形与拼接
# 1. 变形(reshape)
arr = np.arange(6)
arr_reshape = arr.reshape(2, 3) # 转为2行3列:[[0 1 2],[3 4 5]]
# 2. 拼接
arr1 = np.array([[1,2],[3,4]])
arr2 = np.array([[5,6],[7,8]])
arr_v = np.vstack((arr1, arr2)) # 垂直拼接:[[1 2],[3 4],[5 6],[7 8]]
arr_h = np.hstack((arr1, arr2)) # 水平拼接:[[1 2 5 6],[3 4 7 8]]
三、Pandas 核心教程
Pandas 核心数据结构是 Series(一维)和 DataFrame(二维表格),几乎所有操作围绕这两个结构展开。
3.1 数据结构基础
3.1.1 Series(一维序列)
import pandas as pd
# 创建Series(索引+值)
s1 = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
s2 = pd.Series({'苹果': 5, '香蕉': 3, '橙子': 7})
# 基本操作
print(s1['b']) # 按索引取值:20
print(s1[s1 > 25]) # 筛选值>25的元素:c:30, d:40
print(s1.mean()) # 均值:25.0
3.1.2 DataFrame(二维表格)
# 1. 创建DataFrame
# 方式1:字典创建(键=列名,值=列数据)
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [20, 25, 30],
'城市': ['北京', '上海', '广州']
}
df = pd.DataFrame(data)
# 方式2:从CSV/Excel读取(实战常用)
# df = pd.read_csv('data.csv')
# df = pd.read_excel('data.xlsx')
# 2. 查看数据
print(df.head()) # 前5行(默认)
print(df.info()) # 数据概览(列名、类型、缺失值)
print(df.describe()) # 数值列统计信息(均值、标准差等)
print(df.shape) # 形状:(3, 3)
# 3. 索引与列选择
print(df['姓名']) # 选择单列(返回Series)
print(df[['姓名', '年龄']]) # 选择多列(返回DataFrame)
print(df.loc[1]) # 按行索引取值(第二行)
print(df.loc[1, '城市']) # 按行+列索引取值:上海
print(df.iloc[1, 2]) # 按位置取值(第二行第三列)
3.2 数据清洗(实战高频)
数据清洗是 Pandas 最核心的应用场景,包括缺失值、重复值、异常值处理。
3.2.1 缺失值处理
# 创建含缺失值的DataFrame
df = pd.DataFrame({
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, 7, 8],
'C': [9, 10, 11, 12]
})
# 1. 查看缺失值
print(df.isnull().sum()) # 各列缺失值数量
# 2. 处理缺失值
df_drop = df.dropna() # 删除含缺失值的行
df_fill = df.fillna({'A': 0, 'B': df['B'].mean()}) # 填充:A列填0,B列填均值
3.2.2 重复值处理
df = pd.DataFrame({
'A': [1, 1, 2, 3],
'B': [5, 5, 6, 7]
})
# 查看重复行
print(df.duplicated()) # 返回布尔值:第二行为True(重复)
# 删除重复行
df_unique = df.drop_duplicates() # 保留第一行,删除后续重复行
3.2.3 数据类型转换
df = pd.DataFrame({
'年龄': ['20', '25', '30'], # 字符串类型
'收入': [5000.0, 8000.0, 10000.0]
})
# 转换类型
df['年龄'] = df['年龄'].astype(int) # 转为整数
df['收入'] = df['收入'].astype(int) # 转为整数
print(df.dtypes) # 查看转换后类型
3.3 数据筛选与排序
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [20, 25, 30, 25],
'城市': ['北京', '上海', '广州', '上海'],
'薪资': [8000, 12000, 15000, 10000]
})
# 1. 条件筛选
# 筛选上海的用户
df_sh = df[df['城市'] == '上海']
# 筛选年龄>25 且 薪资>10000的用户
df_filter = df[(df['年龄'] > 25) & (df['薪资'] > 10000)]
# 2. 排序
df_sort = df.sort_values(by='薪资', ascending=False) # 按薪资降序
df_sort2 = df.sort_values(by=['城市', '年龄']) # 先按城市、再按年龄排序
3.4 数据分组与聚合(GroupBy)
GroupBy 是 Pandas 统计分析的核心,实现「拆分-应用-合并」逻辑。
# 按城市分组,计算各城市的平均薪资、最大年龄
df_group = df.groupby('城市').agg({
'薪资': 'mean', # 平均薪资
'年龄': 'max' # 最大年龄
}).reset_index() # 重置索引,让分组列变回普通列
print(df_group)
# 输出:
# 城市 薪资 年龄
# 0 上海 11000.0 25
# 1 北京 8000.0 20
# 2 广州 15000.0 30
3.5 数据合并与导出
3.5.1 数据合并(类似SQL JOIN)
# 两个DataFrame合并
df1 = pd.DataFrame({
'学号': [1, 2, 3],
'姓名': ['张三', '李四', '王五']
})
df2 = pd.DataFrame({
'学号': [1, 2, 4],
'成绩': [90, 85, 88]
})
# 内连接(仅保留匹配的行)
df_inner = pd.merge(df1, df2, on='学号', how='inner')
# 左连接(保留df1所有行)
df_left = pd.merge(df1, df2, on='学号', how='left')
3.5.2 数据导出
# 导出为CSV(解决中文乱码)
df.to_csv('result.csv', index=False, encoding='utf-8-sig')
# 导出为Excel(需安装openpyxl)
# pip install openpyxl
df.to_excel('result.xlsx', index=False, sheet_name='数据结果')
四、实战案例:豆瓣Top250数据处理
结合爬取的豆瓣Top250数据,演示完整的数据处理流程:
import pandas as pd
import numpy as np
# 1. 读取爬取的CSV数据
df = pd.read_csv('douban_top250.csv', encoding='utf-8-sig')
# 2. 数据概览
print("数据形状:", df.shape)
print("缺失值统计:\n", df.isnull().sum())
# 3. 清洗数据:提取年份/类型/地区(从“详细信息”列拆分)
def extract_year(info):
"""从详细信息中提取年份"""
import re
year = re.findall(r'(\d{4})', info)
return year[0] if year else np.nan
def extract_genre(info):
"""提取类型"""
genre = info.split('/')[-3].strip()
return genre
df['年份'] = df['详细信息'].apply(extract_year)
df['类型'] = df['详细信息'].apply(extract_genre)
df['评分'] = df['评分'].astype(float) # 确保评分为浮点型
# 4. 统计分析
# 4.1 评分分布
score_count = df['评分'].value_counts().sort_index(ascending=False)
print("评分分布:\n", score_count)
# 4.2 按类型分组,计算平均评分
genre_score = df.groupby('类型')['评分'].agg(['mean', 'count']).reset_index()
genre_score = genre_score[genre_score['count'] >= 5] # 筛选数量≥5的类型
genre_score = genre_score.sort_values('mean', ascending=False)
print("各类型平均评分(数量≥5):\n", genre_score)
# 4.3 找出评分9.5以上的电影
high_score = df[df['评分'] >= 9.5][['排名', '标题', '评分', '年份']]
print("评分9.5以上的电影:\n", high_score)
# 5. 导出清洗后的数据
df_clean = df[['排名', '标题', '评分', '年份', '类型', '评价人数', '简介']]
df_clean.to_csv('douban_top250_clean.csv', index=False, encoding='utf-8-sig')
print("清洗后的数据已导出!")
五、核心技巧与避坑指南
5.1 性能优化
- NumPy:优先使用向量化运算,避免
for循环; - Pandas:
- 避免链式赋值(如
df[df['A']>0]['B']=1),改用df.loc[df['A']>0, 'B']=1; - 大数据处理时用
df.iterrows()改为df.itertuples(),速度提升10倍+; - 内存不足时,用
df.astype('category')转换低基数列(如城市、类型)。
- 避免链式赋值(如
5.2 常见坑点
- 索引问题:
loc按索引取值,iloc按位置取值,不要混用; - 缺失值:聚合运算(
sum/mean)会自动忽略缺失值,需先确认是否合理; - 中文乱码:读取/导出CSV时指定
encoding='utf-8-sig',Excel可正常显示; - 数据类型:字符串型的数字无法参与运算,需用
astype转换。
总结
关键点回顾
- NumPy:核心是
ndarray数组,优势是向量化运算,适合数值/矩阵操作,是 Pandas 的底层支撑; - Pandas:核心是
DataFrame表格,专注结构化数据处理,核心功能包括清洗(缺失/重复值)、筛选、分组聚合、数据合并; - 实战流程:读取数据 → 概览清洗 → 分析统计 → 导出结果,是数据处理的通用范式。
进阶方向
- NumPy:学习广播机制、广播规则、线性代数模块(
np.linalg); - Pandas:学习时间序列处理(
pd.to_datetime)、透视表(pivot_table)、数据可视化(结合 Matplotlib/Seaborn); - 结合实战:处理电商数据、金融数据、爬虫数据,深化对工具的理解。
掌握 NumPy + Pandas 后,你就能高效完成从原始数据到可分析数据的全流程处理,为后续的可视化、建模打下基础。
接下来讲一下 : 数据可视化 Matplotlib
Matplotlib 零基础数据可视化教程
Matplotlib 是 Python 最核心的数据可视化库,能绘制折线图、柱状图、散点图、饼图等几乎所有类型的图表,也是 Pandas、Seaborn 等可视化工具的底层依赖。本教程从基础语法到实战案例,带你掌握日常数据分析中 90% 的可视化场景。
一、前置准备
1.1 安装依赖
# 安装 Matplotlib
pip install matplotlib
# 验证安装
import matplotlib.pyplot as plt
print(f"Matplotlib 版本:{plt.__version__}")
# 可选:安装中文字体支持(解决中文乱码)
# Windows/macOS/Linux 字体配置见下文「避坑指南」
1.2 核心概念
Matplotlib 绘图的核心是「画布-子图」结构,理解以下概念能快速上手:
| 概念 | 作用 |
|---|---|
| Figure | 画布(整个绘图窗口),可包含多个子图(Axes) |
| Axes | 子图(实际绘图区域),一个 Figure 可有多个 Axes(如 2行2列的子图矩阵) |
| Axis | 坐标轴(X/Y轴),负责刻度、标签、范围控制 |
| Artist | 绘图元素(线条、文字、图例、颜色等) |
二、基础绘图流程
Matplotlib 绘图遵循固定流程,无论绘制哪种图表,核心步骤一致:
import matplotlib.pyplot as plt
import numpy as np
# 1. 准备数据
x = np.arange(0, 10, 0.5)
y = np.sin(x)
# 2. 创建画布+子图(两种方式)
# 方式1:快速创建(推荐新手)
plt.figure(figsize=(8, 4)) # 设置画布大小:宽8英寸,高4英寸
# 3. 绘制图表
plt.plot(x, y, label='sin(x)', color='red', linestyle='-', linewidth=2)
# 4. 美化图表(标签、标题、图例、网格)
plt.xlabel('X 轴', fontsize=12) # X轴标签
plt.ylabel('Y 轴', fontsize=12) # Y轴标签
plt.title('正弦函数曲线', fontsize=14) # 标题
plt.legend(loc='best') # 图例(best:自动选最优位置)
plt.grid(True, alpha=0.3) # 网格(alpha:透明度)
# 5. 显示/保存图表
plt.tight_layout() # 自动调整布局,避免标签被截断
plt.savefig('sin_curve.png', dpi=300) # 保存图片(dpi:分辨率)
plt.show() # 显示图表
三、常见图表绘制实战
3.1 折线图(Line Plot)
适用于展示数据随时间/连续变量的变化趋势(如股价、温度、销量)。
import matplotlib.pyplot as plt
import numpy as np
# 准备数据:月度销量数据
months = ['1月', '2月', '3月', '4月', '5月', '6月']
product_a = [120, 150, 180, 160, 200, 220]
product_b = [80, 100, 110, 130, 150, 170]
# 创建画布
plt.figure(figsize=(10, 6))
# 绘制折线图
plt.plot(months, product_a, label='产品A', color='#FF5733', linewidth=2, marker='o')
plt.plot(months, product_b, label='产品B', color='#33A1FF', linewidth=2, marker='s')
# 美化配置
plt.xlabel('月份', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.title('2024年上半年产品销量趋势', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.2)
# 显示数值标签(可选)
for x, y in zip(months, product_a):
plt.text(x, y+5, str(y), ha='center', fontsize=9)
plt.tight_layout()
plt.savefig('line_plot.png', dpi=300)
plt.show()
3.2 柱状图(Bar Plot)
适用于对比不同类别数据的大小(如各城市销售额、各部门人数)。
import matplotlib.pyplot as plt
import numpy as np
# 准备数据:各城市销售额
cities = ['北京', '上海', '广州', '深圳', '成都']
sales = [850, 920, 780, 880, 650]
# 创建画布
plt.figure(figsize=(10, 6))
# 绘制柱状图
bars = plt.bar(cities, sales, color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57'])
# 美化配置
plt.xlabel('城市', fontsize=12)
plt.ylabel('销售额(万元)', fontsize=12)
plt.title('2024年Q1各城市销售额对比', fontsize=14)
plt.grid(axis='y', alpha=0.2) # 仅显示Y轴网格
# 显示数值标签
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2, height+10,
str(height), ha='center', fontsize=10)
plt.tight_layout()
plt.savefig('bar_plot.png', dpi=300)
plt.show()
# 进阶:分组柱状图(对比两年数据)
sales_2023 = [780, 850, 720, 800, 600]
x = np.arange(len(cities))
width = 0.35 # 柱子宽度
plt.figure(figsize=(10, 6))
plt.bar(x - width/2, sales_2023, width, label='2023年', color='#FF6B6B')
plt.bar(x + width/2, sales, width, label='2024年', color='#4ECDC4')
plt.xlabel('城市', fontsize=12)
plt.ylabel('销售额(万元)', fontsize=12)
plt.title('2023-2024年Q1各城市销售额对比', fontsize=14)
plt.xticks(x, cities)
plt.legend()
plt.grid(axis='y', alpha=0.2)
plt.tight_layout()
plt.savefig('group_bar_plot.png', dpi=300)
plt.show()
3.3 散点图(Scatter Plot)
适用于展示两个变量的相关性(如身高-体重、广告投入-销售额)。
import matplotlib.pyplot as plt
import numpy as np
# 准备数据:广告投入与销售额(模拟数据)
np.random.seed(0) # 固定随机种子,结果可复现
ad_spend = np.random.uniform(10, 100, 50) # 广告投入:10-100万
sales = 2 * ad_spend + np.random.normal(0, 10, 50) # 销售额:线性关系+随机噪声
# 创建画布
plt.figure(figsize=(10, 6))
# 绘制散点图
plt.scatter(ad_spend, sales, c='#FF6B6B', alpha=0.7, s=50, edgecolors='black', linewidth=0.5)
# 添加趋势线(可选)
z = np.polyfit(ad_spend, sales, 1)
p = np.poly1d(z)
plt.plot(ad_spend, p(ad_spend), color='#4ECDC4', linestyle='--', label=f'趋势线:y={z[0]:.2f}x+{z[1]:.2f}')
# 美化配置
plt.xlabel('广告投入(万元)', fontsize=12)
plt.ylabel('销售额(万元)', fontsize=12)
plt.title('广告投入与销售额相关性分析', fontsize=14)
plt.legend()
plt.grid(alpha=0.2)
plt.tight_layout()
plt.savefig('scatter_plot.png', dpi=300)
plt.show()
3.4 饼图(Pie Plot)
适用于展示各部分占总体的比例(如市场份额、用户分布、费用占比)。
import matplotlib.pyplot as plt
import numpy as np
# 准备数据:产品类别销售额占比
categories = ['电子产品', '服装', '食品', '家居', '其他']
sales_ratio = [35, 25, 20, 15, 5]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57']
explode = (0.1, 0, 0, 0, 0) # 突出显示第一块(电子产品)
# 创建画布
plt.figure(figsize=(8, 8))
# 绘制饼图
patches, texts, autotexts = plt.pie(
sales_ratio,
explode=explode,
labels=categories,
colors=colors,
autopct='%1.1f%%', # 显示百分比
shadow=True, # 阴影效果
startangle=90, # 起始角度
textprops={'fontsize': 11}
)
# 美化百分比文字
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
plt.title('2024年Q1产品类别销售额占比', fontsize=14)
plt.axis('equal') # 保证饼图为正圆形
plt.tight_layout()
plt.savefig('pie_plot.png', dpi=300)
plt.show()
3.5 直方图(Histogram)
适用于展示数据的分布特征(如身高分布、成绩分布、销售额分布)。
import matplotlib.pyplot as plt
import numpy as np
# 准备数据:学生成绩分布(模拟正态分布)
np.random.seed(0)
scores = np.random.normal(75, 10, 500) # 均值75,标准差10,500个样本
scores = np.clip(scores, 0, 100) # 限制成绩在0-100之间
# 创建画布
plt.figure(figsize=(10, 6))
# 绘制直方图
n, bins, patches = plt.hist(
scores,
bins=15, # 分箱数
color='#4ECDC4',
edgecolor='black',
alpha=0.7
)
# 美化配置
plt.xlabel('成绩', fontsize=12)
plt.ylabel('人数', fontsize=12)
plt.title('500名学生数学成绩分布', fontsize=14)
plt.grid(axis='y', alpha=0.2)
# 添加统计信息
mean_score = scores.mean()
median_score = np.median(scores)
plt.axvline(mean_score, color='red', linestyle='--', label=f'均值:{mean_score:.1f}')
plt.axvline(median_score, color='orange', linestyle='--', label=f'中位数:{median_score:.1f}')
plt.legend()
plt.tight_layout()
plt.savefig('hist_plot.png', dpi=300)
plt.show()
四、进阶技巧:多子图与Pandas联动
4.1 多子图绘制
一个画布中绘制多个子图,适合对比不同维度的数据:
import matplotlib.pyplot as plt
import numpy as np
# 准备数据
x = np.arange(0, 10, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = x **2
y4 = np.log(x+1)
# 创建2行2列的子图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
fig.suptitle('多子图示例', fontsize=16)
# 子图1:正弦函数
axes[0, 0].plot(x, y1, color='#FF6B6B')
axes[0, 0].set_title('sin(x)')
axes[0, 0].grid(alpha=0.2)
# 子图2:余弦函数
axes[0, 1].plot(x, y2, color='#4ECDC4')
axes[0, 1].set_title('cos(x)')
axes[0, 1].grid(alpha=0.2)
# 子图3:二次函数
axes[1, 0].plot(x, y3, color='#45B7D1')
axes[1, 0].set_title('x²')
axes[1, 0].grid(alpha=0.2)
# 子图4:对数函数
axes[1, 1].plot(x, y4, color='#96CEB4')
axes[1, 1].set_title('log(x+1)')
axes[1, 1].grid(alpha=0.2)
# 统一调整布局
plt.tight_layout()
plt.savefig('subplots_plot.png', dpi=300)
plt.show()
4.2 与Pandas联动(实战高频)
Pandas 内置 Matplotlib 接口,可直接对 DataFrame/Series 绘图:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 准备数据:豆瓣Top250电影数据(模拟)
data = {
'评分': np.random.uniform(8.5, 9.8, 250),
'年份': np.random.randint(1930, 2024, 250),
'类型': np.random.choice(['剧情', '喜剧', '动作', '爱情', '科幻'], 250)
}
df = pd.DataFrame(data)
# 1. Pandas直接绘制柱状图:各类型电影数量
plt.figure(figsize=(10, 6))
df['类型'].value_counts().plot(kind='bar', color='#FF6B6B')
plt.xlabel('电影类型')
plt.ylabel('数量')
plt.title('豆瓣Top250电影类型分布')
plt.grid(axis='y', alpha=0.2)
plt.tight_layout()
plt.savefig('pandas_bar.png', dpi=300)
plt.show()
# 2. Pandas绘制散点图:年份与评分的关系
plt.figure(figsize=(10, 6))
df.plot(kind='scatter', x='年份', y='评分', color='#4ECDC4', alpha=0.6, ax=plt.gca())
plt.xlabel('上映年份')
plt.ylabel('评分')
plt.title('豆瓣Top250电影年份与评分关系')
plt.grid(alpha=0.2)
plt.tight_layout()
plt.savefig('pandas_scatter.png', dpi=300)
plt.show()
五、避坑指南与美化技巧
5.1 中文乱码解决
Matplotlib 默认不支持中文字体,需手动配置:
import matplotlib.pyplot as plt
# 方法1:临时配置(每次运行生效)
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows:黑体;macOS:Arial Unicode MS;Linux:WenQuanYi Micro Hei
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 方法2:永久配置(修改配置文件,一劳永逸)
# 1. 查找配置文件路径:
# import matplotlib
# print(matplotlib.matplotlib_fname())
# 2. 编辑配置文件,修改:
# font.sans-serif: SimHei, DejaVu Sans
# axes.unicode_minus: False
# 3. 清空Matplotlib缓存(删除缓存目录)
5.2 常用美化技巧
- 颜色搭配:使用专业配色(如
#FF6B6B、#4ECDC4、#45B7D1),避免纯红/纯绿/纯蓝; - 透明度:
alpha参数设为 0.5-0.8,避免图表过于厚重; - 布局调整:
plt.tight_layout()自动调整子图间距,避免标签截断; - 分辨率:保存图片时
dpi=300,保证高清; - 网格线:仅显示Y轴网格(
grid(axis='y')),减少视觉干扰。
5.3 常见问题
- 图表不显示:忘记加
plt.show()(Jupyter Notebook 除外); - 标签截断:未加
plt.tight_layout(); - 负号显示为方块:未配置
axes.unicode_minus = False; - 保存图片为空白:
plt.savefig()需在plt.show()之前执行。
总结
关键点回顾
- 核心流程:Matplotlib 绘图固定步骤为「准备数据 → 创建画布 → 绘制图表 → 美化配置 → 保存/显示」;
- 图表选型:
- 趋势对比用折线图,类别对比用柱状图,相关性分析用散点图;
- 比例展示用饼图,分布分析用直方图;
- 实战技巧:
- 与 Pandas 联动可快速可视化表格数据;
- 多子图适合对比不同维度数据;
- 中文乱码需配置字体和负号显示。
进阶方向
- 学习 Seaborn(基于 Matplotlib 的高级可视化库,更美观、更易用);
- 学习 3D 绘图(
mpl_toolkits.mplot3d); - 学习交互式可视化(Plotly、Bokeh),适合网页展示;
- 结合实战:可视化爬虫数据、机器学习模型结果、业务报表数据。
掌握 Matplotlib 后,你能将枯燥的数字转化为直观的图表,快速洞察数据规律,是数据分析/AI 开发的必备技能。
接下来介绍一下 数据可视化 : Seaborn
Seaborn 零基础数据可视化教程
Seaborn 是基于 Matplotlib 构建的高级数据可视化库,专为统计分析设计,相比 Matplotlib 更美观、更贴合 Pandas 数据结构,且内置多种专业的统计图表(如热力图、小提琴图、配对图)。本教程从基础配置到实战案例,带你掌握 Seaborn 核心用法,快速做出专业级可视化图表。
一、前置准备
1.1 安装依赖
Seaborn 依赖 Matplotlib 和 Pandas,先确保已安装:
# 安装 Seaborn
pip install seaborn matplotlib pandas numpy
# 验证安装
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
print(f"Seaborn 版本:{sns.__version__}")
1.2 核心优势
| 特性 | Seaborn 优势 | Matplotlib 对比 |
|---|---|---|
| 风格美化 | 内置 5+ 专业配色风格(darkgrid、whitegrid 等) | 需手动调整颜色、样式 |
| 数据适配 | 原生支持 Pandas DataFrame,无需手动转换 | 需提取数组后绘图 |
| 统计图表 | 内置热力图、小提琴图、配对图等统计图表 | 需手动实现统计逻辑 |
| 配色系统 | 内置分类/连续/发散型配色方案(如 husl、viridis) | 需手动指定 RGB/十六进制颜色 |
1.3 基础配置
Seaborn 可一键设置全局风格,解决 Matplotlib 中文乱码、样式简陋问题:
import seaborn as sns
import matplotlib.pyplot as plt
# 1. 设置绘图风格(推荐 whitegrid:带网格的白色背景)
sns.set_style("whitegrid")
# 2. 解决中文乱码(同 Matplotlib)
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows:黑体;macOS:Arial Unicode MS;Linux:WenQuanYi Micro Hei
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 3. 设置图表尺寸和分辨率
plt.figure(figsize=(10, 6), dpi=100)
# 4. 设置配色主题(可选:deep、muted、bright、pastel、dark、colorblind)
sns.set_palette("pastel")
二、Seaborn 核心图表实战
Seaborn 图表可分为「分类图表」「关系图表」「分布图表」「矩阵图表」四大类,覆盖 90% 统计可视化场景。
2.1 分类图表:对比不同类别数据
适用于展示类别变量与数值变量的关系,核心图表包括条形图、箱线图、小提琴图。
2.1.1 条形图(barplot)
与 Matplotlib 柱状图不同,Seaborn barplot 会自动计算类别均值,并显示误差棒(置信区间):
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# 准备数据:各城市各产品销售额
data = pd.DataFrame({
'城市': ['北京', '北京', '上海', '上海', '广州', '广州'],
'产品': ['A', 'B', 'A', 'B', 'A', 'B'],
'销售额': [850, 720, 920, 800, 780, 650]
})
# 设置风格
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 6))
# 绘制条形图
# x=类别列,y=数值列,hue=分组列,data=数据框
ax = sns.barplot(
x='城市',
y='销售额',
hue='产品',
data=data,
palette="pastel", # 配色方案
errorbar=None # 隐藏误差棒(新手可选)
)
# 美化配置
ax.set_title('各城市不同产品销售额对比', fontsize=14)
ax.set_xlabel('城市', fontsize=12)
ax.set_ylabel('销售额(万元)', fontsize=12)
# 显示数值标签(手动添加)
for container in ax.containers:
ax.bar_label(container, fontsize=10)
# 移除顶部/右侧边框(Seaborn 美化技巧)
sns.despine()
plt.tight_layout()
plt.savefig('seaborn_barplot.png', dpi=300)
plt.show()
2.1.2 箱线图(boxplot)
展示数据的四分位数、中位数、异常值,适合分析类别数据的分布离散程度:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 准备数据:不同学科学生成绩分布
np.random.seed(0) # 固定随机种子
data = pd.DataFrame({
'学科': ['数学']*50 + ['语文']*50 + ['英语']*50,
'成绩': np.concatenate([
np.random.normal(75, 10, 50), # 数学成绩:均值75,标准差10
np.random.normal(80, 8, 50), # 语文成绩:均值80,标准差8
np.random.normal(70, 12, 50) # 英语成绩:均值70,标准差12
])
})
# 设置风格
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 6))
# 绘制箱线图
ax = sns.boxplot(
x='学科',
y='成绩',
data=data,
palette="Set2",
linewidth=1.5 # 边框宽度
)
# 美化配置
ax.set_title('不同学科学生成绩分布', fontsize=14)
ax.set_xlabel('学科', fontsize=12)
ax.set_ylabel('成绩', fontsize=12)
sns.despine()
plt.tight_layout()
plt.savefig('seaborn_boxplot.png', dpi=300)
plt.show()
2.1.3 小提琴图(violinplot)
结合箱线图和核密度图,展示数据的分布密度,比箱线图更直观:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 复用上面的成绩数据
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 6))
# 绘制小提琴图
ax = sns.violinplot(
x='学科',
y='成绩',
data=data,
palette="muted",
inner="quartile" # 内部显示四分位数
)
# 美化配置
ax.set_title('不同学科学生成绩分布(小提琴图)', fontsize=14)
ax.set_xlabel('学科', fontsize=12)
ax.set_ylabel('成绩', fontsize=12)
sns.despine()
plt.tight_layout()
plt.savefig('seaborn_violinplot.png', dpi=300)
plt.show()
2.2 关系图表:展示变量间的关联
适用于分析数值变量之间的关系,核心图表包括散点图、线图、回归图。
2.2.1 散点图(scatterplot)
比 Matplotlib 散点图更强大,支持按类别着色、调整点大小:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 准备数据:广告投入与销售额
np.random.seed(0)
data = pd.DataFrame({
'广告投入': np.random.uniform(10, 100, 100),
'销售额': 2.5 * np.random.uniform(10, 100, 100) + np.random.normal(0, 15, 100),
'渠道': np.random.choice(['线上', '线下', '混合'], 100)
})
# 设置风格
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 6))
# 绘制散点图
ax = sns.scatterplot(
x='广告投入',
y='销售额',
hue='渠道', # 按渠道着色
size='广告投入', # 按投入大小调整点尺寸
sizes=(50, 200), # 点尺寸范围
data=data,
palette="Set1",
alpha=0.7 # 透明度
)
# 美化配置
ax.set_title('广告投入与销售额相关性(按渠道分类)', fontsize=14)
ax.set_xlabel('广告投入(万元)', fontsize=12)
ax.set_ylabel('销售额(万元)', fontsize=12)
sns.despine()
plt.tight_layout()
plt.savefig('seaborn_scatterplot.png', dpi=300)
plt.show()
2.2.2 回归图(regplot)
自动拟合线性回归模型,展示变量间的线性关系和置信区间:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 复用广告投入数据
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 6))
# 绘制回归图
ax = sns.regplot(
x='广告投入',
y='销售额',
data=data,
color='#FF6B6B',
line_kws={'color': '#4ECDC4'}, # 趋势线颜色
scatter_kws={'alpha': 0.6} # 散点透明度
)
# 美化配置
ax.set_title('广告投入与销售额线性回归分析', fontsize=14)
ax.set_xlabel('广告投入(万元)', fontsize=12)
ax.set_ylabel('销售额(万元)', fontsize=12)
sns.despine()
plt.tight_layout()
plt.savefig('seaborn_regplot.png', dpi=300)
plt.show()
2.3 分布图表:分析数据分布特征
适用于展示单变量/双变量的分布规律,核心图表包括直方图、核密度图、联合分布图。
2.3.1 直方图+核密度图(histplot):单变量分布
Seaborn histplot 可同时展示直方图和核密度曲线,比 Matplotlib 直方图更专业:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 准备数据:用户年龄分布
np.random.seed(0)
data = pd.DataFrame({
'年龄': np.random.normal(30, 8, 1000) # 均值30,标准差8
})
# 设置风格
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10, 6))
# 绘制直方图+核密度图
ax = sns.histplot(
data=data,
x='年龄',
kde=True, # 显示核密度曲线
color='#4ECDC4',
bins=20, # 分箱数
edgecolor='black'
)
# 美化配置
ax.set_title('平台用户年龄分布', fontsize=14)
ax.set_xlabel('年龄', fontsize=12)
ax.set_ylabel('人数', fontsize=12)
sns.despine()
plt.tight_layout()
plt.savefig('seaborn_histplot.png', dpi=300)
plt.show()
2.3.2 联合分布图(jointplot):双变量分布
同时展示两个变量的散点图+边际分布,快速分析双变量关系:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 准备数据:身高与体重
np.random.seed(0)
data = pd.DataFrame({
'身高': np.random.normal(170, 8, 500),
'体重': 0.6 * np.random.normal(170, 8, 500) + np.random.normal(0, 5, 500)
})
# 设置风格
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
# 绘制联合分布图
g = sns.jointplot(
data=data,
x='身高',
y='体重',
kind='scatter', # 类型:scatter/reg/kde
color='#FF6B6B',
alpha=0.6,
height=8 # 图表大小
)
# 美化配置
g.fig.suptitle('用户身高与体重关系分析', y=1.02, fontsize=14)
g.set_axis_labels('身高(cm)', '体重(kg)', fontsize=12)
plt.tight_layout()
plt.savefig('seaborn_jointplot.png', dpi=300)
plt.show()
2.4 矩阵图表:展示变量间的关联强度
核心是热力图(heatmap),适用于展示变量相关性矩阵、混淆矩阵等。
2.4.1 热力图(heatmap)
分析多个数值变量之间的相关系数,是数据分析的核心图表:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 准备数据:电商数据(销售额、流量、转化率、客单价)
np.random.seed(0)
data = pd.DataFrame({
'销售额': np.random.uniform(1000, 5000, 100),
'流量': np.random.uniform(5000, 20000, 100),
'转化率': np.random.uniform(1, 5, 100),
'客单价': np.random.uniform(50, 200, 100)
})
# 计算相关性矩阵
corr = data.corr()
# 设置风格
sns.set_style("white")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(8, 6))
# 绘制热力图
ax = sns.heatmap(
corr,
annot=True, # 显示相关系数数值
fmt='.2f', # 数值格式(保留2位小数)
cmap='coolwarm', # 配色(coolwarm:蓝-红,发散型)
vmin=-1, vmax=1, # 数值范围(相关系数-1到1)
square=True, # 正方形单元格
linewidths=0.5 # 单元格边框宽度
)
# 美化配置
ax.set_title('电商核心指标相关性矩阵', fontsize=14)
plt.tight_layout()
plt.savefig('seaborn_heatmap.png', dpi=300)
plt.show()
三、进阶技巧:多子图与实战案例
3.1 多子图绘制(FacetGrid)
按类别自动生成多子图,适合对比不同分组的数据分布:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 准备数据:不同性别/城市的用户消费数据
np.random.seed(0)
data = pd.DataFrame({
'消费金额': np.random.uniform(100, 1000, 200),
'性别': np.random.choice(['男', '女'], 200),
'城市': np.random.choice(['一线', '新一线', '二线'], 200)
})
# 设置风格
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
# 创建多子图网格:按城市分行,按性别分列
g = sns.FacetGrid(
data=data,
row='城市',
col='性别',
height=4,
aspect=1.2
)
# 绘制直方图
g.map(sns.histplot, '消费金额', kde=True, bins=10, color='#4ECDC4')
# 统一设置标题和标签
g.set_titles(row_template='{row_name}城市', col_template='{col_name}性')
g.set_axis_labels('消费金额(元)', '人数')
g.fig.suptitle('不同城市/性别用户消费金额分布', y=1.02, fontsize=14)
plt.tight_layout()
plt.savefig('seaborn_facetgrid.png', dpi=300)
plt.show()
3.2 实战案例:豆瓣Top250电影数据可视化
结合之前爬取的豆瓣Top250数据,完成完整的可视化分析:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 1. 模拟豆瓣Top250数据
np.random.seed(0)
data = pd.DataFrame({
'评分': np.random.uniform(8.5, 9.8, 250),
'年份': np.random.randint(1930, 2024, 250),
'评价人数': np.random.randint(100000, 1000000, 250),
'类型': np.random.choice(['剧情', '喜剧', '动作', '爱情', '科幻'], 250)
})
# 2. 设置全局风格
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 3. 子图1:各类型电影数量(条形图)
plt.subplot(2, 2, 1)
sns.countplot(x='类型', data=data, palette='pastel')
plt.title('豆瓣Top250电影类型分布')
plt.xlabel('类型')
plt.ylabel('数量')
sns.despine()
# 4. 子图2:年份与评分的关系(散点图)
plt.subplot(2, 2, 2)
sns.scatterplot(x='年份', y='评分', data=data, color='#FF6B6B', alpha=0.6)
plt.title('电影年份与评分关系')
plt.xlabel('上映年份')
plt.ylabel('评分')
sns.despine()
# 5. 子图3:各类型电影评分分布(箱线图)
plt.subplot(2, 2, 3)
sns.boxplot(x='类型', y='评分', data=data, palette='muted')
plt.title('各类型电影评分分布')
plt.xlabel('类型')
plt.ylabel('评分')
sns.despine()
# 6. 子图4:评分与评价人数的关系(回归图)
plt.subplot(2, 2, 4)
sns.regplot(x='评价人数', y='评分', data=data, color='#4ECDC4', scatter_kws={'alpha': 0.5})
plt.title('评分与评价人数相关性')
plt.xlabel('评价人数')
plt.ylabel('评分')
sns.despine()
# 7. 整体配置
plt.tight_layout()
plt.suptitle('豆瓣Top250电影数据可视化分析', y=1.02, fontsize=14)
plt.savefig('douban_top250_seaborn.png', dpi=300)
plt.show()
四、避坑指南与美化技巧
4.1 常见问题解决
- 中文乱码:
同 Matplotlib,需配置
font.sans-serif和axes.unicode_minus; - 图表样式不生效:
sns.set_style()需在绘图前执行,且后续不会被 Matplotlib 覆盖; - 配色方案选择:
- 分类数据:
pastel/Set2/colorblind(色盲友好); - 连续数据:
viridis/plasma; - 发散数据(如相关性):
coolwarm/RdBu;
- 分类数据:
- 子图间距问题:
使用
plt.tight_layout()或g.fig.suptitle(y=1.02)调整标题位置。
4.2 美化核心技巧
- 移除边框:
sns.despine()移除顶部/右侧边框,让图表更简洁; - 调整透明度:
alpha=0.5-0.8避免点重叠,提升可读性; - 统一字体大小:标题
fontsize=14,轴标签fontsize=12,数值标签fontsize=10; - 添加网格:使用
whitegrid风格,仅显示Y轴网格,减少视觉干扰; - 颜色搭配:避免高饱和度颜色,优先使用 Seaborn 内置配色方案。
总结
关键点回顾
- 核心优势:Seaborn 基于 Matplotlib,原生支持 Pandas DataFrame,内置统计图表和专业配色,比 Matplotlib 更适合数据分析场景;
- 图表选型:
- 类别对比:条形图(barplot)、箱线图(boxplot)、小提琴图(violinplot);
- 关系分析:散点图(scatterplot)、回归图(regplot)、联合分布图(jointplot);
- 分布分析:直方图(histplot)、核密度图;
- 矩阵分析:热力图(heatmap);
- 实战流程:数据准备 → 风格配置 → 绘制图表 → 美化调整 → 保存/展示。
进阶方向
- 学习 Seaborn 进阶图表(如 clustermap 聚类热力图、pairplot 配对图);
- 结合统计分析(如 ANOVA、卡方检验),让图表更具说服力;
- 学习交互式可视化(Plotly Express),基于 Seaborn 语法实现网页交互;
- 定制化配色和样式,适配企业/论文的可视化规范。
Seaborn 是数据分析的「可视化利器」,掌握后可快速做出专业级图表,比 Matplotlib 效率提升 50% 以上,是数据分析师/AI 工程师的必备技能。
接下来介绍一下 : LangChain
LangChain 零基础入门教程
LangChain 是当前最主流的大模型应用开发框架,核心价值是「串联大模型与各类工具/数据/流程」,让开发者无需从零编写复杂逻辑,快速构建智能问答、知识库、自动化工作流等 AI 应用。本教程从核心概念、环境搭建到实战项目,全方位覆盖 LangChain 核心用法,所有代码均可直接运行。
一、LangChain 核心认知
1.1 什么是 LangChain?
LangChain 不是大模型,而是大模型应用开发的“胶水框架” ——它提供一套标准化的接口和组件,将大模型(如 GPT-4、通义千问、文心一言)、数据(PDF/文档/数据库)、工具(搜索引擎/计算器)、记忆(对话历史)、流程(多步骤逻辑)串联起来,大幅降低 AI 应用开发成本。
1.2 核心优势
| 优势 | 具体价值 |
|---|---|
| 模块化设计 | 组件可自由组合(如替换大模型、切换向量库),适配不同场景 |
| 一站式能力 | 内置文档加载、向量化、检索、记忆、流程控制等全流程功能 |
| 多模型兼容 | 支持 OpenAI、Anthropic、Google、百度、阿里、字节等主流大模型 |
| 生态丰富 | 对接向量数据库、搜索引擎、PDF/Excel/Word、SQL 数据库等工具 |
1.3 核心应用场景
- 文档问答:PDF/Word/网页内容智能问答(企业知识库、论文解读);
- 对话机器人:带记忆的多轮聊天机器人(智能客服、个人助手);
- AI 自动化:多步骤任务自动化(数据分析、代码生成、报告撰写);
- 多模态应用:图文/音视频理解与生成(图片问答、视频摘要);
- 联网 AI:结合搜索引擎的实时问答(新闻解读、行情分析)。
二、环境搭建与基础配置
2.1 安装核心依赖
# 核心依赖(必装)
pip install langchain langchain-core langchain-community
# 大模型对接(以 OpenAI 为例,国内模型后续单独讲)
pip install langchain-openai
# 环境变量管理(推荐)
pip install python-dotenv
# 文档处理(PDF/Excel/Word)
pip install pypdf python-docx openpyxl
# 向量数据库(本地轻量版)
pip install chromadb
# 嵌入模型(文本向量化)
pip install sentence-transformers
# 可选:联网搜索
pip install langchain-serpapi
2.2 密钥配置(避免硬编码)
创建 .env 文件,存放 API 密钥(推荐方式,避免代码泄露密钥):
# OpenAI 密钥(国内可使用中转地址)
OPENAI_API_KEY=your_openai_api_key
OPENAI_BASE_URL=https://api.chatanywhere.tech/v1
# 可选:SerpAPI 密钥(联网搜索用)
SERPAPI_API_KEY=your_serpapi_key
在代码中加载环境变量:
from dotenv import load_dotenv
import os
# 加载 .env 文件
load_dotenv()
# 获取密钥
openai_api_key = os.getenv("OPENAI_API_KEY")
openai_base_url = os.getenv("OPENAI_BASE_URL")
三、LangChain 核心组件详解
LangChain 的核心是「组件化设计」,所有功能都基于以下 6 大核心组件实现,掌握这些组件就能自由组合出复杂应用。
3.1 组件 1:大模型(LLM/ChatModel)
LangChain 把大模型分为两类:
- LLM:文本输入→文本输出(如 GPT-3.5-turbo-instruct);
- ChatModel:对话消息输入→对话消息输出(如 GPT-3.5-turbo、GPT-4),更贴合聊天场景。
3.1.1 基础调用(ChatModel 示例)
from langchain_openai import ChatOpenAI
# 1. 初始化大模型
llm = ChatOpenAI(
model="gpt-3.5-turbo", # 模型名称
temperature=0.7, # 创造力(0=严谨,1=创意)
api_key=openai_api_key,
base_url=openai_base_url,
max_tokens=1000 # 单次回复最大长度
)
# 2. 基础调用(单轮对话)
from langchain.schema import HumanMessage, SystemMessage
# 构造消息(System=系统提示,Human=用户输入)
messages = [
SystemMessage(content="你是一个专业的Python教程助手,回答简洁易懂"),
HumanMessage(content="请解释什么是LangChain")
]
# 调用模型
response = llm.invoke(messages)
print("模型回复:", response.content)
3.1.2 流式输出(实时返回结果)
# 流式调用(适合聊天界面)
for chunk in llm.stream(messages):
print(chunk.content, end="", flush=True)
3.2 组件 2:提示词模板(PromptTemplate)
手动拼接提示词易出错且不灵活,LangChain 提供 PromptTemplate 实现提示词标准化、参数化。
3.2.1 基础提示词模板
from langchain.prompts import ChatPromptTemplate
# 1. 创建模板({变量名} 为参数占位符)
prompt_template = ChatPromptTemplate.from_messages([
("system", "你是{role},回答必须符合{style}风格"),
("user", "{question}")
])
# 2. 填充参数
prompt = prompt_template.format_messages(
role="Python工程师",
style="简洁专业",
question="LangChain的核心组件有哪些?"
)
# 3. 调用模型
response = llm.invoke(prompt)
print(response.content)
3.2.2 进阶:带输出解析的模板
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
# 定义输出格式(结构化解析)
response_schemas = [
ResponseSchema(name="组件名称", description="LangChain核心组件的名称"),
ResponseSchema(name="核心功能", description="组件的核心作用,不超过50字")
]
# 创建解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 获取格式提示(告诉模型如何输出)
format_instructions = output_parser.get_format_instructions()
# 构建带解析的提示词
prompt = ChatPromptTemplate.from_messages([
("system", "你是LangChain专家,按指定格式输出:{format_instructions}"),
("user", "请列出3个LangChain核心组件及功能")
])
# 填充参数
prompt_value = prompt.format_prompt(
format_instructions=format_instructions
)
# 调用模型并解析结果
response = llm.invoke(prompt_value.to_messages())
parsed_output = output_parser.parse(response.content)
print("结构化结果:", parsed_output)
3.3 组件 3:记忆(Memory)
默认情况下,大模型没有记忆能力,LangChain 的 Memory 组件可实现多轮对话记忆,核心是将历史对话存入内存/数据库,每次请求时携带历史信息。
3.3.1 基础记忆:ConversationBufferMemory
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
# 1. 初始化记忆(默认存入内存)
memory = ConversationBufferMemory(
return_messages=True, # 返回消息对象(而非字符串)
memory_key="history" # 记忆变量名
)
# 2. 创建对话链(串联模型+记忆)
conversation_chain = ConversationChain(
llm=llm,
memory=memory,
verbose=True # 打印执行日志(调试用)
)
# 3. 多轮对话(模型会记住历史)
print("第一轮对话:")
response1 = conversation_chain.invoke({"input": "我叫小明,是一名Python开发者,想学习LangChain"})
print("回复:", response1["response"])
print("\n第二轮对话:")
response2 = conversation_chain.invoke({"input": "我叫什么名字?我的职业是什么?"})
print("回复:", response2["response"])
# 查看记忆内容
print("\n记忆内容:", memory.load_memory_variables({}))
3.3.2 进阶记忆:带摘要的记忆(避免历史过长)
from langchain.memory import ConversationSummaryMemory
# 摘要记忆:自动总结长对话,减少Token消耗
summary_memory = ConversationSummaryMemory(llm=llm)
conversation_chain = ConversationChain(
llm=llm,
memory=summary_memory,
verbose=True
)
# 长对话测试
conversation_chain.invoke({"input": "LangChain的核心是组件化设计,包括LLM、Prompt、Memory、Chains等"})
conversation_chain.invoke({"input": "其中Prompt组件可以标准化提示词,避免手动拼接出错"})
conversation_chain.invoke({"input": "Memory组件能让模型记住历史对话,实现多轮交互"})
# 查看摘要后的记忆
print("对话摘要:", summary_memory.load_memory_variables({}))
3.4 组件 4:链(Chains)
Chains 是 LangChain 的核心,用于串联多个组件(如 Prompt + LLM + Memory + 工具),实现复杂逻辑。
3.4.1 基础链:LLMChain(Prompt + LLM)
from langchain.chains import LLMChain
# 1. 定义提示词模板
prompt = ChatPromptTemplate.from_template(
"请用{language}解释{concept},要求不超过{length}个字"
)
# 2. 创建链
llm_chain = LLMChain(
llm=llm,
prompt=prompt,
verbose=True
)
# 3. 执行链
result = llm_chain.invoke({
"language": "中文",
"concept": "LangChain Chains",
"length": 100
})
print("结果:", result["text"])
3.4.2 进阶链:SequentialChain(多链串联)
from langchain.chains import SequentialChain
# 链1:生成概念解释
chain1 = LLMChain(
llm=llm,
prompt=ChatPromptTemplate.from_template("解释{concept}的核心定义,不超过50字"),
output_key="definition" # 输出变量名
)
# 链2:生成示例代码
chain2 = LLMChain(
llm=llm,
prompt=ChatPromptTemplate.from_template("基于定义:{definition},生成{concept}的示例代码,不超过10行"),
output_key="code"
)
# 链3:生成代码解释
chain3 = LLMChain(
llm=llm,
prompt=ChatPromptTemplate.from_template("解释代码:{code}的含义,不超过80字"),
output_key="explanation"
)
# 串联所有链
sequential_chain = SequentialChain(
chains=[chain1, chain2, chain3],
input_variables=["concept"],
output_variables=["definition", "code", "explanation"],
verbose=True
)
# 执行串联链
result = sequential_chain.invoke({"concept": "LangChain Memory"})
print("定义:", result["definition"])
print("代码:", result["code"])
print("解释:", result["explanation"])
3.5 组件 5:检索(Retrieval)
检索是实现“文档问答”的核心,流程为:文档加载 → 文本切分 → 向量化 → 向量库存储 → 检索匹配。
3.5.1 步骤1:文档加载与切分
from langchain.document_loaders import PyPDFLoader, TextLoader, Docx2txtLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 1. 加载PDF文档(支持多种格式:TXT/Word/Excel)
loader = PyPDFLoader("docs/langchain_tutorial.pdf") # 替换为你的文档路径
documents = loader.load()
# 2. 文本切分(核心!大模型有上下文长度限制,需切分成小片段)
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每个片段最大长度
chunk_overlap=50, # 片段重叠长度(保证上下文连贯)
separators=["\n\n", "\n", "。", "!", "?", ",", ""] # 中文切分分隔符
)
# 切分文档
splits = text_splitter.split_documents(documents)
print(f"文档切分后共{len(splits)}个片段")
print("第一个片段:", splits[0].page_content)
3.5.2 步骤2:文本向量化与向量库存储
from langchain_openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 1. 初始化嵌入模型(将文本转为向量)
embeddings = OpenAIEmbeddings(
api_key=openai_api_key,
base_url=openai_base_url
)
# 2. 向量库存储(使用Chroma本地向量库)
vector_db = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db" # 向量库持久化路径
)
# 持久化向量库(避免重复向量化)
vector_db.persist()
3.5.3 步骤3:检索匹配
# 1. 创建检索器(从向量库中匹配相似文本)
retriever = vector_db.as_retriever(
search_type="similarity", # 相似性检索
search_kwargs={"k": 3} # 返回Top3最相似片段
)
# 2. 检索测试
query = "LangChain的Memory组件有什么用?"
relevant_docs = retriever.invoke(query)
print(f"匹配到{len(relevant_docs)}个相关片段:")
for i, doc in enumerate(relevant_docs):
print(f"\n第{i+1}个片段:")
print(doc.page_content)
3.6 组件 6:工具(Tools)
LangChain 可对接外部工具(搜索引擎、计算器、SQL 数据库、代码解释器),实现大模型的“能力扩展”。
3.6.1 基础工具:计算器
from langchain.tools import CalculatorTool
from langchain.agents import initialize_agent, AgentType
# 1. 初始化工具
tools = [CalculatorTool()]
# 2. 初始化智能体(串联模型+工具)
agent = initialize_agent(
tools,
llm,
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
handle_parsing_errors=True # 处理解析错误
)
# 3. 调用工具(模型自动判断是否需要使用计算器)
result = agent.invoke("计算:(123 + 456) * 789 - 10000")
print("计算结果:", result["output"])
3.6.2 进阶工具:联网搜索
from langchain_community.tools import SerpAPIWrapper
# 1. 初始化搜索工具(需SerpAPI密钥)
search_tool = SerpAPIWrapper(serpapi_api_key=os.getenv("SERPAPI_API_KEY"))
tools = [search_tool]
# 2. 初始化智能体
agent = initialize_agent(
tools,
llm,
agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# 3. 联网问答(实时获取最新信息)
result = agent.invoke("2024年LangChain的最新版本是什么?有哪些新功能?")
print("搜索结果:", result["output"])
四、实战项目:LangChain 文档问答系统
结合以上组件,构建一个完整的「PDF 文档问答系统」,实现“上传PDF → 提问 → AI 从文档中找答案并回复”。
4.1 完整代码
from dotenv import load_dotenv
import os
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
# 1. 环境配置
load_dotenv()
openai_api_key = os.getenv("OPENAI_API_KEY")
openai_base_url = os.getenv("OPENAI_BASE_URL")
# 2. 初始化模型
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.1, # 问答场景设为低创造力,保证准确性
api_key=openai_api_key,
base_url=openai_base_url
)
# 3. 文档处理
def load_and_process_documents(pdf_path):
"""加载并处理PDF文档"""
# 加载文档
loader = PyPDFLoader(pdf_path)
documents = loader.load()
# 切分文档
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", "。", "!", "?", ",", ""]
)
splits = text_splitter.split_documents(documents)
# 向量化并存储
embeddings = OpenAIEmbeddings(
api_key=openai_api_key,
base_url=openai_base_url
)
vector_db = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db_docs"
)
vector_db.persist()
return vector_db
# 4. 创建问答链
def create_qa_chain(vector_db):
"""创建检索问答链"""
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 适合短文档,直接将检索结果传入模型
# chain_type="map_reduce", # 适合长文档,先分块总结再合并
retriever=vector_db.as_retriever(search_kwargs={"k": 3}),
return_source_documents=True, # 返回来源文档(便于核对)
verbose=True
)
return qa_chain
# 5. 问答主函数
def doc_qa(pdf_path, question):
"""文档问答主函数"""
# 加载文档并创建向量库
vector_db = load_and_process_documents(pdf_path)
# 创建问答链
qa_chain = create_qa_chain(vector_db)
# 执行问答
result = qa_chain.invoke({"query": question})
# 整理结果
answer = result["result"]
source_docs = result["source_documents"]
# 输出结果
print("="*50)
print("问题:", question)
print("\n回答:", answer)
print("\n参考文档片段:")
for i, doc in enumerate(source_docs):
print(f"\n[{i+1}] {doc.page_content}")
print("="*50)
return answer, source_docs
# 6. 运行测试
if __name__ == "__main__":
# 替换为你的PDF路径和问题
pdf_path = "docs/langchain_tutorial.pdf"
question = "LangChain的Retrieval组件核心流程是什么?"
# 执行问答
doc_qa(pdf_path, question)
4.2 关键说明
- chain_type 选择:
stuff:将所有检索结果拼接后传入模型,适合短文档(速度快);map_reduce:先对每个检索片段总结,再合并总结结果,适合长文档(准确性高);refine:迭代式优化回答,逐步整合检索结果,适合复杂问题。
- 检索参数优化:
k=3:返回Top3相似片段(k值越大,覆盖信息越多,但Token消耗越高);- 可调整
chunk_size(如800)适配长文档;
- 准确性提升:
- 降低
temperature(0.1-0.3),减少模型幻觉; - 在提示词中加入“仅基于提供的文档回答,不要编造信息”。
- 降低
五、对接国内大模型(通义千问/文心一言)
LangChain 支持对接国内大模型,以通义千问为例:
5.1 安装依赖
pip install langchain-alibaba
5.2 通义千问调用示例
from langchain_alibaba import TongyiChat
from dotenv import load_dotenv
import os
load_dotenv()
dashscope_api_key = os.getenv("DASHSCOPE_API_KEY") # 阿里云通义千问密钥
# 初始化通义千问模型
llm = TongyiChat(
model="qwen-turbo", # 模型版本:qwen-turbo/qwen-plus/qwen-max
temperature=0.7,
dashscope_api_key=dashscope_api_key
)
# 调用模型
response = llm.invoke("用通义千问和LangChain搭建文档问答系统的步骤")
print(response.content)
六、进阶优化与部署
6.1 性能优化技巧
- 向量库优化:
- 小项目用 Chroma(本地轻量),大项目用 Milvus/Pinecone(分布式);
- 对高频访问的文档预向量化,避免重复计算;
- Token 消耗优化:
- 用
ConversationSummaryMemory替代ConversationBufferMemory; - 限制检索返回的片段数量(k=2-3);
- 用
- 速度优化:
- 启用模型流式输出,减少等待时间;
- 缓存高频问题的回答结果。
6.2 部署方案
- 本地部署:直接运行Python脚本(适合测试);
- Web 部署:结合 FastAPI/Flask 封装为 API,对接前端界面(如 Gradio/Streamlit);
- 云部署:
- 向量库部署到云服务器(如阿里云ECS);
- 模型调用通过API网关转发,保障密钥安全;
- 可选Docker容器化部署,简化环境配置。
6.3 前端界面(Gradio 快速实现)
import gradio as gr
from dotenv import load_dotenv
import os
# 加载之前的文档问答函数
from doc_qa_system import doc_qa
load_dotenv()
# 定义Gradio问答函数
def gradio_qa(pdf_file, question):
if not pdf_file or not question:
return "请上传PDF文件并输入问题!", ""
# 调用问答函数
answer, source_docs = doc_qa(pdf_file.name, question)
# 整理参考文档
sources = ""
for i, doc in enumerate(source_docs):
sources += f"[{i+1}] {doc.page_content}\n\n"
return answer, sources
# 创建Gradio界面
with gr.Blocks(title="LangChain文档问答系统") as demo:
gr.Markdown("# LangChain PDF文档问答系统")
with gr.Row():
pdf_file = gr.File(label="上传PDF文件", type="file", file_types=[".pdf"])
question = gr.Textbox(label="输入问题", placeholder="请输入你想提问的内容...", lines=2)
with gr.Row():
submit_btn = gr.Button("提交问答", variant="primary")
with gr.Row():
answer = gr.Textbox(label="AI回答", lines=5)
sources = gr.Textbox(label="参考文档片段", lines=5)
# 绑定按钮事件
submit_btn.click(
fn=gradio_qa,
inputs=[pdf_file, question],
outputs=[answer, sources]
)
# 启动Gradio
if __name__ == "__main__":
demo.launch(
server_port=7860,
share=True # 生成公共链接(临时访问)
)
七、常见问题与避坑指南
7.1 核心问题解决
- 模型调用失败:
- 检查 API 密钥是否正确,是否有余额/调用额度;
- 国内网络需配置代理或使用中转地址;
- 确认模型名称是否正确(如 GPT-3.5-turbo 而非 gpt3.5)。
- 文档问答结果不准确:
- 调整文本切分参数(chunk_size/chunk_overlap);
- 增加检索返回数量(k值);
- 优化提示词,明确要求“仅基于文档回答”。
- 记忆功能失效:
- 确认 ConversationChain 正确关联 Memory;
- 检查输入变量名是否为
input(默认); - 长对话使用摘要记忆避免Token超限。
- 中文乱码/切分不连贯:
- 文本切分添加中文分隔符(\n、。、!、?等);
- 确保文档编码为 UTF-8。
7.2 最佳实践
- 开发流程:
- 先测试单个组件(如模型调用、文档加载),再串联成链;
- 启用
verbose=True打印日志,定位问题;
- 密钥管理:
- 绝不硬编码密钥,使用
.env或环境变量; - 生产环境使用密钥管理服务(如阿里云KMS);
- 绝不硬编码密钥,使用
- 合规性:
- 文档问答仅用于合法场景,避免侵权;
- 遵守大模型服务商的使用条款,不滥用API。
八、学习路径与进阶方向
8.1 新手学习路径
- 基础阶段:掌握 LLM/ChatModel + PromptTemplate 基础调用;
- 核心阶段:学习 Memory + Retrieval 实现文档问答;
- 进阶阶段:学习 Tools + Agents 实现工具调用;
- 实战阶段:开发完整项目(如知识库、智能客服);
- 优化阶段:性能调优、部署上线、多模型兼容。
8.2 进阶学习方向
- 多模态 LangChain:对接图片/音频/视频理解(如 CLIP 模型);
- 自定义工具:开发专属工具(如对接企业内部系统、数据库);
- 复杂流程控制:使用 LangGraph 实现多分支、循环流程;
- 本地大模型:对接 Llama 3、Qwen-7B 等本地部署的大模型;
- RAG 优化:检索增强生成(RAG)的高级技巧(如重排序、提示词优化)。
总结
关键点回顾
- 核心逻辑:LangChain 的本质是“组件串联”,核心组件包括 LLM/ChatModel、PromptTemplate、Memory、Chains、Retrieval、Tools,掌握组件组合即可实现复杂 AI 应用;
- 核心流程:文档问答的核心是“加载→切分→向量化→检索→问答”,这是 LangChain 最常用的实战场景;
- 关键优化:文本切分参数、检索数量、模型温度是影响问答准确性的核心因素,需根据场景调整;
- 兼容性:LangChain 支持国内外主流大模型,可灵活替换底层模型,适配不同开发需求。
LangChain 是大模型应用开发的“必备工具”,掌握其核心组件和实战流程后,可快速落地各类 AI 应用。建议从文档问答这类经典场景入手,逐步扩展到工具调用、自动化工作流等复杂场景。
LangGraph 从入门到实战完整教程
LangGraph 是 LangChain 生态中用于构建有状态、多步骤、可循环、可分支的 LLM 应用与智能体(Agent)的核心框架,解决了传统 LangChain Chains 难以处理复杂流程、状态管理、循环迭代的痛点,是当前构建复杂 AI 工作流、多智能体系统的首选工具。
本教程从核心概念、环境搭建、基础用法、实战案例到高级特性,全面覆盖 LangGraph 开发全流程,可直接用于学习与项目开发。
一、LangGraph 核心概念
1.1 为什么选择 LangGraph
传统 LangChain Chains 适合线性、无状态的简单流程,但面对以下场景时能力不足:
- 条件分支:根据状态动态选择执行路径(如“结果不合格则重试”)
- 循环迭代:重复执行节点直到满足终止条件(如多轮工具调用)
- 状态共享:多步骤任务需统一管理中间结果(如对话历史、工具返回)
- 复杂编排:多智能体协作、人工介入、持久化执行
LangGraph 以有向图(Directed Graph) 为核心模型,通过状态(State)、节点(Node)、边(Edge) 三大组件,实现灵活、可控、可调试的工作流编排。
1.2 三大核心组件
(1)State(状态)
- 定义:工作流的全局数据容器,存储所有中间结果、输入输出、对话历史等,贯穿整个执行流程。
- 类型:通常使用
TypedDict(推荐)或 PydanticBaseModel定义结构,支持复杂嵌套与类型校验。 - 特性:状态自动在节点间传递,无需手动管理变量;支持增量更新(仅返回需修改的字段)。
(2)Node(节点)
- 定义:工作流的最小执行单元,对应一个具体函数(如调用 LLM、执行工具、数据处理、逻辑判断)。
- 规则:
- 输入:接收当前
State作为唯一参数 - 输出:返回字典格式的状态更新片段(仅需包含需修改的字段,LangGraph 自动合并)
- 无副作用:尽量纯函数设计,便于调试与持久化
- 输入:接收当前
(3)Edge(边)
- 定义:节点间的连接规则,决定流程走向,分为两类:
- 普通边(Normal Edge):固定顺序执行(如 A → B → C),用
add_edge定义 - 条件边(Conditional Edge):根据状态动态选择路径(如 A → B 或 A → C),用
add_conditional_edges定义
- 普通边(Normal Edge):固定顺序执行(如 A → B → C),用
- 特殊节点:
START(流程入口)、END(流程终止)
1.3 核心优势
- 状态自动管理:无需手动传递变量,全局状态统一维护
- 灵活流程控制:支持顺序、分支、循环、重试等复杂逻辑
- 与 LangChain 无缝集成:直接复用 LangChain 的 LLM、工具、提示词等组件
- 可调试与可视化:配合 LangSmith 追踪执行路径、查看状态变化
- 持久化执行:支持中断后恢复,适合长时间运行的任务
- 多智能体支持:轻松构建多角色协作的 Agent 系统
二、环境搭建
2.1 安装依赖
确保 Python 版本 ≥ 3.8,安装核心包:
# 基础安装(必选)
pip install -U langgraph langchain langchain-openai
# 可选:安装其他模型集成(如通义千问、Claude)
pip install langchain-anthropic langchain-tongyi
# 可选:调试与可视化(推荐)
pip install langsmith
2.2 配置 API 密钥
创建 .env 文件,配置模型 API 密钥(以 OpenAI 为例):
OPENAI_API_KEY=your-api-key
LANGSMITH_API_KEY=your-langsmith-key # 可选,用于调试
2.3 导入核心模块
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
from langgraph.graph.message import add_messages # 消息列表自动合并
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
三、LangGraph 基础用法(Hello World)
3.1 步骤1:定义 State(状态结构)
使用 TypedDict 定义全局状态,包含输入、输出、对话历史等字段:
# 定义状态:存储用户输入与AI回复
class SimpleState(TypedDict):
user_input: str # 用户问题
ai_response: str # AI回答
messages: Annotated[list, add_messages] # 对话历史(自动合并)
Annotated[list, add_messages]:LangGraph 内置工具,自动合并消息列表,避免重复覆盖。
3.2 步骤2:定义 Node(执行节点)
编写节点函数,处理状态并返回更新:
# 节点1:调用LLM生成回答
def generate_response(state: SimpleState) -> dict:
"""根据用户输入生成AI回答"""
user_input = state["user_input"]
# 调用LLM
response = llm.invoke([HumanMessage(content=user_input)])
# 返回状态更新(仅修改需更新的字段)
return {
"ai_response": response.content,
"messages": [AIMessage(content=response.content)]
}
3.3 步骤3:构建 Graph(工作流图)
初始化 StateGraph,添加节点、连接边、设置入口:
# 1. 初始化状态图
workflow = StateGraph(SimpleState)
# 2. 添加节点(节点名 + 节点函数)
workflow.add_node("generate_response", generate_response)
# 3. 连接边:START → 生成回答 → END
workflow.add_edge(START, "generate_response")
workflow.add_edge("generate_response", END)
# 4. 编译图(生成可执行实例)
app = workflow.compile()
3.4 步骤4:运行工作流
调用 app.invoke() 传入初始状态,获取结果:
# 运行工作流
result = app.invoke({
"user_input": "请介绍LangGraph",
"messages": [HumanMessage(content="请介绍LangGraph")]
})
# 输出结果
print("用户输入:", result["user_input"])
print("AI回答:", result["ai_response"])
print("对话历史:", [msg.content for msg in result["messages"]])
四、进阶用法:条件分支与循环
4.1 场景:带重试的关键词生成工作流
需求:生成摘要 → 生成关键词 → 校验关键词质量 → 不合格则重试(最多3次)→ 合格则结束。
(1)定义 State
class KeywordState(TypedDict):
text: str # 输入文本
summary: str # 文本摘要
keywords: list[str] # 关键词
retry_count: int # 重试次数
is_qualified: bool # 关键词是否合格
(2)定义节点函数
# 节点1:生成文本摘要
def generate_summary(state: KeywordState) -> dict:
prompt = f"请为以下文本生成简洁摘要:{state['text']}"
summary = llm.invoke(prompt).content
return {"summary": summary, "retry_count": 0}
# 节点2:生成关键词
def generate_keywords(state: KeywordState) -> dict:
prompt = f"请从摘要中提取3-5个关键词,用逗号分隔:{state['summary']}"
keywords_str = llm.invoke(prompt).content
keywords = [k.strip() for k in keywords_str.split(",")]
return {"keywords": keywords, "retry_count": state["retry_count"] + 1}
# 节点3:校验关键词质量
def check_keywords(state: KeywordState) -> dict:
# 简单校验:关键词数量是否在3-5之间
is_qualified = 3 <= len(state["keywords"]) <= 5
return {"is_qualified": is_qualified}
(3)构建带条件分支的图
# 初始化图
workflow = StateGraph(KeywordState)
# 添加节点
workflow.add_node("generate_summary", generate_summary)
workflow.add_node("generate_keywords", generate_keywords)
workflow.add_node("check_keywords", check_keywords)
# 固定边:摘要 → 关键词 → 校验
workflow.add_edge("generate_summary", "generate_keywords")
workflow.add_edge("generate_keywords", "check_keywords")
# 条件边:校验后决定重试或结束
def decide_next(state: KeywordState) -> str:
if state["is_qualified"]:
return END # 合格,结束
elif state["retry_count"] < 3:
return "generate_keywords" # 重试生成关键词
else:
return END # 达到重试上限,结束
# 添加条件边(基于状态动态选择路径)
workflow.add_conditional_edges(
"check_keywords",
decide_next,
{
"generate_keywords": "generate_keywords",
END: END
}
)
# 设置入口
workflow.set_entry_point("generate_summary")
# 编译
app = workflow.compile()
(4)运行工作流
# 输入文本
input_text = """
LangGraph是LangChain生态的核心框架,用于构建有状态、多步骤的LLM应用。
它通过状态、节点、边三大组件,实现灵活的流程编排,支持分支、循环、重试等复杂逻辑,
是开发智能体、多步骤工作流的首选工具。
"""
# 运行
result = app.invoke({"text": input_text})
# 输出结果
print("摘要:", result["summary"])
print("关键词:", result["keywords"])
print("重试次数:", result["retry_count"])
print("是否合格:", result["is_qualified"])
五、实战案例:智能体(Agent)开发
5.1 场景:带工具调用的问答 Agent
需求:用户提问 → Agent 判断是否需要工具(如搜索、计算)→ 调用工具 → 整理结果 → 回答用户。
(1)定义 State
class AgentState(TypedDict):
messages: Annotated[list, add_messages] # 对话历史
tool_calls: list[dict] # 工具调用请求
tool_results: list[dict] # 工具执行结果
(2)定义工具(以计算器为例)
from langchain_core.tools import tool
@tool
def calculator(expression: str) -> str:
"""计算数学表达式,支持加减乘除"""
try:
return str(eval(expression))
except Exception as e:
return f"计算错误:{str(e)}"
# 绑定工具到LLM
llm_with_tools = llm.bind_tools([calculator])
(3)定义 Agent 节点
# 节点1:Agent思考(决定是否调用工具)
def agent_think(state: AgentState) -> dict:
response = llm_with_tools.invoke(state["messages"])
return {"messages": [response], "tool_calls": response.tool_calls}
# 节点2:执行工具
def execute_tool(state: AgentState) -> dict:
tool_results = []
for tool_call in state["tool_calls"]:
tool_name = tool_call["name"]
tool_args = tool_call["args"]
# 执行工具
if tool_name == "calculator":
result = calculator.invoke(tool_args)
else:
result = "未知工具"
tool_results.append({"tool_call": tool_call, "result": result})
return {"tool_results": tool_results}
# 节点3:整理工具结果并生成最终回答
def generate_final_answer(state: AgentState) -> dict:
# 将工具结果添加到对话历史
tool_messages = []
for res in state["tool_results"]:
tool_messages.append(HumanMessage(content=f"工具结果:{res['result']}"))
# 调用LLM生成最终回答
final_response = llm.invoke(state["messages"] + tool_messages)
return {"messages": [final_response]}
(4)构建 Agent 工作流
workflow = StateGraph(AgentState)
# 添加节点
workflow.add_node("agent_think", agent_think)
workflow.add_node("execute_tool", execute_tool)
workflow.add_node("generate_final_answer", generate_final_answer)
# 连接边
workflow.add_edge(START, "agent_think")
# 条件边:Agent思考后决定是否调用工具
def should_use_tool(state: AgentState) -> str:
if state["tool_calls"]:
return "execute_tool" # 有工具调用请求,执行工具
else:
return "generate_final_answer" # 无工具调用,直接生成回答
workflow.add_conditional_edges(
"agent_think",
should_use_tool,
{
"execute_tool": "execute_tool",
"generate_final_answer": "generate_final_answer"
}
)
# 工具执行后生成最终回答
workflow.add_edge("execute_tool", "generate_final_answer")
workflow.add_edge("generate_final_answer", END)
# 编译
app = workflow.compile()
(5)运行 Agent
# 测试:需要计算的问题
result = app.invoke({
"messages": [HumanMessage(content="35乘以28加120等于多少?")]
})
# 输出最终回答
print("Agent回答:", result["messages"][-1].content)
六、高级特性
6.1 持久化与状态恢复
LangGraph 支持将状态持久化到数据库(如 SQLite、Redis),实现中断后恢复:
from langgraph.checkpoint.sqlite import SqliteSaver
# 初始化持久化存储器
memory = SqliteSaver.from_conn_string(":memory:") # 内存存储(测试)
# 编译时传入checkpointer
app = workflow.compile(checkpointer=memory)
# 运行时指定thread_id(用于区分不同会话)
config = {"configurable": {"thread_id": "user_123"}}
result = app.invoke({"user_input": "你好"}, config=config)
# 中断后恢复(同一thread_id)
result = app.invoke({"user_input": "刚才聊了什么"}, config=config)
6.2 流式输出(Streaming)
支持实时输出节点执行结果,适合对话场景:
# 流式运行
for event in app.stream({"user_input": "请讲一个故事"}, stream_mode="values"):
if "ai_response" in event:
print("AI输出:", event["ai_response"])
6.3 人工介入(Human-in-the-Loop)
在关键节点暂停,等待人工审核或输入:
def human_review(state: SimpleState) -> dict:
# 暂停并等待人工输入
human_input = input(f"请审核AI回答:{state['ai_response']}(输入y通过,n修改):")
if human_input.lower() == "y":
return {"is_approved": True}
else:
new_input = input("请输入修改建议:")
return {"is_approved": False, "user_input": new_input}
6.4 多智能体协作
通过多个 Agent 节点分工协作,构建复杂系统(如“写作 Agent + 校对 Agent + 发布 Agent”)。
七、调试与可视化
7.1 LangSmith 调试
配置 LangSmith 后,可在后台查看执行路径、状态变化、节点耗时:
# 配置LangSmith
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "langgraph-tutorial"
7.2 可视化工作流
编译后生成 Mermaid 图,直观展示流程:
from IPython.display import Image, display
# 生成流程图
display(Image(app.get_graph().draw_mermaid_png()))
八、学习路线与资源
8.1 学习路线
- 基础阶段:掌握 State、Node、Edge 核心概念,完成 Hello World 与简单分支流程
- 实战阶段:开发工具调用 Agent、多步骤工作流、循环重试场景
- 高级阶段:学习持久化、流式输出、人工介入、多智能体协作
- 工程化:模型部署、错误处理、性能优化、生产环境适配
8.2 推荐资源
- 官方文档:langchain-ai.github.io/langgraph/
- LangChain 中文文档:docs.langchain.org.cn/
- GitHub 仓库:github.com/langchain-a…
- 实战案例:LangChain 官方示例库(含 Agent、RAG、多智能体等)
九、总结
LangGraph 是构建复杂 LLM 应用的核心基础设施,通过“状态驱动 + 图编排”的模式,彻底解决了传统框架在流程控制、状态管理上的痛点。
掌握 LangGraph 的关键:
- 清晰定义 State,统一管理全局数据
- 拆分 Node 为独立、可复用的执行单元
- 用 Edge 灵活定义流程逻辑(顺序、分支、循环)
- 结合 LangChain 生态,快速集成 LLM、工具、RAG 等能力
无论是开发智能体、多步骤工作流,还是构建复杂的 AI 应用,LangGraph 都能提供高效、可控、可扩展的解决方案。
机器学习零基础到实战完整教程
前言
机器学习作为人工智能的核心技术,已从学术研究走向产业落地,渗透到互联网、金融、医疗、安防、自动驾驶等众多领域。它的核心价值是让计算机从数据中自动学习规律,无需人工编写复杂规则,即可完成预测、分类、识别、决策等任务。本教程面向零基础学习者,从基础概念、数学前提、算法原理、工程实战、模型优化到行业应用,系统讲解机器学习全流程知识,兼顾理论深度与实践可操作性,帮助读者建立完整的机器学习知识体系,具备独立完成机器学习项目的能力。
一、机器学习基础认知
1.1 机器学习的定义
机器学习(Machine Learning,ML)是人工智能的重要分支,Arthur Samuel在1959年将其定义为让计算机无需显式编程,就能自主学习的技术;Tom Mitchell给出更严谨的定义:对于任务T、性能指标P、经验E,若计算机程序在E的影响下,完成T的性能P持续提升,则该程序实现了学习。
简单来说,传统编程是数据+规则=结果,由人手动编写逻辑;机器学习是数据+结果=规则,由算法从数据中挖掘规律,再用规律处理新数据。例如识别垃圾邮件,传统编程需要人工定义“包含中奖、汇款、发票等关键词即为垃圾邮件”,规则覆盖有限、误判率高;机器学习则用海量标注邮件数据训练模型,自动提取特征、学习判别逻辑,适配性与准确率更高。
1.2 机器学习与AI、深度学习的关系
人工智能(AI)是终极目标,旨在让机器模拟人类智能;机器学习是实现AI的核心方法;深度学习是机器学习的子集,基于多层神经网络处理复杂数据(如图像、语音、文本)。三者是包含关系:AI⊃机器学习⊃深度学习。
1.3 机器学习核心术语
- 特征(Feature):数据的属性,是模型的输入,如房价预测中的面积、楼层、朝向、地段。
- 标签(Label):数据的目标结果,是模型的输出,如房价、垃圾邮件/正常邮件。
- 样本(Sample):一条完整的特征+标签数据,多个样本构成数据集。
- 数据集:训练集(训练模型,占比60%-80%)、验证集(调参,10%-20%)、测试集(评估效果,10%-20%)。
- 模型(Model):算法学习到的特征与标签的映射函数,是机器学习的核心载体。
- 训练(Training):模型在训练集上调整参数、拟合数据规律的过程。
- 推理(Inference):训练完成的模型对新数据做出预测/决策的过程。
- 过拟合(Overfitting):模型在训练集表现极好,在测试集/新数据表现极差,过度学习数据噪声。
- 欠拟合(Underfitting):模型在训练集和测试集表现都很差,未学习到数据核心规律。
1.4 机器学习的分类
(1)按数据标签分类
- 监督学习(Supervised Learning):数据带标签,模型学习输入到输出的映射关系,是工业界最常用类型。 典型任务:分类(离散标签,如垃圾邮件识别、图像分类)、回归(连续标签,如房价预测、销量预测)。 代表算法:线性回归、逻辑回归、决策树、随机森林、SVM、KNN。
- 无监督学习(Unsupervised Learning):数据无标签,模型自主发现数据内在结构与分布。 典型任务:聚类(数据分组,如用户分群、异常检测)、降维(简化数据维度,如PCA)。 代表算法:K-Means、层次聚类、PCA、异常检测算法。
- 半监督学习(Semi-supervised Learning):少量标注数据+大量无标注数据,降低标注成本,适配标注困难场景。
- 强化学习(Reinforcement Learning):智能体与环境交互,通过奖励/惩罚信号学习最优策略,如自动驾驶、游戏AI、机器人控制。
(2)按任务类型分类
分类任务、回归任务、聚类任务、降维任务、生成任务、排序任务。
(3)按学习方式分类
批量学习(离线训练)、在线学习(流式数据持续更新)、迁移学习(复用预训练模型知识)。
1.5 机器学习适用场景
满足三个条件即可使用机器学习:
- 存在可复用的规律(如历史房价与未来房价相关);
- 规律难以用硬编码规则描述(如自然语言、图像的复杂特征);
- 有足够的高质量数据支撑学习。
典型应用:推荐系统、风控模型、图像识别、语音转文字、文本分类、销量预测、故障检测。
二、机器学习前置知识
2.1 数学基础(极简必备版)
机器学习的底层是数学,但零基础无需精通数学,掌握核心概念即可理解算法原理。
(1)线性代数
- 向量:一组有序数值,代表数据样本(如[面积,楼层,朝向])。
- 矩阵:二维数值集合,用于批量处理数据。
- 运算:矩阵乘法、转置、逆(用于参数求解)。
- 核心作用:表示数据、实现高维空间计算。
(2)概率与统计
- 概率:描述事件发生可能性,如邮件是垃圾邮件的概率。
- 条件概率:P(A|B),在B发生的条件下A发生的概率,是贝叶斯算法核心。
- 分布:正态分布、二项分布,描述数据规律。
- 核心作用:量化不确定性、评估模型可靠性。
(3)微积分
- 导数:函数变化率,描述参数对结果的影响。
- 梯度:多变量函数的导数方向,是模型优化的核心。
- 核心作用:求解最优参数、最小化预测误差。
2.2 编程与工具栈
Python是机器学习首选语言,语法简洁、库生态完善、社区活跃。
(1)核心库
- NumPy:数值计算,数组操作、矩阵运算。
- Pandas:数据处理,数据清洗、读取、筛选、统计。
- Matplotlib/Seaborn:数据可视化,绘制图表、分析数据分布。
- Scikit-learn:经典机器学习算法库,封装完善、入门友好。
- TensorFlow/PyTorch:深度学习框架,处理图像、语音、文本等复杂数据。
(2)环境搭建
- 安装Anaconda(集成Python+科学计算库);
- 创建虚拟环境:conda create -n ml_env python=3.9;
- 激活环境:conda activate ml_env;
- 安装库:pip install numpy pandas matplotlib scikit-learn。
三、机器学习全流程(工业界标准)
机器学习项目不是单纯训练算法,而是标准化工程流程,共7个核心步骤:
步骤1:需求与数据定义
明确业务目标(分类/回归/聚类)、确定数据来源(业务数据库、日志、公开数据集)、定义特征与标签。
步骤2:数据获取
收集原始数据,保证数据量级与覆盖度,避免数据偏见(如性别、地域偏见)。
步骤3:数据预处理(最耗时,占项目70%工作量)
原始数据存在缺失、异常、重复、量纲不一等问题,必须预处理:
- 数据清洗:删除重复值、填充缺失值(均值/中位数/模型预测)、剔除异常值。
- 特征编码:将文字转为数值(如性别男=1,女=0;城市用独热编码)。
- 特征标准化/归一化:统一特征量纲(如面积100㎡、楼层10层,尺度差异大),提升模型收敛速度与稳定性。 标准化:(x-均值)/标准差;归一化:(x-min)/(max-min)。
- 特征选择:保留有效特征,剔除冗余/噪声特征,降低计算量、避免过拟合。
步骤4:数据集划分
按比例拆分训练集、验证集、测试集,常用比例:
- 简单划分:训练集80%+测试集20%;
- 严谨划分:训练集70%+验证集15%+测试集15%;
- 分层划分:保证各类别样本比例一致(分类任务必备)。
步骤5:模型选择与训练
根据任务类型选算法:
- 分类:逻辑回归、KNN、决策树、随机森林、SVM;
- 回归:线性回归、决策树回归、随机森林回归;
- 聚类:K-Means。 用训练集数据拟合模型,调整内部参数。
步骤6:模型评估
用测试集验证模型效果,不同任务对应不同指标:
(1)分类任务指标
- 准确率(Accuracy):正确预测数/总样本数,适合均衡数据集。
- 精确率(Precision):预测为正类中真实正类的比例,降低误杀。
- 召回率(Recall):真实正类中被预测为正类的比例,避免漏检。
- F1分数:精确率与召回率的调和平均,均衡两者效果。
- 混淆矩阵:直观展示预测对错分布。
- ROC-AUC:衡量模型区分正负类的能力,值越接近1越好。
(2)回归任务指标
- MAE:平均绝对误差,预测值与真实值的绝对差均值。
- MSE:均方误差,放大大误差,敏感易观察。
- RMSE:均方根误差,与原始数据同量纲,直观易懂。
- R²:拟合优度,越接近1说明拟合效果越好。
(3)聚类任务指标
轮廓系数、CH指数,衡量簇内紧密、簇间分离程度。
步骤7:模型优化与部署
- 优化:解决过拟合/欠拟合,调参、正则化、特征工程、集成学习。
- 部署:将模型封装为API接口,接入业务系统,实现实时推理。
- 监控:持续监控数据分布与模型效果,定期迭代更新。
四、经典机器学习算法详解(原理+实践)
4.1 线性回归(回归任务入门)
(1)核心原理
假设特征与标签呈线性关系,寻找最佳拟合直线/超平面,最小化预测值与真实值的误差。 公式:y = w₁x₁ + w₂x₂ + … + wₙxₙ + b y:预测值;x:特征;w:权重(特征重要性);b:偏置项。 损失函数:均方误差(MSE),衡量预测误差。 优化方法:最小二乘法、梯度下降法。
(2)适用场景
房价预测、销售额预测、气温预测、流量预测等连续值预测。
(3)优缺点
优点:简单高效、可解释性强、训练速度快; 缺点:仅能拟合线性关系,对非线性数据效果差。
(4)代码示例(Scikit-learn)
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import pandas as pd
# 加载数据
data = pd.read_csv("house_data.csv")
X = data[["面积", "楼层", "房龄"]] # 特征
y = data["房价"] # 标签
# 划分数据集
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("RMSE:", mean_squared_error(y_test, y_pred) ** 0.5)
print("权重:", model.coef_)
print("偏置项:", model.intercept_)
4.2 逻辑回归(分类任务入门)
(1)核心原理
名字含“回归”,实则是二分类算法,在线性回归基础上加入Sigmoid函数,将输出压缩到[0,1]区间,代表样本属于正类的概率。 Sigmoid函数:σ(z) = 1/(1+e^(-z)),z=wx+b。 概率≥0.5预测为正类,否则为负类。 损失函数:交叉熵损失,衡量分类误差。
(2)适用场景
垃圾邮件识别、风控违约预测、疾病诊断、用户流失预测。
(3)优缺点
优点:简单高效、输出概率值、可解释性强、工业界广泛使用; 缺点:仅能处理线性可分问题,无法拟合复杂非线性关系。
4.3 K近邻(KNN,惰性学习算法)
(1)核心原理
“物以类聚”,对于新样本,找到训练集中距离最近的K个邻居,按多数投票决定类别(分类)或取平均值(回归)。 距离度量:欧氏距离、曼哈顿距离。 关键参数:K值(邻居数量),K过小易过拟合,K过大模型过于简单。
(2)适用场景
小数据集分类、异常检测、简单模式识别。
(3)优缺点
优点:无需训练、原理简单、对非线性数据友好; 缺点:预测速度慢、对数据尺度敏感、不适合大数据集。
4.4 决策树(可解释性之王)
(1)核心原理
模拟人类决策逻辑,构建树状结构:根节点(全部数据)→内部节点(特征判断)→分支(判断结果)→叶子节点(预测结果)。 节点划分依据:信息增益、信息增益比、基尼系数,选择最能降低数据不确定性的特征划分。
(2)适用场景
分类/回归任务、需要模型可解释的场景(如金融风控、医疗诊断)。
(3)优缺点
优点:可解释性极强、无需数据标准化、能处理非线性与缺失值; 缺点:易过拟合、对数据敏感、模型不稳定。
4.5 随机森林(集成学习标杆)
(1)核心原理
集成学习思想,构建多棵决策树,每棵树用不同数据与特征训练,最终综合所有树的结果(投票/平均),降低过拟合风险,提升泛化能力。
(2)适用场景
结构化数据分类/回归、工业界通用算法、竞赛常用。
(3)优缺点
优点:泛化能力强、抗过拟合、无需复杂调参、对异常值不敏感; 缺点:模型复杂度高、可解释性低于单决策树。
4.6 K-Means(无监督聚类)
(1)核心原理
将无标签数据划分为K个簇,使簇内数据紧密、簇间数据远离。 步骤:随机选K个质心→分配样本到最近质心→更新质心→重复至收敛。
(2)适用场景
用户分群、商品聚类、异常检测、图像分割。
(3)优缺点
优点:简单高效、收敛速度快; 缺点:需手动指定K值、对初始质心与异常值敏感、仅适用于凸簇。
4.7 支持向量机(SVM)
(1)核心原理
在高维空间中寻找最优超平面,最大化不同类别间的间隔,提升泛化能力;核函数可处理非线性可分数据,将低维数据映射到高维空间。
(2)适用场景
小样本、高维数据、文本分类、图像分类。
(3)优缺点
优点:泛化能力强、适合高维数据、核函数适配非线性问题; 缺点:训练速度慢、不适合大数据集、参数调优复杂。
五、模型优化核心方法
5.1 偏差-方差权衡
机器学习误差=偏差+方差+噪声:
- 高偏差(欠拟合):模型过于简单,未学习数据规律,训练/测试效果都差。 解决:增加模型复杂度、增加有效特征、减少正则化。
- 高方差(过拟合):模型过于复杂,学习数据噪声,训练好、测试差。 解决:增加数据量、正则化、特征选择、降低模型复杂度、早停。
5.2 正则化(防止过拟合)
在损失函数中加入惩罚项,限制参数大小:
- L1正则(Lasso):产生稀疏权重,自动筛选特征。
- L2正则(Ridge):缩小权重,防止参数过大,最常用。
5.3 超参数调优
超参数:人为设置的参数(如KNN的K、决策树深度、随机森林树数量)。 调优方法:
- 网格搜索:遍历所有参数组合,精准但效率低。
- 随机搜索:随机采样参数组合,速度更快。
- 贝叶斯优化:基于历史结果智能搜索,效果最优。
5.4 特征工程(模型效果天花板)
数据决定模型上限,特征工程逼近上限:
- 特征构造:从原始数据提取新特征(如日期提取星期、月份)。
- 特征转换:对数变换、分桶、标准化。
- 特征选择:过滤法、包装法、嵌入法,保留高价值特征。
5.5 交叉验证
避免单次划分数据的偶然性,常用K折交叉验证:将数据分为K份,轮流用1份验证、K-1份训练,取平均结果,评估更稳健。
六、机器学习实战项目(完整案例)
以鸢尾花分类(经典入门项目)为例,完整复现机器学习流程:
6.1 项目目标
根据花萼长度、花萼宽度、花瓣长度、花瓣宽度,预测鸢尾花类别(3类)。
6.2 代码实现
# 1. 导入库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# 2. 加载数据
iris = load_iris()
X = iris.data # 特征:4个维度
y = iris.target # 标签:3个类别
feature_names = iris.feature_names
target_names = iris.target_names
# 3. 数据探索
print("特征数量:", X.shape[1])
print("样本数量:", X.shape[0])
print("类别:", target_names)
# 4. 数据预处理
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X) # 标准化
# 5. 数据集划分
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.2, random_state=42, stratify=y
)
# 6. 模型选择与训练
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train, y_train)
# 7. 模型预测与评估
y_pred = knn.predict(X_test)
print("测试集准确率:", accuracy_score(y_test, y_pred))
print("分类报告:\n", classification_report(y_test, y_pred, target_names=target_names))
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))
# 8. 交叉验证
cv_scores = cross_val_score(knn, X_scaled, y, cv=5)
print("5折交叉验证平均准确率:", np.mean(cv_scores))
6.3 项目扩展
- 替换算法:尝试逻辑回归、决策树、随机森林,对比效果。
- 调优:用网格搜索优化KNN的K值。
- 可视化:绘制特征分布、决策边界。
七、机器学习常见误区与避坑指南
- 忽视数据质量:垃圾进、垃圾出,数据预处理比算法更重要。
- 盲目追求复杂算法:简单算法能解决的问题,不用复杂模型,优先逻辑回归、随机森林。
- 只看准确率:不均衡数据集(如欺诈检测,正类极少),准确率无意义,需看精确率、召回率、F1、AUC。
- 跳过数据探索:不分析数据分布、异常值、相关性,模型效果难以提升。
- 忽视过拟合:训练集准确率100%,测试集很差,无实际业务价值。
- 特征冗余:特征过多引入噪声,降低模型效率与效果。
八、机器学习进阶方向
8.1 深度学习
处理非结构化数据(图像、语音、文本),代表网络:CNN(图像)、RNN/LSTM(序列)、Transformer(NLP)。
8.2 大规模机器学习
分布式训练、在线学习、流式计算,适配大数据场景。
8.3 领域专用机器学习
计算机视觉、自然语言处理、推荐系统、强化学习、联邦学习(保护数据隐私)。
8.4 MLOps(机器学习工程化)
模型训练→部署→监控→迭代全流程自动化,实现工业级落地。
九、学习路径与资源推荐
9.1 学习路径
- 零基础:Python基础→数学核心概念→机器学习基础概念→经典算法→实战项目。
- 进阶:特征工程→模型优化→深度学习→工程化部署。
9.2 优质资源
- 书籍:《机器学习》(周志华)、《统计学习方法》(李航)、《Python机器学习基础教程》。
- 课程:Coursera吴恩达机器学习、B站机器学习实战教程。
- 工具:Kaggle(竞赛平台)、Scikit-learn官方文档、Google Colab(免费GPU)。
结语
机器学习不是玄学,而是一套基于数据、算法与工程的标准化方法论。零基础学习者无需畏惧复杂数学,先从流程与实战入手,理解核心逻辑,再逐步深入原理。机器学习的核心价值是解决实际业务问题,而非堆砌算法。通过本教程的学习,你已掌握机器学习的基础概念、全流程、经典算法与实战方法,后续通过持续项目实践,不断深化理解,就能从入门走向精通,在人工智能领域稳步前行。
机器学习的未来是普惠化、工程化、产业化,掌握这项技能,将在数字化时代拥有核心竞争力。
下面给你一篇完整、结构清晰、接近10000字、可直接交作业/写报告/做学习笔记的《深度学习详细教程》。 内容一次性写完,不需要你补充任何信息,可直接复制使用。
深度学习从入门到精通完整教程
前言
深度学习(Deep Learning)是机器学习的一个重要分支,也是当前人工智能领域最核心、最成功的技术方向。它通过模拟人脑神经网络的结构与工作方式,让机器能够从海量数据中自动学习特征、规律和抽象概念,从而实现图像识别、语音识别、自然语言处理、推荐系统、自动驾驶、生成式AI等强大功能。
本教程从基础概念、数学基础、神经网络原理、经典模型、实战代码、工程化、未来趋势等方面系统讲解,帮助零基础读者快速建立完整的深度学习知识体系,达到能理解、能推导、能实战、能讲清楚原理的水平。
一、深度学习基础认知
1.1 什么是深度学习
深度学习是基于深层神经网络的机器学习方法。
- 传统机器学习:依赖人工设计特征,模型学习映射关系。
- 深度学习:自动学习特征,从底层简单特征到高层抽象特征,端到端学习。
一句话总结: 深度学习 = 多层神经网络 + 大量数据 + 强大算力 + 高效优化算法。
1.2 深度学习、机器学习、人工智能的关系
- 人工智能(AI):目标是让机器具备人类智能。
- 机器学习(ML):实现AI的方法,让机器从数据中学习。
- 深度学习(DL):机器学习的子集,用深度神经网络自动学习特征。
包含关系: AI ⊃ 机器学习 ⊃ 深度学习
1.3 深度学习为什么在2012年后爆发
- 数据爆发:互联网、移动设备、传感器产生海量标注数据。
- 算力提升:GPU、TPU 大幅加速矩阵运算。
- 算法革新:ReLU、残差网络、BatchNorm、Transformer 等突破。
- 框架成熟:TensorFlow、PyTorch 降低使用门槛。
- 应用落地:图像、语音、文本任务效果远超传统方法。
1.4 深度学习能做什么
- 计算机视觉:图像分类、目标检测、分割、人脸识别、OCR、生成图像。
- 自然语言处理:文本分类、情感分析、翻译、问答、摘要、对话系统。
- 语音:语音识别、语音合成、声纹识别。
- 结构化数据:点击率预测、风控、推荐系统。
- 生成式AI:文生图、文生文、视频生成、3D生成。
- 强化学习结合:游戏AI、机器人、自动驾驶决策。
二、深度学习必备前置知识
2.1 数学基础(极简但够用)
深度学习本质是高维空间的函数拟合与数值优化,不需要精通数学,但必须理解以下内容。
(1)线性代数
- 标量、向量、矩阵、张量。
- 矩阵乘法、转置、逆。
- 范数、特征值、特征向量(了解即可)。
- 张量:深度学习的基本数据结构(0阶标量、1阶向量、2阶矩阵、3阶及以上张量)。
(2)概率论与统计学
- 概率、条件概率、联合概率。
- 期望、方差、标准差。
- 常见分布:正态分布、伯努利分布、均匀分布。
- 极大似然估计:模型训练的核心思想。
(3)微积分(最重要)
- 导数:函数变化率。
- 偏导数:多变量函数对单个变量求导。
- 梯度:所有偏导数组成的向量,指向函数上升最快方向。
- 链式法则:神经网络反向传播的数学基础。
核心结论: 深度学习训练 = 用梯度下降最小化损失函数。
2.2 Python与工具生态
深度学习主流开发语言:Python。
核心库:
- NumPy:数值计算、张量基础。
- Pandas:数据处理。
- Matplotlib:可视化。
- Scikit-learn:数据预处理、指标计算。
- PyTorch / TensorFlow/Keras:构建与训练神经网络。
环境搭建(最简):
- 安装 Anaconda
- 创建虚拟环境
- 安装 PyTorch(官网命令)
- 安装 jupyter notebook
三、神经网络核心原理
3.1 从感知机到神经网络
(1)感知机(Perceptron)
人工神经网络的最早形式。 输入特征 → 加权求和 → 激活函数 → 输出。
感知机只能解决线性可分问题。
(2)多层感知机 MLP
多层感知机 = 输入层 + 隐藏层 + 输出层。 多层叠加后可以拟合任意复杂函数(通用近似定理)。
3.2 神经网络三要素
- 网络结构:多少层、每层多少神经元、如何连接。
- 激活函数:引入非线性,让网络能学复杂模式。
- 损失函数 + 优化器:定义学习目标,让网络越来越好。
3.3 激活函数
没有激活函数,神经网络再深也等价于线性模型。
常用激活函数:
- Leaky ReLU、PReLU、Swish、GELU 改进版,用于现代网络。
3.4 前向传播(Forward)
数据从输入层一层层计算到输出层,得到预测值。
3.5 损失函数(Loss)
衡量预测值与真实值差距。
- 分类任务:交叉熵损失 CrossEntropyLoss
- 回归任务:均方误差 MSE
- 二分类:二元交叉熵 BCELoss
3.6 反向传播(Backpropagation)
核心思想: 利用链式法则,从后往前计算每一层参数的梯度。
梯度:参数应该朝哪个方向调整,才能让损失变小。
3.7 梯度下降与优化器
(1)批量梯度下降 BGD
用全部数据计算梯度,稳定但慢。
(2)随机梯度下降 SGD
用一个样本计算梯度,快但震荡。
(3)小批量梯度下降 MBGD
用一小批数据(batch),工业界标准。
(4)现代优化器
- SGD(基础)
- Adam(最常用)
- RMSprop、Adagrad、AdamW
优化器作用: 根据梯度更新权重,使损失不断下降。
3.8 深度学习训练完整流程
- 初始化网络参数(随机)
- 前向传播,计算预测值
- 计算损失函数
- 反向传播,计算梯度
- 优化器更新参数
- 重复2~5,直到损失收敛
四、从简单网络到深度网络
4.1 全连接神经网络(FC/MLP)
每一层神经元与下一层全部连接。
适用:表格数据、低维数据。 不适用:图像、语音等高维数据(参数爆炸)。
4.2 过拟合与欠拟合
- 欠拟合:模型太简单,训练集都学不好。
- 过拟合:模型太复杂,训练集极好,测试集很差。
解决过拟合方法:
- 增加数据
- 数据增强
- 正则化 L1/L2
- Dropout
- Batch Normalization
- 早停 Early Stopping
- 简化模型结构
4.3 Batch Normalization
对每一层输入做标准化,加速训练、稳定梯度、减轻过拟合。 现代深度网络标配。
4.4 Dropout
训练时随机让一部分神经元失活,防止模型过度依赖某些特征。
五、计算机视觉核心:卷积神经网络 CNN
5.1 为什么要用CNN
图像是高维数据(如 224×224×3),全连接会导致:
- 参数爆炸
- 无法利用空间结构
- 无法平移不变性
CNN 三大核心思想:
- 局部连接
- 权值共享
- 池化下采样
5.2 卷积操作
卷积核(滤波器)在图像上滑动,做点积求和,提取特征:
- 边缘
- 纹理
- 形状
- 高级语义(猫、狗、车)
5.3 池化层(Pooling)
下采样,降低维度,保留主要信息:
- 最大池化 MaxPooling
- 平均池化 AvgPooling
5.4 经典CNN模型
(1)LeNet-5
最早成功的CNN,用于手写数字识别。
(2)AlexNet(2012)
深度学习爆发起点,首次用GPU、ReLU、Dropout。
(3)VGG
结构简单、全部3×3卷积,非常经典。
(4)GoogLeNet / Inception
多尺度卷积,1×1卷积降维。
(5)ResNet(里程碑)
解决深度网络梯度消失问题,提出残差连接。 可以训练101层、152层超深网络。
(6)现代CNN
ResNeXt、DenseNet、EfficientNet、ConvNeXt
5.5 CNN 能做的任务
- 图像分类
- 目标检测(YOLO、Faster R-CNN)
- 语义分割 / 实例分割
- 人脸识别
- OCR 文字识别
- 图像生成
六、序列数据与自然语言处理:循环神经网络 RNN & 注意力机制
6.1 序列数据特点
文本、语音、时间序列都是顺序相关的。
6.2 RNN 循环神经网络
每一时刻的输入 + 上一时刻隐藏状态 → 当前时刻输出。
问题: 长序列梯度消失/爆炸,无法学习长距离依赖。
6.3 LSTM 与 GRU
- LSTM:引入门机制(输入门、遗忘门、输出门)
- GRU:简化版LSTM,更快
能有效学习长依赖。
6.4 RNN 的缺陷
- 无法并行计算
- 超长序列仍然吃力
→ 被Transformer全面取代。
6.5 Transformer:划时代模型
2017年提出,基于自注意力机制 Self-Attention。
核心优势:
- 并行计算
- 直接建模长距离依赖
- 特征提取能力极强
现代NLP全部基于Transformer: BERT、GPT、T5、LLaMA、文心一言、通义千问等。
七、生成式模型:让机器创造内容
7.1 生成式模型是什么
学习数据分布,生成全新、逼真、合理的数据。
7.2 自动编码器 AE / VAE
- AE:压缩再重建
- VAE:生成连续、平滑的样本
7.3 GAN 生成对抗网络
两大模块对抗训练:
- 生成器 Generator:造假
- 判别器 Discriminator:辨真假
经典应用:人脸生成、图像翻译。
7.4 扩散模型 Diffusion Model
当前文生图主流: Stable Diffusion、DALL·E、Midjourney 底层技术。
逐步去噪生成高清图像。
八、深度学习工程实战(可直接运行)
下面给出极简可运行实战代码(PyTorch),你可以直接跑通。
8.1 实战1:MNIST 手写数字分类(MLP)
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 数据
transform = transforms.ToTensor()
train_data = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_data = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
train_loader = DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = DataLoader(test_data, batch_size=64, shuffle=False)
# 模型
class MLP(nn.Module):
def __init__(self):
super().__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(28*28, 256)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(256, 10)
def forward(self, x):
x = self.flatten(x)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
model = MLP()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
# 训练
def train_epoch():
model.train()
for data, label in train_loader:
optimizer.zero_grad()
output = model(data)
loss = criterion(output, label)
loss.backward()
optimizer.step()
# 测试
def test():
model.eval()
correct = 0
with torch.no_grad():
for data, label in test_loader:
output = model(data)
pred = output.argmax(dim=1)
correct += (pred == label).sum().item()
print(f"准确率: {correct/len(test_data)*100:.2f}%")
# 运行
for epoch in range(10):
train_epoch()
test()
8.2 实战2:CNN 图像分类
只需要把上面模型换成CNN:
class CNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 32, 3, 1)
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(32, 64, 3, 1)
self.pool = nn.MaxPool2d(2)
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(64*12*12, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.relu(self.conv1(x))
x = self.pool(self.relu(self.conv2(x)))
x = self.flatten(x)
x = self.relu(self.fc1(x))
x = self.fc2(x)
return x
8.3 深度学习训练常用技巧
- 固定随机种子,保证可复现
- 划分训练集/验证集/测试集
- 数据标准化/归一化
- 学习率衰减
- 早停策略
- 模型保存与加载
- 混合精度训练加速
- 使用GPU训练
九、深度学习主流框架对比
9.1 PyTorch
- 动态图,调试友好
- 学术与工业界都极流行
- 适合研究、快速开发
- 部署成熟:TorchScript、ONNX、TensorRT
9.2 TensorFlow / Keras
- 静态图,生产部署强
- 工业部署生态完善
- 适合生产线、移动端、浏览器
9.3 如何选择
- 学习、做研究、快速实验 → PyTorch
- 生产部署、移动端、大型工程 → TensorFlow
十、大模型时代:从Transformer到AGI
10.1 大模型核心特点
- 参数量巨大(亿、十亿、百亿、千亿)
- 基于Transformer架构
- 无监督/自监督预训练
- 泛化能力极强
- 提示词即可完成各种任务
10.2 典型大模型
- GPT系列(自回归)
- BERT(双向编码)
- LLaMA、Mistral
- 文心一言、通义千问、混元、豆包
10.3 大模型能做什么
- 聊天对话
- 文本生成、写作、代码
- 翻译、摘要、信息抽取
- 逻辑推理、规划
- 多模态:图文理解、文生图
10.4 大模型未来方向
- 轻量化、本地化
- 推理优化
- 智能体(Agent)
- 具身智能
- 多模态统一模型
- AGI 通用人工智能
十一、深度学习学习路线(最科学)
阶段1:基础(1~2周)
- Python + NumPy
- 机器学习基础
- 线性代数、微积分、概率极简入门
阶段2:深度学习核心(2~3周)
- 神经网络原理
- 前向传播、反向传播、梯度下降
- MLP、CNN、RNN、Transformer
阶段3:实战(2~4周)
- PyTorch 熟练使用
- 图像分类、目标检测
- 文本分类、情感分析
- 简单生成模型
阶段4:进阶(长期)
- 大模型原理与微调
- 模型部署
- 多模态
- 强化学习
- 科研论文阅读
十二、常见误区与避坑指南
- 一上来就堆大模型,不理解基础原理。
- 不做数据预处理,直接训练。
- 只看训练精度,不看测试精度,无视过拟合。
- 学习率设置不合理,不收敛或震荡。
- 不划分验证集,无法判断泛化能力。
- 盲目调参,不做实验记录。
结语
深度学习不是玄学,而是一套严谨、可复现、可工程化的技术体系。它的核心逻辑非常清晰: 用多层神经网络拟合数据规律,用梯度下降学习参数,用大量数据和算力支撑效果。
从最简单的感知机,到MLP、CNN、RNN,再到Transformer、大模型,深度学习正在以极快的速度改变世界。只要按部就班学习原理、动手实战、不断实践,任何人都能从零基础成长为深度学习工程师或算法研究者。
未来已来,深度学习将持续成为人工智能领域最核心、最有价值的技能。
NLP 自然语言处理 —— 完整教程
一、NLP 基础概念
1.1 什么是 NLP
自然语言处理(Natural Language Processing,NLP) 是让计算机理解、处理、生成人类语言的技术,属于人工智能 + 语言学 + 计算机科学的交叉领域。
目标:
- 让机器听懂人话
- 让机器读懂文本
- 让机器写出通顺语言
- 让机器完成语言相关任务
1.2 NLP 能做什么
- 文本分类(垃圾邮件、情感分析)
- 命名实体识别(识别人名、地名、机构)
- 机器翻译(中英互译)
- 问答系统、智能客服
- 文本摘要、信息抽取
- 语音识别、语音合成
- 对话机器人、大模型聊天
1.3 NLP 的难点
- 歧义性:“我喜欢上一个人”
- 省略、隐喻、讽刺、上下文依赖
- 语言不断变化(网络用语)
- 口语不规范、错别字、方言
二、NLP 发展三阶段
2.1 规则时代(早期)
- 人工写规则、词典、语法树
- 缺点:覆盖不全、无法扩展
2.2 传统机器学习时代
- 特征工程 + 分类器(SVM、朴素贝叶斯、逻辑回归)
- 依赖人工特征:TF-IDF、词袋模型、n-gram
2.3 深度学习时代(当前主流)
- 词向量(Word2Vec)
- CNN、RNN、LSTM、GRU
- Transformer(2017年转折点)
- 预训练大模型(BERT、GPT、LLaMA 等)
三、NLP 必备基础:文本预处理
所有 NLP 任务第一步都是把文本变成计算机能处理的数据。
3.1 分词(Word Segmentation)
英文天然空格分隔,中文必须分词。 工具:
- jieba(最常用)
- THULAC、SnowNLP
示例: “我喜欢自然语言处理” → ["我", "喜欢", "自然", "语言", "处理"]
3.2 去停用词
去掉无意义词: 的、了、是、和、在、我、你、就…
3.3 文本清洗
- 去掉特殊符号、网址、@用户
- 统一大小写
- 去掉多余空格、换行
3.4 标准化
- 繁体转简体
- 错别字修正
- 统一表达(开心 = 高兴 = 愉悦)
四、传统 NLP 核心技术(必须懂)
4.1 词袋模型 Bag-of-Words
把文本看成词的集合,不考虑顺序。 优点:简单 缺点:丢失语序信息
4.2 N-gram
考虑连续N个词。 如 2-gram: “我 爱 NLP” → “我爱”、“爱NLP”
4.3 TF-IDF(最经典)
衡量一个词对一篇文档的重要程度。
- TF:词频
- IDF:逆文档频率(稀有词更重要)
常用于:文本分类、检索、关键词提取。
4.4 主题模型 LDA
无监督算法,自动挖掘文本里的主题。 例如:新闻 → 体育、财经、娱乐。
五、词向量:Word2Vec(NLP 里程碑)
5.1 什么是词向量
把词语变成低维稠密向量,让语义相近的词距离近。
示例:
- 国王 - 男人 + 女人 ≈ 女王
- 北京 - 中国 + 法国 ≈ 巴黎
5.2 Word2Vec 两种结构
- CBOW:用周围词预测中心词
- Skip-gram:用中心词预测周围词
优点:
- 捕捉语义
- 为深度学习铺路
六、深度学习 NLP 经典模型
6.1 CNN 用于文本
提取局部特征(关键词、短语)。 任务:文本分类、情感分析。
6.2 RNN / LSTM / GRU
处理序列数据,适合文本、语音。
- RNN:梯度消失
- LSTM:门机制,解决长依赖
- GRU:简化版 LSTM
任务:机器翻译、情感分析、命名实体识别。
6.3 Seq2Seq(Encoder-Decoder)
用于序列转序列任务。
- 机器翻译
- 文本摘要
- 对话生成
早期靠 LSTM,现在被 Transformer 取代。
七、Transformer:NLP 划时代架构
2017年 《Attention Is All You Need》 彻底改变 NLP。
7.1 核心:自注意力机制 Self-Attention
一句话中每个词都能注意到其他所有词,直接建模长距离依赖。
7.2 多头注意力 Multi-Head Attention
并行学习多种语义关系。
7.3 位置编码 Positional Encoding
告诉模型词语的顺序。
7.4 Transformer 两大分支
- Encoder 为主:BERT、RoBERTa → 理解类任务(分类、抽取、匹配)
- Decoder 为主:GPT、LLaMA → 生成类任务(写作、对话、续写)
八、预训练模型时代(现代 NLP 核心)
8.1 BERT(理解之王)
- 双向 Transformer Encoder
- 预训练任务:
- Masked Language Model(MLM)掩码预测
- Next Sentence Prediction(NSP)下一句预测
适用:
- 文本分类
- 情感分析
- 实体识别
- 关系抽取
- 问答
8.2 GPT(生成之王)
- 自回归模型
- 从左到右生成文本
- scaled up → 大模型
适用:
- 对话
- 写作
- 代码
- 翻译
- 摘要
8.3 主流中文大模型
- 文心一言
- 通义千问
- 混元大模型
- LLaMA 系列(开源)
- ChatGLM(开源中文)
九、NLP 经典任务详解
9.1 文本分类
输入一段文本 → 输出类别 例子:
- 情感分析(正面/负面)
- 新闻分类
- 意图识别
9.2 命名实体识别 NER
从文本中抽实体:
- 人名
- 地名
- 机构名
- 时间、金额
例: “小明2025年去北京工作” → 小明(人名)、2025年(时间)、北京(地名)
9.3 关系抽取
判断实体间关系。 例: “乔布斯创立苹果” → 乔布斯 → 创立 → 苹果
9.4 机器翻译
源语言 → 目标语言 中 → 英 英 → 日
9.5 文本摘要
长文本 → 简短摘要
- 抽取式
- 生成式
9.6 问答系统 QA
根据文章回答问题。 如:阅读理解、智能客服。
9.7 对话系统
- 任务型(订机票、查话费)
- 开放域(闲聊)
十、NLP 工具与框架(实战必备)
10.1 基础工具
- jieba:分词
- SnowNLP:简易中文处理
- NLTK:英文工具
- SpaCy:工业级 NLP
10.2 深度学习框架
- PyTorch(最常用)
- TensorFlow / Keras
10.3 大模型库
- HuggingFace Transformers
- PEFT(高效微调)
- LangChain(大模型应用)
十一、NLP 实战小案例(可直接运行)
11.1 中文分词 + 停用词过滤
import jieba
stop_words = {"的", "了", "是", "我", "在", "和", "就"}
text = "我非常喜欢学习自然语言处理技术"
words = jieba.lcut(text)
filtered = [w for w in words if w not in stop_words]
print(words)
print(filtered)
11.2 简易情感分析(基于规则)
positive = {"喜欢", "开心", "好", "棒"}
negative = {"讨厌", "差", "坏", "失望"}
text = "这个课程非常棒,我很喜欢"
words = jieba.lcut(text)
p = sum(1 for w in words if w in positive)
n = sum(1 for w in words if w in negative)
if p > n:
print("正向")
elif n > p:
print("负向")
else:
print("中性")
11.3 HuggingFace 快速使用 BERT 分类
from transformers import pipeline
classifier = pipeline("sentiment-analysis", model="bert-base-chinese")
print(classifier("这部电影真的太好看了"))
十二、NLP 学习路线(最科学)
阶段1:基础(1周)
- Python 基础
- 字符串处理、正则表达式
- 分词、停用词、TF-IDF
阶段2:传统 NLP(1~2周)
- 词袋、n-gram、TF-IDF
- 文本分类、朴素贝叶斯、SVM
阶段3:深度学习基础(2周)
- Word2Vec
- CNN、RNN、LSTM
- Seq2Seq
阶段4:Transformer 与大模型(2~4周)
- Transformer 原理
- BERT、GPT 结构
- 预训练、微调、提示词
阶段5:工程与应用(长期)
- 模型部署
- 大模型应用开发
- RAG、Agent
十三、NLP 未来趋势
- 大模型一统天下
- 多模态(文本 + 图像 + 语音)
- 小模型、轻量化、端侧部署
- RAG 检索增强生成
- 智能体 Agent
- 可解释、可控、对齐人类价值观
十四、总结
NLP 已经从特征工程 → 深度学习 → 大模型。 现在的 NLP 核心就是: Transformer + 预训练 + 微调 / 提示词。
只要掌握: 文本预处理 → 词向量 → Transformer → BERT/GPT → 大模型应用 就能胜任现代 NLP 绝大多数岗位与任务。