Кластеризация в двоичном массиве с переменным размером / плотностью кластера и точным номером.нулей - PullRequest
0 голосов
/ 23 ноября 2018

Я новичок в программировании и надеюсь, что кто-нибудь может помочь мне с конкретной проблемой, которая у меня есть.

Я хочу сформировать кластеры в двоичном массиве размером 100x100 при двух условиях:

  1. Я хочу указать количество пикселей со значением ноль и один.
  2. Я хочу иметь входную переменную, которая позволяет мне формировать большие или меньшие кластеры.

С ответами на этой странице я создал ndarray с 300 нулями и 700 единицами.

> import numpy as np

> N=1000 
> K=300 

> arr=[0] * K + [1] * (N-K)
> np.random.shuffle(arr)
> arr1=np.resize(arr,(100,100))

Затем я хотел бы реализовать алгоритм кластеризации, который позволяет мне указать некоторую меру плотности кластера или размера кластера.

Я изучил scipy.ndimage пакет, но не могу найти ничего полезного.

РЕДАКТИРОВАТЬ: Чтобы сделать мой вопрос более ясным, ранее я использовал пакет nlmpy , который использует numpy для создания массивов, представляющих виртуальные ландшафты.

Это делается путем генерациислучайный массив с продолжающимися значениями между [0-1] и использованием классификации «4-окрестности» для подмножества пикселей.После кластеризации пикселей он использует функцию интерполяции для назначения оставшейся части пикселей одному из кластеров.

Например, создание кластеров с 60% пикселей:

import nlmpy
nRow=100
nCol=100
arr=nlmpy.randomClusterNN(nRow, nCol, 0.60, n='4-neighbourhood', mask=None)

Это дает кластеры со значениями в диапазоне от [0-1]:

Clustered array

Затем я использую встроенную функцию nlmpy, чтобы переклассифицировать этот вывод вбинарный ndarray.Например, 50% пикселей должны иметь значение «1» и 50% значение «0».

arrBinair= nlmpy.classifyArray(arr, [0.50, 0.50])

Вывод:

Binary clustered array

Проблема здесь состоит в том, что не совсем 50% значений составляют «1» или «0».

print(arrBinair==1).sum()
output: 3023.0

Это происходит из-за функции nlmpy.randomClusterNN, которая сначала создает разные кластеры, а только потомдвоичная переклассификация кластеров сделана.

У меня вопрос: можно ли генерировать бинарный ландшафт кластеризации быстрее, без предварительной кластеризации в непрерывных классах и без использования пакета nlmpy?

Надеюсь, этого достаточно?Или мне нужно разместить функции «под капотом» пакета nlmpy?Я сомневаюсь, так как кода довольно много.

Большое спасибо.

1 Ответ

0 голосов
/ 23 ноября 2018

Вы можете более или менее получить то, что хотите, используя sklearn.cluster.DBSCAN:

from matplotlib import pyplot as plt
import numpy as np
from sklearn.cluster import DBSCAN

def randones(shape, n, dtype=None):
    arr = np.zeros(shape, dtype=dtype)
    arr.flat[np.random.choice(arr.size, size=n, replace=False)] = 1
    return arr

def cluster(arr, *args, **kwargs):
    data = np.array(arr.nonzero()).T
    c = DBSCAN(*args, **kwargs)
    c.fit(data)
    return data, c

# generate random data
shape = (100, 100)
n = 300
arr = randones(shape, n)

# perform clustering
data, c = cluster(arr, eps=6, min_samples=4)

# plot the clusters in different colors
colors = [('C%d' % (i%10)) if i > -1 else 'k' for i in c.labels_]
fig = plt.figure(figsize=(8,8))
ax = fig.gca()
ax.scatter(*data.T, c=colors)

Вывод:

enter image description here

Минимальное количество точек в кластере определяется параметром min_samples.Вы можете настроить минимальную плотность идентифицированных кластеров, поворачивая параметр eps (который определяет максимальное расстояние между двумя точками в кластере).Например, вы можете определить более крупные и менее плотные кластеры, увеличив eps:

# perform clustering
data, c = cluster(arr, eps=8, min_samples=4)

Если мы построим эту менее плотную кластеризацию так же, как и раньше, это даст:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...