まず、機械学習スパークmlのパイプラインに対して
機械学習プロセスの複数含む典型的な構築物
1を、データソースETL
2、データ前処理
の選択を特徴3、
4、モデルのトレーニング及び検証
上記の4つのステップは、複数を含むように抽象化することができます私たちが必要とする最終的な出力結果に作業手順、最初からデータ収集を合理化。したがって、上記の複数のステップ、抽象モデル、簡略化パイプラインワークフロースパーク機械学習ユーザの使用の可能性があり、パイプラインの機械学習に簡単に単一の独立したモデリングのステップ、より効率的ですと。
scikit学習プログラムにインスピレーションを与え、それが医療過誤、複雑な機械学習の問題でMLlibをまとめたもの(主に仕事のために複雑なプロセスが明確ではないが)、それ以上にデータフレームのAPIライブラリに基づいて、より高いレベルをユーザーに提供するために設計さ複雑な機械学習のワークフローアプリケーションを構築するのは簡単。パイプライン構造では、1つ以上のステージを含むことになる、各ステージは、問題の異なる種類に応じて、そのようなデータ変換処理セットとして、このようなMLステージのようなモデルのトレーニング、予測パラメータの設定やデータを、タスクを完了します処理され対応する定義と実装。変圧器や見積もりのための2つの主要な舞台。変圧器は、主にデータフレームのデータフレームのデータを操作するために使用され、このようなSVMモデル、特徴抽出ツールとして更なるデータを生成する変圧器に抽象化することができます。見積もりは、主にモデルのフィットを作るために使用され、変圧器を生成するために使用されます。理解することはより困難と言うことが、ここではスパークmlのパイプラインを説明するために、完全な機械学習の場合にのは、機械学習のワークフローを構築する方法です。
第二に、スパークmlのパイプラインのワークフローを使用して学習ビルドマシン
(データは、ユーザーがクリック予測を備えて使用して設定)Kaggleデータ競争のディスプレイ広告チャレンジデータセットにより本明細書には、スパークmlのパイプラインを使用して、完全な機械学習のワークフローを構築するために開始します。
データ表示広告チャレンジ自体を導入していない、主に3つの部分、数値型の機能セット、カテゴリ型機能セット、クラスラベルを含んでいます。
まず、サンプル収集を読み、サンプルセットは、トレーニングセットとテストセットに分割されています。
// ローカルスパーク読み出しファイルできるように、ファイルパスタグ・ファイルを使用して 文字列fileReadPath = " \\ D:ファイル\\ \\ dac_sample.txt dac_sample "を; //は、テキストファイルを使用してデータを読み取る SparkContext SC = Contexts.sparkContext。 RDDの<string>ファイル= sc.textFile(fileReadPath、1 )。 JavaRDD <文字列>キック内容= file.toJavaRDD(); JavaRDD <行> sampleRow = sparkContent.map(新機能<文字列、行> (){ 公共行コール(文字列の文字列){ 文字列tempStr = 文字列 .replace(" \ tの"、" " ); 文字列[]機能 = tempStr.split(" " )。 INT intLable = Integer.parseInt(特徴[ 0 ])。 ストリングintFeature1は =機能[ 1 ]。 ストリングintFeature2は =機能[ 2 ]。
ストリングCatFeature1 =機能[ 14 ]。 ストリングCatFeature2 =機能[ 15 ]。 返すRowFactory.create(intLable、intFeature1、intFeature2、CatFeature1、CatFeature2を)。 } }); ダブル []重み= { 0.8、0.2 }。 ロングシード = 42L ; JavaRDDの<row> [] sampleRows = sampleRow.randomSplit(重量、種子)。
スパークmlのパイプラインに使用されるサンプルセット構築データフレームのデータ形式を取得した後。
一覧<StructField>フィールド= 新しいのArrayList <StructField> ();
fields.add(DataTypes.createStructField(" lable "、DataTypes.IntegerType、偽));
fields.add(DataTypes.createStructField(" intFeature1 "、DataTypes.StringType、真));
fields.add(DataTypes.createStructField(" intFeature2 "、DataTypes.StringType、真));
fields.add(DataTypes.createStructField(" CatFeature1 "、DataTypes.StringType、真));
fields.add(DataTypes.createStructField(" CatFeature2 "、DataTypes.StringType、真));
// など
StructTypeスキーマ = DataTypes.createStructType(フィールド)。
データフレームdfTrain = Contexts.hiveContext.createDataFrame(sampleRows [ 0 ]、スキーマ)。// 训练数据
dfTrain.registerTempTable(" tmpTable1 " );
データフレームdfTest = Contexts.hiveContext.createDataFrame(sampleRows [ 1 ]、スキーマ)。// 测试数据
dfTest.registerTempTable(" tmpTable2 ");
dfTrainので、dfTestすべての機能は、現在の文字列を入力して、機械学習に必要な特徴の数値タイプ、処理および変換欠損値の種類を含む変換特性を、行う必要があります。
まず、表の列文字列で指定されたタイプの二重intFeature、キャスト()メソッドへの文字列は、二重に変換され、intFeature1Tempという名前の新しい列が、
その後、元のデータ列と新しい列リネームを削除する必要がありますintFeature1は、そう、文字列型は、得られた二変換特性を備えています。
//Cast integer features from String to Double
dfTest = dfTest.withColumn("intFeature1Temp",dfTest.col("intFeature1").cast("double"));
dfTest = dfTest.drop("intFeature1").withColumnRenamed("intFeature1Temp","intFeature1");
如果intFeature特征是年龄或者特征等类型,则需要进行分箱操作,将一个特征按照指定范围进行划分:
/*特征转换,部分特征需要进行分箱,比如年龄,进行分段成成年未成年等 */
double[] splitV = {0.0,16.0,Double.MAX_VALUE};
Bucketizer bucketizer = new Bucketizer().setInputCol("").setOutputCol("").setSplits(splitV);
再次,需要将categorical 类型的特征转换为numerical类型。主要包括两个步骤,缺失值处理和编码转换。
缺失值处理方面,可以使用全局的NA来统一标记缺失值:
/*将categoricalb类型的变量的缺失值使用NA值填充*/
String[] strCols = {"CatFeature1","CatFeature2"};
dfTrain = dfTrain.na().fill("NA",strCols);
dfTest = dfTest.na().fill("NA",strCols);
缺失值处理完成之后,就可以正式的对categorical类型的特征进行numerical转换了。在spark ml中,可以借助StringIndexer和oneHotEncoder完成
这一任务:
// StringIndexer oneHotEncoder 将 categorical变量转换为 numerical 变量
// 如某列特征为星期几、天气等等特征,则转换为七个0-1特征
StringIndexer cat1Index = new StringIndexer().setInputCol("CatFeature1").setOutputCol("indexedCat1").setHandleInvalid("skip");
OneHotEncoder cat1Encoder = new OneHotEncoder().setInputCol(cat1Index.getOutputCol()).setOutputCol("CatVector1");
StringIndexer cat2Index = new StringIndexer().setInputCol("CatFeature2").setOutputCol("indexedCat2");
OneHotEncoder cat2Encoder = new OneHotEncoder().setInputCol(cat2Index.getOutputCol()).setOutputCol("CatVector2");
至此,特征预处理步骤基本完成了。由于上述特征都是处于单独的列并且列名独立,为方便后续模型进行特征输入,需要将其转换为特征向量,并统一命名,
可以使用VectorAssembler类完成这一任务:
/*转换为特征向量*/
String[] vectorAsCols = {"intFeature1","intFeature2","CatVector1","CatVector2"};
VectorAssembler vectorAssembler = new VectorAssembler().setInputCols(vectorAsCols).setOutputCol("vectorFeature");
通常,预处理之后获得的特征有成千上万维,出于去除冗余特征、消除维数灾难、提高模型质量的考虑,需要进行选择。在此,使用卡方检验方法,
利用特征与类标签之间的相关性,进行特征选取:
/*特征较多时,使用卡方检验进行特征选择,主要是考察特征与类标签的相关性*/
ChiSqSelector chiSqSelector = new ChiSqSelector().setFeaturesCol("vectorFeature").setLabelCol("label").setNumTopFeatures(10)
.setOutputCol("selectedFeature");
在特征预处理和特征选取完成之后,就可以定义模型及其参数了。简单期间,在此使用LogisticRegression模型,并设定最大迭代次数、正则化项:
/* 设置最大迭代次数和正则化参数 setElasticNetParam=0.0 为L2正则化 setElasticNetParam=1.0为L1正则化*/
/*设置特征向量的列名,标签的列名*/
LogisticRegression logModel = new LogisticRegression().setMaxIter(100).setRegParam(0.1).setElasticNetParam(0.0)
.setFeaturesCol("selectedFeature").setLabelCol("lable");
在上述准备步骤完成之后,就可以开始定义pipeline并进行模型的学习了:
/*将特征转换,特征聚合,模型等组成一个管道,并调用它的fit方法拟合出模型*/
PipelineStage[] pipelineStage = {cat1Index,cat2Index,cat1Encoder,cat2Encoder,vectorAssembler,logModel};
Pipeline pipline = new Pipeline().setStages(pipelineStage);
PipelineModel pModle = pipline.fit(dfTrain);
上面pipeline的fit方法得到的是一个Transformer,我们可以使它作用于测试集得到模型在测试集上的预测结果:
//拟合得到模型的transform方法进行预测
DataFrame output = pModle.transform(dfTest).select("selectedFeature", "label", "prediction", "rawPrediction", "probability");
DataFrame prediction = output.select("label", "prediction");
prediction.show();
分析计算,得到模型在训练集上的准确率,看看模型的效果怎么样:
/*测试集合上的准确率*/
long correct = prediction.filter(prediction.col("label").equalTo(prediction.col("'prediction"))).count();
long total = prediction.count();
double accuracy = correct / (double)total;
System.out.println(accuracy);
最后,可以将模型保存下来,下次直接使用就可以了:
String pModlePath = ""file:\\D:\\dac_sample\\";
pModle.save(pModlePath);
三,梳理和总结:
上述,借助代码实现了基于spark ml pipeline的机器学习,包括数据转换、特征生成、特征选取、模型定义及模型学习等多个stage,得到的pipeline
模型后,就可以在新的数据集上进行预测,总结为两部分并用流程图表示如下:
训练阶段:
预测阶段:
借助于Pepeline,在spark上进行机器学习的数据流向更加清晰,同时每一stage的任务也更加明了,因此,无论是在模型的预测使用上、还是
模型后续的改进优化上,都变得更加容易。