Hdbscan: ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ๊ฑฐ๋ฆฌ ์ธก์ •๋ฒ•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2017๋…„ 03์›” 10์ผ  ยท  8์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: scikit-learn-contrib/hdbscan

๊ฐ ์ƒ˜ํ”Œ์— ์œ„๋„/๊ฒฝ๋„์™€ ํŠน์ • ์ง€์ ์˜ ์†๋„๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Haversine ๊ฑฐ๋ฆฌ๋ฅผ ๋ฉ”ํŠธ๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์น˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํฌ์ธํŠธ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ๋งํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์†๋„๋ฅผ ๊ธฐ๋Šฅ์œผ๋กœ ํฌํ•จํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค๋ฅธ ์ธก์ •ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐ€๊นŒ์ด์— ์žˆ๋Š” ๋ชจ๋“  ํฌ์ธํŠธ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋‹ค๋ฅธ ํฌ์ธํŠธ์™€ ์ฃผ์–ด์ง„ ์†๋„ ์ฐจ์ด ๋‚ด์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

๊ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค๋ฅธ ๋ฉ”ํŠธ๋ฆญ์„ ๊ฐ€์ง„ ball_tree๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์›ƒ์„ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ํ›„ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ˆ˜๋™ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์ง€๋งŒ hdbscan์— ๋น„ํ•ด ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ฑฐ๋ฆฌ ๋ฉ”ํŠธ๋ฆญ์„ ๊ณ„์‚ฐํ•˜๊ณ  ๋ฏธ๋ฆฌ ๊ณ„์‚ฐ๋œ ๊ฒƒ์œผ๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ํฌ๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ์ž…๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋ถˆํ–‰ํžˆ๋„ ์ •ํ™•ํ•œ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ๋„์›€์„ ๋“œ๋ฆด ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๊ฑฐ๋ฆฌ ๋ฉ”ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•  ๋•Œ ๊ฑฐ๋ฆฌ ๋ฉ”ํŠธ๋ฆญ์ด ๋„ˆ๋ฌด ์ž์ฃผ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— Cython์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ ํ™”๋ฉ๋‹ˆ๋‹ค. Python์„ ์‚ฌ์šฉํ•˜๊ณ  Cython ์ฝ”๋“œ๊ฐ€ ์†๋„๋ฅผ ์œ„ํ•ด C ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ๋  ์ˆ˜ ์žˆ๋„๋ก ์ •์  ํƒ€์ดํ•‘์„ ์ถ”๊ฐ€ํ•˜๋Š” ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ Python ์ฝ”๋“œ์—์„œ ์ง์ ‘ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

scikit-learn์—๋Š” scikit-learn/sklearn/neighbors/dist_metrics.pyx์— dist_metrics.pyx ๋ชจ๋“ˆ(cython์„ ๋‚˜ํƒ€๋‚ด๋Š” .pyx ๋Œ€ ์ผ๋ฐ˜ ํŒŒ์ด์ฌ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ .py)์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ lmcinnes๊ฐ€ ์ž์‹ ์˜ HDBSCAN ์ €์žฅ์†Œ์— ํšจ๊ณผ์ ์œผ๋กœ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. . ์ด dist_metrics.pyx๋Š” ๋‚˜์ค‘์— C๋กœ ์ปดํŒŒ์ผ๋˜๋Š” Cython ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์„ค๋ช…ํ•œ ๊ฒƒ์˜ 1๋‹จ๊ณ„๋Š” Cython ๊ฑฐ๋ฆฌ ์ธก์ •๋ฒ•์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(์†๋„๋ฅผ ์œ„ํ•ด Cython ์‚ฌ์šฉ). ๋‹ค์Œ์€ ๊ธฐ์กด dist_metrics.pyx ํŒŒ์ผ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

#------------------------------------------------------------
# SEuclidean Distance
#  d = sqrt(sum((x_i - y_i2)^2 / v_i))
cdef class SEuclideanDistance(DistanceMetric):
    r"""Standardized Euclidean Distance metric
    .. math::
       D(x, y) = \sqrt{ \sum_i \frac{ (x_i - y_i) ^ 2}{V_i} }
    """
    def __init__(self, V):
        self.vec = np.asarray(V, dtype=DTYPE)
        self.vec_ptr = get_vec_ptr(self.vec)
        self.size = self.vec.shape[0]
        self.p = 2

    cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2,
                              ITYPE_t size) nogil except -1:
        if size != self.size:
            with gil:
                raise ValueError('SEuclidean dist: size of V does not match')
        cdef DTYPE_t tmp, d=0
        cdef np.intp_t j
        for j in range(size):
            tmp = x1[j] - x2[j]
            d += tmp * tmp / self.vec_ptr[j]
        return d

    cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2,
                             ITYPE_t size) nogil except -1:
        return sqrt(self.rdist(x1, x2, size))

    cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) nogil except -1:
        return sqrt(rdist)

    cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1:
        return dist * dist

    def rdist_to_dist(self, rdist):
        return np.sqrt(rdist)

    def dist_to_rdist(self, dist):
        return dist ** 2

๋”ฐ๋ผ์„œ 1๋‹จ๊ณ„๋Š” ์œ„์—์„œ ๊ตฌํ˜„ํ•œ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” SEuclideanDistance์™€ ์œ ์‚ฌํ•œ cdef ํด๋ž˜์Šค MyMetric(DistanceMetric) ๋ฐ ๋ชจ๋“  ์†์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ƒˆ ๋ฉ”ํŠธ๋ฆญ์— ๋Œ€ํ•ด dist_metrics.pyx์˜ 68ํ–‰ ์ฃผ์œ„์— METRIC_MAPPING ๊ฐœ์ฒด์— string-to-class ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ถ๊ทน์ ์œผ๋กœ ์ด ์ฝ”๋“œ๋Š” ์‹ค์ œ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. Cython ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ์œผ๋ฉด ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. Python๊ณผ ๋‹ฌ๋ฆฌ Cython์€ ์ปดํŒŒ์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์ด ๋ชจ๋“  Cython ๋‚ด์šฉ์„ ์ด๋ฏธ ์•Œ๊ณ  ๊ณ„์‹œ๋‹ค๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ฒ ์ €ํ•˜๊ฒŒ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.)

2๋‹จ๊ณ„ - @lmcinnes ์— ์‹ค์ œ๋กœ ๋ณด๊ณ ํ•œ ๊ฒƒ์€ ๊ทธ๊ฐ€ ๋‹ค์–‘ํ•œ ํŠธ๋ฆฌ ์œ ํ˜•์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” API์ž…๋‹ˆ๋‹ค. ๊ทธ์˜ API ํ˜ธ์ถœ์ด ์•ฝ๊ฐ„ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•œ ์ผ์„ ๋ณต์ œํ•˜๊ณ  dist_metrics.pyx ํŒŒ์ผ๋กœ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ๊ณ ์œ ํ•œ ํŠน์ • ํ‚ค์›Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ Cython ๊ฑฐ๋ฆฌ ์ธก์ •๋ฒ•์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌ๋˜๋„๋ก ํ•˜๋ ค๋ฉด hdbscan/hdbscan_.py๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. lmcinnes๋Š” hdbscan_.py์— ๋‹ค์–‘ํ•œ ํŠธ๋ฆฌ ์œ ํ˜•์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
_hdbscan_prims_kdtree(171ํ–‰)
_hdbscan_prims_balltree(204ํ–‰)
_hdbscan_boruvka_kdtree(235ํ–‰)
๋“ฑ๋“ฑ.
์ด๋Ÿฌํ•œ ๊ฐ ํŠธ๋ฆฌ ์œ ํ˜• ๋‚ด์—์„œ ๊ทธ๋Š” ์‹ค์ œ๋กœ 'kwargs'์—์„œ 'metric_params' ๊ฐœ์ฒด๋ฅผ ํŒ์—…ํ•ด์•ผ ํ•  ๋•Œ 'kwargs' ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ BallTree ๋ฐ KDTree ๋ฐ DistanceMetric๊ณผ ๊ฐ™์€ ํŠน์ • scikit-learn ์œ ํ˜•์— ํ‚ค์›Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๋Œ€์‹  metric_params๋ฅผ ์ด๋Ÿฌํ•œ ๊ฐœ์ฒด์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ๋ธ”๋ก์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ชจ๋‘ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ์ด๊ฒƒ์ด lmcinnes์˜ ์šฐ์„  ์ˆœ์œ„ ๋ชฉ๋ก์— ์ถฉ๋ถ„ํžˆ ์˜ฌ๋ผ๊ฐˆ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋ฉด ์–ธ์  ๊ฐ€ ๋‹น์‹ ์„ ์œ„ํ•ด ๊ทธ๊ฒƒ์„ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋ชจ๋“  8 ๋Œ“๊ธ€

