code is done

This commit is contained in:
StarLee 2016-06-16 21:50:04 +08:00
parent 8daec32ca2
commit 73970eca34
4 changed files with 106 additions and 7 deletions

2
.gitignore vendored
View File

@ -3,4 +3,4 @@
*.log
*.aux
*.pdf
*.gz
*.gz*

View File

@ -8,7 +8,7 @@
\usepackage{fancyhdr}
\pagestyle{fancy}
\lhead{李志星 15060025 }
\chead{比较分析报告}
\chead{Spark MLlib应用报告}
\rhead{\leftmark}
%文档信息/同时也用于生成报告封面
@ -17,15 +17,26 @@
\usepackage{graphicx}
\usepackage{subfigure}
\DeclareGraphicsExtensions{.eps,.ps,.jpg,.bmp,.gif,.png}
\usepackage{pythonhighlight}
\begin{document}
\maketitle
\section{MLlib相关概念}
\section{前言}
\subsection{手写识别}
手写识别Handwriting recognition是计算机在纸、照片、触摸屏或其他设备中接收并识别人手写的文字等信息的技术主要应用于光学字符识别OCR。手写识别系统能够用来识别汉字、英语、数字等字符。不过本报告的重点不在手写识别而在于理解MLlib中的logistic回归因此以识别数字为例。识别数字09是个十类别问题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}
\begin{itemize}
\item DataFrameMLlib使用SaprkSQL中DataFrame来操作数据集。通过\emph{DataFrame}可以操作各种各样的数据:文本、图像和结构化数据等。\emph{DataFrame}以命名列的方式组织的分布式数据集 等同于关系型数据库中的一个表和R/Python中的\emph{DataFrame}类似,不过进行了很多的优化。
\item DataFrameMLlib使用SaprkSQL中DataFrame来操作数据集是最近才添加的API。在MLLib模块中有两个包都可以用来调用机器学习算法mllib和ml。mllibRDD操作而ml基于DataFrameml是官方推荐使用的。通过\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 TransformerTransformer是对特征转换和学习得到的模型的抽象每一个\emph{Transfromer}都要实现transform()方法,它把一个\emph{DataFrame}处理后得到另一个\emph{DataFrame},一般来说新的DataFrame比原来的DataFrame要多一些列。
\item EstimatorEstimator是对一些机器学习算法或者其他的数据处理算法的抽象每一个\emph{Estimator}都有一个方法fit(),它以\emph{DataFrame}为参数,返回一个模型,也就是\emph{Transformer}比如在MLlib中 LogisticRegression 就是一个\emph{Estimator}而LogisticRegressionModel就是一个\emph{Transformer}
@ -41,10 +52,98 @@
\end{figure}
\section{问题求解}
手写识别Handwriting recognition是计算机在纸、照片、触摸屏或其他设备中接收并识别人手写的文字等信息的技术主要应用于光学字符识别OCR。手写识别系统能够用来识别汉字、英语、数字等字符。不过本报告的重点不在手写识别而在于理解MLlib中的logistic回归因此以识别数字为例。识别数字09是个十类别问题logistic回归最常用的场景是二分类如果要用logistic回归解决这个问题要采用one-against-one和one-against-all等做法进行处理虽然复杂些但是基本原理是一样的。因此本报告把主要关注点放在对MLlib算法的研究只利用0和1的样本从而解决二分类问题。
\section{解决方案}
\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}

BIN
data_0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
data_1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB