df2をkmeansにフィードしようとすると、次のエラーが発生します
clusters = KMeans.train(df2, 10, maxIterations=30,
runs=10, initializationMode="random")
私が得るエラー:
Cannot convert type <class 'pyspark.sql.types.Row'> into Vector
df2は、次のように作成されたデータフレームです。
df = sqlContext.read.json("data/ALS3.json")
df2 = df.select('latitude','longitude')
df2.show()
latitude| longitude|
60.1643075| 24.9460844|
60.4686748| 22.2774728|
この2つの列をVectorに変換して、KMeansにフィードするにはどうすればよいですか?
問題は、 ドキュメントの例 を見逃したことです。また、メソッドtrain
がDataFrame
を機能として持つVector
を必要とすることは明らかです。
現在のデータの構造を変更するには、 VectorAssembler を使用できます。あなたの場合、それは次のようなものである可能性があります。
from pyspark.sql.functions import *
vectorAssembler = VectorAssembler(inputCols=["latitude", "longitude"],
outputCol="features")
# For your special case that has string instead of doubles you should cast them first.
expr = [col(c).cast("Double").alias(c)
for c in vectorAssembler.getInputCols()]
df2 = df2.select(*expr)
df = vectorAssembler.transform(df2)
さらに、より良い結果を得るには、クラス MinMaxScaler を使用してfeatures
を正規化する必要もあります。
MLLib
を使用してこれを実現するには、最初にマップ関数を使用して、すべてのstring
値をDouble
に変換し、それらを DenseVector 。
rdd = df2.map(lambda data: Vectors.dense([float(c) for c in data]))
この時点以降、rdd
変数を使用して MLlibのKMeansモデル をトレーニングできます。
次のように、PySpark 2.3.1で DataFrame に対して KMeans を実行しました。
feat_cols = ['latitude','longitude']`
expr = [col(c).cast("Double").alias(c) for c in feat_cols]
df2 = df2.select(*expr)
mllib.linalg.Vectors
を使用してfeaturesベクトルを作成します。from pyspark.ml.feature import VectorAssembler
assembler = VectorAssembler(inputCols=feat_cols, outputCol="features")
df3 = assembler.transform(df2).select('features')
from pyspark.ml.feature import StandardScaler
scaler = StandardScaler(
inputCol="features",
outputCol="scaledFeatures",
withStd=True,
withMean=False)
scalerModel = scaler.fit(df3)
df4 = scalerModel.transform(df3).drop('features')\
.withColumnRenamed('scaledFeatures', 'features')
df4
を密なベクトルに変換します [〜#〜] rdd [〜#〜] :from pyspark.mllib.linalg import Vectors
data5 = df4.rdd.map(lambda row: Vectors.dense([x for x in row['features']]))
from pyspark.mllib.clustering import KMeans
model = KMeans.train(data5, k=3, maxIterations=10)
prediction = model.predict(p)