code is done
This commit is contained in:
parent
8daec32ca2
commit
73970eca34
|
@ -3,4 +3,4 @@
|
||||||
*.log
|
*.log
|
||||||
*.aux
|
*.aux
|
||||||
*.pdf
|
*.pdf
|
||||||
*.gz
|
*.gz*
|
|
@ -8,7 +8,7 @@
|
||||||
\usepackage{fancyhdr}
|
\usepackage{fancyhdr}
|
||||||
\pagestyle{fancy}
|
\pagestyle{fancy}
|
||||||
\lhead{李志星 15060025 }
|
\lhead{李志星 15060025 }
|
||||||
\chead{比较分析报告}
|
\chead{Spark MLlib应用报告}
|
||||||
\rhead{\leftmark}
|
\rhead{\leftmark}
|
||||||
|
|
||||||
%文档信息/同时也用于生成报告封面
|
%文档信息/同时也用于生成报告封面
|
||||||
|
@ -17,15 +17,26 @@
|
||||||
|
|
||||||
|
|
||||||
\usepackage{graphicx}
|
\usepackage{graphicx}
|
||||||
|
\usepackage{subfigure}
|
||||||
\DeclareGraphicsExtensions{.eps,.ps,.jpg,.bmp,.gif,.png}
|
\DeclareGraphicsExtensions{.eps,.ps,.jpg,.bmp,.gif,.png}
|
||||||
|
|
||||||
|
\usepackage{pythonhighlight}
|
||||||
|
|
||||||
|
|
||||||
\begin{document}
|
\begin{document}
|
||||||
\maketitle
|
\maketitle
|
||||||
\section{MLlib相关概念}
|
\section{前言}
|
||||||
|
|
||||||
|
\subsection{手写识别}
|
||||||
|
手写识别(Handwriting recognition)是计算机在纸、照片、触摸屏或其他设备中接收并识别人手写的文字等信息的技术,主要应用于光学字符识别(OCR)。手写识别系统能够用来识别汉字、英语、数字等字符。不过本报告的重点不在手写识别,而在于理解MLlib中的logistic回归,因此以识别数字为例。识别数字0~9是个十类别问题,logistic回归最常用的场景是二分类,如果要用logistic回归解决这个问题,要采用one-against-one和one-against-all等做法进行处理,虽然复杂些,但是基本原理是一样的。因此本报告把主要关注点放在对MLlib算法的研究,只利用0和1的样本从而解决二分类问题。
|
||||||
|
|
||||||
|
\subsection{Logistic Regression}
|
||||||
|
|
||||||
|
\subsection{MLlib算法主要机制}
|
||||||
在MLlib中有许多的概念,其中对理解其算法比较重要的有:\emph{DataFrame},\emph{Pipeline},\emph{Transfromer}和\emph{Estimator}。
|
在MLlib中有许多的概念,其中对理解其算法比较重要的有:\emph{DataFrame},\emph{Pipeline},\emph{Transfromer}和\emph{Estimator}。
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item DataFrame:MLlib使用SaprkSQL中DataFrame来操作数据集。通过\emph{DataFrame}可以操作各种各样的数据:文本、图像和结构化数据等。\emph{DataFrame}以命名列的方式组织的分布式数据集 ,等同于关系型数据库中的一个表,和R/Python中的\emph{DataFrame}类似,不过进行了很多的优化。
|
\item DataFrame:MLlib使用SaprkSQL中DataFrame来操作数据集,是最近才添加的API。在MLLib模块中有两个包都可以用来调用机器学习算法:mllib和ml。mllibRDD操作,而ml基于DataFrame,ml是官方推荐使用的。通过\emph{DataFrame}可以操作各种各样的数据:文本、图像和结构化数据等。\emph{DataFrame}以命名列的方式组织的分布式数据集 ,等同于关系型数据库中的一个表,和R/Python中的\emph{DataFrame}类似,不过进行了很多的优化。
|
||||||
\item Pipeline:在MLlib中有一个很关键的概念:\emph{Pipeline}。在利用解决机器学习问题时,经常要用对数据进行一系列的处理,MLlib用\emph{Pipeline}来表示这样的工作流,在\emph{Pipeline}中,包含一组以一定顺序执行的\emph{ PipelineStage}( \emph{Transformer}和\emph{Estimator})。
|
\item Pipeline:在MLlib中有一个很关键的概念:\emph{Pipeline}。在利用解决机器学习问题时,经常要用对数据进行一系列的处理,MLlib用\emph{Pipeline}来表示这样的工作流,在\emph{Pipeline}中,包含一组以一定顺序执行的\emph{ PipelineStage}( \emph{Transformer}和\emph{Estimator})。
|
||||||
\item Transformer:Transformer是对特征转换和学习得到的模型的抽象,每一个\emph{Transfromer}都要实现transform()方法,它把一个\emph{DataFrame}处理后得到另一个\emph{DataFrame},一般来说新的DataFrame比原来的DataFrame要多一些列。
|
\item Transformer:Transformer是对特征转换和学习得到的模型的抽象,每一个\emph{Transfromer}都要实现transform()方法,它把一个\emph{DataFrame}处理后得到另一个\emph{DataFrame},一般来说新的DataFrame比原来的DataFrame要多一些列。
|
||||||
\item Estimator:Estimator是对一些机器学习算法或者其他的数据处理算法的抽象,每一个\emph{Estimator}都有一个方法fit(),它以\emph{DataFrame}为参数,返回一个模型,也就是\emph{Transformer},比如在MLlib中 LogisticRegression 就是一个\emph{Estimator},而LogisticRegressionModel就是一个\emph{Transformer}。
|
\item Estimator:Estimator是对一些机器学习算法或者其他的数据处理算法的抽象,每一个\emph{Estimator}都有一个方法fit(),它以\emph{DataFrame}为参数,返回一个模型,也就是\emph{Transformer},比如在MLlib中 LogisticRegression 就是一个\emph{Estimator},而LogisticRegressionModel就是一个\emph{Transformer}。
|
||||||
|
@ -41,10 +52,98 @@
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
|
||||||
\section{问题求解}
|
|
||||||
手写识别(Handwriting recognition)是计算机在纸、照片、触摸屏或其他设备中接收并识别人手写的文字等信息的技术,主要应用于光学字符识别(OCR)。手写识别系统能够用来识别汉字、英语、数字等字符。不过本报告的重点不在手写识别,而在于理解MLlib中的logistic回归,因此以识别数字为例。识别数字0~9是个十类别问题,logistic回归最常用的场景是二分类,如果要用logistic回归解决这个问题,要采用one-against-one和one-against-all等做法进行处理,虽然复杂些,但是基本原理是一样的。因此本报告把主要关注点放在对MLlib算法的研究,只利用0和1的样本从而解决二分类问题。
|
|
||||||
|
|
||||||
|
\section{解决方案}
|
||||||
\subsection{数据集}
|
\subsection{数据集}
|
||||||
|
本报告用到的数据集是我从网上搜集到的,一个文本文件对应一个样本,里面包含一个32*32的0/1矩阵,矩阵中每一个点相当于手写图像处理后一个像素点的值(如下图*)。训练数据和测试数据中分别有300和76个样本。
|
||||||
|
|
||||||
|
\begin{figure}[h!]
|
||||||
|
\centering
|
||||||
|
\subfigure[数字0对应的一个样本]{
|
||||||
|
\label{0} %% label for first subfigure
|
||||||
|
\includegraphics[width=1.0in]{data_0.jpg}}
|
||||||
|
\hspace{0.2in}
|
||||||
|
\subfigure[数字1对应的一个样本]{
|
||||||
|
\label{1} %% label for second subfigure
|
||||||
|
\includegraphics[width=1.0in]{data_1.jpg}}
|
||||||
|
|
||||||
|
\caption{样本示例}
|
||||||
|
\label{0_1} %% label for entire figure
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsection{代码}
|
||||||
|
如前言中所述,MLlib中有两个用于机器学习的包mllib和ml,根据应用趋势和其官方网站的建议,我采用了ml。详细代码见文件***.py。代码解释如下:
|
||||||
|
|
||||||
|
\subsubsection{导入依赖}
|
||||||
|
此段代码导入需要用到的包,包括数据处理的Vectors、算法训练的 LogisticRegression、算法评估BinaryClassificationEvaluator以及其他的一些用于和Spark操作的包。
|
||||||
|
\begin{python}
|
||||||
|
from pyspark import SparkContext
|
||||||
|
from pyspark.sql import SQLContext
|
||||||
|
from pyspark.ml.classification import LogisticRegression
|
||||||
|
from pyspark.mllib.linalg import Vectors
|
||||||
|
from os import listdir
|
||||||
|
from pyspark.ml.evaluation import BinaryClassificationEvaluator
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{初始化环境}
|
||||||
|
SparkContext是在写Spark程序时入口,用来连接Spark并进行后续的操作,一般还会结合SparkConf对象来设置对Saprk集群的配置。这里我们用默认的设置即可。
|
||||||
|
SQLContext用来创建DataFrame。
|
||||||
|
\begin{python}
|
||||||
|
sc = SparkContext(appName="PythonlogExample")
|
||||||
|
sqlContext = SQLContext(sc)
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{加载数据}
|
||||||
|
用于训练的DataFrame中应该包含两列:特征向量和类别。其中类别是数字1或者0.特征向量就是把32*32的矩阵转换成一个1024维的向量即可。load\_data函数接受一个表示训练样本的所在的目录的参数,遍历该目录下所有的文件也就是样本,从样本的名字解析出它的类别是0还是1,从文件内容中读取特征向量。然后生成DataFrame数据并返回。
|
||||||
|
|
||||||
|
\begin{python}
|
||||||
|
def load_data(data_folder):
|
||||||
|
file_list=listdir(data_folder)
|
||||||
|
file_num=len(file_list)
|
||||||
|
datas = list()
|
||||||
|
file_num=len(file_list)
|
||||||
|
datas = list()
|
||||||
|
for i in range(file_num):
|
||||||
|
filename=file_list[i]
|
||||||
|
fr=open('%s/%s' %(data_folder,filename))
|
||||||
|
data_in_line = list()
|
||||||
|
for j in range(32):
|
||||||
|
\end{python}
|
||||||
|
\newpage
|
||||||
|
\begin{python}
|
||||||
|
line_str=fr.readline()
|
||||||
|
for k in range(32):
|
||||||
|
data_in_line.append(int(line_str[k]))
|
||||||
|
label = filename.split('.')[0].split("_")[0]
|
||||||
|
datas.append((float(label),Vectors.dense(data_in_line)))
|
||||||
|
return sqlContext.createDataFrame(datas,["label","features"])
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{模型训练}
|
||||||
|
再加载完训练数据后,即可用LogisticRegression来对其进行训练。新建LogisticRegression对象时可以指定一些参数,我在这里制定了最大迭代数和正则化参数。调用LogisticRegression的fit函数即可生成相应的LogisticRegressionModel。
|
||||||
|
|
||||||
|
\begin{python}
|
||||||
|
train_df = load_data("train")
|
||||||
|
lr = LogisticRegression(maxIter=10, regParam=0.3)
|
||||||
|
lrModel = lr.fit(train_df)
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{模型评估}
|
||||||
|
利用测试数据对训练得到的模型进行评估,BinaryClassificationEvaluator用于评估二分类结果,我最后利用它计算了一下该模型的正确率。
|
||||||
|
\begin{python}
|
||||||
|
test_df = load_data("test")
|
||||||
|
predictions = lrModel.transform(test_df)
|
||||||
|
evaluator = BinaryClassificationEvaluator(labelCol="label", rawPredictionCol="rawPrediction", metricName="areaUnderPR")
|
||||||
|
accuracy = evaluator.evaluate(predictions)
|
||||||
|
print("Test Error = %g " % (1.0 - accuracy))
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsection{结果}
|
||||||
|
|
||||||
|
|
||||||
|
\subsection{算法分析}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sdfsdf
|
|
||||||
\end{document}
|
\end{document}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
Loading…
Reference in New Issue