์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž ์ •์˜ ์ธก์ •ํ•ญ๋ชฉ์ด ํ•„์š”ํ•˜๋ฉฐ ์‹ค์ œ๋กœ๋Š”
์ฒœ์ฒœํžˆ ํ•˜๋Š” ๊ฒƒ. ์›์น™์ ์œผ๋กœ balltrees๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์ง€์›ํ•˜๋ฏ€๋กœ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
python ํ•จ์ˆ˜๋ฅผ ๋ฉ”ํŠธ๋ฆญ์œผ๋กœ ์ž‘์„ฑํ•˜๊ณ  ์ด๋ฅผ balltree์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
์•ฝ๊ฐ„์˜ ์ž‘์—…์„ ํ†ตํ•ด ๋๊นŒ์ง€ ๋ฐ€์–ด๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•Œ๊ณ ๋ฆฌ์ฆ˜(๋˜๋Š” ๋Œ€์‹  ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ์ง€๊ธˆ ์ž‘๋™ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฌธ์ž์—ด์„ ๋ฉ”ํŠธ๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ํŠนํžˆ algorithm='boruvka_balltree'๋ฅผ ์‚ฌ์šฉ).
๋ฌธ์ œ๋Š” ๊ณ„์‚ฐ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ฒƒ์ด Cython์— ์žˆ๊ณ 
๊ฐ ๊ฑฐ๋ฆฌ ํ˜ธ์ถœ์— ๋Œ€ํ•ด C์—์„œ ํŒŒ์ด์ฌ์œผ๋กœ ์™•๋ณตํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€
๋งค์šฐ ๋น„์Œ€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.๋‹น์‹ ์„ ๊ฑฐ๊ธฐ์— ๋ฐ๋ ค๊ฐ€๊ธฐ์— ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์žฅ๊ธฐ์ ์œผ๋กœ ํ•„์š”ํ•œ ๊ฒƒ์€ ๊ณต๊ฐ„์— ํฌ์ธํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค.
๋ฉ”ํŠธ๋ฆญ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‹ค์ œ๋กœ ๊ฑด๋ฌผ์„ ์ง“๋Š” ์ผ์„ ํ•˜๊ณ  ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ์•„์ง ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋Š” ์—†์Šต๋‹ˆ๋‹ค(์ด๋ก ์  ๊ฒฐ๊ณผ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค).
๋” ์ด์ƒ ๋„์™€๋“œ๋ฆด ์ˆ˜ ์—†์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

2017๋…„ 3์›” 10์ผ ๊ธˆ์š”์ผ ์˜ค์ „ 3์‹œ 1๋ถ„, thomasht86 [email protected]
์ผ๋‹ค:

๊ฐ ์ƒ˜ํ”Œ์— ์œ„๋„/๊ฒฝ๋„์™€ ์†๋„๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฃผ์–ด์ง„ ์ . ๊ทธ๋ƒฅ ๊ธฐ๋ฐ˜์œผ๋กœ ํฌ์ธํŠธ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ๋งํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.
ํ•˜๋ฒ„์‚ฌ์ธ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฏธํ„ฐ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ•  ๊ฒƒ์ด๋‹ค, ๊ทธ๋Ÿฌ๋‚˜
์†๋„๋ฅผ ๊ธฐ๋Šฅ์œผ๋กœ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ๋‹ค๋ฅธ
๋ฏธํ„ฐ๋ฒ•. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‘˜ ๋‹ค ๊ฐ€๊นŒ์ด์— ์žˆ๋Š” ๋ชจ๋“  ์ ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๋˜ํ•œ ์ฃผ์–ด์ง„ ์†๋„ ์ฐจ์ด ๋‚ด์—์„œ ๋‹ค๋ฅธ ์ง€์ ๊ณผ
๋ฌด๋ฆฌ.

๊ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ
ํ•ด๊ฒฐ. ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” -ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค
์„œ๋กœ ๋‹ค๋ฅธ ball_tree๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์›ƒ์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
๋ฉ”ํŠธ๋ฆญ. ๊ทธ ํ›„ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ˆ˜๋™ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์ง€๋งŒ
hdbscan์— ๋น„ํ•ด ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฉ”ํŠธ๋ฆญ์„ ๋งŒ๋“ค๊ณ  ๋ฏธ๋ฆฌ ๊ณ„์‚ฐ๋œ ๊ฒƒ์œผ๋กœ ์ œ๊ณตํ•˜์ง€๋งŒ ํฐ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์ด
๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ์ž…๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

โ€”
์ด ์Šค๋ ˆ๋“œ์— ๊ฐ€์ž…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/scikit-learn-contrib/hdbscan/issues/91 , ๋˜๋Š” ์Œ์†Œ๊ฑฐ
์‹ค
https://github.com/notifications/unsubscribe-auth/ALaKBYaCK6hJ9LrJdrwAm9H0c25hC1uBks5rkQNwgaJpZM4MZFTK
.

์ž…๋ ฅํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!
ball_tree์™€ ์ž˜ ์ž‘๋™ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ๋ฉ”ํŠธ๋ฆญ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
์ž์ฒด์ด์ง€๋งŒ hdbscan์— ์ „๋‹ฌํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
๋ฉ”์‹œ์ง€: ์ด ์ธก์ •ํ•ญ๋ชฉ์— ๋Œ€ํ•ด BallTree์™€ ํ•จ๊ป˜ Boruvka๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!

