Я выполняю кластеризацию на наборе данных, используя PySpark.Чтобы найти число кластеров, я выполнил кластеризацию по диапазону значений (2,20) и нашел значения wsse
(сумма квадратов внутри кластера) для каждого значения k
.Это где я нашел что-то необычное.Насколько я понимаю, при увеличении количества кластеров wsse
монотонно уменьшается.Но результаты, которые я получил, говорят иначе.Я отображаю wsse
только для первых нескольких кластеров
Results from spark
For k = 002 WSSE is 255318.793358
For k = 003 WSSE is 209788.479560
For k = 004 WSSE is 208498.351074
For k = 005 WSSE is 142573.272672
For k = 006 WSSE is 154419.027612
For k = 007 WSSE is 115092.404604
For k = 008 WSSE is 104753.205635
For k = 009 WSSE is 98000.985547
For k = 010 WSSE is 95134.137071
Если вы посмотрите на значение wsse
для k=5
и k=6
, вы увидите, что wsse
увеличилось,Я повернулся к sklearn, чтобы увидеть, получаю ли я похожие результаты.Коды, которые я использовал для spark и sklearn, находятся в приложении к концу поста.Я попытался использовать те же значения для параметров в модели KMeans для spark и sklearn.Ниже приведены результаты от sklearn, и они, как я и ожидал, будут монотонно убывающими.
Results from sklearn
For k = 002 WSSE is 245090.224247
For k = 003 WSSE is 201329.888159
For k = 004 WSSE is 166889.044195
For k = 005 WSSE is 142576.895154
For k = 006 WSSE is 123882.070776
For k = 007 WSSE is 112496.692455
For k = 008 WSSE is 102806.001664
For k = 009 WSSE is 95279.837212
For k = 010 WSSE is 89303.574467
Я не уверен, почему я увеличиваю значения wsse
в Spark.Я пытался использовать разные наборы данных и обнаружил там похожее поведение.Есть ли место, где я иду не так?Любые подсказки были бы отличными.
ПРИЛОЖЕНИЕ Набор данных находится здесь .
Считать данные и установить переменные объявления
# get data
import pandas as pd
url = "https://raw.githubusercontent.com/vectosaurus/bb_lite/master/3.0%20data/adult_comp_cont.csv"
df_pandas = pd.read_csv(url)
df_spark = sqlContext(df_pandas)
target_col = 'high_income'
numeric_cols = [i for i in df_pandas.columns if i !=target_col]
k_min = 2 # 2 in inclusive
k_max = 21 # 2i is exlusive. will fit till 20
max_iter = 1000
seed = 42
Этот код я использую для получения результатов sklearn :
from sklearn.cluster import KMeans as KMeans_SKL
from sklearn.preprocessing import StandardScaler as StandardScaler_SKL
ss = StandardScaler_SKL(with_std=True, with_mean=True)
ss.fit(df_pandas.loc[:, numeric_cols])
df_pandas_scaled = pd.DataFrame(ss.transform(df_pandas.loc[:, numeric_cols]))
wsse_collect = []
for i in range(k_min, k_max):
km = KMeans_SKL(random_state=seed, max_iter=max_iter, n_clusters=i)
_ = km.fit(df_pandas_scaled)
wsse = km.inertia_
print('For k = {i:03d} WSSE is {wsse:10f}'.format(i=i, wsse=wsse))
wsse_collect.append(wsse)
Это код, который я использую для получения результатов искры
from pyspark.ml.feature import StandardScaler, VectorAssembler
from pyspark.ml.clustering import KMeans
standard_scaler_inpt_features = 'ss_features'
kmeans_input_features = 'features'
kmeans_prediction_features = 'prediction'
assembler = VectorAssembler(inputCols=numeric_cols, outputCol=standard_scaler_inpt_features)
assembled_df = assembler.transform(df_spark)
scaler = StandardScaler(inputCol=standard_scaler_inpt_features, outputCol=kmeans_input_features, withStd=True, withMean=True)
scaler_model = scaler.fit(assembled_df)
scaled_data = scaler_model.transform(assembled_df)
wsse_collect_spark = []
for i in range(k_min, k_max):
km = KMeans(featuresCol=kmeans_input_features, predictionCol=kmeans_prediction_col,
k=i, maxIter=max_iter, seed=seed)
km_fit = km.fit(scaled_data)
wsse_spark = km_fit.computeCost(scaled_data)
wsse_collect_spark .append(wsse_spark)
print('For k = {i:03d} WSSE is {wsse:10f}'.format(i=i, wsse=wsse_spark))
ОБНОВЛЕНИЕ
После @Michail N'sответ, я изменил значения tol
и maxIter
для модели Spark KMeans
.Я перезапустил код, но увидел, что повторяется то же самое поведение.Но так как Михаил упомянул
Spark, MLlib, фактически, реализует K-средства ||
, я увеличил число initSteps
в 50 раз и повторнозапустил процесс, который дал следующие результаты:
For k = 002 WSSE is 255318.718684
For k = 003 WSSE is 212364.906298
For k = 004 WSSE is 185999.709027
For k = 005 WSSE is 168616.028321
For k = 006 WSSE is 123879.449228
For k = 007 WSSE is 113646.930680
For k = 008 WSSE is 102803.889178
For k = 009 WSSE is 97819.497501
For k = 010 WSSE is 99973.198132
For k = 011 WSSE is 89103.510831
For k = 012 WSSE is 84462.110744
For k = 013 WSSE is 78803.619605
For k = 014 WSSE is 82174.640611
For k = 015 WSSE is 79157.287447
For k = 016 WSSE is 75007.269644
For k = 017 WSSE is 71610.292172
For k = 018 WSSE is 68706.739299
For k = 019 WSSE is 65440.906151
For k = 020 WSSE is 66396.106118
Увеличение wsse
с k=5
и k=6
исчезает.Хотя поведение сохраняется, если вы посмотрите на k=13
и k=14
и в других местах, но, по крайней мере, я узнал, откуда это происходит.