为什么DBSCAN群集会在Movie镜头数据集上返回单个群集?

时间:2018-01-01 17:35:02

标签: python pandas cluster-analysis dbscan

场景:

我正在通过电影镜头数据集执行群集,我有两种格式的数据集:

旧格式:

uid iid rat
941 1   5
941 7   4
941 15  4
941 117 5
941 124 5
941 147 4
941 181 5
941 222 2
941 257 4
941 258 4
941 273 3
941 294 4

新格式:

uid 1               2               3               4
1   5               3               4               3
2   4               3.6185548023    3.646073985     3.9238342172
3   2.8978348799    2.6692556753    2.7693015618    2.8973463681
4   4.3320762062    4.3407749532    4.3111995162    4.3411425423
940 3.7996234581    3.4979386925    3.5707888503    2
941 5               NaN             NaN             NaN
942 4.5762594612    4.2752554573    4.2522440019    4.3761477591
943 3.8252406362    5               3.3748860659    3.8487417604

我需要使用KMeans,DBSCAN和HDBSCAN执行群集。 使用KMeans,我可以设置和获取集群。

问题

问题仅存在于DBSCAN& HDBSCAN,我无法获得足够数量的集群(我知道我们无法手动设置集群)

尝试的技术:

  • 使用 IRIS data-set尝试此操作,我发现 Species 未包含在内。显然,这是在字符串中,除了是预测,并且只有works fine与数据集(片段1)
  • 尝试使用OLD FORMAT中的电影镜头100K dataset(有和没有UID),因为我尝试了一个类比,UID == SPECIES,因此在没有它的情况下尝试过。 (摘录2)
  • 尝试使用NEW FORMAT(有和没有UID)但结果却以相同的风格结束。

代码段1:

print "\n\n FOR IRIS DATA-SET:"
from sklearn.datasets import load_iris

iris = load_iris()
dbscan = DBSCAN()

d = pd.DataFrame(iris.data)
dbscan.fit(d)
print "Clusters", set(dbscan.labels_)

代码段1(输出):

FOR IRIS DATA-SET:
Clusters set([0, 1, -1])
Out[30]: 
array([ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0,  0,  1,
        1,  1,  1,  1,  1,  1, -1,  1,  1, -1,  1,  1,  1,  1,  1,  1,  1,
       -1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
        1,  1, -1,  1,  1,  1,  1,  1, -1,  1,  1,  1,  1, -1,  1,  1,  1,
        1,  1,  1, -1, -1,  1, -1, -1,  1,  1,  1,  1,  1,  1,  1, -1, -1,
        1,  1,  1, -1,  1,  1,  1,  1,  1,  1,  1,  1, -1,  1,  1, -1, -1,
        1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1])

代码段2:

import pandas as pd
from sklearn.cluster import DBSCAN

data_set = pd.DataFrame

ch = int(input("Extended Cluster Methods for:\n1. Main Matrix IBCF \n2. Main Matrix UBCF\nCh:"))
if ch is 1:
    data_set = pd.read_csv("MainMatrix_IBCF.csv")
    data_set = data_set.iloc[:, 1:]
    data_set = data_set.dropna()
elif ch is 2:
    data_set = pd.read_csv("MainMatrix_UBCF.csv")
    data_set = data_set.iloc[:, 1:]
    data_set = data_set.dropna()
else:
    print "Enter Proper choice!"

print "Starting with DBSCAN for Clustering on\n", data_set.info()

db_cluster = DBSCAN()
db_cluster.fit(data_set)
print "Clusters assigned are:", set(db_cluster.labels_)

代码段2(输出):

Extended Cluster Methods for:
1. Main Matrix IBCF 
2. Main Matrix UBCF
Ch:>? 1
Starting with DBSCAN for Clustering on
<class 'pandas.core.frame.DataFrame'>
Int64Index: 942 entries, 0 to 942
Columns: 1682 entries, 1 to 1682
dtypes: float64(1682)
memory usage: 12.1 MB
None
Clusters assigned are: set([-1])

如图所示,它仅返回1个群集。我想听听我做错了什么。

4 个答案:

答案 0 :(得分:2)

需要选择适当的参数。由于epsilon太小,一切都变成了噪音。 sklearn 不应该具有此参数的默认值,需要为每个数据集选择不同的值。

您还需要预处理数据。

使用毫无意义的kmeans获得“集群”是微不足道的......

不要只是调用随机函数。你需要了解你在做什么,或者你只是在浪费时间。

答案 1 :(得分:1)

首先,您需要预处理数据,删除任何无用的属性,例如ids和不完整的实例(如果您选择的距离度量无法处理它)。

很高兴理解这些算法来自两种不同的范例,基于质心(KMeans)和基于密度(DBSCAN&amp; HDBSCAN *)。虽然基于质心的算法通常将簇的数量作为输入参数,但基于密度的算法需要邻居的数量(minPts)和邻域的半径(eps)。

通常在文献中,邻居的数量(minPts)设置为4,并且通过分析不同的值来找到半径(eps)。你可能会发现HDBSCAN *更容易使用,因为你只需要通知邻居的数量(minPts)。

如果在尝试不同的配置后,您仍然会得到无用的群集,可能您的数据根本没有群集,而KMeans输出则毫无意义。

答案 2 :(得分:1)

正如@faraway和@ Anony-Mousse指出的那样,解决方案更多的是关于数据集的数学而不是编程。

最终可以找出群集。以下是:

db_cluster = DBSCAN(eps=9.7, min_samples=2, algorithm='ball_tree', metric='minkowski', leaf_size=90, p=2)
arr = db_cluster.fit_predict(data_set)
print "Clusters assigned are:", set(db_cluster.labels_)

uni, counts = np.unique(arr, return_counts=True)
d = dict(zip(uni, counts))
print d

Epsilon和Out-lier概念从here变得更加明亮。

答案 3 :(得分:0)

您是否尝试过使用PCA(例如)查看集群在2D空间中的外观。如果整个数据密集并且实际上形成单个组,那么您可能会得到单个群集。

更改其他参数,例如min_samples = 5,算法,指标。您可以从sklearn.neighbors.VALID_METRICS中检查算法和指标的可能值。