ball_tree๊ฐ€ ์ด ๋ฉ”ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์™œ hdbscan์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ?

2017-03-10 14:19 GMT+01:00 Leland McInnes [email protected] :

์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž ์ •์˜ ์ธก์ •ํ•ญ๋ชฉ์ด ํ•„์š”ํ•˜๋ฉฐ ์‹ค์ œ๋กœ๋Š”
์ฒœ์ฒœํžˆ ํ•˜๋Š” ๊ฒƒ. ์›์น™์ ์œผ๋กœ balltrees๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์ง€์›ํ•˜๋ฏ€๋กœ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
python ํ•จ์ˆ˜๋ฅผ ๋ฉ”ํŠธ๋ฆญ์œผ๋กœ ์ž‘์„ฑํ•˜๊ณ  ์ด๋ฅผ balltree์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
์•ฝ๊ฐ„์˜ ์ž‘์—…์„ ํ†ตํ•ด ๋๊นŒ์ง€ ๋ฐ€์–ด๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•Œ๊ณ ๋ฆฌ์ฆ˜(๋˜๋Š” ๋Œ€์‹  ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ์ง€๊ธˆ ์ž‘๋™ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฌธ์ž์—ด์„ ๋ฉ”ํŠธ๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ํŠนํžˆ algorithm='boruvka_balltree'๋ฅผ ์‚ฌ์šฉ).
๋ฌธ์ œ๋Š” ๊ณ„์‚ฐ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ฒƒ์ด Cython์— ์žˆ๊ณ 
๊ฐ ๊ฑฐ๋ฆฌ ํ˜ธ์ถœ์— ๋Œ€ํ•ด C์—์„œ ํŒŒ์ด์ฌ์œผ๋กœ ์™•๋ณตํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€
๋งค์šฐ ๋น„์Œ€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.๋‹น์‹ ์„ ๊ฑฐ๊ธฐ์— ๋ฐ๋ ค๊ฐ€๊ธฐ์— ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์žฅ๊ธฐ์ ์œผ๋กœ ํ•„์š”ํ•œ ๊ฒƒ์€ ๊ณต๊ฐ„์— ํฌ์ธํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค.
๋ฉ”ํŠธ๋ฆญ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‹ค์ œ๋กœ ๊ฑด๋ฌผ์„ ์ง“๋Š” ์ผ์„ ํ•˜๊ณ  ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ์•„์ง ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋Š” ์—†์Šต๋‹ˆ๋‹ค(์ด๋ก ์  ๊ฒฐ๊ณผ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค).
๋” ์ด์ƒ ๋„์™€๋“œ๋ฆด ์ˆ˜ ์—†์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

2017๋…„ 3์›” 10์ผ ๊ธˆ์š”์ผ ์˜ค์ „ 3์‹œ 1๋ถ„, thomasht86 [email protected]
์ผ๋‹ค:

๊ฐ ์ƒ˜ํ”Œ์— ์œ„๋„/๊ฒฝ๋„์™€ ์†๋„๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
ใ…
์ฃผ์–ด์ง„ ์ . ํฌ์ธํŠธ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ๋งํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ๋ฐ˜์„ ๋‘”
ํ•˜๋ฒ„์‚ฌ์ธ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฏธํ„ฐ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ•  ๊ฒƒ์ด๋‹ค, ๊ทธ๋Ÿฌ๋‚˜
์†๋„๋ฅผ ๊ธฐ๋Šฅ์œผ๋กœ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ๋‹ค๋ฅธ
๋ฏธํ„ฐ๋ฒ•. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‘˜ ๋‹ค ์œ„์น˜ํ•œ ๋ชจ๋“  ํฌ์ธํŠธ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ซ๋‹ค,
๊ทธ๋Ÿฌ๋‚˜ ๋˜ํ•œ ์ฃผ์–ด์ง„ ์†๋„ ์ฐจ์ด ๋‚ด์—์„œ ๋‹ค๋ฅธ ์ง€์ ๊ณผ
๋ฌด๋ฆฌ.

๊ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ
be
ํ•ด๊ฒฐ. ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” -ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค
ball_tree๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์›ƒ์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
๋‹ค๋ฅธ
๋ฉ”ํŠธ๋ฆญ. ๊ทธ ํ›„ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ˆ˜๋™ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์ง€๋งŒ
๊ทธ๊ฒƒ
hdbscan์— ๋น„ํ•ด ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์—ฐํžˆ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค
๊ฑฐ๋ฆฌ
๋ฉ”ํŠธ๋ฆญ์„ ๋งŒ๋“ค๊ณ  ๋ฏธ๋ฆฌ ๊ณ„์‚ฐ๋œ ๊ฒƒ์œผ๋กœ ์ œ๊ณตํ•˜์ง€๋งŒ ํฐ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ์ด
๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ์ž…๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

