2 is done

This commit is contained in:
StarLee 2016-06-27 09:49:02 +08:00
parent 3153e01b2c
commit c363d11157
2 changed files with 63 additions and 31 deletions

48
2.tex
View File

@ -28,7 +28,7 @@
%文档信息/同时也用于生成报告封面 %文档信息/同时也用于生成报告封面
\author{李志星\\ 15060025} \author{李志星\\ 15060025}
\date{2016年6月20日} \date{2016年6月20日}
\title{\Huge MLlib中Logistic Regression的应用} \title{\Huge 基于Spark MLlib的手写数字识别\newline \Large Logistic Regression的应用}
@ -91,7 +91,7 @@ tabsize=3
\begin{figure}[h!] \begin{figure}[h!]
\centering \centering
\includegraphics[width=8cm]{LG_arch.png} \includegraphics[width=8cm]{LG_arch.png}
\caption{Logistic Regression示意图} \caption{Logistic Regression原理示意图}
\label{LG_arch} \label{LG_arch}
\end{figure} \end{figure}
@ -120,7 +120,7 @@ tabsize=3
\section{实验过程} \section{实验过程}
\subsection{数据集} \subsection{数据集}
本报告用到的数据集是MNIST的手写识别数据集原始数据集中包含***************个文件分别是训练数据和测试数据的特征值和类标号。这些文件存储的都是二进制格式处理起来比较不方便因此我在网上又找了一些经过别人处理过了的版本它把数据转换成txt文件一个文本文件对应一个样本文件名表示了类标号和序号文件里面包含一个32*32的0/1矩阵矩阵中每一个点可以看成是手写图像中对应的一个像素点如下图*。训练数据和测试数据中分别有400个样本左右虽然样本量有些小但是对于体验一下Spark机器学习算法的还是可以的。 本报告用到的数据集是MNIST的手写识别数据集原始数据集分为多个文件分别是训练数据和测试数据的特征值和类标号。这些文件存储的都是二进制格式处理起来比较不方便因此我在网上又找了一些经过别人处理过了的版本它把数据转换成txt文件一个文本文件对应一个样本文件名表示了类标号和序号文件里面包含一个32*32的0/1矩阵矩阵中每一个点可以看成是手写图像中对应的一个像素点如下图*。训练数据和测试数据中分别有400个样本左右虽然样本量有些小但是对于体验一下Spark机器学习算法的还是可以的。
\begin{figure}[h!] \begin{figure}[h!]
\centering \centering
@ -137,7 +137,7 @@ tabsize=3
\end{figure} \end{figure}
\subsection{代码} \subsection{代码}
如前言中所述MLlib中有两个用于机器学习的包mllib和ml根据应用趋势和其官方网站的建议我采用了ml。Spark本身使用Scala语言编写的但是它同样为Java、Python和R提供了几乎一致的接口在本次报告中我使用的python。详细代码见文件***.py。代码解释如下: 如前言中所述MLlib中有两个用于机器学习的包mllib和ml根据应用趋势和其官方网站的建议我采用了ml。Spark本身使用Scala语言编写的但是它同样为Java、Python和R提供了几乎一致的接口在本次报告中我使用的python。代码解释如下
\subsubsection{导入依赖} \subsubsection{导入依赖}
此段代码导入需要用到的包包括数据处理的Vectors、算法训练的 LogisticRegression、算法评估BinaryClassificationEvaluator以及其他的一些用于和Spark操作的包。 此段代码导入需要用到的包包括数据处理的Vectors、算法训练的 LogisticRegression、算法评估BinaryClassificationEvaluator以及其他的一些用于和Spark操作的包。
@ -174,9 +174,6 @@ def load_data(data_folder):
data_in_line = list() data_in_line = list()
for j in range(32): for j in range(32):
line_str=fr.readline() line_str=fr.readline()
\end{python}
\newpage
\begin{python}
for k in range(32): for k in range(32):
data_in_line.append(int(line_str[k])) data_in_line.append(int(line_str[k]))
label = filename.split('.')[0].split("_")[0] label = filename.split('.')[0].split("_")[0]
@ -186,7 +183,7 @@ def load_data(data_folder):
\end{python} \end{python}
\subsubsection{模型训练} \subsubsection{模型训练}
加载完训练数据后即可用LogisticRegression来对其进行训练。新建LogisticRegression对象时可以指定一些参数我在这里定了最大迭代数和正则化参数。调用LogisticRegression的fit函数即可生成相应的LogisticRegressionModel。 加载完训练数据后即可用LogisticRegression来对其进行训练。新建LogisticRegression对象时可以指定一些参数我在这里定了最大迭代数和正则化参数。调用LogisticRegression的fit函数即可生成相应的LogisticRegressionModel。
\begin{python} \begin{python}
train_df = load_data("train") train_df = load_data("train")
@ -196,7 +193,6 @@ lrModel = lr.fit(train_df)
\subsubsection{模型评估} \subsubsection{模型评估}
利用测试数据对训练得到的模型进行评估BinaryClassificationEvaluator用于评估二分类结果我最后利用其提供的两个指标areaUnderROC和areaUnderPR中的areaUnderROC评价了一下该模型。areaUnderROC是ROC曲线右下角部分占正方形格子的面积比例该值越大说明分类的效果越好。 利用测试数据对训练得到的模型进行评估BinaryClassificationEvaluator用于评估二分类结果我最后利用其提供的两个指标areaUnderROC和areaUnderPR中的areaUnderROC评价了一下该模型。areaUnderROC是ROC曲线右下角部分占正方形格子的面积比例该值越大说明分类的效果越好。
\newpage
\begin{python} \begin{python}
test_df = load_data("test") test_df = load_data("test")
predictions = lrModel.transform(test_df) predictions = lrModel.transform(test_df)
@ -206,10 +202,10 @@ print("Test Error = %g " % (1.0 - accuracy))
\end{python} \end{python}
\section{实验结果} \section{实验结果}
在本次试验中我分别设置最大迭代次数为0,5,10来观察算法的训练效果。利用训练得到模型在测试数据上预测得到DataFrame predictions然后调用predictions的show()方法该方法会打印出前20个结果一共五列分别是label,features,rawPrediction,probability和prediction。label和features这两个列是加载的测试数据的类标号和特征向量。rawPrediction,probability和prediction是利用模型对测试数据进行预测得到的我查了一下相关文档rawPrediction和probability都是一个向量其维数就是类标号的个数rawPrediction字面上的意思是原始的预测直观的讲就是每个类的置信度confidence并且这个向量中的所有元素相加得到的和是0,probability是在给定rawPrediction的条件概率该样本属于每个类的可能性其计算方法根据所采用的分类算法而不同。在Logistic Regression中是这样计算的 1/(1+exp(-rawPrediction)。prediction是最后对样本的预测它是对rawPrediction利用argmax函数得到的也就是取对应rawPrediction最大的那个类。 在本次试验中我分别设置最大迭代次数为0,5,10来观察算法的训练效果。利用训练得到模型在测试数据上预测得到DataFrame predictions然后调用predictions的show()方法该方法会打印出前20个结果一共五列分别是label,features,rawPrediction,probability和prediction。label和features这两个列是加载的测试数据的类标号和特征向量。rawPrediction,probability和prediction是利用分别对训练数据训练以及模型对测试数据进行预测得到的我查了一下相关文档rawPrediction和probability都是一个向量其维数就是类标号的个数rawPrediction字面上的意思是原始的预测直观的讲就是每个类的置信度confidence并且这个向量中的所有元素相加得到的和是0,probability是在给定rawPrediction的条件概率该样本属于每个类的可能性其计算方法根据所采用的分类算法而不同。在Logistic Regression中是这样计算的 1/(1+exp(-rawPrediction)。prediction是最后对样本的预测它是对rawPrediction利用argmax函数得到的也就是取对应rawPrediction最大的那个类。
\begin{itemize} \begin{itemize}
\item maxIter=0时算法每个样本都预测为0这样就有一半的测试样本是错误的最后的areaUnderROC为0.5。\newline \item maxIter=0时算法没有进行迭代因为测试数据中有0和1的样本数是一样的因此它会设置每个类标号的概率为0.5,算法把每个样本都预测为0这样就有一半的测试样本是错误的最后的areaUnderROC为0.5。\newline
\begin{figure}[h!] \begin{figure}[h!]
\centering \centering
\subfigure{ \subfigure{
@ -224,7 +220,7 @@ print("Test Error = %g " % (1.0 - accuracy))
\end{figure} \end{figure}
\item maxIter=5时areaUnderROC为0.5\newline \item maxIter=5时areaUnderROC为0.9979\newline
\begin{figure}[h!] \begin{figure}[h!]
\centering \centering
\subfigure{ \subfigure{
@ -239,7 +235,7 @@ print("Test Error = %g " % (1.0 - accuracy))
\end{figure} \end{figure}
\item maxIter=10时areaUnderROC为0.5\newline \item maxIter=10时areaUnderROC为0.9993\newline
\begin{figure}[h!] \begin{figure}[h!]
\centering \centering
\subfigure{ \subfigure{
@ -262,15 +258,14 @@ print("Test Error = %g " % (1.0 - accuracy))
\begin{itemize} \begin{itemize}
\item 参数设置,算法一开始都是一些基本的对参数的设置,比如迭代次数,规则化参数,是否对数据标准化等等。例如: \item 参数设置,算法一开始都是一些基本的对参数的设置,比如迭代次数,规则化参数,是否对数据标准化等等。例如:
\begin{figure}[h!] \begin{lstlisting}[escapeinside='']
\centering @Since("1.2.0")
\includegraphics[width=16cm]{setMaxIter.jpg} def setMaxIter(value: Int):this.type = set(maxIter,value)
\caption{setMaxIter} setDefault(maxIter -> 100)
\label{setMaxIter} ...
\end{figure} \end{lstlisting}
\item train()方法进行训练。\newline
首先是对训练数据集进行统计便于后续的处理。\newline \item train()方法进行训练。首先是对训练数据集进行统计便于后续的处理。\newline
\newpage
\begin{lstlisting}[escapeinside=''] \begin{lstlisting}[escapeinside='']
val (summarizer, labelSummarizer) = { val (summarizer, labelSummarizer) = {
//'此处用于生成相应的统计数据' //'此处用于生成相应的统计数据'
@ -308,7 +303,6 @@ if (!$(fitIntercept) && numClasses == 2 && histogram(0) == 0.0) {
\end{lstlisting} \end{lstlisting}
上面两段代码也是判断训练数据中的样本是否都是属于正样本否者负样本,但是模型函数中如果不需要截距的话,那么本次训练可能就会出现问题,所以它会进行警告。 上面两段代码也是判断训练数据中的样本是否都是属于正样本否者负样本,但是模型函数中如果不需要截距的话,那么本次训练可能就会出现问题,所以它会进行警告。
\newpage
\begin{lstlisting} \begin{lstlisting}
val optimizer = if ($(elasticNetParam) == 0.0 || $(regParam) == 0.0) { val optimizer = if ($(elasticNetParam) == 0.0 || $(regParam) == 0.0) {
new BreezeLBFGS[BDV[Double]]($(maxIter), 10, $(tol)) new BreezeLBFGS[BDV[Double]]($(maxIter), 10, $(tol))
@ -320,7 +314,6 @@ if (!$(fitIntercept) && numClasses == 2 && histogram(0) == 0.0) {
这段代码用来选择算法的优化器在mllib的实现中Logistic Regression有两种实现LogisticRegressionWithSGD和LogisticRegressionWithLBFGS并且官方推荐使用LogisticRegressionWithLBFGS。而在最新的ml的版本中已经看不到SGD版本的了他根据用户传参情况使用LBFGS或者OWLQN。 这段代码用来选择算法的优化器在mllib的实现中Logistic Regression有两种实现LogisticRegressionWithSGD和LogisticRegressionWithLBFGS并且官方推荐使用LogisticRegressionWithLBFGS。而在最新的ml的版本中已经看不到SGD版本的了他根据用户传参情况使用LBFGS或者OWLQN。
至此,算法的主要逻辑已经分析的差不多了,剩余的就是对模型函数的系数和截距的计算了,比如: 至此,算法的主要逻辑已经分析的差不多了,剩余的就是对模型函数的系数和截距的计算了,比如:
\newpage
\begin{lstlisting} \begin{lstlisting}
val rawCoefficients = state.x.toArray.clone() val rawCoefficients = state.x.toArray.clone()
var i = 0 var i = 0
@ -337,14 +330,15 @@ if ($(fitIntercept)) {
} }
\end{lstlisting} \end{lstlisting}
\end{itemize} \end{itemize}
\newpage
\section{总结} \section{总结}
通过本次实验我对Spark尤其是其MLlib库有了初步的了解。在如今大数据盛行的时代Saprk有广泛的应用场景流处理、交互式SQL查询和机器学习等。尤其是在机器学习方面它基于内存的处理架构很适合机器学习的迭代运算。对于Spark来说15年最重要的变化应该是DataFrame的引入它能够适应更广泛的数据处理要求也吸引了更多的使用者。而随着DataFrame起初的机器学习库mllib也逐渐迁移到基于DataFrame接口的库ml。在本次实验中我感受到的有以下几点 通过本次实验我对Spark尤其是其MLlib库有了初步的了解。在如今大数据盛行的时代Saprk有广泛的应用场景流处理、交互式SQL查询和机器学习等。尤其是在机器学习方面它基于内存的处理架构很适合机器学习的迭代运算。对于Spark来说2015年最重要的变化应该是DataFrame的引入它能够适应更广泛的数据处理要求也吸引了更多的使用者。而随着DataFrame起初的机器学习库mllib也逐渐迁移到基于DataFrame接口的库ml。在本次实验中我感受到的有以下几点
\begin{itemize} \begin{itemize}
\item Spark官方文档很完善并且讲述的也很详细对我这样的Spark初学者来说有很大的帮助。 \item Spark官方文档很完善并且讲述的也很详细对我这样的Spark初学者来说有很大的帮助。
\item Spark对API的支持很棒虽然Spark使用scala开发的但是它还提供了几乎一致的针对Java、python和R的接口这能使更多语言背景的开发者轻松的使用Saprk进行开发。 \item Spark对API的支持很棒虽然Spark使用scala开发的但是它还提供了几乎一致的针对Java、python和R的接口这能使更多语言背景的开发者轻松的使用Saprk进行开发。
\item 机器学习库工具比较完善虽然目前Saprk MLlib实现的知识一些常用的算法,但是它却提供了很多的工具类,比如能够方便地对数据进行切分,拆分出训练数据和测试数据,对于训练的模型也提供了能够进行专业评估的工具类。因此 用Spark开发机器学习应用很方便效率很快。 \item 机器学习库工具比较完善虽然目前Saprk MLlib实现的只是一些常用的算法,但是它却提供了很多的工具类,比如能够方便地对数据进行切分,拆分出训练数据和测试数据,对于训练的模型也提供了能够进行专业评估的工具类。因此 用Spark开发机器学习应用很方便效率很快。
\end{itemize} \end{itemize}
很感谢谭老师给我们布置这样的作业让我接触到了Spark为我以后的研究工作储备了更多的方法。否则我很难有机会主动地去接触这些新鲜的大数据技术通过对Spark的了解熟悉我也对软件工程中的软件设计和架构有了进一步的理解。总之通过本次报告我受益匪浅。 很感谢谭老师给我们布置这样的作业让我接触到了Spark为我以后的研究工作储备了更多的方法。否则我很难有机会主动地去接触这些新鲜的大数据技术通过对Spark的了解熟悉我也对软件工程中的软件设计和架构有了进一步的理解。总之通过本次报告我受益匪浅。
\end{spacing} \end{spacing}
\end{document} \end{document}

View File

@ -1,4 +1,18 @@
\documentclass[a4paper,12pt,UTF8,titlepage]{ctexart} %\documentclass[a4paper,12pt,UTF8,titlepage]{ctexart}
\documentclass[12pt,a4paper,titlepage]{article}
\usepackage{xltxtra,fontspec,xunicode}
\usepackage[slantfont,boldfont]{xeCJK}
\setmainfont{STSong} % 设置文档默认字体
\usepackage{setspace}%使用间距宏包
\usepackage{indentfirst}
\setlength{\parindent}{2em}
\usepackage{titlesec}
\titleformat*{\section}{\centering\huge\bfseries}
%页边距 %页边距
\usepackage{geometry} \usepackage{geometry}
@ -8,6 +22,7 @@
\usepackage{fancyhdr} \usepackage{fancyhdr}
\pagestyle{fancy} \pagestyle{fancy}
\lhead{李志星 15060025 } \lhead{李志星 15060025 }
\date{2016年6月20日}
\chead{KNN在Spark上的实现} \chead{KNN在Spark上的实现}
\rhead{\leftmark} \rhead{\leftmark}
@ -24,6 +39,7 @@
\begin{document} \begin{document}
\begin{spacing}{1.5}
\maketitle \maketitle
\section{实验内容} \section{实验内容}
@ -135,7 +151,7 @@ for x in testData:
print "error rate is %f(%d/%d)" % (1.0 * errorCount / count,errorCount,count) print "error rate is %f(%d/%d)" % (1.0 * errorCount / count,errorCount,count)
\end{python} \end{python}
\section{实验结果} \section{实验结果}
本次报告分别从K值、距离算法和Spark 特性三个方面对实现的KNN算法进行测试 本次报告分别从K值和距离算法两个方面对实现的KNN算法进行测试
\subsection{K值的影响} \subsection{K值的影响}
k = 10: error rate is 0.021142(20/946) cost time : 1491 k = 10: error rate is 0.021142(20/946) cost time : 1491
@ -152,8 +168,30 @@ for x in testData:
k = 1 : error rate is 0.011628(11/946) cost time : 1512 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{距离算法的影响}
@ -163,5 +201,5 @@ for x in testData:
1. api使用不熟悉比如dataframevector的数据类型得利用输出多次测试才晓得咋使用。map reduce等等 1. api使用不熟悉比如dataframevector的数据类型得利用输出多次测试才晓得咋使用。map reduce等等
2. driver programe 和worker program 2. driver programe 和worker program
\end{spacing}
\end{document} \end{document}