From 6bfbf5b95c06b050d0badec33c6a6f042cbb0d67 Mon Sep 17 00:00:00 2001 From: jiangzhonglian Date: Tue, 5 Sep 2017 12:35:35 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=B4=E6=96=B015=E7=AB=A0=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/15.大数据与MapReduce.md | 101 +++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/docs/15.大数据与MapReduce.md b/docs/15.大数据与MapReduce.md index 109cc0f4..cad066ba 100644 --- a/docs/15.大数据与MapReduce.md +++ b/docs/15.大数据与MapReduce.md @@ -2,31 +2,52 @@ ![大数据与MapReduce首页](/images/15.BigData_MapReduce/mr_headPage.jpg "大数据与MapReduce首页") +## 大数据 概述 + `大数据: 收集到的数据已经远远超出了我们的处理能力。` -## MapReduce + +## 大数据 场景 ``` -Hadoop 是 MapRedece框架的一个免费开源实现。 +假如你为一家网络购物商店工作,很多拥护访问该网站,其中有些人会购买商品,有些人则随意浏览后就离开。 +对于你来说,可能很想识别那些有购物意愿的用户。 +那么问题就来了,数据集可能会非常大,在单机上训练要运行好几天。 +接下来:我们讲讲 Hadoop 如何来解决这样的问题 +``` + + +## MapReduce + +### Hadoop 概述 + +``` +Hadoop 是 MapRedece 框架的一个免费开源实现。 MapReduce: 分布式的计算框架,可以将单个计算作业分配给多台计算机执行。 +``` + +### MapRedece 原理 + +> MapRedece 工作原理 + +* 主节点控制 MapReduce 的作业流程 +* MapReduce 的作业可以分成map任务和reduce任务 +* map 任务之间不做数据交流,reduce 任务也一样 +* 在 map 和 reduce 阶段中间,有一个 sort 和 combine 阶段 +* 数据被重复存放在不同的机器上,以防止某个机器失效 +* mapper 和 reducer 传输的数据形式为 key/value对 + +![MapReduce框架的示意图](/images/15.BigData_MapReduce/mr_1_cluster.jpg "MapReduce框架的示意图") + +> MapRedece 特点 + +``` 优点: 使程序以并行的方式执行,可在短时间内完成大量工作。 缺点: 算法必须经过重写,需要对系统工程有一定的理解。 适用数据类型: 数值型和标称型数据。 ``` -* MapReduce框架的示意图 -* ![MapReduce框架的示意图](/images/15.BigData_MapReduce/mr_1_cluster.jpg "MapReduce框架的示意图") - -> 关于MapRduce的学习要点 - -* 主节点控制MapReduce的作业流程 -* MapReduce的作业可以分成map任务和reduce任务 -* map任务之间不做数据交流,reduce任务也一样 -* 在map和reduce阶段中间,有一个sort和combine阶段 -* 数据被重复存放在不同的机器上,以防止某个机器实效 -* mapper和reducer传输的数据形式为key/value对 - -## Python中Hadoop流的使用 +### Hadoop 流(Python 调用) > 理论简介 @@ -44,19 +65,19 @@ cat inputFile.txt | python mapper.py | sort | python reducer.py > outputFile.txt # 测试 Mapper # Linux cat input/15.BigData_MapReduce/inputFile.txt | python src/python/15.BigData_MapReduce/mrMeanMapper.py -# # Window +# Window # python src/python/15.BigData_MapReduce/mrMeanMapper.py < input/15.BigData_MapReduce/inputFile.txt # 测试 Reducer # Linux cat input/15.BigData_MapReduce/inputFile.txt | python src/python/15.BigData_MapReduce/mrMeanMapper.py | python src/python/15.BigData_MapReduce/mrMeanReducer.py -# # Window +# Window # python src/python/15.BigData_MapReduce/mrMeanMapper.py < input/15.BigData_MapReduce/inputFile.txt | python src/python/15.BigData_MapReduce/mrMeanReducer.py ``` -## MapReduce上的机器学习 +### MapReduce 机器学习 -> Mahout in Action +#### Mahout in Action 1. 简单贝叶斯: 2. k-近邻算法: @@ -64,7 +85,7 @@ cat input/15.BigData_MapReduce/inputFile.txt | python src/python/15.BigData_MapR 4. 奇异值分解:Lanczos算法是一个有效的求解近似特征值的算法。 5. k-均值聚类:canopy算法初始化k个簇,然后再运行K-均值求解结果。 -## 使用mrjob库将MapReduce自动化 +#### 使用 mrjob 库将 MapReduce 自动化 > 理论简介 @@ -85,23 +106,12 @@ python mrMean.py < inputFile.txt > myOut.txt python src/python/15.BigData_MapReduce/mrMean.py < input/15.BigData_MapReduce/inputFile.txt ``` -## 利用Pegasos算法并行训练支持向量机 +#### 利用 Pegasos 算法并行训练支持向量机 -> 在MapReduce框架上使用SVM的一般方法 +Pegasos是指原始估计梯度求解器(Peimal Estimated sub-GrAdient Solver) -``` -收集数据:数据按文本格式存放。 -准备数据:输入数据已经是可用的格式,所以不需任何准备工作。如果你需要解析一个大规模的数据集,建议使用map作业来完成,从而达到并行处理的目的。 -分析数据:无。 -训练算法:与普通的SVM一样,在分类器训练上仍需花费大量的时间。 -测试算法:在二维空间上可视化之后,观察超平面,判断算法是否有效。 -使用算法:本例不会展示一个完整的应用,但会展示如何在大数据集上训练SVM。该算法其中一个应用场景就是本文分类,通常在文本分类里可能有大量的文档和成千上万的特征。 -``` +> Pegasos 工作原理 -> Pegasos 算法 - -Pegasos是指原始估计梯度求解器(Peimal Estimated sub-GrAdient Solver)。 -Pegasos算法工作流程是: 1. 从训练集中随机挑选一些样本点添加到带处理列表中 2. 按序判断每个样本点是否被正确分类 * 如果是则忽略 @@ -111,19 +121,30 @@ Pegasos算法工作流程是: 上述算法伪代码如下: ``` -将w初始化为0 +将 w 初始化为0 对每次批处理 - 随机选择k个样本点(向量) + 随机选择 k 个样本点(向量) 对每个向量 如果该向量被错分: - 更新权重向量w - 累加对w的更新 + 更新权重向量 w + 累加对 w 的更新 ``` -我们继续看Python版本的代码实现。 +> 开发流程 + +``` +收集数据:数据按文本格式存放。 +准备数据:输入数据已经是可用的格式,所以不需任何准备工作。如果你需要解析一个大规模的数据集,建议使用 map 作业来完成,从而达到并行处理的目的。 +分析数据:无。 +训练算法:与普通的 SVM 一样,在分类器训练上仍需花费大量的时间。 +测试算法:在二维空间上可视化之后,观察超平面,判断算法是否有效。 +使用算法:本例不会展示一个完整的应用,但会展示如何在大数据集上训练SVM。该算法其中一个应用场景就是本文分类,通常在文本分类里可能有大量的文档和成千上万的特征。 +``` + +我们继续看 Python 版本的代码实现。 * * * -* **作者:[片刻](http://www.apache.wiki/display/~jiangzhonglian) [小瑶](http://www.apache.wiki/display/~chenyao)** +* **作者:[片刻](http://cwiki.apachecn.org/display/~jiangzhonglian) [小瑶](http://cwiki.apachecn.org/display/~chenyao)** * [GitHub地址](https://github.com/apachecn/MachineLearning): * **版权声明:欢迎转载学习 => 请标注信息来源于 [ApacheCN](http://www.apachecn.org/)** From 788540d70ca29d3772b8bd1c4a8efd8b7dfecc01 Mon Sep 17 00:00:00 2001 From: jiangzhonglian Date: Thu, 7 Sep 2017 18:21:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=2014=E7=AB=A0=20?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/14.利用SVD简化数据.md | 42 +++++++++++++--------- images/14.SVD/SVD公式的测试案例.jpg | Bin 0 -> 15976 bytes images/14.SVD/使用SVD简化数据-SVD公式.jpg | Bin 0 -> 14358 bytes images/14.SVD/使用SVD简化数据-SVD公式.png | Bin 26202 -> 0 bytes src/python/14.SVD/svdRecommend.py | 35 +++++++++++------- 5 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 images/14.SVD/SVD公式的测试案例.jpg create mode 100644 images/14.SVD/使用SVD简化数据-SVD公式.jpg delete mode 100644 images/14.SVD/使用SVD简化数据-SVD公式.png diff --git a/docs/14.利用SVD简化数据.md b/docs/14.利用SVD简化数据.md index 1765dbe5..995384d4 100644 --- a/docs/14.利用SVD简化数据.md +++ b/docs/14.利用SVD简化数据.md @@ -7,7 +7,7 @@ ``` 奇异值分解(SVD, Singular Value Decomposition): - 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征。从生物信息学到金融学,SVD 是提出信息的强大工具。 + 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征。从生物信息学到金融学,SVD 是提取信息的强大工具。 ``` ## SVD 场景 @@ -19,10 +19,10 @@ ![LSA举例](/images/14.SVD/使用SVD简化数据-LSI举例.png) -> 推荐引擎 +> 推荐系统 1. 利用 SVD 从数据中构建一个主题空间。 -2. 再在该空间下计算其相似度。(从高维-低维空间的转化,在低维空间来计算相似度,SVD提升了推荐引擎的效率。) +2. 再在该空间下计算其相似度。(从高维-低维空间的转化,在低维空间来计算相似度,SVD 提升了推荐系统的效率。) ![主题空间案例1](/images/14.SVD/SVD_推荐系统_主题空间案例1.jpg) @@ -32,6 +32,8 @@ 例如:`32*32=1024 => 32*2+2*1+32*2=130`(2*1表示去掉了除对角线的0), 几乎获得了10倍的压缩比。 +![SVD公式](/images/14.SVD/使用SVD简化数据-SVD公式.jpg) + ## SVD 原理 ### SVD 工作原理 @@ -39,32 +41,38 @@ > 矩阵分解 * 矩阵分解是将数据矩阵分解为多个独立部分的过程。 -* 矩阵分解可以将原始矩阵表示成新的易于处理的形式,这种新形式时两个或多个矩阵的乘积。(类似代数中的因数分解) +* 矩阵分解可以将原始矩阵表示成新的易于处理的形式,这种新形式是两个或多个矩阵的乘积。(类似代数中的因数分解) * 举例:如何将12分解成两个数的乘积?(1,12)、(2,6)、(3,4)都是合理的答案。 > SVD 是矩阵分解的一种类型,也是矩阵分解最常见的技术 -* SVD 将原始的数据集矩阵Data分解成三个矩阵U、∑、\\(V^T\\) +* SVD 将原始的数据集矩阵 Data 分解成三个矩阵 U、∑、V * 举例:如果原始矩阵 \\(Data_{m*n}\\) 是m行n列, - * \\(U_{m*m}\\) 表示m行m列 - * \\(∑_{m*n}\\) 表示m行n列 - * \\(V^T_{n*n}\\) 表示n行n列。 + * \\(U_{m*n}\\) 表示m行n列 + * \\(∑_{m*k}\\) 表示m行k列 + * \\(V_{k*n}\\) 表示k行n列。 -![SVD公式](/images/14.SVD/使用SVD简化数据-SVD公式.png) +\\(Data_{m*n} = U_{m\*k} \* ∑_{k\*k} \* V_{k\*n}\\) -* 上述分解中会构建出一个矩阵∑,该矩阵只有对角元素,其他元素均为0(近似于0)。另一个惯例就是,∑的对角元素是从大到小排列的。这些对角元素称为奇异值,它们对应原始矩阵 Data 的奇异值。 -* 奇异值与特征值(PCA 数据中重要特征)是有关系的。这里的奇异值就是矩阵 \\(Data * Date^T\\) 特征值的平方根。 +![SVD公式](/images/14.SVD/使用SVD简化数据-SVD公式.jpg) + +具体的案例:(大家可以试着推导一下:https://wenku.baidu.com/view/b7641217866fb84ae45c8d17.html ) + +![SVD公式](/images/14.SVD/SVD公式的测试案例.jpg) + +* 上述分解中会构建出一个矩阵∑,该矩阵只有对角元素,其他元素均为0(近似于0)。另一个惯例就是,∑的对角元素是从大到小排列的。这些对角元素称为奇异值。 +* 奇异值与特征值(PCA 数据中重要特征)是有关系的。这里的奇异值就是矩阵 \\(Data * Data^T\\) 特征值的平方根。 * 普遍的事实:在某个奇异值的数目(r 个=>奇异值的平方和累加到总值的90%以上)之后,其他的奇异值都置为0(近似于0)。这意味着数据集中仅有 r 个重要特征,而其余特征则都是噪声或冗余特征。 ### SVD 算法特点 ``` -优点:简化数据,去除噪声,提高算法的结果 +优点:简化数据,去除噪声,优化算法的结果 缺点:数据的转换可能难以理解 使用的数据类型:数值型数据 ``` -## 推荐引擎 +## 推荐系统 ### 推荐系统 概述 @@ -87,10 +95,12 @@ > 基于物品的相似度和基于用户的相似度:物品比较少则选择物品相似度,用户比较少则选择用户相似度。【矩阵还是小一点好计算】 * 基于物品的相似度:计算物品之间的距离。【耗时会随物品数量的增加而增加】 +* 由于物品A和物品C 相似度(相关度)很高,所以给买A的人推荐C。 ![SVD公式](/images/14.SVD/使用SVD简化数据-基于物品相似度.png) * 基于用户的相似度:计算用户之间的距离。【耗时会随用户数量的增加而增加】 +* 由于用户A和用户C 相似度(相关度)很高,所以A和C是兴趣相投的人,对于C买的物品就会推荐给A。 ![SVD公式](/images/14.SVD/使用SVD简化数据-基于用户相似度.png) @@ -111,9 +121,9 @@ * `相似度= 0.5 + 0.5*( float(inA.T*inB) / la.norm(inA)*la.norm(inB))` * 如果夹角为90度,则相似度为0;如果两个向量的方向相同,则相似度为1.0。 -> 推荐引擎的评价 +> 推荐系统的评价 -* 采用交叉测试的方法。 +* 采用交叉测试的方法。【拆分数据为训练集和测试集】 * 推荐引擎评价的指标: 最小均方根误差(Root mean squared error, RMSE),也称标准误差(Standard error),就是计算均方误差的平均值然后取其平方根。 * 如果RMSE=1, 表示相差1个星级;如果RMSE=2.5, 表示相差2.5个星级。 @@ -126,7 +136,7 @@ 3. 对这些物品的评分从高到低进行排序,返回前N个物品。 -### 项目案例: 餐馆菜肴推荐引擎 +### 项目案例: 餐馆菜肴推荐系统 #### 项目概述 diff --git a/images/14.SVD/SVD公式的测试案例.jpg b/images/14.SVD/SVD公式的测试案例.jpg new file mode 100644 index 0000000000000000000000000000000000000000..85c034201e4b709f6924ec08591cb87551da3ad7 GIT binary patch literal 15976 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 BlOg~B literal 0 HcmV?d00001 diff --git a/images/14.SVD/使用SVD简化数据-SVD公式.jpg b/images/14.SVD/使用SVD简化数据-SVD公式.jpg new file mode 100644 index 0000000000000000000000000000000000000000..970abd76440928062027414f18e18bbba3776797 GIT binary patch literal 14358 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 b`4>M*U~+}Q-9qc12@X(4YAe?uEJOYmYef7L diff --git a/src/python/14.SVD/svdRecommend.py b/src/python/14.SVD/svdRecommend.py index e2a905f6..b0ddb0fa 100644 --- a/src/python/14.SVD/svdRecommend.py +++ b/src/python/14.SVD/svdRecommend.py @@ -52,14 +52,20 @@ def loadExData(): [1, 1, 1, 0, 0], [5, 5, 5, 0, 0]] """ + # # 原矩阵 + # return[[1, 1, 1, 0, 0], + # [2, 2, 2, 0, 0], + # [1, 1, 1, 0, 0], + # [5, 5, 5, 0, 0], + # [1, 1, 0, 2, 2], + # [0, 0, 0, 3, 3], + # [0, 0, 0, 1, 1]] + # 原矩阵 - return[[1, 1, 1, 0, 0], - [2, 2, 2, 0, 0], - [1, 1, 1, 0, 0], - [5, 5, 5, 0, 0], - [1, 1, 0, 2, 2], - [0, 0, 0, 3, 3], - [0, 0, 0, 1, 1]] + return[[0, -1.6, 0.6], + [0, 1.2, 0.8], + [0, 0, 0], + [0, 0, 0]] # 相似度计算,假定inA和inB 都是列向量 @@ -297,12 +303,15 @@ def imgCompress(numSV=3, thresh=0.8): if __name__ == "__main__": # # 对矩阵进行SVD分解(用python实现SVD) - # Data = loadExData() - # print Data - # U, Sigma, VT = linalg.svd(Data) + Data = loadExData() + print 'Data:', Data + U, Sigma, VT = linalg.svd(Data) # # 打印Sigma的结果,因为前3个数值比其他的值大了很多,为9.72140007e+00,5.29397912e+00,6.84226362e-01 # # 后两个值比较小,每台机器输出结果可能有不同可以将这两个值去掉 - # print Sigma + print 'U:', U + print 'Sigma', Sigma + print 'VT:', VT + print 'VT:', VT.T # # 重构一个3x3的矩阵Sig3 # Sig3 = mat([[Sigma[0], 0, 0], [0, Sigma[1], 0], [0, 0, Sigma[2]]]) @@ -326,10 +335,10 @@ if __name__ == "__main__": """ # 计算相似度的方法 - myMat = mat(loadExData2()) + # myMat = mat(loadExData2()) # print myMat # 计算相似度的第一种方式 - print recommend(myMat, 1, estMethod=svdEst) + # print recommend(myMat, 1, estMethod=svdEst) # 计算相似度的第二种方式 # print recommend(myMat, 1, estMethod=svdEst, simMeas=pearsSim)