โ€”
์ด ์Šค๋ ˆ๋“œ์— ๊ฐ€์ž…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/scikit-learn-contrib/hdbscan/issues/91 , ๋˜๋Š” ์Œ์†Œ๊ฑฐ
์‹ค
ALaKBYaCK6hJ9LrJdrwAm9H0c25hC1uBks5rkQNwgaJpZM4MZFTK>
.

โ€”
์Šค๋ ˆ๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/scikit-learn-contrib/hdbscan/issues/91#issuecomment-285666973 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AXbP8MIOO7inlKJIDNmDHXIoSq_fWm1uks5rkU3XgaJpZM4MZFTK
.

๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์กฐ์‚ฌํ•˜๊ณ  ๋‹ค์‹œ ์—ฐ๋ฝ์„ ๋“œ๋ ค์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค
์‚ฌ์šฉ์ž ์ •์˜ ์ธก์ •ํ•ญ๋ชฉ์„ ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
๊ณ ์น˜๊ธฐ ์–ด๋ ต๋‹ค.

2017๋…„ 3์›” 13์ผ ์›”์š”์ผ ์˜ค์ „ 4์‹œ 24๋ถ„, thomasht86 [email protected]
์ผ๋‹ค:

์ž…๋ ฅํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!
ball_tree์™€ ์ž˜ ์ž‘๋™ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ๋ฉ”ํŠธ๋ฆญ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
์ž์ฒด์ด์ง€๋งŒ hdbscan์— ์ „๋‹ฌํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
๋ฉ”์‹œ์ง€: ์ด ์ธก์ •ํ•ญ๋ชฉ์— ๋Œ€ํ•ด BallTree์™€ ํ•จ๊ป˜ Boruvka๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!

ball_tree๊ฐ€ ์ด ๋ฉ”ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์™œ hdbscan์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ?

2017-03-10 14:19 GMT+01:00 Leland McInnes [email protected] :

์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ์ธก์ •ํ•ญ๋ชฉ์ด ํ•„์š”ํ•˜๋ฉฐ ์‹ค์ œ๋กœ๋Š”
be
์ฒœ์ฒœํžˆ ํ•˜๋Š” ๊ฒƒ. ์›์น™์ ์œผ๋กœ ๋ณผํŠธ๋ฆฌ๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์ง€์›ํ•˜๋ฏ€๋กœ
~ ํ•  ์ˆ˜์žˆ๋‹ค
python ํ•จ์ˆ˜๋ฅผ ๋ฉ”ํŠธ๋ฆญ์œผ๋กœ ์ž‘์„ฑํ•˜๊ณ  ์ด๋ฅผ balltree์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
์•ฝ๊ฐ„์˜ ์ž‘์—…์„ ํ†ตํ•ด ๋๊นŒ์ง€ ๋ฐ€์–ด๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•Œ๊ณ ๋ฆฌ์ฆ˜(๋˜๋Š” ๋Œ€์‹  ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ์ง€๊ธˆ ์ž‘๋™ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฌธ์ž์—ด์„ ๋ฉ”ํŠธ๋ฆญ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ํŠนํžˆ algorithm='boruvka_balltree'๋ฅผ ์‚ฌ์šฉ).
๋ฌธ์ œ๋Š” ๊ณ„์‚ฐ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ฒƒ์ด Cython์— ์žˆ๊ณ 
๊ฐ ๊ฑฐ๋ฆฌ ํ˜ธ์ถœ์— ๋Œ€ํ•ด C์—์„œ ํŒŒ์ด์ฌ์œผ๋กœ ์™•๋ณตํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€
๋งค์šฐ ๋น„์Œ€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.๋‹น์‹ ์„ ๊ฑฐ๊ธฐ์— ๋ฐ๋ ค๊ฐ€๊ธฐ์— ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์žฅ๊ธฐ์ ์œผ๋กœ ํ•„์š”ํ•œ ๊ฒƒ์€ ๊ณต๊ฐ„์— ํฌ์ธํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค.
๋ฉ”ํŠธ๋ฆญ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‹ค์ œ๋กœ ๊ฑด๋ฌผ์„ ์ง“๋Š” ์ผ์„ ํ•˜๊ณ  ์žˆ๋‹ค.
๊ทธ๋Ÿฐ ๊ฒƒ์ด์ง€๋งŒ ์•„์ง ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค(์ด๋ก ์ 
๊ฒฐ๊ณผ).
๋” ์ด์ƒ ๋„์™€๋“œ๋ฆด ์ˆ˜ ์—†์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

