.net网站开发框架,如何做招聘网站的方案,商丘做网站汉狮网络,wordpress主题seo混合高斯模型聚类 #机器学习#人工智能#特征提取#特征融合#特征降维#聚类#分类器#无监督学习 [火]代码描述#xff1a; 1、导入数据#xff1b; 2、利用混合高斯模型对数据进行聚类。这是一个基于 混合高斯模型 (Gaussian Mixture Model, GMM) 的完整聚类代码。 代码特点…混合高斯模型聚类#机器学习#人工智能#特征提取#特征融合#特征降维#聚类#分类器#无监督学习[火]代码描述1、导入数据2、利用混合高斯模型对数据进行聚类。这是一个基于 混合高斯模型 (Gaussian Mixture Model, GMM) 的完整聚类代码。代码特点全流程覆盖包含数据导入、特征预处理标准化、GMM 聚类、结果可视化。自动寻优使用 BIC (贝叶斯信息准则) 和 AIC 自动寻找最佳的聚类数量 (K值)无需手动猜测分几类。概率输出GMM 是软聚类代码展示了如何获取每个样本属于各个类别的概率。可视化如果是2维数据直接绘制聚类分布椭圆如果是高维数据使用 PCA 降维后可视化。可替换数据内置了模拟数据生成器只需取消注释即可替换为你的 CSV/Excel 数据。Python 代码实现import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsfrom sklearn.mixture import GaussianMixturefrom sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCAfrom sklearn.metrics import silhouette_score, calinski_harabasz_scoreimport warnings忽略警告warnings.filterwarnings(‘ignore’)设置绘图风格sns.set(style“whitegrid”)plt.rcParams[‘font.sans-serif’] [‘SimHei’] # 用来正常显示中文标签plt.rcParams[‘axes.unicode_minus’] False # 用来正常显示负号数据导入与预处理def load_and_preprocess_data(file_pathNone):“”加载数据并进行标准化处理。如果 file_path 为 None则生成模拟数据用于演示。“”if file_path:print(f正在加载数据: {file_path})# 支持 csv, excel 等格式if file_path.endswith(‘.csv’):df pd.read_csv(file_path)elif file_path.endswith(‘.xlsx’):df pd.read_excel(file_path)else:raise ValueError(“不支持的文件格式请使用 .csv 或 .xlsx”)# 假设最后一列是标签如果有或者全部作为特征 # 这里假设所有列都是特征进行无监督聚类 X df.values feature_names df.columns.tolist() else: print(未提供文件正在生成模拟高斯混合数据...) # 生成模拟数据3个不同的高斯分布簇 np.random.seed(42) n_samples 600 # 簇 1 X1 np.random.multivariate_normal(mean[2, 2], cov[[1, 0.5], [0.5, 1]], sizen_samples//3) # 簇 2 X2 np.random.multivariate_normal(mean[-2, -2], cov[[1.5, 0], [0, 1.5]], sizen_samples//3) # 簇 3 X3 np.random.multivariate_normal(mean[2, -3], cov[[1, -0.5], [-0.5, 1]], sizen_samples//3) X np.vstack([X1, X2, X3]) feature_names [Feature_1, Feature_2] # 数据标准化 (GMM 对特征的尺度非常敏感必须标准化) scaler StandardScaler() X_scaled scaler.fit_transform(X) return X, X_scaled, feature_names确定最佳聚类数 (K)def find_best_k(X_scaled, k_rangerange(2, 8)):“”使用 BIC 和 AIC 准则寻找最佳的聚类数量 K。BIC/AIC 越小越好。“”bic_scores []aic_scores []silhouettes []print(n正在搜索最佳聚类数量 (K)...) for k in k_range: gmm GaussianMixture(n_componentsk, covariance_typefull, random_state42, n_init10) gmm.fit(X_scaled) bic_scores.append(gmm.bic(X_scaled)) aic_scores.append(gmm.aic(X_scaled)) # 计算轮廓系数 (Silhouette Score) 辅助评估 (越高越好) labels gmm.predict(X_scaled) if len(np.unique(labels)) 1: sil_score silhouette_score(X_scaled, labels) silhouettes.append(sil_score) else: silhouettes.append(-1) print(fK{k}: BIC{bic_scores[-1]:.2f}, AIC{aic_scores[-1]:.2f}, Silhouette{silhouettes[-1]:.3f}) # 找到 BIC 最小的 K best_k_idx np.argmin(bic_scores) best_k list(k_range)[best_k_idx] # 绘图展示寻优过程 plt.figure(figsize(10, 5)) plt.subplot(1, 2, 1) plt.plot(k_range, bic_scores, markero, labelBIC (越低越好)) plt.plot(k_range, aic_scores, markers, labelAIC (越低越好)) plt.xlabel(聚类数量 K) plt.ylabel(得分) plt.title(BIC/AIC 寻优曲线) plt.legend() plt.subplot(1, 2, 2) plt.plot(k_range, silhouettes, marker^, colorgreen, label轮廓系数 (越高越好)) plt.xlabel(聚类数量 K) plt.ylabel(得分) plt.title(轮廓系数评估) plt.legend() plt.tight_layout() plt.show() print(fn[结论] 基于 BIC 准则建议的最佳聚类数量 K {best_k}) return best_kGMM 聚类主函数def run_gmm_clustering(X_raw, X_scaled, n_components, feature_names):“”执行 GMM 聚类并可视化结果“”print(fn正在使用 K{n_components} 进行混合高斯模型聚类…)# 初始化模型 # covariance_type: full (每个簇有自己的通用协方差矩阵最灵活但参数多) # tied (所有簇共享同一个协方差矩阵) # diag (对角协方差计算快) # spherical (球状协方差) gmm GaussianMixture( n_componentsn_components, covariance_typefull, random_state42, n_init10, # 运行10次取最优避免局部最优 max_iter300, tol1e-4 ) # 训练模型 gmm.fit(X_scaled) # 预测类别 (硬聚类) labels gmm.predict(X_scaled) # 预测属于每个类别的概率 (软聚类) probabilities gmm.predict_proba(X_scaled) # 评估指标 if len(np.unique(labels)) 1: sil_score silhouette_score(X_scaled, labels) ch_score calinski_harabasz_score(X_scaled, labels) print(f聚类完成) print(f轮廓系数 (Silhouette): {sil_score:.4f} (范围 -1 到 1, 越接近 1 越好)) print(fCH 指数 (Calinski-Harabasz): {ch_score:.2f} (越大越好)) else: print(聚类失败所有样本被分到了同一类。) # # 4. 结果可视化 # visualize_results(X_raw, X_scaled, labels, gmm, n_components, feature_names, probabilities) # 返回结果 DataFrame results_df pd.DataFrame(X_raw, columnsfeature_names) results_df[Cluster_Label] labels # 添加概率列 (例如: Prob_Class_0, Prob_Class_1...) for i in range(n_components): results_df[fProb_Class_{i}] probabilities[:, i] return results_df, gmmdef visualize_results(X_raw, X_scaled, labels, gmm_model, n_components, feature_names, probabilities):“”可视化聚类结果。如果特征是2维直接画否则使用 PCA 降维到2维。“”# 决定使用哪些数据进行绘图if X_scaled.shape[1] 2:X_plot X_scaledx_label, y_label feature_names[0], feature_names[1]title_suffix “”else:# 降维到 2Dpca PCA(n_components2, random_state42)X_plot pca.fit_transform(X_scaled)x_label, y_label f’PC1 ({pca.explained_variance_ratio_[0]:.2%})‘, f’PC2 ({pca.explained_variance_ratio_[1]:.2%})’title_suffix (PCA 降维后)print(f数据维度 2已使用 PCA 降维可视化。解释方差比: {pca.explained_variance_ratio_.sum():.2%})plt.figure(figsize(10, 8)) # 1. 绘制样本点 scatter plt.scatter(X_plot[:, 0], X_plot[:, 1], clabels, cmapviridis, s50, alpha0.7, edgecolorsk, linewidth0.5) # 2. 绘制高斯分布的椭圆 (仅在 2D 情况下有意义) # 注意如果做了 PCA这里的协方差矩阵需要转换回 PCA 空间才能画得准确 # 为了简化演示如果做了 PCA我们只画点不画椭圆或者仅画中心点。 if X_scaled.shape[1] 2: covariances gmm_model.covariances_ means gmm_model.means_ for i in range(n_components): # 获取特征值和特征向量以绘制椭圆 v, w np.linalg.eigh(covariances[i]) v 2. * np.sqrt(2.) * np.sqrt(v) # 2标准差覆盖约95%的数据 u w[0] / np.linalg.norm(w[0]) angle np.arctan2(u[1], u[0]) angle 180. * angle / np.pi ell plt.matplotlib.patches.Ellipse(means[i], v[0], v[1], angleangle, colorscatter.cmap(i/n_components), fillFalse, linewidth2, linestyle--) ell.set_clip_box(plt.gca().bbox) plt.gca().add_artist(ell) # 绘制均值中心 plt.plot(means[i, 0], means[i, 1], rx, markersize15, markeredgewidth3) else: # 如果是降维后的图绘制映射后的中心点 means_pca pca.transform(gmm_model.means_) plt.scatter(means_pca[:, 0], means_pca[:, 1], cred, markerX, s200, edgecolorsblack, linewidths2, label聚类中心) plt.legend() plt.title(fGMM 聚类结果 (K{n_components}){title_suffix}, fontsize14) plt.xlabel(x_label) plt.ylabel(y_label) plt.colorbar(scatter, label类别 Label) plt.tight_layout() plt.show()主程序入口if name “main”:# — 步骤 1: 导入数据 —# 【用户操作区】如果你有数据文件将路径填在下面例如 ‘data.csv’# 如果留空 (None)程序将自动生成模拟数据运行DATA_FILE_PATH NoneX_raw, X_scaled, feature_names load_and_preprocess_data(DATA_FILE_PATH) # --- 步骤 2: 自动寻找最佳 K 值 --- # 搜索范围设为 2 到 8可根据数据量调整 best_k find_best_k(X_scaled, k_rangerange(2, 8)) # --- 步骤 3: 执行聚类 --- final_df, final_model run_gmm_clustering(X_raw, X_scaled, best_k, feature_names) # --- 步骤 4: 查看结果 --- print(n--- 前 5 条聚类结果预览 ---) print(final_df.head()) # 如果需要保存结果 # final_df.to_csv(gmm_clustering_result.csv, indexFalse) # print(结果已保存为 gmm_clustering_result.csv) # 展示某个样本属于各类别的概率 (软聚类特性) print(n--- 软聚类概率示例 (样本 0) ---) sample_probs final_df.iloc[0] print(sample_probs) print(f该样本最可能属于类别: {np.argmax(sample_probs.values)})如何使用这段代码准备环境确保安装了必要的库pip install numpy pandas matplotlib seaborn scikit-learn替换数据找到代码底部的 DATA_FILE_PATH None。将其修改为你的文件路径例如DATA_FILE_PATH ‘my_data.csv’。代码会自动读取 CSV 或 Excel 文件并将所有列视为特征进行聚类。核心功能解析自动寻优 (find_best_k)代码会尝试 K2 到 K7 的不同情况计算 BIC (贝叶斯信息准则)。BIC 越低说明模型在拟合度和复杂度之间取得了更好的平衡。程序会自动画出 BIC 曲线图帮你确认最佳 K 值。标准化 (StandardScaler)GMM 基于距离和概率密度如果特征的量纲不同例如一个是“年龄”一个是“收入”必须标准化否则结果会失真。代码已自动包含此步骤。软聚类 (predict_proba)与 K-Means 不同GMM 能告诉你一个样本有 70% 的概率属于 A 类30% 的概率属于 B 类。结果 DataFrame 中包含了 Prob_Class_X 列。可视化如果是 2维数据会画出漂亮的置信椭圆展示每个高斯分布的形状和方向。如果是 高维数据会自动使用 PCA 降维到 2 维进行展示并标出聚类中心。数据源X轴是“叶子长度”Petal LengthY轴是“叶子宽度”Petal Width。这是经典的 Iris 数据集特征。聚类结果分成了3类红色点、绿色点、蓝色点。等高线每个类别周围都有灰色的同心椭圆线这代表高斯分布的概率密度等高线。中心点每个类的中心有一个紫色的 号标记。图例左上角有清晰的图例区分了类别 1, 2, 3 以及 data1, data2这里可能是指代不同的分布组件或样本集但在标准 GMM 绘图中通常指代聚类簇。下面是能够完美复现这张图的 Python 代码。我使用了 sklearn 的 GaussianMixture 和 matplotlib 来绘制等高线和散点。Python 代码实现import numpy as npimport matplotlib.pyplot as pltimport seaborn as snsfrom sklearn import datasetsfrom sklearn.mixture import GaussianMixturefrom sklearn.preprocessing import StandardScalerimport warnings忽略警告warnings.filterwarnings(‘ignore’)设置绘图风格使其更像学术图表sns.set(style“whitegrid”)plt.rcParams[‘font.sans-serif’] [‘SimHei’] # 支持中文显示plt.rcParams[‘axes.unicode_minus’] Falsedef plot_gmm_contours(X, labels, gmm, feature_names):“”绘制 GMM 聚类结果及高斯分布等高线“”n_components gmm.n_componentscolors [‘red’, ‘green’, ‘blue’] # 对应图中的红绿蓝markers [‘o’, ‘s’, ‘^’] # 不同的标记形状fig, ax plt.subplots(figsize(8, 6)) # 1. 绘制散点 (样本) # 为了完全复现图片我们根据标签颜色绘制 for i in range(n_components): cluster_data X[labels i] ax.scatter(cluster_data[:, 0], cluster_data[:, 1], ccolors[i], markermarkers[i], s40, edgecolorsblack, linewidth0.5, labelf{i1}) # 2. 绘制均值中心 (图中的紫色 号) means gmm.means_ ax.scatter(means[:, 0], means[:, 1], cpurple, marker, s200, linewidths3, labeldata1) # 对应图例中的 data1 # 3. 绘制高斯等高线 # 生成网格数据 x_min, x_max X[:, 0].min() - 0.5, X[:, 0].max() 0.5 y_min, y_max X[:, 1].min() - 0.5, X[:, 1].max() 0.5 xx, yy np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100)) XX np.c_[xx.ravel(), yy.ravel()] # 计算每个网格点的概率密度 Z_prob gmm.predict_proba(XX) # 对每个分量绘制等高线 # 注意predict_proba 返回的是归一化后的概率要画单个高斯的等高线 # 最好直接计算该分量的 PDF或者利用协方差矩阵手动计算。 # 这里为了简化且效果接近我们利用协方差矩阵手动绘制椭圆等高线这样更精准控制形状。 covariances gmm.covariances_ for i in range(n_components): v, w np.linalg.eigh(covariances[i]) v 2. * np.sqrt(2.) * np.sqrt(v) # 2倍标准差覆盖约95% u w[0] / np.linalg.norm(w[0]) angle np.arctan2(u[1], u[0]) angle 180. * angle / np.pi # 创建椭圆 ell plt.matplotlib.patches.Ellipse(means[i], v[0], v[1], angleangle, colorgray, fillFalse, linewidth1) ax.add_artist(ell) # 为了画出多层等高线像图中那样我们可以缩放椭圆大小画几个 for scale in [0.5, 1.0, 1.5]: ell_scaled plt.matplotlib.patches.Ellipse(means[i], v[0scale, v[1]scale, angleangle, colorgray, fillFalse, linewidth0.8, linestyle--, alpha0.6) ax.add_artist(ell_scaled) # 添加图例 (模拟原图图例) # 原图图例有点特殊我们手动构造一下 from matplotlib.lines import Line2D custom_lines [ Line2D([0], [0], markero, colorw, markerfacecolorred, markersize10), Line2D([0], [0], markers, colorw, markerfacecolorgreen, markersize10), Line2D([0], [0], marker^, colorw, markerfacecolorblue, markersize10), Line2D([0], [0], marker, colorw, markeredgecolorpurple, markersize15, markeredgewidth2), Line2D([0], [0], colorgray, linewidth1) ] ax.legend(custom_lines, [1, 2, 3, data1, data2], locupper left, frameonTrue, facecolorwhite, edgecolorblack) # 设置标签和标题 ax.set_xlabel(feature_names[0], fontsize12) ax.set_ylabel(feature_names[1], fontsize12) ax.set_title(高斯模型等高线图, fontsize14) # 设置坐标轴范围 (尽量贴近原图) ax.set_xlim(0.5, 7.5) ax.set_ylim(0, 2.6) plt.tight_layout() plt.show()def main():print(“— 开始复现高斯模型等高线图 —”)# 1. 加载数据 (使用经典的 Iris 数据集) iris datasets.load_iris() # 选取花瓣长度 (index 2) 和 花瓣宽度 (index 3) 作为特征对应图中的 X 和 Y X iris.data[:, 2:4] feature_names [叶子长度, 叶子宽度] # 对应图中的中文标签 # 2. 数据标准化 (GMM 对尺度敏感虽然 Iris 量纲差不多但标准化是好习惯) scaler StandardScaler() X_scaled scaler.fit_transform(X) # 3. 训练 GMM 模型 # 假设我们要聚成 3 类 (Iris 通常有 3 个品种) n_components 3 gmm GaussianMixture(n_componentsn_components, covariance_typefull, random_state42, n_init10) gmm.fit(X_scaled) # 预测类别 labels gmm.predict(X_scaled) # 注意由于我们进行了标准化绘图时需要将均值和协方差逆变换回原始空间 # 或者直接将原始数据 X 传入绘图函数但在绘图函数内部用 scaled 数据计算逻辑。 # 为了简单且准确复现坐标轴数值原图是原始数值我们在绘图前将模型参数逆变换回来。 # 逆变换均值 means_original scaler.inverse_transform(gmm.means_) # 逆变换协方差 (Sigma_orig D * Sigma_scaled * D, D 是标准差对角阵) std_devs scaler.scale_ covariances_original np.empty_like(gmm.covariances_) for k in range(n_components): covariances_original[k] np.diag(std_devs).dot(gmm.covariances[k]).dot(np.diag(std_devs)) # 创建一个临时的 GMM 对象用于绘图填入逆变换后的参数 gmm_original_space GaussianMixture(n_componentsn_components, covariance_typefull) gmm_original_space.means_ means_original gmm_original_space.covariances_ covariances_original gmm_original_space.precisions_cholesky_ gmm.precisions_cholesky_ # 这个不影响绘图随便填 # 4. 绘图 plot_gmm_contours(X, labels, gmm_original_space, feature_names)if name “main”:main()代码关键点解析坐标轴还原GMM 训练时通常需要对数据进行标准化StandardScaler否则算法难以收敛。但是标准化后的数据坐标是均值为 0、方差为 1 的画出来的图坐标轴不对。技巧代码中在训练完成后使用 scaler.inverse_transform 将聚类中心Means和协方差矩阵Covariances从“标准化空间”逆变换回“原始数据空间”。这样画出来的椭圆和中心点其坐标值就是真实的“叶子长度”和“叶子宽度”例如 4.0 ~等高线绘制图中的灰色线条是高斯分布的等概率密度线。代码通过计算协方差矩阵的特征值和特征向量构建 matplotlib.patches.Ellipse 来绘制椭圆。图中“多层嵌套”的效果代码循环绘制了不同缩放比例0.5, 1.0, 1.5的椭圆。样式复刻颜色红、绿、蓝对应三个簇。标记圆形、方形、三角形区分不同簇的点。中心紫色的 号。字体设置了中文字体支持确保“叶子长度”、“叶子宽度”能正常显示。