def calculate_metric_value(knn_model, knn_df): result = knn_model.transform(knn_df) # map predicted result string types to numeric type indexer = StringIndexer() indexer.setInputCol('predict') indexer.setOutputCol('predictIndexer') index_model = indexer.fit(result) index_result = index_model.transform(result) # generate label column dataset = index_result.withColumn('label', expr("predictIndexer")) evaluator = MulticlassClassificationEvaluator( predictionCol="predictIndexer") # calculate metric metric_dict["f1"] = (evaluator.evaluate(dataset, {evaluator.metricName: "f1"})) metric_dict["accuracy"] = (evaluator.evaluate( dataset, {evaluator.metricName: "accuracy"})) metric_dict["precision"] = (evaluator.evaluate( dataset, {evaluator.metricName: "weightedPrecision"})) metric_dict["recall"] = (evaluator.evaluate( dataset, {evaluator.metricName: "weightedRecall"}))
data = spark.sparkContext.textFile("file:///home/tianlei/iris.txt").map( lambda line: line.split(',')).map(lambda p: Row(**f(p))).toDF() data.show() # 因为我们现在处理的是2分类问题,所以我们不需要全部的3类数据,我们要从中选出两类的数据。这里首先把刚刚得到的数据注册成一个表iris, # 注册成这个表之后,我们就可以通过sql语句进行数据查询,比如我们这里选出了所有不属于“Iris-setosa”类别的数据; # 选出我们需要的数据后,我们可以把结果打印出来看一下,这时就已经没有“Iris-setosa”类别的数据。 data.createOrReplaceTempView("iris") df = spark.sql("select * from iris where label != 'Iris-setosa'") rel = df.map(lambda t: str(t[1]) + ":" + str(t[0])).collect() for item in rel: print(item) # 构建ML的pipeline # 分别获取标签列和特征列,进行索引,并进行了重命名。 lalelIndexer = StringIndexer.setInputCol("label").setOutputCol( "indexeLabel").fit(df) featureIndexer = VectorIndexer.setInputCol("features").setOutputCol( "indexeFeatures").fit(df) # 数据集随机分成训练集和测试集,其中训练集占70%。 trainingData, testData = df.randomSplit([0.7, 0.3]) # 设置logistic的参数,这里我们统一用setter的方法来设置,也可以用ParamMap来设置(具体的可以查看spark mllib的官网)。 # 这里我们设置了循环次数为10次,正则化项为0.3等,具体的可以设置的参数可以通过explainParams()来获取, # 还能看到我们已经设置的参数的结果。 lr = LogisticRegression.setLabelCol("lalelIndexer").setFeaturesCol( "featureIndexer").setMaxIter(10).setRegParam(0.3).setElasticNetParam( 0.8) print("LogisticRegression parameters:\n" + lr.explainParams()) # 设置一个labelConverter,目的是把预测的类别重新转化成字符型的。 labelConverter = IndexToString().setInputCol("prediction").setOutputCol( "predictedLabel").setLabels(lalelIndexer.labels)