Python实战开发及案例分析(27)—— 均值算法

        均值算法通常指的是用于聚类的k-均值(k-means)算法。k-means是一种常见的无监督学习算法,用于将数据集划分为k个不同的簇(cluster),使得同一簇内的数据点彼此相似而不同簇间的数据点差异较大。

k-means算法的基本步骤

  1. 初始化:随机选择k个初始质心(centroid)。
  2. 分配数据点:将每个数据点分配到最近的质心所在的簇中。
  3. 更新质心:计算每个簇的质心,即簇中所有点的平均值,更新质心的位置。
  4. 重复:重复步骤2和步骤3,直到质心位置不再变化或达到最大迭代次数。

Python实现k-means算法

        我们将使用Python和scikit-learn库来实现k-means算法,并通过一个具体的案例来展示其应用。

步骤一:加载数据和库

        首先,我们需要加载必要的库和数据集。在本例中,我们将使用一个简单的二维数据集进行聚类。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans

# 生成示例数据
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# 可视化数据
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.show()
步骤二:使用k-means进行聚类

        接下来,我们使用scikit-learn中的KMeans类进行聚类。

# 创建k-means模型
kmeans = KMeans(n_clusters=4)

# 训练模型
kmeans.fit(X)

# 预测簇标签
y_kmeans = kmeans.predict(X)

# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')

centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='x')
plt.show()

案例分析:客户分群

        假设我们有一个客户数据集,其中包含客户的年收入和消费分数。我们希望通过k-means聚类将客户分为不同的群组,以便进行个性化营销。

数据加载和预处理

        我们使用一个示例数据集,其中包含客户的年收入和消费分数。

import pandas as pd

# 生成示例客户数据
np.random.seed(42)
income = np.random.normal(50000, 15000, 100)
spending_score = np.random.normal(50, 10, 100)
data = {'Income': income, 'Spending_Score': spending_score}
df = pd.DataFrame(data)

# 可视化数据
plt.scatter(df['Income'], df['Spending_Score'], s=50)
plt.xlabel('Annual Income')
plt.ylabel('Spending Score')
plt.show()
使用k-means进行客户分群
# 提取特征
X = df[['Income', 'Spending_Score']].values

# 创建并训练k-means模型
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
y_kmeans = kmeans.predict(X)

# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='x')
plt.xlabel('Annual Income')
plt.ylabel('Spending Score')
plt.show()

结果分析

        通过k-means聚类,我们将客户数据集分为了3个不同的群组。每个群组代表具有相似年收入和消费分数的客户群体。这种分群可以帮助我们进行更加有针对性的营销策略,如为高收入高消费的客户提供高级会员服务,为低收入低消费的客户提供优惠活动等。

总结

        k-means算法是一种简单且高效的聚类方法,广泛应用于各个领域的聚类分析。通过Python和scikit-learn库,我们可以方便地实现k-means聚类,并通过具体案例展示其在客户分群中的应用。通过合理选择k值和理解数据的结构,k-means算法能够有效地揭示数据中的模式和群组特性。

        继续探讨 k-means 算法在更多应用领域中的应用,我们可以通过更多的优化和扩展技术来增强其性能和适用性。这包括处理高维数据、使用 k-means++ 进行初始质心选择,以及利用 k-means 进行图像压缩和文档聚类等。

优化 k-means 算法

  1. k-means++ 初始质心选择
    • k-means++ 是一种改进的质心初始化方法,可以显著提高 k-means 的收敛速度和聚类质量。它通过选择具有最大最小距离的点作为初始质心,避免了随机初始化导致的收敛缓慢和局部最优问题。
from sklearn.cluster import KMeans

# 使用 k-means++ 进行初始质心选择
kmeans_plus = KMeans(n_clusters=3, init='k-means++')
kmeans_plus.fit(X)
y_kmeans_plus = kmeans_plus.predict(X)

# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans_plus, s=50, cmap='viridis')
centers = kmeans_plus.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='x')
plt.xlabel('Annual Income')
plt.ylabel('Spending Score')
plt.show()
  1. 处理高维数据
    • 高维数据通常会面临维度灾难的问题,可以通过降维技术(如 PCA、t-SNE)来降低数据的维度,同时保留主要特征。
from sklearn.decomposition import PCA

# 使用 PCA 将数据降维到 2 维
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

# 进行 k-means 聚类
kmeans_pca = KMeans(n_clusters=3)
kmeans_pca.fit(X_pca)
y_kmeans_pca = kmeans_pca.predict(X_pca)

# 可视化结果
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y_kmeans_pca, s=50, cmap='viridis')
centers = kmeans_pca.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='x')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()

扩展 k-means 算法的应用

  1. 图像压缩
    • k-means 可以用于图像压缩,通过将图像的像素颜色值聚类为 k 个类别,并用这些类别的质心值替代原始像素值,从而减少图像的颜色种类,达到压缩效果。
from sklearn.cluster import KMeans
import numpy as np
import matplotlib.pyplot as plt
from skimage import io

# 读取图像
image = io.imread('image_path.jpg')
image = np.array(image, dtype=np.float64) / 255

# 将图像展平成二维数组,每一行是一个像素点
w, h, d = image.shape
image_array = np.reshape(image, (w * h, d))

# 使用 k-means 聚类像素点颜色
kmeans = KMeans(n_clusters=64, random_state=0).fit(image_array)
labels = kmeans.predict(image_array)

# 用质心颜色替换原始颜色
image_compressed = kmeans.cluster_centers_[labels]
image_compressed = np.reshape(image_compressed, (w, h, d))

