来源:原始 Jupyter Notebook。内容已转换为网页阅读格式;下载原文件。
第1章 机器学习基础
1.1 何谓机器学习
1.1.1 传感器和海量数据
1.1.2 机器学习非常重要
1.2 关键术语
1.3 机器学习的主要任务
1.4 如何选择合适的算法
1.5 开发机器学习应用程序的步骤
1.6 Python语言的优势
1.6.1 可执行伪代码
1.6.2 Python比较流行
1.6.3 Python语言的特色
1.6.4 Python语言的缺点
1.7 NumPy函数库基础
1.8 本章小结
第2章 k-近邻算法
2.1 k-近邻算法概述
2.1.1 准备:使用Python导入数据
2.1.2 从文本文件中解析数据
2.1.3 如何测试分类器
2.2 示例:使用k-近邻算法改进约会网站的配对效果
2.2.1 准备数据:从文本文件中解析数据
2.2.2 分析数据:使用Matplotlib创建散点图
2.2.3 准备数据:归一化数值
2.2.4 测试算法:作为完整程序验证分类器
2.2.5 使用算法:构建完整可用系统
2.3 示例:手写识别系统
2.3.1 准备数据:将图像转换为测试向量
2.3.2 测试算法:使用k-近邻算法识别手写数字
2.4 本章小结
第3章 决策树
3.1 决策树的构造
3.1.1 信息增益
3.1.2 划分数据集
3.1.3 递归构建决策树
3.2 在Python中使用Matplotlib注解绘制树形图
3.2.1 Matplotlib注解
3.2.2 构造注解树
3.3 测试和存储分类器
3.3.1 测试算法:使用决策树执行分类
3.3.2 使用算法:决策树的存储
3.4 示例:使用决策树预测隐形眼镜类型
3.5 本章小结
第4章 基于概率论的分类方法:朴素贝叶斯
4.1 基于贝叶斯决策理论的分类方法
4.2 条件概率
4.3 使用条件概率来分类
4.4 使用朴素贝叶斯进行文档分类
4.5 使用Python进行文本分类
4.5.1 准备数据:从文本中构建词向量
4.5.2 训练算法:从词向量计算概率
4.5.3 测试算法:根据现实情况修改分类器
4.5.4 准备数据:文档词袋模型
4.6 示例:使用朴素贝叶斯过滤垃圾邮件
4.6.1 准备数据:切分文本
4.6.2 测试算法:使用朴素贝叶斯进行交叉验证
4.7 示例:使用朴素贝叶斯分类器从个人广告中获取区域倾向
4.7.1 收集数据:导入RSS源
4.7.2 分析数据:显示地域相关的用词
4.8 本章小结
第5章 Logistic回归
在这一节我们将首次接触最优化问题和算法。
5.1 基于Logistic回归和Sigmoid函数的分类
对于二分类问题,通常使用 海维塞德阶跃函数(Heaviside step function)作为预测函数,也称为 单位阶跃函数,但是该函数在跳跃点上从 0 瞬间跳跃到 1,不是一个连续函数,所以使用 Sigmoid 函数 来近似:
5.2 基于最优化方法的最佳回归系数确定
5.2.1 梯度上升法
梯度算法的迭代公式:
梯度上升法用来求函数的最大值,梯度下降法用来求函数的最小值。
准备如下数据集,并通过梯度上升法求解 Logistic 回归:
import matplotlib.pyplot as plt
import numpy as np
# 加载数据集
def loadDataSet(dataPath):
dataMat = []
labelMat = []
fr = open(dataPath)
for line in fr.readlines():
lineArr = line.strip().split()
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
labelMat.append(int(lineArr[2]))
return dataMat, labelMat
# 画散点图
def plotDataSet(dataMat, labelMat):
dataArr = np.array(dataMat)
n = np.shape(dataArr)[0]
xcord1 = []
ycord1 = []
xcord2 = []
ycord2 = []
for i in range(n):
if int(labelMat[i]) == 1:
xcord1.append(dataArr[i, 1])
ycord1.append(dataArr[i, 2])
else:
xcord2.append(dataArr[i, 1])
ycord2.append(dataArr[i, 2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
ax.scatter(xcord2, ycord2, s=30, c='green')
plt.show()
dataMat, labelMat = loadDataSet('./data/1.txt')
plotDataSet(dataMat, labelMat)
运行结果

5.2.2 训练算法:使用梯度上升找到最佳参数
def sigmoid(inX):
return 1.0 / (1 + np.exp(-inX))
def gradAscent(dataMatIn, classLabels):
dataMatrix = np.mat(dataMatIn)
labelMat = np.mat(classLabels).transpose()
m, n = np.shape(dataMatrix)
alpha = 0.001
maxCycles = 200
weights = np.ones((n, 1))
for k in range(maxCycles):
h = sigmoid(dataMatrix * weights)
error = (labelMat - h)
weights = weights + alpha * dataMatrix.transpose() * error
return weights
weights = gradAscent(dataMat, labelMat)
print(weights)
运行结果
[[ 2.77955136]
[ 0.36268202]
[-0.44923697]]
5.2.3 分析数据:画出决策边界
在 Sigmoid 函数 中,当 时, 为决策边界。所以我们令:
这就是 Logistic 回归的决策边界:
# 画散点图和分界线
def plotBestFit(dataMat, labelMat, weights):
dataArr = np.array(dataMat)
n = np.shape(dataArr)[0]
xcord1 = []
ycord1 = []
xcord2 = []
ycord2 = []
for i in range(n):
if int(labelMat[i]) == 1:
xcord1.append(dataArr[i, 1])
ycord1.append(dataArr[i, 2])
else:
xcord2.append(dataArr[i, 1])
ycord2.append(dataArr[i, 2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
ax.scatter(xcord2, ycord2, s=30, c='green')
# 决策边界
x = np.arange(-3.0, 3.0, 0.1)
y = (-weights[0,0]-weights[1,0]*x)/weights[2,0]
ax.plot(x, y)
plt.show()
plotBestFit(dataMat, labelMat, weights)
运行结果

5.2.4 训练算法:随机梯度上升
上面的算法需要大量的计算,它在每次更新回归系数时都需要遍历整个数据集,可以改进为一次只用一个样本来更新回归系数,这被称为 随机梯度上升算法。由于可以在新样本到来时对分类器进行增量式更新,所以它也是一种 在线学习算法,于此相对应,一次处理所有数据的算法被称为 批处理。
def stocGradAscent0(dataMatIn, classLabels):
dataMatrix = np.array(dataMatIn)
m, n = np.shape(dataMatrix)
alpha = 0.001
weights = np.ones(n)
for i in range(m):
h = sigmoid(np.sum(dataMatrix[i] * weights))
error = (labelMat[i] - h)
weights = weights + alpha * error * dataMatrix[i]
return weights
weights = stocGradAscent0(dataMat, labelMat)
print(weights)
运行结果
[0.963951 0.9826866 0.49153886]
随机梯度上升算法和梯度上升算法在代码上很相似,但也有一些区别:第一,梯度上升算法中 h 和 error 是向量,而随机梯度上升算法中是数值;第二,随机梯度上升算法中没有矩阵的转换过程。
画出分界线,可以看出随机梯度上升的拟合效果没有上面的梯度上升算法完美,但是,这并不能表示这种算法不好,判断优化算法优劣的一个方法是看它是否收敛,可以在数据集上多运行几次,看参数是否达到一个稳定值。
针对上面的随机梯度上升算法,还可以进行一些改进:
- alpha 每次迭代时需要调整:alpha = 4/(1.0+i+j)+0.01
- 随机选择样本来更新回归系数
这样可以缓解参数收敛的数据波动。