2017๋…„ 3์›” 10์ผ ๊ธˆ์š”์ผ ์˜ค์ „ 3์‹œ 1๋ถ„, thomasht86 [email protected]
์ผ๋‹ค:

๊ฐ ์ƒ˜ํ”Œ์— ์œ„๋„/๊ฒฝ๋„์™€ ์†๋„๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
~์„์œ„ํ•œ
ใ…
์ฃผ์–ด์ง„ ์ . ํฌ์ธํŠธ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ๋งํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ๋ฐ˜์„ ๋‘”
ํ•˜๋ฒ„์‚ฌ์ธ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฏธํ„ฐ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ•  ๊ฒƒ์ด๋‹ค, ๊ทธ๋Ÿฌ๋‚˜
์†๋„๋ฅผ ๊ธฐ๋Šฅ์œผ๋กœ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค๋ฅธ
๋‹ค๋ฅธ
๋ฏธํ„ฐ๋ฒ•. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‘˜ ๋‹ค ์œ„์น˜ํ•œ ๋ชจ๋“  ํฌ์ธํŠธ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ซ๋‹ค,
๊ทธ๋Ÿฌ๋‚˜ ๋˜ํ•œ ์ฃผ์–ด์ง„ ์†๋„ ์ฐจ์ด ๋‚ด์—์„œ ๋‹ค๋ฅธ ์ง€์ ๊ณผ
๋ฌด๋ฆฌ.

๊ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ
be
ํ•ด๊ฒฐ. ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ์ˆ˜ ์žˆ์–ด์š”
์—๊ฒŒ
ball_tree๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์›ƒ์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
๋‹ค๋ฅธ
๋ฉ”ํŠธ๋ฆญ. ๊ทธ ํ›„ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ˆ˜๋™ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ
๊ทธ๊ฒƒ
hdbscan์— ๋น„ํ•ด ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์—ฐํžˆ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค
๊ฑฐ๋ฆฌ
์ธก์ •ํ•ญ๋ชฉ์„ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•˜์—ฌ ์ œ๊ณตํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ์„ธํŠธ๊ฐ€ ํฌ๊ธฐ ๋•Œ๋ฌธ์—
์ด๊ฒƒ
๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ์ž…๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

โ€”
์ด ์Šค๋ ˆ๋“œ์— ๊ฐ€์ž…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/scikit-learn-contrib/hdbscan/issues/91 ๋˜๋Š” ์Œ์†Œ๊ฑฐ
๊ทธ๋งŒํผ
์‹ค
ALaKBYaCK6hJ9LrJdrwAm9H0c25hC1uBks5rkQNwgaJpZM4MZFTK>
.

โ€”
์Šค๋ ˆ๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
91#์ด์Šˆ๋Œ“๊ธ€-285666973>,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
AXbP8MIOO7inlKJIDNmDHXIoSq_fWm1uks5rkU3XgaJpZM4MZFTK>
.

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/scikit-learn-contrib/hdbscan/issues/91#issuecomment-286042146 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ALaKBU0fC8JSdexhCyYDi5yPkD2_EMO7ks5rlP1OgaJpZM4MZFTK
.

์•ˆ๋…• ์–˜๋“ค์•„!

๋จผ์ € ๋งํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค - ์ด๊ฒƒ์— ๋Œ€ํ•œ ๋ฉ‹์ง„ ์ž‘์—…. ์ƒˆ๋กœ์šด ์ด์Šˆ๋ฅผ ์—ด์–ด์•ผ ํ• ์ง€ ๋ง์•„์•ผ ํ• ์ง€ ํ™•์‹ ์ด ์„œ์ง€ ์•Š์•˜์ง€๋งŒ, ์ด ์ด์Šˆ์— ๊ด€ํ•ด ์—ฌ๋Ÿฌ๋ถ„์ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ๋Š” ์ปค์Šคํ…€ ๋ฉ”ํŠธ๋ฆญ์€ ์ œ๊ฐ€ ์‹ค์ œ๋กœ ํ•œ ์ผ์ž…๋‹ˆ๋‹ค. scikit-learn ๋ฐฐํฌํŒ์„ ๋ถ„๊ธฐํ•˜๊ณ  dist_metrics.pyx Cython ์ฝ”๋“œ์— ์‚ฌ์šฉ์ž ์ง€์ • ๋ฉ”ํŠธ๋ฆญ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ผ๋ถ€ ํ•ญ๋ชฉ์—์„œ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ํŒจํ„ด์„ ๋”ฐ๋ฅด๋ ค๊ณ  ํ•˜๋ฉด hdbscan_.py ๋ฉ”์„œ๋“œ๊ฐ€ dist_metrics.pyx API๋ฅผ ์•ฝ๊ฐ„ ์ž˜๋ชป ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ

