【问题标题】:Problem with missing values in cluster id column集群 id 列中缺少值的问题
【发布时间】:2021-04-05 14:23:09
【问题描述】:

我正在寻求有关如何在我的 df 中添加包含集群 ID 的列的帮助(用于集群数据集的算法是 DBSCAN,我尝试了以下方法

# Compute DBSCAN

db = DBSCAN(eps=1, min_samples=30, algorithm='kd_tree', n_jobs=-1).fit(X)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_
np.sum(labels)
# Number of clusters in labels, ignoring noise if present.
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
n_clusters_
n_noise_ = list(labels).count(-1)

print('Estimated number of clusters: %d' % n_clusters_)
print('Estimated number of noise points: %d' % n_noise_)
print("Silhouette Coefficient: %0.3f"
      % metrics.silhouette_score(X, labels))
    df = df.join(pd.DataFrame(labels))
    df = df.rename(columns={0:'Cluster'})
    df.head

但我有一个看起来不合逻辑的问题。在聚类之前,我的数据集没有缺失值,而当我添加列(集群)时,clsuter=-1 用于噪声等,我也得到了缺失值( !),所以当我尝试清理我的数据集时,我没有任何选择,而不是排除 cluster=-1 和缺失值,这是我不想要的。你能帮我解决我的问题吗?

您可以找到包含问题的附加输出。 聚类列中有大约 3000 个缺失值,我不明白这是怎么发生的。

输入额外列之前的数据集列有 38037 行。

任何评论都会有所帮助。

谢谢

Problem with missing values

【问题讨论】:

    标签: python cluster-analysis outliers dbscan


    【解决方案1】:

    代码中的这一行导致缺失值:

    df = df.join(pd.DataFrame(labels))

    说明:

    pandas.DataFrame.join() 按索引连接 DataFrame 对象。 “df”DataFrame 有一个 Int64Index,其值范围从 0 到 41187,但只有 38037 个条目 - 这意味着索引值不是连续的但包含间隙,可能是在创建数据帧之后和代码之前删除/过滤行 - p 被处决了。

    包含您使用pd.DataFrame(labels) 创建的标签的 DataFrame 将有自己的索引,其值范围为 0 到 38037。如果此 DataFrame 与原始 DataFrame 连接,则生成的 DataFrame 将仅包含索引值为您的原始 DataFrame 和标签 DataFrame 匹配,并且由于原始 DataFrame 索引中的差距,这仅适用于 35246 行。

    最简单的解决方案是重新索引原始 DataFrame,使其再次包含连续的索引值:

    df = df.reset_index(drop=True).join(pd.DataFrame(labels))

    【讨论】:

    • 感谢您的及时回答。它似乎有效!只是为了更好地理解,因为我在 Pyhton 和一般数据科学中迈出了第一步,在这种特殊情况下,ia 被要求集群数据,然后去除出现的异常值。然后,我必须比较算法效率的准确性,f-score等。这里的重点是评估异常值对算法效率的影响。
    • 据我所知,由于预处理,我确实从我的 df 中排除了一些行,但我没有删除它们。这会影响我第一次运行 DBSCAN 的效率吗(在异常值检测)还是在我尝试在原始 df 中添加具有集群 ID 的列时发生这种情况?
    【解决方案2】:

    您的df 中的索引发生了一些问题。正如你在 Pandas 中看到的那样joindocs,如果参数on 没有被指定:

    调用者中的列或索引级别名称加入其他中的索引,否则加入 index-on-index。

    所以,这样的事情正在发生:

    labels
    Out[66]: array([ 0,  0,  0,  1,  1, -1], dtype=int64)
    
    # make dataframe that exactly matches labels
    df = pd.DataFrame(labels, columns=['a'])
    
    df
    Out[68]: 
       a
    0  0
    1  0
    2  0
    3  1
    4  1
    5 -1
    
    # change indices
    df = df.set_index([pd.Index([0, 1, 3, 5, 7, 8])])
    
    df
    Out[70]: 
       a
    0  0
    1  0
    3  0
    5  1
    7  1
    8 -1
    
    df.join(pd.DataFrame(labels))
    Out[71]: 
       a    0
    0  0  0.0
    1  0  0.0
    3  0  1.0
    5  1 -1.0
    7  1  NaN
    8 -1  NaN
    

    如果您不需要当前索引,我建议在 DBSCAN 之前重置索引:df.reset_index(drop=True, inplace=True)

    【讨论】:

      猜你喜欢
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多