K có nghĩa là trăn hình ảnh 3d

trên cùng bên phải. Ảnh hưởng của việc khởi tạo xấu là gì đối với quá trình phân loại. Bằng cách đặt n_init thành chỉ 1 (mặc định là 10), số lần thuật toán sẽ được chạy với các centroid seed khác nhau sẽ giảm đi

Trong một vài phần trước, chúng ta đã khám phá một loại mô hình học máy không giám sát. giảm kích thước. Ở đây chúng ta sẽ chuyển sang một lớp mô hình học máy không giám sát khác. thuật toán phân cụm. Các thuật toán phân cụm tìm cách học, từ các thuộc tính của dữ liệu, phân chia tối ưu hoặc ghi nhãn rời rạc của các nhóm điểm

Nhiều thuật toán phân cụm có sẵn trong Scikit-Learn và các nơi khác, nhưng có lẽ cách hiểu đơn giản nhất là thuật toán được gọi là phân cụm k-mean, được triển khai trong

plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')

centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='black', s=200, alpha=0.5);
0

Chúng tôi bắt đầu với việc nhập khẩu tiêu chuẩn

Trong 1]

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()  # for plot styling
import numpy as np

Giới thiệu k-Means

Thuật toán k-means tìm kiếm một số cụm được xác định trước trong tập dữ liệu đa chiều không được gắn nhãn. Nó thực hiện điều này bằng cách sử dụng một khái niệm đơn giản về phân cụm tối ưu trông như thế nào

  • "Tâm cụm" là trung bình cộng của tất cả các điểm thuộc cụm
  • Mỗi điểm gần trung tâm cụm của chính nó hơn so với các trung tâm cụm khác

Hai giả định đó là cơ sở của mô hình k-means. Chúng tôi sẽ sớm đi sâu vào chính xác cách thuật toán đạt được giải pháp này, nhưng bây giờ chúng ta hãy xem một bộ dữ liệu đơn giản và xem kết quả k-means

Đầu tiên, hãy tạo tập dữ liệu hai chiều chứa bốn đốm màu riêng biệt. Để nhấn mạnh rằng đây là một thuật toán không được giám sát, chúng tôi sẽ loại bỏ các nhãn khỏi trực quan hóa

Trong 2]

from sklearn.datasets.samples_generator import make_blobs
X, y_true = make_blobs(n_samples=300, centers=4,
                       cluster_std=0.60, random_state=0)
plt.scatter(X[:, 0], X[:, 1], s=50);

K có nghĩa là trăn hình ảnh 3d

Thuật toán k-Means đủ đơn giản để chúng ta có thể viết nó trong một vài dòng mã. Sau đây là một thực hiện rất cơ bản

K-Means là một thuật toán phân cụm không giám sát, tương tự như các thuật toán phân loại được giám sát. Do tên, thuật toán K-Means thường bị nhầm lẫn với thuật toán KNN(K Nearest Neighbhours) được giám sát, được sử dụng cho cả bài toán phân loại và hồi quy

Như tên cho thấy, thuật toán K-Means bao gồm "K" "Phương tiện" tương ứng với số lượng cụm mà thuật toán cố gắng tìm trong dữ liệu chưa được gắn nhãn. Hoạt động của thuật toán mặc dù khá đơn giản nhưng thách thức nằm ở việc mở rộng thuật toán cho các tập dữ liệu lớn và chọn một thước đo thích hợp cho khoảng cách

