恐怖解谜密室逃脱
109.73M · 2026-03-09
Python 拥有全球最丰富、最成熟的 AI/ML 专用库,无需从零写算法,直接调用封装好的高性能接口即可:
| 领域 | 核心库 | 核心能力 |
|---|---|---|
| 机器学习 | Scikit-learn | 封装了所有经典算法(线性回归、决策树、SVM、聚类等),一行代码就能训练模型 |
| 深度学习 | TensorFlow / PyTorch | 工业级深度学习框架,支持 GPU/TPU 加速,覆盖计算机视觉、NLP、大模型开发 |
| 数据处理 | NumPy / Pandas | 高效处理矩阵 / 表格数据(AI 开发 80% 时间在处理数据),性能接近 C 语言 |
| 数据可视化 | Matplotlib / Seaborn | 快速绘制模型结果、数据分布,直观分析效果 |
| 大模型开发 | LangChain / Transformers | 基于 HuggingFace 生态,快速搭建大模型应用(问答、摘要、多模态) |
Python 语言教程
Python Web 框架
数据处理-数据分析 教程
1.数据可视化 教程
2.数据可视化 教程
LangChain 教程
LangGraph 教程
机器学习 教程
深度学习 教程
NLP 自然语言处理 —— 完整教程
Python Web 框架主要分两类,核心区别是「是否包含全栈功能」:
| 类型 | 特点 | 代表框架 |
|---|---|---|
| 全栈框架(Full-Stack) | 内置模板引擎、ORM、表单验证、会话管理等全套功能,开箱即用 | Django、Web2py |
| 微框架(Micro-Framework) | 轻量、极简,只实现核心的路由 / 请求响应,其他功能需靠第三方库扩展 | Flask、FastAPI、Bottle |
核心特点
适用场景
核心优势
入门示例(快速创建一个页面)
# 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
# 访问 即可看到结果
核心特点
适用场景
核心优势
入门示例
# 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,访问
核心特点
适用场景
核心优势
入门示例
# 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
# 访问 可看到自动生成的接口文档
| 框架 | 核心特点 | 适用场景 |
|---|---|---|
| Bottle | 超轻量(单文件),无依赖,无需安装额外库 | 小型脚本、嵌入式 Web 应用 |
| Tornado | 异步非阻塞,原生支持 WebSocket,高性能 | 实时应用(聊天、直播、推送) |
| Web2py | 全栈、自带数据库 / 后台 / 部署工具,零配置 | 快速开发、低维护成本的小型项目 |
| Sanic | 异步、高性能,语法接近 Flask | 高并发 API、IO 密集型服务 |
| 需求场景 | 推荐框架 |
|---|---|
| 大型企业应用、内容管理系统 | Django |
| 小型 API、原型开发、个人项目 | Flask |
| 高性能 API、微服务、异步场景 | FastAPI |
| 实时应用(WebSocket) | Tornado/FastAPI |
| 超轻量、嵌入式应用 | Bottle |
总结
数据处理是 Python 数据分析/AI 开发的核心环节,NumPy 负责高效处理数值型数组(矩阵),Pandas 基于 NumPy 构建,专注于结构化数据(表格/行列)处理。本教程从基础语法到实战案例,带你掌握 80% 日常数据处理场景的用法。
# 安装 NumPy + Pandas
pip install numpy pandas
# 验证安装
import numpy as np
import pandas as pd
print(f"NumPy 版本:{np.__version__}")
print(f"Pandas 版本:{pd.__version__}")
| 工具 | 核心优势 | 适用场景 |
|---|---|---|
| NumPy | 高性能数组运算、广播机制 | 数值计算、矩阵操作、AI 数据预处理 |
| Pandas | 行列索引、缺失值处理、分组 | 表格数据清洗、统计分析、数据可视化 |
NumPy 的核心是 ndarray 数组,比 Python 列表更高效(底层 C 实现)。
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
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]
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]
# 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 核心数据结构是 Series(一维)和 DataFrame(二维表格),几乎所有操作围绕这两个结构展开。
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
# 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]) # 按位置取值(第二行第三列)
数据清洗是 Pandas 最核心的应用场景,包括缺失值、重复值、异常值处理。
# 创建含缺失值的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列填均值
df = pd.DataFrame({
'A': [1, 1, 2, 3],
'B': [5, 5, 6, 7]
})
# 查看重复行
print(df.duplicated()) # 返回布尔值:第二行为True(重复)
# 删除重复行
df_unique = df.drop_duplicates() # 保留第一行,删除后续重复行
df = pd.DataFrame({
'年龄': ['20', '25', '30'], # 字符串类型
'收入': [5000.0, 8000.0, 10000.0]
})
# 转换类型
df['年龄'] = df['年龄'].astype(int) # 转为整数
df['收入'] = df['收入'].astype(int) # 转为整数
print(df.dtypes) # 查看转换后类型
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=['城市', '年龄']) # 先按城市、再按年龄排序
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
# 两个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')
# 导出为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数据,演示完整的数据处理流程:
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("清洗后的数据已导出!")
for 循环;df[df['A']>0]['B']=1),改用 df.loc[df['A']>0, 'B']=1;df.iterrows() 改为 df.itertuples(),速度提升10倍+;df.astype('category') 转换低基数列(如城市、类型)。loc 按索引取值,iloc 按位置取值,不要混用;sum/mean)会自动忽略缺失值,需先确认是否合理;encoding='utf-8-sig',Excel可正常显示;astype 转换。ndarray 数组,优势是向量化运算,适合数值/矩阵操作,是 Pandas 的底层支撑;DataFrame 表格,专注结构化数据处理,核心功能包括清洗(缺失/重复值)、筛选、分组聚合、数据合并;np.linalg);pd.to_datetime)、透视表(pivot_table)、数据可视化(结合 Matplotlib/Seaborn);掌握 NumPy + Pandas 后,你就能高效完成从原始数据到可分析数据的全流程处理,为后续的可视化、建模打下基础。
Matplotlib 是 Python 最核心的数据可视化库,能绘制折线图、柱状图、散点图、饼图等几乎所有类型的图表,也是 Pandas、Seaborn 等可视化工具的底层依赖。本教程从基础语法到实战案例,带你掌握日常数据分析中 90% 的可视化场景。
# 安装 Matplotlib
pip install matplotlib
# 验证安装
import matplotlib.pyplot as plt
print(f"Matplotlib 版本:{plt.__version__}")
# 可选:安装中文字体支持(解决中文乱码)
# Windows/macOS/Linux 字体配置见下文「避坑指南」
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() # 显示图表
适用于展示数据随时间/连续变量的变化趋势(如股价、温度、销量)。
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()
适用于对比不同类别数据的大小(如各城市销售额、各部门人数)。
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()
适用于展示两个变量的相关性(如身高-体重、广告投入-销售额)。
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()
适用于展示各部分占总体的比例(如市场份额、用户分布、费用占比)。
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()
适用于展示数据的分布特征(如身高分布、成绩分布、销售额分布)。
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()
一个画布中绘制多个子图,适合对比不同维度的数据:
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()
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()
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缓存(删除缓存目录)
#FF6B6B、#4ECDC4、#45B7D1),避免纯红/纯绿/纯蓝;alpha 参数设为 0.5-0.8,避免图表过于厚重;plt.tight_layout() 自动调整子图间距,避免标签截断;dpi=300,保证高清;grid(axis='y')),减少视觉干扰。plt.show()(Jupyter Notebook 除外);plt.tight_layout();axes.unicode_minus = False;plt.savefig() 需在 plt.show() 之前执行。mpl_toolkits.mplot3d);掌握 Matplotlib 后,你能将枯燥的数字转化为直观的图表,快速洞察数据规律,是数据分析/AI 开发的必备技能。
Seaborn 是基于 Matplotlib 构建的高级数据可视化库,专为统计分析设计,相比 Matplotlib 更美观、更贴合 Pandas 数据结构,且内置多种专业的统计图表(如热力图、小提琴图、配对图)。本教程从基础配置到实战案例,带你掌握 Seaborn 核心用法,快速做出专业级可视化图表。
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__}")
| 特性 | Seaborn 优势 | Matplotlib 对比 |
|---|---|---|
| 风格美化 | 内置 5+ 专业配色风格(darkgrid、whitegrid 等) | 需手动调整颜色、样式 |
| 数据适配 | 原生支持 Pandas DataFrame,无需手动转换 | 需提取数组后绘图 |
| 统计图表 | 内置热力图、小提琴图、配对图等统计图表 | 需手动实现统计逻辑 |
| 配色系统 | 内置分类/连续/发散型配色方案(如 husl、viridis) | 需手动指定 RGB/十六进制颜色 |
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 图表可分为「分类图表」「关系图表」「分布图表」「矩阵图表」四大类,覆盖 90% 统计可视化场景。
适用于展示类别变量与数值变量的关系,核心图表包括条形图、箱线图、小提琴图。
与 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()
展示数据的四分位数、中位数、异常值,适合分析类别数据的分布离散程度:
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()
结合箱线图和核密度图,展示数据的分布密度,比箱线图更直观:
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()
适用于分析数值变量之间的关系,核心图表包括散点图、线图、回归图。
比 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()
自动拟合线性回归模型,展示变量间的线性关系和置信区间:
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()
适用于展示单变量/双变量的分布规律,核心图表包括直方图、核密度图、联合分布图。
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()
同时展示两个变量的散点图+边际分布,快速分析双变量关系:
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()
核心是热力图(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()
按类别自动生成多子图,适合对比不同分组的数据分布:
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()
结合之前爬取的豆瓣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()
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) 调整标题位置。sns.despine() 移除顶部/右侧边框,让图表更简洁;alpha=0.5-0.8 避免点重叠,提升可读性;fontsize=14,轴标签 fontsize=12,数值标签 fontsize=10;whitegrid 风格,仅显示Y轴网格,减少视觉干扰;Seaborn 是数据分析的「可视化利器」,掌握后可快速做出专业级图表,比 Matplotlib 效率提升 50% 以上,是数据分析师/AI 工程师的必备技能。
LangChain 是当前最主流的大模型应用开发框架,核心价值是「串联大模型与各类工具/数据/流程」,让开发者无需从零编写复杂逻辑,快速构建智能问答、知识库、自动化工作流等 AI 应用。本教程从核心概念、环境搭建到实战项目,全方位覆盖 LangChain 核心用法,所有代码均可直接运行。
LangChain 不是大模型,而是大模型应用开发的“胶水框架” ——它提供一套标准化的接口和组件,将大模型(如 GPT-4、通义千问、文心一言)、数据(PDF/文档/数据库)、工具(搜索引擎/计算器)、记忆(对话历史)、流程(多步骤逻辑)串联起来,大幅降低 AI 应用开发成本。
| 优势 | 具体价值 |
|---|---|
| 模块化设计 | 组件可自由组合(如替换大模型、切换向量库),适配不同场景 |
| 一站式能力 | 内置文档加载、向量化、检索、记忆、流程控制等全流程功能 |
| 多模型兼容 | 支持 OpenAI、Anthropic、Google、百度、阿里、字节等主流大模型 |
| 生态丰富 | 对接向量数据库、搜索引擎、PDF/Excel/Word、SQL 数据库等工具 |
# 核心依赖(必装)
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
创建 .env 文件,存放 API 密钥(推荐方式,避免代码泄露密钥):
# OpenAI 密钥(国内可使用中转地址)
OPENAI_API_KEY=your_openai_api_key
OPENAI_BASE_URL=
# 可选: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 的核心是「组件化设计」,所有功能都基于以下 6 大核心组件实现,掌握这些组件就能自由组合出复杂应用。
LangChain 把大模型分为两类:
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)
# 流式调用(适合聊天界面)
for chunk in llm.stream(messages):
print(chunk.content, end="", flush=True)
手动拼接提示词易出错且不灵活,LangChain 提供 PromptTemplate 实现提示词标准化、参数化。
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)
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)
默认情况下,大模型没有记忆能力,LangChain 的 Memory 组件可实现多轮对话记忆,核心是将历史对话存入内存/数据库,每次请求时携带历史信息。
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({}))
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({}))
Chains 是 LangChain 的核心,用于串联多个组件(如 Prompt + LLM + Memory + 工具),实现复杂逻辑。
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"])
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"])
检索是实现“文档问答”的核心,流程为:文档加载 → 文本切分 → 向量化 → 向量库存储 → 检索匹配。
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=["nn", "n", "。", "!", "?", ",", ""] # 中文切分分隔符
)
# 切分文档
splits = text_splitter.split_documents(documents)
print(f"文档切分后共{len(splits)}个片段")
print("第一个片段:", splits[0].page_content)
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()
# 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)
LangChain 可对接外部工具(搜索引擎、计算器、SQL 数据库、代码解释器),实现大模型的“能力扩展”。
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"])
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"])
结合以上组件,构建一个完整的「PDF 文档问答系统」,实现“上传PDF → 提问 → AI 从文档中找答案并回复”。
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=["nn", "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)
stuff:将所有检索结果拼接后传入模型,适合短文档(速度快);map_reduce:先对每个检索片段总结,再合并总结结果,适合长文档(准确性高);refine:迭代式优化回答,逐步整合检索结果,适合复杂问题。k=3:返回Top3相似片段(k值越大,覆盖信息越多,但Token消耗越高);chunk_size(如800)适配长文档;temperature(0.1-0.3),减少模型幻觉;LangChain 支持对接国内大模型,以通义千问为例:
pip install langchain-alibaba
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)
ConversationSummaryMemory 替代 ConversationBufferMemory;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}nn"
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 # 生成公共链接(临时访问)
)
input(默认);verbose=True 打印日志,定位问题;.env 或环境变量;LangChain 是大模型应用开发的“必备工具”,掌握其核心组件和实战流程后,可快速落地各类 AI 应用。建议从文档问答这类经典场景入手,逐步扩展到工具调用、自动化工作流等复杂场景。
LangGraph 是 LangChain 生态中用于构建有状态、多步骤、可循环、可分支的 LLM 应用与智能体(Agent)的核心框架,解决了传统 LangChain Chains 难以处理复杂流程、状态管理、循环迭代的痛点,是当前构建复杂 AI 工作流、多智能体系统的首选工具。
本教程从核心概念、环境搭建、基础用法、实战案例到高级特性,全面覆盖 LangGraph 开发全流程,可直接用于学习与项目开发。
传统 LangChain Chains 适合线性、无状态的简单流程,但面对以下场景时能力不足:
LangGraph 以有向图(Directed Graph) 为核心模型,通过状态(State)、节点(Node)、边(Edge) 三大组件,实现灵活、可控、可调试的工作流编排。
TypedDict(推荐)或 Pydantic BaseModel 定义结构,支持复杂嵌套与类型校验。State 作为唯一参数add_edge 定义add_conditional_edges 定义START(流程入口)、END(流程终止)确保 Python 版本 ≥ 3.8,安装核心包:
# 基础安装(必选)
pip install -U langgraph langchain langchain-openai
# 可选:安装其他模型集成(如通义千问、Claude)
pip install langchain-anthropic langchain-tongyi
# 可选:调试与可视化(推荐)
pip install langsmith
创建 .env 文件,配置模型 API 密钥(以 OpenAI 为例):
OPENAI_API_KEY=your-api-key
LANGSMITH_API_KEY=your-langsmith-key # 可选,用于调试
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)
使用 TypedDict 定义全局状态,包含输入、输出、对话历史等字段:
# 定义状态:存储用户输入与AI回复
class SimpleState(TypedDict):
user_input: str # 用户问题
ai_response: str # AI回答
messages: Annotated[list, add_messages] # 对话历史(自动合并)
Annotated[list, add_messages]:LangGraph 内置工具,自动合并消息列表,避免重复覆盖。编写节点函数,处理状态并返回更新:
# 节点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)]
}
初始化 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()
调用 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"]])
需求:生成摘要 → 生成关键词 → 校验关键词质量 → 不合格则重试(最多3次)→ 合格则结束。
class KeywordState(TypedDict):
text: str # 输入文本
summary: str # 文本摘要
keywords: list[str] # 关键词
retry_count: int # 重试次数
is_qualified: bool # 关键词是否合格
# 节点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}
# 初始化图
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()
# 输入文本
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 判断是否需要工具(如搜索、计算)→ 调用工具 → 整理结果 → 回答用户。
class AgentState(TypedDict):
messages: Annotated[list, add_messages] # 对话历史
tool_calls: list[dict] # 工具调用请求
tool_results: list[dict] # 工具执行结果
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])
# 节点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]}
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()
# 测试:需要计算的问题
result = app.invoke({
"messages": [HumanMessage(content="35乘以28加120等于多少?")]
})
# 输出最终回答
print("Agent回答:", result["messages"][-1].content)
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)
支持实时输出节点执行结果,适合对话场景:
# 流式运行
for event in app.stream({"user_input": "请讲一个故事"}, stream_mode="values"):
if "ai_response" in event:
print("AI输出:", event["ai_response"])
在关键节点暂停,等待人工审核或输入:
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}
通过多个 Agent 节点分工协作,构建复杂系统(如“写作 Agent + 校对 Agent + 发布 Agent”)。
配置 LangSmith 后,可在后台查看执行路径、状态变化、节点耗时:
# 配置LangSmith
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "langgraph-tutorial"
编译后生成 Mermaid 图,直观展示流程:
from IPython.display import Image, display
# 生成流程图
display(Image(app.get_graph().draw_mermaid_png()))
LangGraph 是构建复杂 LLM 应用的核心基础设施,通过“状态驱动 + 图编排”的模式,彻底解决了传统框架在流程控制、状态管理上的痛点。
掌握 LangGraph 的关键:
无论是开发智能体、多步骤工作流,还是构建复杂的 AI 应用,LangGraph 都能提供高效、可控、可扩展的解决方案。
机器学习作为人工智能的核心技术,已从学术研究走向产业落地,渗透到互联网、金融、医疗、安防、自动驾驶等众多领域。它的核心价值是让计算机从数据中自动学习规律,无需人工编写复杂规则,即可完成预测、分类、识别、决策等任务。本教程面向零基础学习者,从基础概念、数学前提、算法原理、工程实战、模型优化到行业应用,系统讲解机器学习全流程知识,兼顾理论深度与实践可操作性,帮助读者建立完整的机器学习知识体系,具备独立完成机器学习项目的能力。
机器学习(Machine Learning,ML)是人工智能的重要分支,Arthur Samuel在1959年将其定义为让计算机无需显式编程,就能自主学习的技术;Tom Mitchell给出更严谨的定义:对于任务T、性能指标P、经验E,若计算机程序在E的影响下,完成T的性能P持续提升,则该程序实现了学习。
简单来说,传统编程是数据+规则=结果,由人手动编写逻辑;机器学习是数据+结果=规则,由算法从数据中挖掘规律,再用规律处理新数据。例如识别垃圾邮件,传统编程需要人工定义“包含中奖、汇款、发票等关键词即为垃圾邮件”,规则覆盖有限、误判率高;机器学习则用海量标注邮件数据训练模型,自动提取特征、学习判别逻辑,适配性与准确率更高。
人工智能(AI)是终极目标,旨在让机器模拟人类智能;机器学习是实现AI的核心方法;深度学习是机器学习的子集,基于多层神经网络处理复杂数据(如图像、语音、文本)。三者是包含关系:AI⊃机器学习⊃深度学习。
分类任务、回归任务、聚类任务、降维任务、生成任务、排序任务。
批量学习(离线训练)、在线学习(流式数据持续更新)、迁移学习(复用预训练模型知识)。
满足三个条件即可使用机器学习:
典型应用:推荐系统、风控模型、图像识别、语音转文字、文本分类、销量预测、故障检测。
机器学习的底层是数学,但零基础无需精通数学,掌握核心概念即可理解算法原理。
Python是机器学习首选语言,语法简洁、库生态完善、社区活跃。
机器学习项目不是单纯训练算法,而是标准化工程流程,共7个核心步骤:
明确业务目标(分类/回归/聚类)、确定数据来源(业务数据库、日志、公开数据集)、定义特征与标签。
收集原始数据,保证数据量级与覆盖度,避免数据偏见(如性别、地域偏见)。
原始数据存在缺失、异常、重复、量纲不一等问题,必须预处理:
按比例拆分训练集、验证集、测试集,常用比例:
根据任务类型选算法:
用测试集验证模型效果,不同任务对应不同指标:
轮廓系数、CH指数,衡量簇内紧密、簇间分离程度。
假设特征与标签呈线性关系,寻找最佳拟合直线/超平面,最小化预测值与真实值的误差。 公式:y = w₁x₁ + w₂x₂ + … + wₙxₙ + b y:预测值;x:特征;w:权重(特征重要性);b:偏置项。 损失函数:均方误差(MSE),衡量预测误差。 优化方法:最小二乘法、梯度下降法。
房价预测、销售额预测、气温预测、流量预测等连续值预测。
优点:简单高效、可解释性强、训练速度快; 缺点:仅能拟合线性关系,对非线性数据效果差。
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_)
名字含“回归”,实则是二分类算法,在线性回归基础上加入Sigmoid函数,将输出压缩到[0,1]区间,代表样本属于正类的概率。 Sigmoid函数:σ(z) = 1/(1+e^(-z)),z=wx+b。 概率≥0.5预测为正类,否则为负类。 损失函数:交叉熵损失,衡量分类误差。
垃圾邮件识别、风控违约预测、疾病诊断、用户流失预测。
优点:简单高效、输出概率值、可解释性强、工业界广泛使用; 缺点:仅能处理线性可分问题,无法拟合复杂非线性关系。
“物以类聚”,对于新样本,找到训练集中距离最近的K个邻居,按多数投票决定类别(分类)或取平均值(回归)。 距离度量:欧氏距离、曼哈顿距离。 关键参数:K值(邻居数量),K过小易过拟合,K过大模型过于简单。
小数据集分类、异常检测、简单模式识别。
优点:无需训练、原理简单、对非线性数据友好; 缺点:预测速度慢、对数据尺度敏感、不适合大数据集。
模拟人类决策逻辑,构建树状结构:根节点(全部数据)→内部节点(特征判断)→分支(判断结果)→叶子节点(预测结果)。 节点划分依据:信息增益、信息增益比、基尼系数,选择最能降低数据不确定性的特征划分。
分类/回归任务、需要模型可解释的场景(如金融风控、医疗诊断)。
优点:可解释性极强、无需数据标准化、能处理非线性与缺失值; 缺点:易过拟合、对数据敏感、模型不稳定。
集成学习思想,构建多棵决策树,每棵树用不同数据与特征训练,最终综合所有树的结果(投票/平均),降低过拟合风险,提升泛化能力。
结构化数据分类/回归、工业界通用算法、竞赛常用。
优点:泛化能力强、抗过拟合、无需复杂调参、对异常值不敏感; 缺点:模型复杂度高、可解释性低于单决策树。
将无标签数据划分为K个簇,使簇内数据紧密、簇间数据远离。 步骤:随机选K个质心→分配样本到最近质心→更新质心→重复至收敛。
用户分群、商品聚类、异常检测、图像分割。
优点:简单高效、收敛速度快; 缺点:需手动指定K值、对初始质心与异常值敏感、仅适用于凸簇。
在高维空间中寻找最优超平面,最大化不同类别间的间隔,提升泛化能力;核函数可处理非线性可分数据,将低维数据映射到高维空间。
小样本、高维数据、文本分类、图像分类。
优点:泛化能力强、适合高维数据、核函数适配非线性问题; 缺点:训练速度慢、不适合大数据集、参数调优复杂。
机器学习误差=偏差+方差+噪声:
在损失函数中加入惩罚项,限制参数大小:
超参数:人为设置的参数(如KNN的K、决策树深度、随机森林树数量)。 调优方法:
数据决定模型上限,特征工程逼近上限:
避免单次划分数据的偶然性,常用K折交叉验证:将数据分为K份,轮流用1份验证、K-1份训练,取平均结果,评估更稳健。
以鸢尾花分类(经典入门项目)为例,完整复现机器学习流程:
根据花萼长度、花萼宽度、花瓣长度、花瓣宽度,预测鸢尾花类别(3类)。
# 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))
处理非结构化数据(图像、语音、文本),代表网络:CNN(图像)、RNN/LSTM(序列)、Transformer(NLP)。
分布式训练、在线学习、流式计算,适配大数据场景。
计算机视觉、自然语言处理、推荐系统、强化学习、联邦学习(保护数据隐私)。
模型训练→部署→监控→迭代全流程自动化,实现工业级落地。
机器学习不是玄学,而是一套基于数据、算法与工程的标准化方法论。零基础学习者无需畏惧复杂数学,先从流程与实战入手,理解核心逻辑,再逐步深入原理。机器学习的核心价值是解决实际业务问题,而非堆砌算法。通过本教程的学习,你已掌握机器学习的基础概念、全流程、经典算法与实战方法,后续通过持续项目实践,不断深化理解,就能从入门走向精通,在人工智能领域稳步前行。
机器学习的未来是普惠化、工程化、产业化,掌握这项技能,将在数字化时代拥有核心竞争力。
下面给你一篇完整、结构清晰、接近10000字、可直接交作业/写报告/做学习笔记的《深度学习详细教程》。 内容一次性写完,不需要你补充任何信息,可直接复制使用。
深度学习(Deep Learning)是机器学习的一个重要分支,也是当前人工智能领域最核心、最成功的技术方向。它通过模拟人脑神经网络的结构与工作方式,让机器能够从海量数据中自动学习特征、规律和抽象概念,从而实现图像识别、语音识别、自然语言处理、推荐系统、自动驾驶、生成式AI等强大功能。
本教程从基础概念、数学基础、神经网络原理、经典模型、实战代码、工程化、未来趋势等方面系统讲解,帮助零基础读者快速建立完整的深度学习知识体系,达到能理解、能推导、能实战、能讲清楚原理的水平。
深度学习是基于深层神经网络的机器学习方法。
一句话总结: 深度学习 = 多层神经网络 + 大量数据 + 强大算力 + 高效优化算法。
包含关系: AI ⊃ 机器学习 ⊃ 深度学习
深度学习本质是高维空间的函数拟合与数值优化,不需要精通数学,但必须理解以下内容。
核心结论: 深度学习训练 = 用梯度下降最小化损失函数。
深度学习主流开发语言:Python。
核心库:
环境搭建(最简):
人工神经网络的最早形式。 输入特征 → 加权求和 → 激活函数 → 输出。
感知机只能解决线性可分问题。
多层感知机 = 输入层 + 隐藏层 + 输出层。 多层叠加后可以拟合任意复杂函数(通用近似定理)。
没有激活函数,神经网络再深也等价于线性模型。
常用激活函数:
数据从输入层一层层计算到输出层,得到预测值。
衡量预测值与真实值差距。
核心思想: 利用链式法则,从后往前计算每一层参数的梯度。
梯度:参数应该朝哪个方向调整,才能让损失变小。
用全部数据计算梯度,稳定但慢。
用一个样本计算梯度,快但震荡。
用一小批数据(batch),工业界标准。
优化器作用: 根据梯度更新权重,使损失不断下降。
每一层神经元与下一层全部连接。
适用:表格数据、低维数据。 不适用:图像、语音等高维数据(参数爆炸)。
解决过拟合方法:
对每一层输入做标准化,加速训练、稳定梯度、减轻过拟合。 现代深度网络标配。
训练时随机让一部分神经元失活,防止模型过度依赖某些特征。
图像是高维数据(如 224×224×3),全连接会导致:
CNN 三大核心思想:
卷积核(滤波器)在图像上滑动,做点积求和,提取特征:
下采样,降低维度,保留主要信息:
最早成功的CNN,用于手写数字识别。
深度学习爆发起点,首次用GPU、ReLU、Dropout。
结构简单、全部3×3卷积,非常经典。
多尺度卷积,1×1卷积降维。
解决深度网络梯度消失问题,提出残差连接。 可以训练101层、152层超深网络。
ResNeXt、DenseNet、EfficientNet、ConvNeXt
文本、语音、时间序列都是顺序相关的。
每一时刻的输入 + 上一时刻隐藏状态 → 当前时刻输出。
问题: 长序列梯度消失/爆炸,无法学习长距离依赖。
能有效学习长依赖。
→ 被Transformer全面取代。
2017年提出,基于自注意力机制 Self-Attention。
核心优势:
现代NLP全部基于Transformer: BERT、GPT、T5、LLaMA、文心一言、通义千问等。
学习数据分布,生成全新、逼真、合理的数据。
两大模块对抗训练:
经典应用:人脸生成、图像翻译。
当前文生图主流: Stable Diffusion、DALL·E、Midjourney 底层技术。
逐步去噪生成高清图像。
下面给出极简可运行实战代码(PyTorch),你可以直接跑通。
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()
只需要把上面模型换成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
深度学习不是玄学,而是一套严谨、可复现、可工程化的技术体系。它的核心逻辑非常清晰: 用多层神经网络拟合数据规律,用梯度下降学习参数,用大量数据和算力支撑效果。
从最简单的感知机,到MLP、CNN、RNN,再到Transformer、大模型,深度学习正在以极快的速度改变世界。只要按部就班学习原理、动手实战、不断实践,任何人都能从零基础成长为深度学习工程师或算法研究者。
未来已来,深度学习将持续成为人工智能领域最核心、最有价值的技能。
自然语言处理(Natural Language Processing,NLP) 是让计算机理解、处理、生成人类语言的技术,属于人工智能 + 语言学 + 计算机科学的交叉领域。
目标:
所有 NLP 任务第一步都是把文本变成计算机能处理的数据。
英文天然空格分隔,中文必须分词。 工具:
示例: “我喜欢自然语言处理” → ["我", "喜欢", "自然", "语言", "处理"]
去掉无意义词: 的、了、是、和、在、我、你、就…
把文本看成词的集合,不考虑顺序。 优点:简单 缺点:丢失语序信息
考虑连续N个词。 如 2-gram: “我 爱 NLP” → “我爱”、“爱NLP”
衡量一个词对一篇文档的重要程度。
常用于:文本分类、检索、关键词提取。
无监督算法,自动挖掘文本里的主题。 例如:新闻 → 体育、财经、娱乐。
把词语变成低维稠密向量,让语义相近的词距离近。
示例:
优点:
提取局部特征(关键词、短语)。 任务:文本分类、情感分析。
处理序列数据,适合文本、语音。
任务:机器翻译、情感分析、命名实体识别。
用于序列转序列任务。
早期靠 LSTM,现在被 Transformer 取代。
2017年 《Attention Is All You Need》 彻底改变 NLP。
一句话中每个词都能注意到其他所有词,直接建模长距离依赖。
并行学习多种语义关系。
告诉模型词语的顺序。
适用:
适用:
输入一段文本 → 输出类别 例子:
从文本中抽实体:
例: “小明2025年去北京工作” → 小明(人名)、2025年(时间)、北京(地名)
判断实体间关系。 例: “乔布斯创立苹果” → 乔布斯 → 创立 → 苹果
源语言 → 目标语言 中 → 英 英 → 日
长文本 → 简短摘要
根据文章回答问题。 如:阅读理解、智能客服。
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)
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("中性")
from transformers import pipeline
classifier = pipeline("sentiment-analysis", model="bert-base-chinese")
print(classifier("这部电影真的太好看了"))
NLP 已经从特征工程 → 深度学习 → 大模型。 现在的 NLP 核心就是: Transformer + 预训练 + 微调 / 提示词。
只要掌握: 文本预处理 → 词向量 → Transformer → BERT/GPT → 大模型应用 就能胜任现代 NLP 绝大多数岗位与任务。