人工智能与机器学习基础
人工智能与机器学习基础
简介
人工智能(Artificial Intelligence,AI)是计算机科学的一个分支,致力于构建能够模拟人类智能的系统。机器学习(Machine Learning,ML)是 AI 的核心子领域,通过数据驱动的方式让计算机自动学习规律,无需显式编程。本篇介绍 AI/ML 的基础概念、常见算法和工作流程。
人工智能的发展经历了多次浪潮。1956 年达特茅斯会议首次提出"人工智能"概念;早期的符号主义 AI(专家系统)通过人工编写规则来实现智能,但知识获取瓶颈严重;1980 年代连接主义兴起,神经网络开始发展;2006 年 Hinton 提出深度信念网络,开启了深度学习时代;2012 年 AlexNet 在 ImageNet 上的突破标志着深度学习的全面崛起;2017 年 Transformer 的提出和 2022 年 ChatGPT 的发布,将 AI 推向了大模型时代。
机器学习的本质是函数逼近:给定一组输入-输出对 {(x_i, y_i)},找到一个函数 f 使得 f(x_i) ≈ y_i,并且 f 能对未见过的输入做出好的预测。不同的机器学习范式通过不同的方式定义这个学习问题:
- 监督学习:直接给定输入-输出对
- 无监督学习:只有输入,没有输出,目标是发现数据的结构
- 强化学习:通过试错和奖励信号学习最优策略
- 自监督学习:从输入本身构造监督信号(如预测被遮盖的词)
特点
偏差-方差权衡
偏差-方差权衡是理解机器学习模型行为的核心框架:
- 偏差(Bias):模型对真实关系的系统性偏离。高偏差意味着模型过于简单(欠拟合),无法捕捉数据的复杂模式。
- 方差(Variance):模型对不同训练集的敏感程度。高方差意味着模型过于复杂(过拟合),记住了训练数据中的噪声。
- 噪声(Irreducible Error):数据本身的固有噪声,无法通过任何模型消除。
总误差 = 偏差^2 + 方差 + 噪声
模型复杂度的增加通常会降低偏差但增加方差,因此需要在两者之间找到平衡点。正则化、交叉验证、集成学习等方法都是用来管理偏差-方差权衡的工具。
机器学习分类
监督学习
# 分类任务 — 鸢尾花分类
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
# 加载数据
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
iris.data, iris.target, test_size=0.2, random_state=42
)
# 训练随机森林
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)
# 评估
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred, target_names=iris.target_names))回归任务
# 回归任务 — 房价预测
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.preprocessing import StandardScaler
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
# 特征缩放
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 线性回归
model = LinearRegression()
model.fit(X_train_scaled, y_train)
y_pred = model.predict(X_test_scaled)
print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
print(f"R2: {r2_score(y_test, y_pred):.4f}")无监督学习
# 聚类 — KMeans 客户分群
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import numpy as np
# 生成模拟数据
X, _ = make_blobs(n_samples=300, centers=4, random_state=42)
# KMeans 聚类
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
print(f"聚类中心:\n{kmeans.cluster_centers_}")
print(f"惯性值: {kmeans.inertia_:.2f}")
# PCA 降维
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_reduced = pca.fit_transform(X)
print(f"解释方差比: {pca.explained_variance_ratio_}")分类算法深入对比
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
import numpy as np
def compare_classifiers():
"""系统对比常见分类算法的性能"""
X, y = make_classification(
n_samples=1000, n_features=20, n_informative=10,
n_redundant=5, random_state=42
)
classifiers = {
"逻辑回归": LogisticRegression(max_iter=1000, random_state=42),
"决策树": DecisionTreeClassifier(max_depth=5, random_state=42),
"随机森林": RandomForestClassifier(n_estimators=100, random_state=42),
"梯度提升": GradientBoostingClassifier(n_estimators=100, random_state=42),
"SVM (RBF)": SVC(kernel='rbf', random_state=42),
"KNN (k=5)": KNeighborsClassifier(n_neighbors=5),
"朴素贝叶斯": GaussianNB(),
}
print(f"{'算法':>15s} | {'准确率均值':>10s} | {'准确率标准差':>12s}")
print("-" * 45)
for name, clf in classifiers.items():
scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
print(f"{name:>15s} | {scores.mean():>10.4f} | {scores.std():>12.4f}")
compare_classifiers()评估指标详解
import numpy as np
from sklearn.metrics import (
accuracy_score, precision_score, recall_score, f1_score,
roc_auc_score, confusion_matrix, classification_report
)
def comprehensive_evaluation():
"""分类评估指标的全面解释
1. Accuracy (准确率): 正确预测数 / 总预测数
- 问题:类别不平衡时误导性强
- 例:99% 负样本 + 1% 正样本,全预测为负也能达到 99%
2. Precision (精确率): TP / (TP + FP)
- 预测为正的样本中真正为正的比例
- 适合"宁缺毋滥"的场景(垃圾邮件过滤)
3. Recall (召回率): TP / (TP + FN)
- 真正为正的样本中被正确预测的比例
- 适合"宁可错杀不可放过"的场景(疾病筛查)
4. F1 Score: 2 * Precision * Recall / (Precision + Recall)
- 精确率和召回率的调和平均
- 适合两者都重要的场景
5. ROC-AUC: 不依赖阈值的全局评估指标
- 衡量模型区分正负样本的能力
- AUC = 0.5 等于随机猜测
"""
# 模拟预测结果
y_true = np.array([1, 1, 0, 1, 0, 0, 1, 0, 0, 1])
y_pred = np.array([1, 0, 0, 1, 0, 1, 1, 0, 0, 0])
y_scores = np.array([0.9, 0.3, 0.2, 0.8, 0.1, 0.6, 0.7, 0.15, 0.05, 0.4])
print("混淆矩阵:")
cm = confusion_matrix(y_true, y_pred)
print(cm)
print(f"\nTP={cm[1,1]}, FP={cm[0,1]}, FN={cm[1,0]}, TN={cm[0,0]}")
print(f"\n准确率: {accuracy_score(y_true, y_pred):.4f}")
print(f"精确率: {precision_score(y_true, y_pred):.4f}")
print(f"召回率: {recall_score(y_true, y_pred):.4f}")
print(f"F1 分数: {f1_score(y_true, y_pred):.4f}")
print(f"ROC-AUC: {roc_auc_score(y_true, y_scores):.4f}")
print("\n完整分类报告:")
print(classification_report(y_true, y_pred, target_names=["负类", "正类"]))
comprehensive_evaluation()过拟合与正则化
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import learning_curve
import numpy as np
def demonstrate_regularization():
"""正则化方法详解
过拟合的信号:
- 训练集表现很好,验证集表现差
- 训练损失持续下降,验证损失开始上升
- 模型参数量远大于数据量
正则化方法:
1. L1 正则化 (Lasso): |w| -> 产生稀疏解,自动特征选择
2. L2 正则化 (Ridge): w^2 -> 防止参数过大,平滑模型
3. Elastic Net: α|w| + βw^2 -> L1 和 L2 的组合
4. Dropout: 随机丢弃神经元(深度学习)
5. 早停 (Early Stopping): 验证集性能下降时停止训练
6. 数据增强: 增加训练数据的多样性
7. 集成学习: 多模型投票/平均降低方差
"""
X, y = make_classification(n_samples=500, n_features=20, n_informative=5, random_state=42)
# 不同正则化强度的对比
Cs = [0.001, 0.01, 0.1, 1.0, 10.0, 100.0]
print("L2 正则化强度 (C 越小正则化越强):")
print(f"{'C':>8s} | {'训练准确率':>12s} | {'非零系数':>10s}")
print("-" * 40)
for C in Cs:
lr = LogisticRegression(C=C, max_iter=1000, random_state=42)
lr.fit(X, y)
train_acc = lr.score(X, y)
n_nonzero = np.sum(np.abs(lr.coef_) > 1e-6)
print(f"{C:>8.3f} | {train_acc:>12.4f} | {n_nonzero:>10d}")
# L1 正则化产生稀疏解
print("\nL1 正则化 (自动特征选择):")
for C in [0.01, 0.1, 1.0, 10.0]:
lr_l1 = LogisticRegression(C=C, penalty='l1', solver='saga', max_iter=5000, random_state=42)
lr_l1.fit(X, y)
n_nonzero = np.sum(np.abs(lr_l1.coef_) > 1e-6)
print(f" C={C:>6.2f}: 非零系数={n_nonzero} / {X.shape[1]}")
demonstrate_regularization()ML 工作流程
端到端流程
# 完整的 ML Pipeline
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import cross_val_score
# 定义数值型和类别型特征
numeric_features = ['age', 'income', 'score']
categorical_features = ['city', 'category']
# 数值型处理
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
# 类别型处理
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
('encoder', OneHotEncoder(handle_unknown='ignore'))
])
# 组合预处理
preprocessor = ColumnTransformer(transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
])
# 完整 Pipeline
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', GradientBoostingClassifier(n_estimators=100, random_state=42))
])
# 交叉验证
# scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy')
# print(f"平均准确率: {scores.mean():.4f}")模型保存与加载
import joblib
# 保存模型
joblib.dump(pipeline, 'model_pipeline.pkl')
# 加载模型
loaded_model = joblib.load('model_pipeline.pkl')
# 预测
# predictions = loaded_model.predict(new_data)交叉验证策略
from sklearn.model_selection import (
KFold, StratifiedKFold, TimeSeriesSplit, cross_val_score
)
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
import numpy as np
def demonstrate_cv_strategies():
"""不同的交叉验证策略
1. K-Fold: 将数据随机分为 K 份,轮流用一份做验证
- 适合数据量适中、类别均衡的场景
2. Stratified K-Fold: 分层 K 折,保持每折中类别比例一致
- 适合类别不平衡的场景(推荐用于分类)
3. Time Series Split: 时间序列分割,只用历史数据训练
- 适合时序数据,防止未来信息泄漏
4. Group K-Fold: 同一组的数据不会被分到训练和验证中
- 适合有重复观测的数据(同一用户的多条记录)
"""
X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
# 标准 K-Fold
kf = KFold(n_splits=5, shuffle=True, random_state=42)
# 分层 K-Fold(分类任务推荐)
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
# 时间序列分割
tscv = TimeSeriesSplit(n_splits=5)
# 对比不同 CV 策略
clf = RandomForestClassifier(n_estimators=50, random_state=42)
for name, cv in [("K-Fold", kf), ("Stratified K-Fold", skf)]:
scores = cross_val_score(clf, X, y, cv=cv, scoring='accuracy')
print(f"{name:>20s}: {scores.mean():.4f} ± {scores.std():.4f}")
demonstrate_cv_strategies()超参数调优
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import make_classification
import numpy as np
def demonstrate_hyperparameter_tuning():
"""超参数调优方法
1. 网格搜索 (GridSearchCV): 穷举所有参数组合
- 优点:保证找到最优组合
- 缺点:组合爆炸,耗时极长
2. 随机搜索 (RandomizedSearchCV): 随机采样参数组合
- 优点:在有限预算内探索更广的参数空间
- 缺点:不保证找到最优
3. 贝叶斯优化 (Optuna/Hyperopt): 根据历史结果智能选择下一组参数
- 优点:高效,适合参数空间大的场景
- 缺点:实现复杂
4. 超参数选择的一般原则:
- 先用随机搜索确定大致范围
- 再用网格搜索在最优区域精调
- 最后用贝叶斯优化进一步微调
"""
X, y = make_classification(n_samples=500, n_features=20, random_state=42)
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1, 0.2],
'min_samples_split': [2, 5, 10],
}
# 随机搜索(推荐先用这个)
random_search = RandomizedSearchCV(
GradientBoostingClassifier(random_state=42),
param_distributions=param_grid,
n_iter=20, cv=3, scoring='accuracy',
random_state=42, n_jobs=-1
)
random_search.fit(X, y)
print("随机搜索最佳参数:", random_search.best_params_)
print("最佳分数:", random_search.best_score_)
demonstrate_hyperparameter_tuning()常见算法对比
| 算法 | 类型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 线性回归 | 回归 | 连续值预测 | 简单可解释 | 线性假设 |
| 决策树 | 分类/回归 | 非线性关系 | 可解释性强 | 易过拟合 |
| 随机森林 | 分类/回归 | 通用场景 | 抗过拟合 | 训练慢 |
| SVM | 分类 | 小样本分类 | 泛化能力强 | 大数据慢 |
| KMeans | 聚类 | 无标签分群 | 简单高效 | 需指定 K |
| XGBoost | 分类/回归 | 竞赛常用 | 精度高 | 调参复杂 |
算法选择决策指南
def algorithm_selection_guide():
"""机器学习算法选择指南
根据数据特征和任务需求选择合适的算法:
1. 数据量小 (< 1000 样本):
- 优先: 逻辑回归、SVM、决策树
- 避免: 深度学习、大规模集成
2. 数据量中等 (1000 - 100,000):
- 优先: 随机森林、XGBoost、LightGBM
- 结构化数据: XGBoost 通常最好
- 非结构化数据: 考虑深度学习
3. 数据量大 (> 100,000):
- 结构化数据: LightGBM、CatBoost
- 图像/文本/语音: 深度学习
- 流式数据: 在线学习算法
4. 可解释性要求高:
- 逻辑回归、决策树、线性模型
- 配合 SHAP/LIME 解释
5. 延迟要求高:
- 简单模型: 逻辑回归、决策树
- 避免大集成模型
"""
print("算法选择快速参考:")
scenarios = [
("表格数据 + 小数据 + 需要解释", "逻辑回归 / 决策树"),
("表格数据 + 中等数据 + 追求精度", "XGBoost / LightGBM"),
("图像分类", "CNN (ResNet, EfficientNet)"),
("文本分类", "BERT / 预训练模型"),
("时序预测", "LSTM / Prophet / XGBoost"),
("异常检测", "Isolation Forest / One-Class SVM"),
("推荐系统", "矩阵分解 / DeepFM / 协同过滤"),
("聚类分析", "KMeans / DBSCAN / 层次聚类"),
]
for scenario, algo in scenarios:
print(f" {scenario:40s} -> {algo}")
algorithm_selection_guide()优点
缺点
总结
机器学习核心流程:数据收集 -> 特征工程 -> 模型选择 -> 训练 -> 评估 -> 部署。监督学习处理标注数据(分类/回归),无监督学习发现隐藏结构(聚类/降维)。sklearn Pipeline 统一预处理和模型训练。模型评估用交叉验证,保存用 joblib。实际项目中,数据质量和特征工程往往比算法选择更重要。
一个常见的经验法则是:"数据和特征决定了模型效果的上限,而算法只是尽可能接近这个上限。"这意味着在投入大量时间调参之前,应该先确保数据质量和特征工程做到位。
关键知识点
- 先分清模型能力边界、数据边界和工程边界。
- 任何 AI 主题都不只看效果,还要看延迟、成本、可解释性和安全性。
- 评估方式和失败样例往往比"换哪个模型"更重要。
- 偏差-方差权衡是理解模型行为的核心框架。
- 正则化(L1/L2/Dropout/早停)是防止过拟合的关键工具。
- 交叉验证是评估模型泛化能力的标准方法。
项目落地视角
- 给数据来源、Prompt 模板、Embedding 版本、评估集和实验结果做版本管理。
- 上线前准备兜底策略,例如拒答、回退、人工审核或缓存降级。
- 观察错误类型时,区分数据问题、召回问题、提示词问题和模型问题。
MLOps 基本概念
def explain_mlops():
"""MLOps(机器学习运维)是 ML 模型从实验到生产的工程化实践
核心组件:
1. 数据管理:数据版本控制(DVC)、数据质量监控
2. 实验管理:MLflow、Weights & Biases、Neptune
3. 模型训练:自动化训练流水线、超参数搜索
4. 模型注册:模型版本管理、审批流程
5. 模型部署:A/B 测试、灰度发布、回滚
6. 模型监控:数据漂移检测、性能衰减告警
7. 模型再训练:定期或触发式的模型更新
成熟度级别:
- Level 0: 手动,脚本驱动的训练和部署
- Level 1: 自动化训练流水线(CI/CD for ML)
- Level 2: 自动化再训练(CI/CD + CT)
"""
print("MLOps 核心实践:")
print(" 1. 使用 MLflow 追踪实验参数和结果")
print(" 2. 使用 DVC 管理数据版本")
print(" 3. 建立模型性能监控和告警机制")
print(" 4. 实现自动化的模型再训练流水线")
print(" 5. 建立模型审批和回滚流程")
explain_mlops()常见误区
- 只关注 Demo 效果,不考虑线上稳定性和可复现性。
- 没有评估集就频繁调参,最后无法解释为什么变好或变差。
- 忽略权限、审计、隐私和模型输出的安全边界。
- 在数据质量差的情况下花费大量时间调参——数据质量比算法选择更重要。
- 用准确率评估类别不平衡的分类任务——应该用 F1 或 AUC。
- 在测试集上反复调参——测试集应该只使用一次,最终评估时使用。
进阶路线
- 继续补齐训练、推理、评估、MLOps 和治理链路。
- 把主题放回真实业务流程,思考谁提供数据、谁消费结果、谁负责兜底。
- 把 PoC 逐步升级到可观测、可回滚、可演进的生产方案。
- 深入学习集成学习(Bagging、Boosting、Stacking)的原理和变体。
- 掌握模型可解释性工具(SHAP、LIME、Anchors)。
- 学习 AutoML 和 Neural Architecture Search 的基本原理。
适用场景
- 当你准备把《人工智能与机器学习基础》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合企业知识问答、内容生成、分类抽取和智能助手等场景。
- 当需求同时关注效果、时延、成本和安全边界时,这类主题最有价值。
落地建议
- 先定义评估集、成功标准和失败样例,再开始调模型或调提示。
- 把数据来源、分块方式、Embedding 版本和 Prompt 模板纳入版本管理。
- 上线前准备兜底策略,例如拒答、回退、人工审核或检索降级。
- 建立完整的实验追踪体系,确保每次实验可复现。
排错清单
- 先判断问题出在数据、检索、Prompt、模型还是后处理。
- 检查上下文是否过长、分块是否过碎或召回是否偏题。
- 对错误回答做分类,区分幻觉、事实过时、指令误解和格式错误。
- 检查训练集和测试集的分布是否一致(数据泄漏/分布漂移)。
复盘问题
- 如果把《人工智能与机器学习基础》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《人工智能与机器学习基础》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《人工智能与机器学习基础》最大的收益和代价分别是什么?