Trước khi chúng tôi đi vào bất kỳ chi tiết nào khác, chúng ta hãy xem các bước bao gồm thuật toán K-Means-

  1. Đầu vào cho thuật toán-
    1. Dữ liệu đến cụm
    2. Số lượng cụm để xác định
    3. tiêu chí hội tụ i. e. khi nào dừng lại
      1. Thông thường, giá trị dung sai được đưa ra được sử dụng để quan sát khi vị trí "Trung bình" không thay đổi nữa
      2. Tùy chọn khác là số lần lặp lại tối đa để thực hiện
    4. Chức năng được sử dụng làm Thước đo - thường sử dụng khoảng cách cartesian nhưng khi dữ liệu là văn bản hoặc bất kỳ dữ liệu trừu tượng nào khác, phải chọn các thước đo đặc biệt
  2. Dựa trên không gian dữ liệu tôi. e. giới hạn (tối thiểu và tối đa) và số lượng cụm cần xác định, nhiều điểm Trung bình ngẫu nhiên trong cùng một không gian khi dữ liệu được tạo
  3. Khoảng cách của tất cả các mẫu/điểm dữ liệu trong không gian dữ liệu, giả sử $\mathbb{R}^n$, tương ứng với K số Phương tiện được tính toán (i. e. nếu có 10 mẫu và 2 cụm cần tìm thì số khoảng cách đo được là 20(1x10 + 1x10))
  4. Dựa trên khoảng cách mà mỗi mẫu dữ liệu được liên kết với Giá trị trung bình gần nhất của chúng
  5. Dựa trên các liên kết được thực hiện ở bước 4, các giá trị Trung bình được cập nhật bằng cách tính giá trị trung bình của tất cả các giá trị được liên kết với một Giá trị trung bình cụ thể. Điều này được thực hiện cho K số Phương tiện
  6. Các bước từ 3 đến 5 sau đó được lặp lại cho đến khi thuật toán vượt quá số lần lặp tối đa được phép hoặc cho đến khi các giá trị của K Mean ổn định. e. thay đổi sau khi cập nhật nhỏ hơn giá trị dung sai được chỉ định trong đầu vào

Tiếp theo, chúng ta chuyển sang phần triển khai và viết mã của thuật toán và thảo luận về kết quả

mã bắt đầu

Xử lý nhập khẩu

%matplotlib widget

import time
import IPython
import numpy as np
import pandas as pd
import numpy.linalg as LA
import matplotlib.pyplot as plt
from matplotlib import animation
from mpl_toolkits.mplot3d import Axes3D

from IPython.display import Video

plt.rcParams['figure.figsize'] = [8.0, 8.0]
plt.rcParams['figure.dpi'] = 100

Lớp K-Means để giữ dữ liệu, phương pháp tính toán khoảng cách, cập nhật phương tiện và vẽ biểu đồ tiến trình và kết quả

