Sklearn的DBSCAN的sample_weight的一点小探究(一)

我的朋友最近在搞大数据研究,但是他本人又懒得写代码,于是找人帮他用DBSCAN聚类一些数据,但是啊。这些聚类效果,不是很满意。或者说,它希望能对DBSCAN进行一些改进,于是就找到了我。可我毕竟不是个大佬,只能瞎改。

1.对dbscan_.py的研究

虽然自己没学过python,可是毕竟要恰饭的。只能硬着头皮去研究。于是我打开DBSCAN的源码,因为你要对一个东西进行改进,必须先理解它。
Sklearn的DBSCAN的sample_weight的一点小探究(一)_第1张图片

2.dbscan函数的研究

def dbscan(X, eps=0.5, min_samples=5, metric='minkowski', metric_params=None,
           algorithm='auto', leaf_size=30, p=2, sample_weight=None,
           n_jobs=None):

这个时候我们就看到了大量的参数,于是就有必要搞懂这些参数,在这里我翻阅了官方文档。但是很多用使用DBSCAN只使用了eps和min_sample两个参数。但是我阅读源码的时候发现sample_weight,于是相对这个参数进行一些小尝试。
 
 

    if not eps > 0.0:
        raise ValueError("eps must be positive.")

这句没的说,要保证eps大于0
 
 

X = check_array(X, accept_sparse='csr')
if sample_weight is not None:
	sample_weight = np.asarray(sample_weight)
    check_consistent_length(X, sample_weight)

首先对X验证和转换(除合法性校验以外,其并没有对特征和目标值进行任何处理)
然后就是假如sample_weight非空,那么就把现有的sample_weight转换为np.asarray,同时检验Xsample_weight第一维是否一致。检查数组中的所有对象是否具有相同的形状或长度
 
 

    if metric == 'precomputed' and sparse.issparse(X):
        neighborhoods = np.empty(X.shape[0], dtype=object)
        X.sum_duplicates()  # XXX: modifies X's internals in-place

        # set the diagonal to explicit values, as a point is its own neighbor
        with ignore_warnings():
            X.setdiag(X.diagonal())  # XXX: modifies X's internals in-place

        X_mask = X.data <= eps
        masked_indices = X.indices.astype(np.intp, copy=False)[X_mask]
        masked_indptr = np.concatenate(([0], np.cumsum(X_mask)))
        masked_indptr = masked_indptr[X.indptr[1:-1]]

        # split into rows
        neighborhoods[:] = np.split(masked_indices, masked_indptr)
    else:
        neighbors_model = NearestNeighbors(radius=eps, algorithm=algorithm,
                                           leaf_size=leaf_size,
                                           metric=metric,
                                           metric_params=metric_params, p=p,
                                           n_jobs=n_jobs)
        neighbors_model.fit(X)
        # This has worst case O(n^2) memory complexity
        neighborhoods = neighbors_model.radius_neighbors(X, eps,
                                                         return_distance=False)

首先我们不管if里面的,那个是对稀疏矩阵(X)的一些处理,但是一般数据集都不是稀疏矩阵,所以击中精力研究else里面的。
首先创建了一个名neighbors_model的NearestNeighbors 执行无监督的最近邻方法
说起这个NearestNeighbors那又是另外一回事了。我们今天的重点是sample_weight,所以没必要在追溯下去了。然后以X作为训练数据拟合模型。
然后使用neighbors_modelradius_neighbors
在一个或多个点的给定半径内找到相邻点。返回数据集中每个点的索引和距离在一个球的大小’ ’ ‘半径’ '周围的查询点数组中。边界上的点包括在结果中。结果点并不一定按到它们的距离排序查询点。
 
 

    if sample_weight is None:
        n_neighbors = np.array([len(neighbors)
                                for neighbors in neighborhoods])
    else:
        n_neighbors = np.array([np.sum(sample_weight[neighbors])
                                for neighbors in neighborhoods])

sample_weight的处理,如果sample_weight是没有的,就把
neighborhoods的长度作为sample_weight
否则就按照neighborhoods的索引将sample_weight加和作为新的sample_weight
 
 

labels = np.full(X.shape[0], -1, dtype=np.intp)

labels填满了-1(-1代表噪声点)
 
 

core_samples = np.asarray(n_neighbors >= min_samples, dtype=np.uint8)
dbscan_inner(core_samples, neighborhoods, labels)
return np.where(core_samples)[0], labels

返回结果

你可能感兴趣的:(Python,sklearn,python,机器学习)