conclud of 3 is done
This commit is contained in:
parent
c363d11157
commit
cd3df88598
127
3.tex
127
3.tex
|
@ -54,6 +54,14 @@ KNN算法流程大致如下:
|
|||
\item 返回k个点出现频率最多的类别作预测分类
|
||||
\end{itemize}
|
||||
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=8cm]{knn.png}
|
||||
\caption{KNN示意图}
|
||||
\label{knn}
|
||||
\end{figure}
|
||||
以上图为例,在这个图中我假设有三类数据:五角星、三角形和多边形。中间的圆形是未知类型的数据点,现在需要判断这个数据是属于五角星、三角形和多边形中的哪一类。按照NKK的思想,先把离这个圆圈最近的几个点找到,因为离圆圈最近的点对它的类别有判断的帮助。那到底要用多少个来判断呢?这个个数就是k了。如果k=3,就表示要选择离圆圈最近的3个点来判断,由于三角形所占比例为2/3,所以可以认为圆形表示的未知类是和三角形是一类的。如果k=6,由于多边形多占比例最大为1/2,为因此圆圈被认为是属于多边形一类的。从这个例子也可以看出k值对最后结果的影响还是挺大的。
|
||||
|
||||
在使用KNN算法的时候有些地方需要注意。数据的所有特征都要做可比较的量化,若是数据特征中存在非数值的类型,必须采取手段将其量化为数值。举个例子,若样本特征中包含颜色(红黑蓝)一项,颜色之间是没有距离可言的,可通过将颜色转换为灰度值来实现距离计算;另外,样本有多个参数,每一个参数都有自己的定义域和取值范围,他们对distance计算的影响也就不一样,如取值较大的影响力会盖过取值较小的参数。为了公平,样本参数必须做一些scale处理,最简单的方式就是所有特征的数值都采取归一化处置; 需要一个distance函数以计算两个样本之间的距离。距离的定义有很多,如欧氏距离、余弦距离、汉明距离、曼哈顿距离等等。 一般情况下,选欧氏距离作为距离度量,但是这是只适用于连续变量。通常情况下,如果运用一些特殊的算法来计算度量的话,K近邻分类精度可显著提高,如运用大边缘最近邻法或者近邻成分分析法;K值的确定,K是一个自定义的常数,K的值也直接影响最后的估计,一种选择K值得方法是使用 cross-validate(交叉验证)误差统计选择法。交叉验证的概念之前提过,就是数据样本的一部分作为训练样本,一部分作为测试样本,比如选择95\%作为训练样本,剩下的用作测试样本。通过训练数据训练一个机器学习模型,然后利用测试数据测试其误差率。 cross-validate(交叉验证)误差统计选择法就是比较不同K值时的交叉验证平均误差率,选择误差率最小的那个K值。例如选择K=1,2,3,… , 对每个K=i做100次交叉验证,计算出平均误差,然后比较、选出最小的那个。
|
||||
|
||||
|
||||
|
@ -75,9 +83,9 @@ NKK缺点有:
|
|||
\item Spark:1.6.1,Spark官网提供多个下载形式,可以下载源代码也可以下载预编译好的。我下载的是编译好了的Pre-built for Hadoop 2.6。下载地址为:http://www.apache.org/dyn/closer.lua/spark/spark-1.6.1/spark-1.6.1-bin-hadoop2.6.tgz
|
||||
\item 依赖:JDK,因为Spark运行在JVM之上,所以首先需要安装JDK并配置好系统环境变量。
|
||||
\item 操作系统:Ubuntu 14.04,Spark声称是可以支持Windows和类Unix系统(Linux和Mac OS),不过我在我笔记本Windows系统试了下,会出现一些小问题,所以我干脆在虚拟机里的Ubuntu系统上跑的,运行状态良好,未出现问题。
|
||||
\item 机器配置(虚拟机):2G内存,单CPU4核
|
||||
\item 机器配置(虚拟机):我使用的是Spark的单节点模式,2G内存,单CPU4核
|
||||
\item 编程语言:Python,如报告2中所述,Spark本身使用scala语言编写的,但是它还提供了Java、Python和R的接口,综合考虑开发效率和编程语言的易用性,我最后选用的Python。相对Java来说,实现同样的功能,Python写出的代码更简洁些,因此Python很适合来做这种科学研究性质的程序。
|
||||
\item 其他配置:con目录下的log4j.properties用于配置Spark的日志输出,Spark默认是把INFO级别及以上的日志信息都进行输出,虽然这对了解它干了哪些工作很有帮助,但是我觉得过多的信息输出到控制台上会影响正常的输出。因此在这里可以把输出日志级别提高些,比如设置为WARN或者ERROR。
|
||||
\item 其他配置:conf目录下的log4j.properties用于配置Spark的日志输出,Spark默认是把INFO级别及以上的日志信息都进行输出,虽然这对了解它干了哪些工作很有帮助,但是我觉得过多的信息输出到控制台上会影响正常的输出。因此在这里可以把输出日志级别提高些,比如设置为WARN或者ERROR。
|
||||
\end{itemize}
|
||||
|
||||
\subsection{数据集}
|
||||
|
@ -85,6 +93,9 @@ NKK缺点有:
|
|||
|
||||
\section{实验过程}
|
||||
|
||||
\subsection{算法设计}
|
||||
|
||||
|
||||
\subsection{实现KNN算法}
|
||||
在实现KNN算法的时候,我尽量按照Spark库提供的API设计的,因此传递给KNN的数据都是DataFrame类型的。在新建KNN对象进行分类的时候,需要提供DataFrame的列信息,目前用到的有特征向量列和类标签列,所以初始化函数可疑传递测试数据DataFrame的信息,默认值分别是“features”和“label”。其代码如下所示:
|
||||
\begin{python}
|
||||
|
@ -150,56 +161,90 @@ for x in testData:
|
|||
count += 1
|
||||
print "error rate is %f(%d/%d)" % (1.0 * errorCount / count,errorCount,count)
|
||||
\end{python}
|
||||
|
||||
\subsection{运行算法}
|
||||
我把KNN算法实现文件KNN.py放到了和Spark同级的目录中,因此要把该文件提交给Spark执行只需执行以下命令:
|
||||
\begin{figure}[h!]
|
||||
\centering
|
||||
\includegraphics[width=12cm]{launch_knn.jpg}
|
||||
\caption{运行knn.py命令}
|
||||
\label{launch_knn}
|
||||
\end{figure}
|
||||
|
||||
\section{实验结果}
|
||||
本次报告分别从K值和距离算法两个方面对实现的KNN算法进行测试:
|
||||
本次报告分别从K值和距离算法两个方面对实现的KNN算法进行测试,下面两个表分别是K值从1到10时利用欧几里得距离和余弦相似度对946个样本利用KNN预测得到的结果:
|
||||
|
||||
\subsection{K值的影响}
|
||||
k = 10: error rate is 0.021142(20/946) cost time : 1491
|
||||
\begin{table}[!hbp]
|
||||
\centering
|
||||
\begin{tabular}{c c c}
|
||||
\hline
|
||||
K值 & 预测错误数 & 越策错误率 \\
|
||||
\hline
|
||||
1 & 13 & 0.013742 \\
|
||||
|
||||
k = 5 : error rate is 0.017970(17/946) cost time : 1482
|
||||
2 & 12 & 0.012685 \\
|
||||
|
||||
k = 4 : error rate is 0.012685(12/946) cost time : 1447,1337
|
||||
3 & 11 & 0.011628 \\
|
||||
|
||||
k = 3 : error rate is 0.011628(11/946) cost time : 2377
|
||||
4 & 12 & 0.012685 \\
|
||||
|
||||
k = 2 : error rate is 0.012685(12/946) cost time : 3261
|
||||
5 & 17 & 0.017970 \\
|
||||
|
||||
k = 1 : error rate is 0.013742(13/946) cost time : 1596
|
||||
6 & 17 & 0.017970 \\
|
||||
|
||||
7 & 20 & 0.021142 \\
|
||||
|
||||
8 & 19 & 0.020085 \\
|
||||
|
||||
9 & 22 & 0.023256 \\
|
||||
|
||||
10 & 20 & 0.021142 \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\caption{利用欧几里得距离得到的结果}
|
||||
\end{table}
|
||||
|
||||
\begin{table}[!h]
|
||||
\centering
|
||||
\begin{tabular}{c c c}
|
||||
\hline
|
||||
K值 & 预测错误数 & 越策错误率 \\
|
||||
\hline
|
||||
1 & 11 & 0.011628 \\
|
||||
|
||||
2 & 17 & 0.017970 \\
|
||||
|
||||
3 & 13 & 0.013742 \\
|
||||
|
||||
4 & 14 & 0.014799 \\
|
||||
|
||||
5 & 14 & 0.014799 \\
|
||||
|
||||
6 & 15 & 0.015856 \\
|
||||
|
||||
7 & 18 & 0.019027 \\
|
||||
|
||||
8 & 20 & 0.021142 \\
|
||||
|
||||
9 & 25 & 0.026427 \\
|
||||
|
||||
10 & 26 & 0.027484 \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\caption{利用余弦相似度得到的结果}
|
||||
\end{table}
|
||||
|
||||
|
||||
|
||||
error rate is 0.011628(11/946)
|
||||
|
||||
error rate is 0.017970(17/946)
|
||||
|
||||
error rate is 0.013742(13/946)
|
||||
|
||||
error rate is 0.014799(14/946)
|
||||
|
||||
error rate is 0.014799(14/946)
|
||||
|
||||
|
||||
error rate is 0.015856(15/946)
|
||||
|
||||
|
||||
error rate is 0.019027(18/946)
|
||||
|
||||
|
||||
error rate is 0.021142(20/946)
|
||||
|
||||
|
||||
error rate is 0.026427(25/946)
|
||||
|
||||
|
||||
error rate is 0.027484(26/946)
|
||||
|
||||
\subsection{距离算法的影响}
|
||||
|
||||
\subsection{Spark cache方法的影响}
|
||||
|
||||
\section{实验总结}
|
||||
|
||||
1. api使用不熟悉,比如dataframe,vector的数据类型,得利用输出多次测试,才晓得咋使用。map, reduce等等
|
||||
2. driver programe 和worker program
|
||||
通过本次实验,我基于Spark实现了KNN算法,Spark提供了非常丰富的API来支持分布式计算,同时KNN算法的计算过程又很简洁,所以本次的实验过程没有遇到太大的问题。在实现KNN算法的过程中,为了搞懂Spark的原理,需要翻阅很多的资料,虽然在完成报告2的过程中已经对Spark有了一定的了解,但是那还都是停留在基本的使用层次,大部分工作是学习官网提供的教程和网络相关介绍,只是对一些基本的概念和MLlib的API的使用有了个大概的认识。但是对于如何使用Spark 进行分布式编程还是了解的太少,这个时候我就找了些论文和书籍来看看,由于时间比较紧,虽然只看了部分内容,但是对于编程实现KNN我感觉还是起到了很大的帮助。这次实验让我感受到了Spark编程的强大以及简洁,往往几行代码就能够实现很复杂的功能。不过在实验过程中也还是遇到了很多的问题:
|
||||
\begin{itemize}
|
||||
\item Spark提供了丰富的API,但是因为是第一次接触,所以用起来不太熟悉,比如一个函数产生的dataframe得利用输出查看才晓得具体包含了哪些信息。Rdd的操作函数map, reduce等函数具体有什么效果或者返回的数据类型是什么,需要经常查看API以及结合具体的调试来体会。
|
||||
\item 对Spark的编程模型理解不深,一开始我曾经试图在worker proggram中访问外部变量,但是这是不允许的,Spark要求函数必须是闭包函数,因此在运行的时候报了错。目前算法在预测大量测试数据的时候,运行时间有点长,这是在后续工作中需要改进的地方。
|
||||
\end{itemize}
|
||||
|
||||
在前段时间召开的2016Spark峰会上,Spark2.0已经被发布了,据称新一代的Spark会更简单、快速和智能。Spark的迅猛发展已经收到业内各大公司的广泛关注,包括IBM、Microsoft在内的许多企业都在积极推广Spark。对于机器学习模块,
|
||||
基于DataFrame的机器学习API也就是ml包将作为主要的ML API,尽管原本的mllib包仍然保留,但以后的开发重点会集中在基于DataFrame的API上。此外任何编程语言的用户都将可以保留与载入机器学习的管道与模型了。还是如报告2中所总结,通过谭老师的作业,我算是开始接触了Spark这门快速发展的技术,对于我以后的研究工作提供了更多思路,目前我正打算把Spark应用到我们正在开发的一个系统中来处理大量数据的匹配问题,希望能在处理效率方面有所提升。
|
||||
\end{spacing}
|
||||
\end{document}
|
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Loading…
Reference in New Issue