我正在尝试在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)
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)广播是否可以解决此类问题?
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)]