_hdbscan_prims_balltree

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Ball_Tree๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
ํŠธ๋ฆฌ = BallTree(X, metric=metric, leaf_size=leaf_size, **kwargs)

๊ทธ๋Ÿฌ๋‚˜ ๋ฉ”ํŠธ๋ฆญ ํ‚ค์›Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์ „๋‹ฌํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹ค์ œ ํ‚ค์›Œ๋“œ๋ฅผ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

if 'metric_params' in kwargs:
        metric_params = kwargs.pop('metric_params')
else:
        metric_params = None

tree = BallTree(X, metric=metric, leaf_size=leaf_size, **metric_params)

์‚ฌ์šฉ์ž ์ง€์ • ๊ฑฐ๋ฆฌ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์ง€์›ํ•˜๋ ค๋ฉด ๊ฐ _hdbscan_METHOD_TREETYPE ํ•จ์ˆ˜์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ช‡ ์ค„์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ง€์ • ๊ฑฐ๋ฆฌ ์ธก์ •๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๊ณ  ๊ฝค ๊ฐ„๋‹จํ•œ ์ˆ˜์ •์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์„ (ํฌํ•จ) ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ๋ฆฌํŒฉํ† ๋ง์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”๋ฐ, ์ง€๊ธˆ์€ ๋ฐ”์˜๊ฒŒ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณง ๋„์ฐฉํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@QuiteAFoxtrot ์ฝ”๋“œ์˜ ๋” ํฐ ๋ถ€๋ถ„์„ ๊ณต์œ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ์•ฝ๊ฐ„ ํ˜ผ๋ž€์Šค๋Ÿฝ๋‹ค.
๊ฐ์‚ฌ ํ•ด์š”

๋ถˆํ–‰ํžˆ๋„ ์ •ํ™•ํ•œ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ๋„์›€์„ ๋“œ๋ฆด ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๊ฑฐ๋ฆฌ ๋ฉ”ํŠธ๋ฆญ์„ ์‚ฌ์šฉํ•  ๋•Œ ๊ฑฐ๋ฆฌ ๋ฉ”ํŠธ๋ฆญ์ด ๋„ˆ๋ฌด ์ž์ฃผ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— Cython์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ ํ™”๋ฉ๋‹ˆ๋‹ค. Python์„ ์‚ฌ์šฉํ•˜๊ณ  Cython ์ฝ”๋“œ๊ฐ€ ์†๋„๋ฅผ ์œ„ํ•ด C ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ๋  ์ˆ˜ ์žˆ๋„๋ก ์ •์  ํƒ€์ดํ•‘์„ ์ถ”๊ฐ€ํ•˜๋Š” ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ Python ์ฝ”๋“œ์—์„œ ์ง์ ‘ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

scikit-learn์—๋Š” scikit-learn/sklearn/neighbors/dist_metrics.pyx์— dist_metrics.pyx ๋ชจ๋“ˆ(cython์„ ๋‚˜ํƒ€๋‚ด๋Š” .pyx ๋Œ€ ์ผ๋ฐ˜ ํŒŒ์ด์ฌ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ .py)์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์€ lmcinnes๊ฐ€ ์ž์‹ ์˜ HDBSCAN ์ €์žฅ์†Œ์— ํšจ๊ณผ์ ์œผ๋กœ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค. . ์ด dist_metrics.pyx๋Š” ๋‚˜์ค‘์— C๋กœ ์ปดํŒŒ์ผ๋˜๋Š” Cython ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์„ค๋ช…ํ•œ ๊ฒƒ์˜ 1๋‹จ๊ณ„๋Š” Cython ๊ฑฐ๋ฆฌ ์ธก์ •๋ฒ•์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(์†๋„๋ฅผ ์œ„ํ•ด Cython ์‚ฌ์šฉ). ๋‹ค์Œ์€ ๊ธฐ์กด dist_metrics.pyx ํŒŒ์ผ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

#------------------------------------------------------------
# SEuclidean Distance
#  d = sqrt(sum((x_i - y_i2)^2 / v_i))
cdef class SEuclideanDistance(DistanceMetric):
    r"""Standardized Euclidean Distance metric
    .. math::
       D(x, y) = \sqrt{ \sum_i \frac{ (x_i - y_i) ^ 2}{V_i} }
    """
    def __init__(self, V):
        self.vec = np.asarray(V, dtype=DTYPE)
        self.vec_ptr = get_vec_ptr(self.vec)
        self.size = self.vec.shape[0]
        self.p = 2

    cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2,
                              ITYPE_t size) nogil except -1:
        if size != self.size:
            with gil:
                raise ValueError('SEuclidean dist: size of V does not match')
        cdef DTYPE_t tmp, d=0
        cdef np.intp_t j
        for j in range(size):
            tmp = x1[j] - x2[j]
            d += tmp * tmp / self.vec_ptr[j]
        return d

    cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2,
                             ITYPE_t size) nogil except -1:
        return sqrt(self.rdist(x1, x2, size))

    cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) nogil except -1:
        return sqrt(rdist)

    cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1:
        return dist * dist

    def rdist_to_dist(self, rdist):
        return np.sqrt(rdist)

    def dist_to_rdist(self, dist):
        return dist ** 2

