c++向量和数组的区别_Spark机器学习-Java版(一)-向量和矩阵
1、概述
Spark早期版本時,MLlib是基于RDD來進行分析的,其使用的是 spark. mllib包。而言2.0版本后,由RDD這種抽象數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換到了基于 dataframe上,其相關(guān)API也被封裝到了 spark.ml包下。而在 spark MLlib/ML中為了方便數(shù)據(jù)的整理和分析,將存儲數(shù)據(jù)的格式轉(zhuǎn)化為向量和矩陣進行存儲和計算,以便將數(shù)據(jù)定量化。
1.1 向量和矩陣的概念
向量:類比于數(shù)學中的概念,在spark中可以將其理解為由一維數(shù)組刻畫的數(shù)據(jù)模型;
矩陣:是由行和列組成的數(shù)據(jù)類型,是由多組向量構(gòu)成的,較向量而言計算效率更高。
1.2 向量和矩陣的應(yīng)用場景
向量:標簽向量因其帶有標記,常被用在監(jiān)督學習算法中,如回歸( Regression)和分類( Classification)等。
矩陣:以向量為基礎(chǔ),可以用來處理更多的數(shù)據(jù),可以應(yīng)用于回歸預(yù)測,協(xié)同過等算法中。
2、Spark中的使用說明
Spark MLlib使用的數(shù)據(jù)格式類型是矩陣和向量,而兩者又可以分為本地向量,向量標簽,本地矩陣,分布式矩陣,其中,分布式矩陣又可以細分為行矩陣,帶有索引的行矩陣,坐標矩陣和分塊矩陣。
2.1 本地向量(LocalVector
本地化向量集主要由稀疏型數(shù)據(jù)集(sparse)和密集型數(shù)據(jù)集(dense),而兩者是基于數(shù)組(Array)的向量的頂級接囗是 Vector。兩者主要區(qū)別如下:
密集型數(shù)據(jù)集的數(shù)值數(shù)組中的元素類型為 double類型;
稀疏性數(shù)據(jù)集的向量格式由索引(下標)數(shù)組和數(shù)值數(shù)組組成,其中,索引的類型為整型,數(shù)組元素的類型仍舊為double雙精度類型, 密集型數(shù)據(jù)簡而言之就是每個索引位置都有數(shù)值,而稀疏型矩陣則是可以只在特定位置有數(shù)值。
創(chuàng)建密集型數(shù)據(jù)集的方式:
//創(chuàng)建一個密集型向量,官方推薦使用Vectors工廠方式創(chuàng)建Vector v = Vectors.dense(1.0,2.0,3.0);//第二種創(chuàng)建方Vector v2 = Vectors.dense(new double[] {1.0, 2.0 3.0});創(chuàng)建稀疏型索引的方式:
//創(chuàng)建一個稀疏型索引,參數(shù)一表示向量最多可以存9個數(shù)據(jù),參數(shù)二表示給定的索引,//該例中給定的索引是0和2,沒有給定1,參數(shù)三便是給定的數(shù)據(jù),這里的數(shù)據(jù)是1.0和2.0,//索引個數(shù)和元素的個數(shù)要嚴格一致,且索引要呈現(xiàn)遞增趨勢Vector v1 = Vectors.sparse(9,new int[]{0,2},new double[]{8.0,2.0});2.2 向量標簽( LabeledPoint)
向量標簽,是一種基于密集型向量和稀疏型向量而額外給定一個標簽(Label)的類型,這些統(tǒng)稱為一個標記點。這些標簽點的設(shè)置是有用戶自己給定的,標記常用double類型的數(shù)據(jù)予以給定,這些值的給定是對數(shù)據(jù)進行標記,目的是為了分類和回歸算法中的應(yīng)用。簡單理解就是一個向量組會對應(yīng)的一個特殊值,但是這些標記值是可以重復的。
創(chuàng)建密集型向量標簽的方式:
//創(chuàng)建一個帶有標記點的密集型數(shù)據(jù) LabeledPoint pos = new LabeledPoint(1.0, Vectors.dense(1.0, 2.0,3.0));創(chuàng)建稀疏型向量標簽的方式:
//創(chuàng)建一個帶有標記點的稀疏型數(shù)據(jù):LabeledPoint neg = new LabeledPoint(0.0, Vectors.sparse(3, new int[]{0,2},new double[]{1.0,2.5}));另外,Spak還提供了一種讀取特定文件格式的方式來獲取標簽向量:
//使用外來文件(格式需要符合LIBSVM)創(chuàng)建labeledPoint//使用該API需要注意下面幾點:1)、文件格式必須符合LIBSVM要求:label index1:value1 index2:value22)、其中的label可以相同,但是index必須保證唯一性,3)、index是從0開始的,且必須呈現(xiàn)出遞增的趨勢4)、若其中index2的value值為0,則可以不寫,那么index1和index2的數(shù)據(jù)就可以寫為index1:value1 index3:value3JavaRDD examples = MLUtils.loadLibSVMFile(jsc.sc(),"src/main/resources/labeled.txt").tpJavaRDD();2.3 本地矩陣(LocalMatrix)
同樣矩陣也分為集型矩陣和稀型矩陣,推薦使用工廠方法 Matrices來創(chuàng)建,需要額外注意的是矩陣是以列為優(yōu)先存儲的,簡單而言,對于一組數(shù)據(jù),會優(yōu)先墳充列值,再埴充行值。對于密集型矩陣,數(shù)據(jù)類型為數(shù)組,元素類型為 double:但與向量不同的是,矩陣需要指定行和列:對于稀疏型矩陣,數(shù)據(jù)類型為 double,采用的是CSC格式(一種存儲稀疏教據(jù)的矩陣方式)。
創(chuàng)建密集向矩陣的方式:
//創(chuàng)建一個密集型矩陣,明確指定行為3,列為2Matrix dm = Matrices dense(3, 2, new double[]{1.0, 2.0, 3.0,4.0,5.0, 6.0});//打印出的格式是://1.0 4.0//2.0 5.0//3.0 6.0//這表明使用給定的數(shù)據(jù),矩陣會優(yōu)先進行列的存儲創(chuàng)建稀疏型矩陣的方式:
//創(chuàng)建一個稀疏型矩陣,spark使用的是CSC格式的稀疏矩陣//①參是指定矩陣的行//②參是指定矩陣的列//③參,其元素的個數(shù)的矩陣的列數(shù)加1,該例矩陣的列數(shù)為2,則該參數(shù)個數(shù)有3個,//且該數(shù)組中的第一個元素一直是0,第二個元素是第一列的非零元素的數(shù)量,//后續(xù)的值為前一個元素的值加上下一列非零元素的數(shù)量Matrix sm= Matrices. sparse(3, 2, new int[] {0, 1, 3}, new int[] {0, 2, 3}, new double[] {9, 6, 8});2.4 分布式矩陣(DistributedMatrix)
分布式矩陣,見名知意,采用的是分布式架構(gòu)處理教據(jù),因此分布式矩陣存儲的數(shù)據(jù)量是非常大的。其處理速度和選用的存儲格式有關(guān),mblib提供了4中分布式矩陣存儲格式,行和列均是Long類型,而存儲的數(shù)據(jù)內(nèi)容是 double類型。這4種矩陣分別是行矩陣,帶有行索引的行矩陣,坐標矩陣和分塊矩陣。應(yīng)用比較廣泛的是帶有行索引的行矩陣和坐標矩陣。
2.4.1 行矩陣(RowMatrix)
行矩陣是分布式矩陣下的最基本的矩陣類型,行矩陣是以行作為基本方向的矩陣存儲格式,列的作用相對較小,可以將其理解為行矩陣是一個巨大的特征向量的集合,每行就是具有相同格式的向量數(shù)據(jù),且每一行的向量內(nèi)容是可以單獨取出來進行操作的。但是不能按照行號訪問。
創(chuàng)建行矩陣的格式如下:
SparkConf conf = new SparkConf().setMaster(“l(fā)ocal”).setAppName(“DistributedMatrixRowMatrix”);JavaSparkContext jsc = new JavaSparkContext(conf);JavaRDD rows = jsc.parallelize(Arrays.asList(Vectors.dense(4.0,5.0,6.0),Vectors.dense(2.0,12.0,6.0)));RowMatrix matrix = new RowMatrix(rows.rdd());2.4.2帶有索引的行矩陣( IndexedRowMatrix)
為了后續(xù)回歸,分類等算法應(yīng)用不同的特征值,需要對不同的行向量打不同的標記點,因此可以為每一行向量打上能夠代表該行的索引,素引是可以重復的,但類型為Long。
創(chuàng)建帶有索引行的行矩陣的方式:
SparkConf conf = new SparkConf(). setMaster ("local").setAppName("DistributedMatrixIndexedRowMatrix");JavaSparkContext jsc = new JavaSparkContext(conf);JavaRDD rows = jsc.parallelize(Arrays.asList(new IndexedRow(1, Vectors. dense(1. 0, 2.3, 2.6)), new Indexed Row (2, Vectors.dense(1.0,2.3,50.6));IndexedRowMatrix mat = new IndexedRowMatrix(rows. Rdd());2.4.3 坐標矩陣(Coordinatematrix)
顧名思義,坐標矩陣就是給每個數(shù)據(jù)都用一組坐標進行標識,其類型格式為( x Long y Long, value: Double),這種矩陣的應(yīng)用場一般是數(shù)據(jù)比較多且數(shù)據(jù)較為分散的情形下或者是矩陣維度比較大,即矩陣中含0或某個具體值較多的情況下。
創(chuàng)建坐標矩陣的格式如下:
SparkConf conf new SparkConfo. setMaster("local" ).setAppName("spark-standalone");JavaSparkContext jsc = new JavaSparkContext(conf);//創(chuàng)建一個坐標矩陣,如果兩個value的坐標點相同,后者的數(shù)據(jù)會覆蓋前者數(shù)據(jù)JavaRDD rows = jsc.parallelize(Arrays.asList(new MatrixEntry(0,0,1.0), new MatrixEntry (1,0,2.0)));CoordinatMatrix mat = new CoordinateMatrix(rows.rdd());2.4.4 分塊矩陣( BlockMatrix)
分塊矩陣是基于矩陣塊構(gòu)成的RDD的分布式矩陣,其中每個矩陣塊部是一個元組((Int,Int) Matrix)其中( Int,Int)是塊的索引,而Matrix是對應(yīng)位置的子矩陣,其尺寸由 rowsPerBlock和 colPerBlock決央定,默認1024*1024,分塊矩陣支持和另一個分塊矩陣的加法和乘法,并提供了 validate()來判斷分塊矩陣是否創(chuàng)建成功,分塊矩陣可以由索引行短陣和坐標矩陣調(diào)用 toBlockMatrix0方法獲得,默認塊的大小是1024*1024,也可使用 toBlockMatrix( rowsPerBlock, colPerBlock來調(diào)整分塊的尺寸。
創(chuàng)建分塊矩陣:
SparkConf conf new SparkConfo. setMaster("local" ).setAppName("spark-standalone");JavaSparkContext jsc = new JavaSparkContext(conf);//創(chuàng)建一個坐標矩陣,如果兩個value的坐標點相同,后者的數(shù)據(jù)會覆蓋前者數(shù)據(jù)JavaRDD rows = jsc.parallelize(Arrays.asList(new MatrixEntry(0,0,1.0), new MatrixEntry (1,0,2.0)));CoordinatMatrix mat = new CoordinateMatrix(rows.rdd());BlockMatrix matA = mat.toBlockMatrix().cache();3、Spark中的實踐
3.1 本地向量( Localvector)
//創(chuàng)建一個密集型向量,官方推薦用Vectors工廠模式創(chuàng)建Vector v = Vectors. dense(5.0, 2.0,3.0);//第二種創(chuàng)建方式Vector v2= Vectors. dense(new double[] {1.0, 2.0, 3.0});//獲取指定下標元素的值v.apply(0);//獲取最大的元素數(shù)值所在的索引v.argmax();//獲取向量中元素的個數(shù)v.size();//轉(zhuǎn)化為double[]v.toArray();//轉(zhuǎn)化為一個稀疏型向量v.toSparse();//與另一個向量做比較,判斷是否完全一致v.equals(v2);//轉(zhuǎn)化為一個JSON格式的字符串v.toString(); //創(chuàng)建一個密集型索引,表明給向量最多可以存9個數(shù)據(jù),該例中給定的下標是0和2,沒//有給定1,給定的數(shù)據(jù)是1.0和2.0,這里的索引個數(shù)要和元素的個數(shù)嚴格一致,且索引要//呈現(xiàn)出遞增趨勢Vector v1 = Vectors.sparse(9,new int[]{0,2},new double[]{8.0,2.0});//在稀疏型矩陣中,獲取的下標如果沒有給定值,那么為0v1.apply(0);//獲取向量中最大的值v.agrmax();//轉(zhuǎn)為密集型向量//結(jié)果為:[8.0,0.0,2.0,0.0,0.0,0.0,0.0,0.0,0.0]v1.toDense();3.2 向量標簽( LabeledPoint)
SparkConf conf = new SparkConf().setMaster ("local").setAppName("LabeledpointDemo"); JavasparkContext jsc = new JavasparkContext(conf);LabeledPoint pos= new LabeledPoint(1.0, Vectors. dense(1.0,2.0,3.0,5.9));//獲取向量數(shù)據(jù)-成為特征值pos.features();//獲取標記pos.label();//將向量標簽轉(zhuǎn)化為String類型的數(shù)據(jù)pos.toString();//獲取該向量標簽中的元素pos.productElement(0);//獲取該向量標簽中的迭代集pos.productIterator();//創(chuàng)建一個帶有標記點的稀疏型數(shù)據(jù)LabeledPoint neg = new LabeledPoint(0. 0, Vectors. sparse(3, new int[](0, 2), new double[]{1.0, 2.5}));//獲取向量數(shù)據(jù)成為特征值neg.features();//獲取標記值neg.label();//比較兩個向量標簽是否完全一致,要求標記點一致,對應(yīng)的數(shù)據(jù)一致才判定為truepos.equals(neg);3.3 本地矩陣( LocalMatrix)
//創(chuàng)建一個密集型矩陣,明確指定行為3,列為2Matrix dm = Matrices. dense(3,2, new double[]{1.0,2.0,3.0,4.0,5.0,6.0});//打印出的數(shù)據(jù)格式為//1.0 4.0//2.0 5.0//3.0 6.0//這表明使用給定的數(shù)據(jù),矩陣會優(yōu)先進行列的存儲 System. out.println(dm);//依據(jù)(i,j)來獲取數(shù)值,需要注意的是,在sparkMatrix中,起始下標為0,因此(2,1)拿到的是6.0dm.apply(2,1);//獲取列式的一個向量迭代器,因為spark中的矩陣是以列進行優(yōu)先存儲的Iterator it =dm. colIter();while(it.haxNext()){System. out. println(it next();}//獲取行式的一個向量迭代器dm.rowIter()//獲取該坐標對應(yīng)數(shù)組中的索引位置dm.index(2,1)獲取行數(shù),列數(shù)等基本信息dm.numRows();dm.numCols();//依據(jù)列來獲得一個double[]數(shù)組dm.toArray();//更新一個位置的元素dm, update(0,1,5.6);3.4 分布式矩陣( DistributedMatrix)
3.4.1 行矩陣( RowMatrix)
SparkConf conf = new SparkConf().setMaster(“l(fā)ocal”).setAppName(“DistributedMatrixRowMatrix”);JavaSparkContext jsc = new JavaSparkContext(conf);//建立行矩陣的前期是創(chuàng)建JavaRDD,這里要用到的是MLlib包下的類JavaRDD rowd = jsc.parallize(Arrays.asList(Vectors.dense(4.0,8.0,6.0),Vectors.dense(12.0,2.0,3.0)));//從JavaRDD中可以單獨提取出每一行向量List s = rows.take(1);//使用RowMatrix創(chuàng)建行矩陣RowMatrix matrix = new RowMatrix(rows.rdd());//獲取行矩陣的行數(shù)matrix.numRows();//獲取行矩陣的列數(shù)matrix.numCols();//計算各列的余弦相似性matrix.columSimilarities();//計算每列的統(tǒng)計信息,然后通過調(diào)用min,max,mean,count,normaL1,variance分別計算最大值,最小值,行數(shù),L1范數(shù)(曼哈頓距離)MultivariateStatisticalSummary si = matrix.computeColumnSummaryStatistics();si.min();si.max();si.mean();si.count();si.normaL1();si.variance();//計算每列之間的協(xié)方差,生成協(xié)方差矩陣matrix.computeCovariance();//計算QR分解QRDecomposition result = matrix.tallSkinnyQR(false);result.Q();result.R();//與另一個矩陣相乘matrix.multiply(m2);3.4.2 帶有索引行的行矩陣(IndexedRowMatrix)
SparkConf conf = new SparkConf().setMaster(“l(fā)ocal”).setAppName(“DistributedMatrixIndexedRowMatrix”);JavaSparkContext jsc = new JavaSparkContext(conf);//創(chuàng)建一個帶有行索引的行矩陣//在行矩陣的基礎(chǔ)上,對每一行向量新增了一個Long類型的索引JavaRDD rows = jsc.parallelize(Arrays.asList(new IndexedRow(1,Vectors.dense(1.0,2.3,2.6))));IndexedRowMatrix mat = new IndexedRowMatrix(rows.rdd());//獲取矩陣的行數(shù)和列數(shù)mat.numRows();mat.numCols();//計算每行之間的余弦相似度mat.columSimilarities();//轉(zhuǎn)化為普通的行矩陣mat.toRowMatrix();//轉(zhuǎn)化為塊矩陣mat.toBlockMatrix();//轉(zhuǎn)化為坐標矩陣mat.toCoordinateMatrix();3.4.3 坐標矩陣(CoordinateMatrix)
SparkConf conf = new SparkConf().setMaster(“l(fā)ocal”).setAppName("DistributedCoordinateMatrix");JavaSparkContext jsc = new JavaSparkContext(conf);//創(chuàng)建一個坐標矩陣,如果兩個value的坐標點相同,則后者的數(shù)據(jù)會覆蓋前者數(shù)據(jù)JavaRDD entries = jsc.parallelize(Arrays.asList(new MatrixEntry(0,0,1.0),new MatrixEntry(1,0,2.0)));CoordinateMatrix mat = new CoordinatMatrix(entries.rdd());//獲取矩陣的行數(shù)和列數(shù)mat.numRows();mat.numCols();//轉(zhuǎn)化為帶有行索引的行矩陣,會將坐標矩陣中的列值作為索引//但是要保證列值的大小要小于Integer.MAX_VALUEmat.toIndexedRowMatrix();//轉(zhuǎn)化為行矩陣,是先將其轉(zhuǎn)化為帶有行索引的行矩陣再將其轉(zhuǎn)化為行矩陣mat.toRowMatrix();//將矩陣轉(zhuǎn)置mat.transpose();3.4.4 分塊矩陣(BlockMatrix)SparkConf conf = new SparkConf().setMaster(“l(fā)ocal”).setAppName("DistributedBlockMatrix");JavaSparkContext jsc = new JavaSparkContext(conf);//創(chuàng)建塊矩陣一般是通過坐標矩陣來創(chuàng)建的JavaRDD entries = jsc.parallelize(Arrays.asList(new MatrixEntry(0,0,1.0),new MatrixEntry(1,0,2.0)));CoordinateMatrix coormat = new CoordinatMatrix(entries.rdd());//通過坐標矩陣來轉(zhuǎn)化為塊矩陣BlockMatrix mat = coormat.toBlockMatrix().cache();//檢查創(chuàng)建塊矩陣是否成功,成功則無反應(yīng),失敗則拋出異常mat.validate();//在原有矩陣的基礎(chǔ)上,拼接一個新的塊矩陣mat.add(matA);//獲取塊矩陣的行數(shù)和列數(shù)mat.numRows();mat.numCols();//獲取塊矩陣的塊的列數(shù)(將一個分塊視為一個單位列) mat.numColBlocks(); //獲取分塊矩陣的塊的行數(shù) mat.numRowBlocks();3.4.4 分塊矩陣(BlockMatrix)
SparkConf conf = new SparkConf().setMaster(“l(fā)ocal”).setAppName("DistributedBlockMatrix");JavaSparkContext jsc = new JavaSparkContext(conf);//創(chuàng)建塊矩陣一般是通過坐標矩陣來創(chuàng)建的JavaRDD entries = jsc.parallelize(Arrays.asList(new MatrixEntry(0,0,1.0),new MatrixEntry(1,0,2.0)));CoordinateMatrix coormat = new CoordinatMatrix(entries.rdd());//通過坐標矩陣來轉(zhuǎn)化為塊矩陣BlockMatrix mat = coormat.toBlockMatrix().cache();//檢查創(chuàng)建塊矩陣是否成功,成功則無反應(yīng),失敗則拋出異常mat.validate();//在原有矩陣的基礎(chǔ)上,拼接一個新的塊矩陣mat.add(matA);//獲取塊矩陣的行數(shù)和列數(shù)mat.numRows();mat.numCols();//獲取塊矩陣的塊的列數(shù)(將一個分塊視為一個單位列) mat.numColBlocks(); //獲取分塊矩陣的塊的行數(shù) mat.numRowBlocks();總結(jié)
以上是生活随笔為你收集整理的c++向量和数组的区别_Spark机器学习-Java版(一)-向量和矩阵的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: grafana mysql插件_graf
- 下一篇: c mysql 双主复制_mysql双