PySpark嵌套的RDD操作

时间:2018-10-31 19:11:13

标签: python machine-learning knn

我正在尝试在PySpark中实现K最近邻居。 我在遍历整个测试数据集的过程中遇到了“ for循环”的速度问题,因此我尝试使用 Test数据集上的“ map”函数给出了SPARK-5063的错误,这意味着Spark不支持嵌套的RDD。

下面是代码

import findspark
findspark.init()
import pyspark
import pyarrow.parquet as pq
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
sc = spark.sparkContext
import pandas as pd

距离功能

def distanceBetweenTuples(data1 , data2) :
 squaredSum = 0.0
 for i in range(len(data1)):
     squaredSum = squaredSum + (data1[i] - data2[i])**2
 return(squaredSum**0.5)

KNN函数

def KNN_Classify(Train,Test,K,Test_class):
    for j in range(len(Test)):    
    KNN_Data=[data[0] for data
    in((Train.cartesian(sc.parallelize([Test[j]],1)))\
                .map(lambda data : (data[0][1] 
    ,distanceBetweenTuples(data[0][0], data[1]))))\
                .takeOrdered(K, key = lambda data : data[1])] 
    Test_class.append(max(KNN_Data,key=KNN_Data.count))

读取数据功能

def read_file(path,parts=None,target_var=None):
    col_names=[]
    Data= pd.DataFrame()
    if target_var is not None:
       Data=pd.read_csv(path)
       col_names = list(Data.drop([target_var,],axis=1))
       return sc.parallelize(list(zip([tuple(x) for x in 
       Data[col_names].values], tuple(Data[target_var]))),parts)
    else:
       Data=pd.read_csv(path)
       return [tuple(x) for x in Data.values]

读取火车和测试数据

Train_RDD=read_file(path="Train.csv",target_var='Target',parts=1)
Test_RDD= read_file(path="Test.csv")

火车的第一行

Train_RDD.first()

(((2.027175118,5.6410692529999995,10.98619243,1.1699097090000001,1.406686778),     'class1')

测试的类型和第一行

 print("The type of Test_RDD is",type(Test_RDD))
 Test_RDD[0]

Test_RDD的类型为“列表”

array([1.7156137,4.39461976,5.66608099,1.7953647,-1.54322475])

将该功能应用于整个数据集

T1=[]
KNN_Classify(Train=Train_RDD,Test=Test_RDD,K=3,Test_class=T1)    
print(T1)

['class1','class1','class1','class1','class1','class1','class1','class1']

现在,以上代码可以正常工作。我主要关心的是“ for循环”,它用于遍历Test_RDD数据集的所有行。当我有大量数据集(例如100K火车行V / S 100K测试行)时,“ for循环”会花费很多时间。我什至尝试了“地图”功能,但会引发错误:SPARK-5063。

现在,基于此,我也正在探索Train数据上的“广播”属性,但是它没有笛卡尔属性,并且如果数据很大,从我的研究中通常不建议这样做(此处有建议可访问)。

我的问题

1)在我当前的代码中,我可以使用“ for循环”之外的其他方式来加快过程吗?像“地图”,而不会引起SPARK-5063错误。

2)广播是否可以解决此类问题?

PS:用于复制数据集的代码

Train_List = [((3.09,1.97,3.73),'group1'),
                          ((2.96,2.15,4.16),'group1'),
                          ((2.87,1.93,4.39),'group1'),
                          ((3.02,1.55,4.43),'group1'),
                          ((1.80,3.65,2.08),'group2'),
                          ((1.36,9.43,1.95),'group2'),
                          ((1.71,7.35,1.94),'group2'),
                          ((1.03,9.75,2.12),'group2'),
                          ((2.30,7.59,1.99),'group2')]

Train_Data_RDD = sc.parallelize(Train_List,1)

Test_data = [(2.5, 1.7, 4.2),(8.5, 7.7, 2.1),(2.5, 1.7, 2.2)]

0 个答案:

没有答案