๋”ฐ๋ผ์„œ 1๋‹จ๊ณ„๋Š” ์œ„์—์„œ ๊ตฌํ˜„ํ•œ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” SEuclideanDistance์™€ ์œ ์‚ฌํ•œ cdef ํด๋ž˜์Šค MyMetric(DistanceMetric) ๋ฐ ๋ชจ๋“  ์†์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ƒˆ ๋ฉ”ํŠธ๋ฆญ์— ๋Œ€ํ•ด dist_metrics.pyx์˜ 68ํ–‰ ์ฃผ์œ„์— METRIC_MAPPING ๊ฐœ์ฒด์— string-to-class ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ถ๊ทน์ ์œผ๋กœ ์ด ์ฝ”๋“œ๋Š” ์‹ค์ œ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. Cython ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ์œผ๋ฉด ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. Python๊ณผ ๋‹ฌ๋ฆฌ Cython์€ ์ปดํŒŒ์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์ด ๋ชจ๋“  Cython ๋‚ด์šฉ์„ ์ด๋ฏธ ์•Œ๊ณ  ๊ณ„์‹œ๋‹ค๋ฉด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ฒ ์ €ํ•˜๊ฒŒ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.)

2๋‹จ๊ณ„ - @lmcinnes ์— ์‹ค์ œ๋กœ ๋ณด๊ณ ํ•œ ๊ฒƒ์€ ๊ทธ๊ฐ€ ๋‹ค์–‘ํ•œ ํŠธ๋ฆฌ ์œ ํ˜•์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” API์ž…๋‹ˆ๋‹ค. ๊ทธ์˜ API ํ˜ธ์ถœ์ด ์•ฝ๊ฐ„ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•œ ์ผ์„ ๋ณต์ œํ•˜๊ณ  dist_metrics.pyx ํŒŒ์ผ๋กœ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ๊ณ ์œ ํ•œ ํŠน์ • ํ‚ค์›Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ Cython ๊ฑฐ๋ฆฌ ์ธก์ •๋ฒ•์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌ๋˜๋„๋ก ํ•˜๋ ค๋ฉด hdbscan/hdbscan_.py๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. lmcinnes๋Š” hdbscan_.py์— ๋‹ค์–‘ํ•œ ํŠธ๋ฆฌ ์œ ํ˜•์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
_hdbscan_prims_kdtree(171ํ–‰)
_hdbscan_prims_balltree(204ํ–‰)
_hdbscan_boruvka_kdtree(235ํ–‰)
๋“ฑ๋“ฑ.
์ด๋Ÿฌํ•œ ๊ฐ ํŠธ๋ฆฌ ์œ ํ˜• ๋‚ด์—์„œ ๊ทธ๋Š” ์‹ค์ œ๋กœ 'kwargs'์—์„œ 'metric_params' ๊ฐœ์ฒด๋ฅผ ํŒ์—…ํ•ด์•ผ ํ•  ๋•Œ 'kwargs' ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ BallTree ๋ฐ KDTree ๋ฐ DistanceMetric๊ณผ ๊ฐ™์€ ํŠน์ • scikit-learn ์œ ํ˜•์— ํ‚ค์›Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๋Œ€์‹  metric_params๋ฅผ ์ด๋Ÿฌํ•œ ๊ฐœ์ฒด์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ๋ธ”๋ก์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ชจ๋‘ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ์ด๊ฒƒ์ด lmcinnes์˜ ์šฐ์„  ์ˆœ์œ„ ๋ชฉ๋ก์— ์ถฉ๋ถ„ํžˆ ์˜ฌ๋ผ๊ฐˆ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋ฉด ์–ธ์  ๊ฐ€ ๋‹น์‹ ์„ ์œ„ํ•ด ๊ทธ๊ฒƒ์„ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@QuiteAFoxtrot ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. EuclideanDistance ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ๊ณผ ๋‹ค์Œ์„ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

def calculate distance():
        d = euclideanDistance(tens1, tens2)
        #normalize in between [0, 1]
        mn = np.min(d)
        sqz = np.max(d) - mn
        d = (d - mn) / sqz
        d[d[:]<=0.001] = 0.001
        d[d[:]>=1.0] = 1.0
        return d

๋ฏธ๋ฆฌ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