# 显示压缩后的图像
plt.figure(figsize=(8, 4))
plt.subplot(121)
plt.title('Original Image')
plt.imshow(image)
plt.axis('off')
plt.subplot(122)
plt.title('Compressed Image with 64 colors')
plt.imshow(image_compressed)
plt.axis('off')
plt.show()
  1. 文档聚类
    • k-means 可以用于文档聚类,通过将文本向量化(如使用TF-IDF),然后进行聚类分析,发现文档之间的隐藏关系。
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans

# 示例文档
documents = [
    "Machine learning is fascinating.",
    "Artificial intelligence and machine learning are closely related.",
    "Deep learning is a subset of machine learning.",
    "We use machine learning in many fields.",
    "Artificial intelligence is the future.",
    "Deep learning algorithms are powerful.",
]

# 将文档转为 TF-IDF 特征向量
vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(documents)

# 使用 k-means 进行文档聚类
kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
labels = kmeans.labels_

# 输出聚类结果
for i, label in enumerate(labels):
    print(f"Document {i+1}: Cluster {label}")

总结

        通过优化 k-means 算法的初始质心选择和降维处理,我们可以大大提高其效率和聚类质量。此外,k-means 的应用非常广泛,从简单的二维数据聚类,到图像压缩和文档聚类等复杂场景,都可以有效利用这一算法来揭示数据中的结构和模式。通过不断的实践和调整,k-means 算法能够在多种领域中发挥重要作用。

继续探讨k-means算法在更多实际应用中的扩展,以及进一步的优化策略和案例分析,我们可以通过一些高级方法和技术来提高k-means算法的效率和效果。以下内容包括一些更复杂的案例分析以及k-means算法的改进版本。

k-means++ 初始化的详细分析

        k-means++是k-means算法的改进版,它通过优化初始质心选择来提高算法的收敛速度和聚类质量。

k-means++ 初始化步骤
  1. 选择第一个质心:从数据点中随机选择一个点作为第一个质心。
  2. 选择下一个质心:对每个数据点计算其与最近已选择质心的距离,选择一个点作为新的质心,选择的概率与该距离的平方成正比。
  3. 重复步骤2:直到选择了k个质心。
import numpy as np
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

# 生成示例数据
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# k-means++ 初始化
def kmeans_plus_plus(X, k):
    n_samples, _ = X.shape
    centers = np.zeros((k, X.shape[1]))

    # 选择第一个质心
    centers[0] = X[np.random.randint(n_samples)]
    
    # 选择其余的质心
    for i in range(1, k):
        distances = np.min([np.sum((X - centers[j])**2, axis=1) for j in range(i)], axis=0)
        probabilities = distances / np.sum(distances)
        cumulative_probabilities = np.cumsum(probabilities)
        r = np.random.rand()
        index = np.searchsorted(cumulative_probabilities, r)
        centers[i] = X[index]
    
    return centers

k = 4
centers = kmeans_plus_plus(X, k)

# 可视化初始质心
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.75, marker='x')
plt.title('k-means++ Initial Centers')
plt.show()

图像分割

        k-means算法可以用于图像分割,通过将图像的像素聚类为不同的簇,从而达到分割图像的效果。

示例:图像分割        
from sklearn.cluster import KMeans
import cv2

# 读取图像
image = cv2.imread('path_to_image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 将图像数据重塑为二维数组
pixel_values = image.reshape((-1, 3))
pixel_values = np.float32(pixel_values)

# 定义 k-means 参数
k = 3
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)

# 应用 k-means
_, labels, centers = cv2.kmeans(pixel_values, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
centers = np.uint8(centers)
segmented_image = centers[labels.flatten()]

# 重塑图像为原始形状
segmented_image = segmented_image.reshape(image.shape)

# 显示原始图像和分割后的图像
plt.figure(figsize=(12, 6))
plt.subplot(121)
plt.title('Original Image')
plt.imshow(image)
plt.axis('off')
plt.subplot(122)
plt.title('Segmented Image')
plt.imshow(segmented_image)
plt.axis('off')
plt.show()

轮廓系数(Silhouette Coefficient)

        轮廓系数是一种评估聚类质量的方法,通过计算每个数据点与其所在簇的平均距离和与最近簇的平均距离来衡量聚类效果。

示例:计算轮廓系数        
from sklearn.metrics import silhouette_score

# 训练 k-means 模型
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
labels = kmeans.labels_

# 计算轮廓系数
score = silhouette_score(X, labels)
print(f'Silhouette Coefficient: {score}')

DBSCAN(密度聚类)

        DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它可以识别噪声点和发现任意形状的簇。相比于k-means,DBSCAN不需要预先指定簇的数量。

示例:DBSCAN 聚类
from sklearn.cluster import DBSCAN

# 定义 DBSCAN 模型
dbscan = DBSCAN(eps=0.3, min_samples=10)

# 训练模型并预测标签
labels = dbscan.fit_predict(X)

# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')
plt.title('DBSCAN Clustering')
plt.show()

总结

        通过进一步优化和扩展,k-means 算法在实际应用中表现出色,特别是在图像处理和文档聚类等领域。此外,使用改进的初始化方法(如 k-means++)和评估技术(如轮廓系数),可以提高聚类质量和模型性能。而使用基于密度的聚类算法(如 DBSCAN),可以解决k-means在处理噪声和任意形状簇时的局限性。通过不断实践和调整,聚类算法能够更好地揭示数据中的结构和模式,为数据分析和挖掘提供有力支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贾贾乾杯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值