
如何高效爬取全球新闻网站 – 整合Scrapy、Selenium与Mediastack API实现自动化新闻采集
先来简单说说K-均值聚类是什么吧。
K-均值聚类 主要用于将数据分成几个组(称为簇)。它的名字里有个“K”,就是你要提前告诉算法你想把数据分成几组。
下面举一个通俗易懂的例子,很容易可以理解~
目的:K-均值聚类的目的是让同一组的学生(数据点)在身高体重(特征)上尽量相似,不同组之间的学生在身高体重上尽量不同。
优点很明显,理解起来简单易懂,计算起来速度快。而且对大部分常见的分组问题效果不错。
有些缺点可以容忍,需要提前指定K值(组数)。对于初始中心点的选择敏感,有时候结果不太稳定。最致命的,如果数据本身有明显的噪声或者异常点,效果可能不太好。
总之,K-均值聚类是一种把数据分组的方法,它通过找到每组数据的中心点,并不断调整这些中心点的位置,来达到分组的目的。
1. 目标函数
K-均值聚类的目标是最小化每个簇内样本到簇中心的距离之和。用数学符号表示,即最小化以下目标函数:
其中:
2. 质心的计算
质心是簇内所有点的平均值。第 个簇的质心 的计算公式为:
其中 是簇 中的样本点数量。
算法流程
将 分配到最近的质心所对应的簇 :
综上,K-均值聚类通过迭代优化,逐步最小化样本点到质心的距离平方和,达到将数据分成多个相似簇的目的。
我们来进行一个完整的K-均值聚类实际案例示例。
还是使用经典的鸢尾花数据集(Iris Dataset),这个数据集包含150个样本,每个样本有4个特征:花萼长度、花萼宽度、花瓣长度和花瓣宽度。此外,每个样本还标注了其所属的花的品种(鸢尾花的三种品种:Iris-setosa、Iris-versicolor和Iris-virginica)。
完整代码,大家可以根据注释进行理解,后面可以使用自己的数据集进行实现,加强理解。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
# 将数据集转换为DataFrame,便于处理
df = pd.DataFrame(X, columns=feature_names)
df['target'] = y
# 数据可视化
sns.pairplot(df, hue='target', markers=["o", "s", "D"])
plt.suptitle('Iris Data Pair Plot', y=1.02)
plt.show()
# 使用PCA进行降维到2D,以便于可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
df_pca = pd.DataFrame(X_pca, columns=['PCA1', 'PCA2'])
df_pca['target'] = y
# 可视化降维后的数据
plt.figure(figsize=(10, 6))
sns.scatterplot(x='PCA1', y='PCA2', hue='target', data=df_pca, palette='deep', markers=["o", "s", "D"])
plt.title('PCA of Iris Dataset')
plt.show()
# 确定最优的簇数
inertia = []
silhouette_scores = []
K_range = range(2, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(X)
inertia.append(kmeans.inertia_)
score = silhouette_score(X, kmeans.labels_)
silhouette_scores.append(score)
# 绘制肘部法图和轮廓系数图
fig, ax1 = plt.subplots(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.plot(K_range, inertia, 'bo-')
plt.xlabel('Number of clusters (k)')
plt.ylabel('Inertia')
plt.title('Elbow Method For Optimal k')
plt.subplot(1, 2, 2)
plt.plot(K_range, silhouette_scores, 'bo-')
plt.xlabel('Number of clusters (k)')
plt.ylabel('Silhouette Score')
plt.title('Silhouette Scores For Optimal k')
plt.show()
# 选择最优簇数并进行K-均值聚类
optimal_k = 3 # 根据肘部法和轮廓系数选择
kmeans = KMeans(n_clusters=optimal_k, random_state=42)
kmeans.fit(X)
labels = kmeans.labels_
# 将聚类结果加入到DataFrame
df_pca['cluster'] = labels
# 可视化聚类结果
plt.figure(figsize=(10, 6))
sns.scatterplot(x='PCA1', y='PCA2', hue='cluster', data=df_pca, palette='deep', markers=["o", "s", "D"])
plt.title('K-means Clustering of Iris Dataset')
plt.show()
# 打印聚类中心
centroids = kmeans.cluster_centers_
centroids_df = pd.DataFrame(centroids, columns=feature_names)
print("Cluster Centers (Centroids):\n", centroids_df)
# 打印轮廓系数
final_silhouette_score = silhouette_score(X, labels)
print(f"Final Silhouette Score: {final_silhouette_score}")
其中需要注意的几个步骤:
算法优化方面,可以考虑三方面:
1. 初始质心选择优化:使用k-means++
算法来优化初始质心的选择,从而提高聚类的稳定性和准确性。
kmeans = KMeans(n_clusters=optimal_k, init='k-means++', random_state=42)
2. 数据标准化:在聚类之前,对数据进行标准化处理,使得每个特征的均值为0,方差为1。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
3. 重复实验:运行多次K-均值聚类,并选择最小的目标函数值对应的聚类结果。
kmeans = KMeans(n_clusters=optimal_k, init='k-means++', n_init=10, random_state=42)
通过整个的代码和优化策略,大家可以感受整个过程。代码中,实现了鸢尾花数据集的聚类分析,并且通过可视化、评估指标等手段对聚类效果进行了详细的评估和优化。
优点:
缺点:
K-均值聚类 vs 层次聚类(Hierarchical Clustering):
K-均值聚类 vs 密度聚类(Density-Based Clustering,如DBSCAN):
K-均值聚类适用情况:
考虑其他算法的情况:
K-均值聚类是一种简单且有效的聚类算法,特别适合处理大规模数据集和具有明显球状分布的数据。在选择算法时,需要根据数据的特点(如簇的形状、数据量、簇数量的确定性等)来权衡不同算法的优缺点,以达到最佳的聚类效果。
本文章转载微信公众号@深夜努力写Python