class kmeans:
    def __init__(self, dimensions, sample_size, clusters, tolerance, max_iters):
        """
        Use the initialisation parameters as attributes of the object and create
        a matplotlib figure canvas on which each iteration progress can be drawn
        :param dimesnions: Dimension of data
        :param sample_size: Not necessary for real data, here used for generating sample data
        :param clusters: Number of clusters to identify in the data, control the number of Means 
        :param tolerance: The tolearance value
        :param max_iters: Maximum iterations to execute
        """
        self.dimensions = dimensions
        self.sample_size = sample_size
        self.clusters = clusters
        self.tolerance = tolerance
        self.max_iters = max_iters
        self.colors = ['y', 'r', 'b', 'm', 'k', 'c', 'b', 'm', 'k', 'c']
        
        if self.dimensions == 1:
            self.fig, self.ax = plt.subplots(1,1)
            self.sample_pts = np.array([[]])
            self.ax.grid(True)
        elif self.dimensions == 2:
            self.fig, self.ax = plt.subplots(1,1)
            self.sample_pts = np.array([[], []])
            self.ax.grid(True)
        elif self.dimensions == 3:
            self.fig = plt.figure(1, figsize=(8, 6))
            self.sample_pts = np.array([[], [], []])
            self.ax = Axes3D(self.fig, rect=(0.0, 0.0, .95, 1.0), elev=48, azim=134)
    
    def kmeans_init(self):
        """
        Generate sample data and draw the initial state of the data and display the initial position
        of the Means
        """
        ##################################################################################################################################
        # Creating clusters using normal distribution and random variance and mean
        # every cluster will have equal number of points
        ##################################################################################################################################
        for i in range(0, self.clusters):
            np.random.seed(int((-i) ** 2))
            tmp = np.random.randn(1, (self.sample_size // self.clusters) * self.dimensions) * np.random.randint(1, 10) + np.random.randint(-100, 100)
            self.sample_pts = np.hstack((self.sample_pts, tmp.reshape(self.dimensions, self.sample_size // self.clusters)))
        np.random.seed(22)
        self.previous_means = np.random.randn(self.clusters, self.dimensions) * np.random.randint(1, 12)  # Randomly selected means i.e., cluster centers
        # print(f'Starting means are: {self.previous_means}')
        self.new_means = np.zeros((self.clusters, self.dimensions))  # To store the new means after every iteration
    
        ##################################################################################################################################
        # plot initial means and all data samples to see the distribution
        ##################################################################################################################################
        if self.dimensions == 1:
            self.ax.scatter(self.previous_means[:, 0], np.zeros((self.clusters, 1)), marker='o', c='r', label='Initial Means')
            self.ax.scatter(self.sample_pts[0, :], np.zeros((1, self.sample_size)),
                        marker='*')  # Plotting all the points to see the clusters
        elif self.dimensions == 2:
            self.ax.scatter(self.previous_means[:, 0], self.previous_means[:, 1], marker='o', c='r', label='Initial Means')
            self.ax.scatter(self.sample_pts[0, :], self.sample_pts[1, :], marker='*')  # Plotting all the points to see the clusters
        elif self.dimensions == 3:
            self.ax.scatter(self.previous_means[:, 0], self.previous_means[:, 1], self.previous_means[:, 2], marker='o', c='r',
                       label='Initial Means', depthshade=False)
            self.ax.scatter(self.sample_pts[0, :], self.sample_pts[1, :], self.sample_pts[2, :],
                       marker='*')  # Plotting all the points to see the clusters
        self.ax.legend(loc='upper right')
    
    ##################################################################################################################################
    # Loop till convergence
    ##################################################################################################################################
    def kmeans_iter(self, iteration_count):
        """
        Iteration part of the algorithm which iterates until the tolerance criteria is met while
        limiting the maximum number of iterations to preven infinite loops when the algorithm 
        cannot associate a Mean value with a cluster
        """
        if (abs(self.previous_means - self.new_means) > self.tolerance).any() and (iteration_count < self.max_iters) and (iteration_count != 0):
            print(f'Iteration number {iteration_count}')
            if iteration_count != 1:
                self.previous_means = self.new_means.copy()
            dist = pd.DataFrame()
            
            ##################################################################################################################################
            # Compute distances of all points with respect to each mean
            ##################################################################################################################################
            for i in range(0, self.clusters):
                # distance_to_mean_1_iter_1 naming used
                dist['dtm_' + str(i + 1) + f'_iter_{iteration_count}'] = LA.norm(
                    self.sample_pts - self.previous_means[i, :].T.reshape(self.dimensions, 1), axis=0)
            # Assign a data sample to the mean it is nearest to by extracting the digit in the name of the index i.e., column
            # name where the minimum value is found
            # dtm_{1}_iter_1
            dist['assign_to_mean'] = dist.idxmin(axis=1).str[4]
            
            ##################################################################################################################################
            # compute the new means based on the classes assigned
            ##################################################################################################################################
            for i in range(0, self.clusters):
                indices = dist.assign_to_mean[dist.assign_to_mean == str(i + 1)]
                if self.dimensions > 1:
                    if len(indices.index) != 0:
                        self.new_means[i, :] = np.mean(self.sample_pts[:, indices.index], axis=1)
                    else:
                        # Re-initialise a mean if it is not associated with any data sample
                        self.new_means[i, :] = np.random.randn(1, self.dimensions) * 100
                else:
                    if len(indices.index) != 0:
                        self.new_means[i, 0] = np.mean(self.sample_pts[0, indices.index])
                    else:
                        # Re-initialise a mean if it is not associated with any data sample
                        self.new_means[i, 0] = np.random.randn(1, self.dimensions) * 100
            # print(f'New means are:{self.new_means}')

            ##################################################################################################################################
            # Plot the movement of the means
            ##################################################################################################################################
            if self.dimensions == 1:
                for i in range(0, self.clusters):
                    self.ax.plot([self.previous_means[i, 0], self.new_means[i, 0]],
                                 [0, 0], label='mean movement' if iteration_count == 1 else "", c=self.colors[i])
                    self.ax.scatter(self.new_means[i, 0], 0, marker='o', c='g', label='new Means' if i == 0 and iteration_count == 1 else "")
            elif self.dimensions == 2:
                for i in range(0, self.clusters):
                    self.ax.plot([self.previous_means[i, 0], self.new_means[i, 0]],
                                 [self.previous_means[i, 1], self.new_means[i, 1]],
                                 label='mean movement' if iteration_count == 1 else "", c=self.colors[i])
                    self.ax.scatter(self.new_means[i, 0], self.new_means[i, 1], marker='o', c='g',
                                label='new Means' if i == 0 and iteration_count == 1 else "")
            elif self.dimensions == 3:
                for i in range(0, self.clusters):
                    self.ax.plot([self.previous_means[i, 0], self.new_means[i, 0]],
                                 [self.previous_means[i, 1], self.new_means[i, 1]],
                                 [self.previous_means[i, 2], self.new_means[i, 2]],
                                 label='mean movement' if iteration_count == 1 else "", c=self.colors[i])
                    self.ax.scatter(self.new_means[i, 0], self.new_means[i, 1], self.new_means[i, 2], marker='o', c='g',
                                   label='new Means' if i == 0 and iteration_count == 1 else "")
            self.ax.legend(loc='upper right')
            # iteration_count += 1
            # self.fig.canvas.draw()
            
            ##################################################################################################################################
            # Plot the clustering results upon convergence
            ##################################################################################################################################
            if (abs(self.previous_means - self.new_means) < self.tolerance).all():
                cluster_pts = []
                division = self.sample_size // self.clusters

                if self.dimensions == 1:
                    for i in range(0, self.clusters):
                        indices = dist.assign_to_mean[dist.assign_to_mean == str(i + 1)]
                        cluster_pts.append(len(indices.index))
                        self.ax.scatter(self.sample_pts[0, indices.index], np.zeros((1, cluster_pts[i])), marker='*',
                                    label=f'predicted cluster {i + 1}')
                        self.ax.scatter(self.sample_pts[0, i * division:(i + 1) * division - 1], np.zeros((1, division - 1)),
                                    marker='o', facecolors='none', edgecolors=self.colors[i], s=200, linewidths=2,
                                    label=f'real cluster {i + 1}')
                elif self.dimensions == 2:
                    for i in range(0, self.clusters):
                        indices = dist.assign_to_mean[dist.assign_to_mean == str(i + 1)]
                        cluster_pts.append(len(indices.index))
                        self.ax.scatter(self.sample_pts[0, indices.index], self.sample_pts[1, indices.index], marker='*',
                                    label=f'predicted cluster {i + 1}')
                        self.ax.scatter(self.sample_pts[0, i * division:(i + 1) * division - 1],
                                    self.sample_pts[1, i * division:(i + 1) * division - 1],
                                    marker='o', facecolors='none', edgecolors=self.colors[i], s=200, linewidths=2,
                                    label=f'real cluster {i + 1}')
                elif self.dimensions == 3:
                    for i in range(0, self.clusters):
                        indices = dist.assign_to_mean[dist.assign_to_mean == str(i + 1)]
                        cluster_pts.append(len(indices.index))
                        self.ax.scatter(self.sample_pts[0, indices.index], self.sample_pts[1, indices.index], self.sample_pts[2, indices.index],
                                   marker='*',
                                   label=f'predicted cluster {i + 1}')
                        self.ax.scatter(self.sample_pts[0, i * division:(i + 1) * division - 1],
                                   self.sample_pts[1, i * division:(i + 1) * division - 1],
                                   self.sample_pts[2, i * division:(i + 1) * division - 1],
                                   marker='o', label=f'real cluster {i + 1}', s=40)
                        # facecolors='none', edgecolors=self.colors[i], s=200, linewidths=2)

                ##################################################################################################################################
                # set title with the clustering results and show legend
                ##################################################################################################################################
                if self.dimensions < 3:
                    self.ax.set_title('Number of points in each cluster are: ' + str(cluster_pts))
                    self.ax.legend(loc='upper right')
                else:
                    self.ax.text2D(0.05, 0.95, 'Number of points in each cluster are: ' + str(cluster_pts), transform=self.ax.transAxes)
                    self.ax.legend(loc='upper right')

Thông số hoạt hình

fps = 0.5

Writer = animation.writers['ffmpeg']
writer = Writer(fps=fps, metadata=dict(artist='Sai'), bitrate=1800)

Ví dụ 1D về K-Means đang hoạt động

max_iterations = 5

kmeans1d = kmeans(dimensions=1, sample_size=100, clusters=2, tolerance=1e-8, max_iters=max_iterations)
animation.FuncAnimation(kmeans1d.fig, kmeans1d.kmeans_iter, init_func=kmeans1d.kmeans_init ,frames=max_iterations, interval=(1/fps)*1000, repeat=False).save('../images/kmeans/kmeans_1D.mp4', writer=writer);

Trong video/hình ảnh động bên dưới ban đầu, các điểm dữ liệu trong không gian 1D thuộc hai cụm cùng với phương tiện được tạo ngẫu nhiên ban đầu được hiển thị. Sau đó, chuyển động của phương tiện được hiển thị và khi các giá trị trung bình được hội tụ, kết quả sẽ được hiển thị. Vì dữ liệu đang được tạo thủ công tại đây nên có khả năng xác minh mức độ chính xác của kết quả. Là bước cuối cùng để xác minh, các cụm được dự đoán/xác định cùng với các chi tiết được cho là cụm thực được hiển thị

Trong trường hợp cụ thể này, thuật toán K-Means phân cụm chính xác với 50 mẫu dữ liệu 1D của mỗi cụm trong số hai cụm

Video("../images/kmeans/kmeans_1D.mp4", embed=True)

Trình duyệt của bạn không hỗ trợ thẻ video

Ví dụ 2D về hoạt động của K-Means

________số 8

Giống như trường hợp trước, ở đây thay vì các mẫu dữ liệu 1D, các mẫu dữ liệu 2D đang được sử dụng để phân cụm với mục tiêu xác định 4 cụm trong dữ liệu. Sự di chuyển của một trong các giá trị Mean nếu lộn xộn/hỗn loạn vì khi Mean không thể liên kết với bất kỳ mẫu dữ liệu nào, vị trí của Mean lại được khởi tạo ngẫu nhiên, tính ngẫu nhiên này đảm bảo rằng sẽ tìm thấy chính xác 4 cụm ngay cả khi vị trí bắt đầu

Trong trường hợp này, chúng ta cũng có thể thấy rằng việc phân cụm không chính xác 100%, vì kết quả phân cụm cuối cùng dẫn đến các mẫu dữ liệu 150, 150, 152 và 148 được liên kết với từng cụm, lý tưởng nhất là giá trị chẵn 150 cho tất cả các cụm

Video("../images/kmeans/kmeans_2D.mp4", embed=True)

Trình duyệt của bạn không hỗ trợ thẻ video

Ví dụ 3D về hoạt động của K-Means

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()  # for plot styling
import numpy as np
0

Giống như các trường hợp trước, ở đây thay vì các mẫu dữ liệu 1D hoặc 2D, các mẫu dữ liệu 3D đang được sử dụng để phân cụm với mục tiêu xác định 3 cụm trong dữ liệu

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()  # for plot styling
import numpy as np
1

Trình duyệt của bạn không hỗ trợ thẻ video

Nhận xét

Trong sổ ghi chép bài đăng/jupyter này, thước đo khoảng cách được sử dụng là "khoảng cách cartesian", nhưng cũng có thể sử dụng các thước đo khoảng cách khác như khoảng cách "cosine". Trong sổ ghi chép bài đăng/jupyter này, dữ liệu được sử dụng cũng là dữ liệu số được tạo ngẫu nhiên, nhưng khi dữ liệu ở dạng văn bản thì các chi tiết triển khai sẽ khác nhau

Làm cách nào để vẽ 3 cụm trong Python?

MatPlotLib với Python .
Đặt kích thước hình và điều chỉnh phần đệm giữa và xung quanh các ô con
Tạo các điểm dữ liệu x và y, Cụm và trung tâm bằng cách sử dụng numpy
Tạo một hình mới hoặc kích hoạt một hình hiện có
Thêm một sự sắp xếp ô con vào hình hiện tại
Vẽ các điểm dữ liệu phân tán bằng phương pháp phân tán ()

có thể k

K-Means++ xấp xỉ 𝟓. Nhanh hơn 𝟒𝟗𝙭 lần so với thuật toán Lloyd-Forgy ban đầu, trong khi được sử dụng để phân cụm các bộ dữ liệu nhiều chiều .

Làm cách nào để tự động hóa phân đoạn và phân cụm đám mây điểm 3D bằng Python?

DBSCAN lặp lại các điểm trong tập dữ liệu. .
Bước 1. Dữ liệu (đám mây điểm), luôn là dữ liệu 😁.
Bước 2. Thiết lập môi trường Python của bạn. .
Bước 3. Vòng phân loại đầu tiên. .
Bước 4. Mở rộng quy mô và tự động hóa

Tại sao k

K-means cần một khái niệm cụm dựa trên nguyên mẫu . DBSCAN cần một khái niệm dựa trên mật độ. K-means gặp khó khăn với các cụm không hình cầu và cụm nhiều kích cỡ. DBSCAN được sử dụng để xử lý các cụm có nhiều kích cỡ và cấu trúc và không bị ảnh hưởng mạnh bởi nhiễu hoặc ngoại lệ.