尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

一个没有做完的工作

一个没有做完的工作 只是做一个记录后续还会修改这个代码来使用。20260318import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.preprocessing import StandardScaler, MinMaxScaler from sklearn.model_selection import train_test_split, cross_val_score from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier from sklearn.svm import SVC from sklearn.neighbors import KNeighborsClassifier from sklearn.linear_model import LogisticRegression from sklearn.metrics import r2_score, silhouette_score, davies_bouldin_score, classification_report, confusion_matrix from sklearn.decomposition import PCA import warnings warnings.filterwarnings(ignore) # 设置中文显示 plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, DejaVu Sans] plt.rcParams[axes.unicode_minus] False # 1. 数据加载和预处理 def load_and_prepare_data(file_path): 加载数据并准备特征 # 加载数据 data pd.read_csv(file_path) print(原始数据形状:, data.shape) print(\n前5行数据:) print(data.head()) # 选择需要的特征 features [评论, 收藏, 转发] # 检查特征是否存在 missing_features [f for f in features if f not in data.columns] if missing_features: print(f警告: 数据中缺少以下特征: {missing_features}) # 尝试使用可能的列名 possible_features { 评论: [评论数, 评论量, 评论数, comments, comment], 收藏: [收藏数, 收藏量, favorites, favorite], 转发: [转发数, 转发量, 转发次数, shares, share, reposts] } for missing in missing_features: for possible in possible_features[missing]: if possible in data.columns: features[features.index(missing)] possible print(f使用 {possible} 替代 {missing}) break # 提取特征 X data[features].copy() print(f\n使用的特征: {list(X.columns)}) # 数据清洗 print(f\n数据清洗前 - 缺失值数量:) print(X.isnull().sum()) # 填充缺失值如果有 X X.fillna(X.median()) # 检查0值 print(f\n0值统计:) for col in X.columns: zero_count (X[col] 0).sum() zero_percentage (zero_count / len(X)) * 100 print(f{col}: {zero_count}个0值 ({zero_percentage:.2f}%)) # 数据探索 print(f\n数据统计描述:) print(X.describe()) return data, X, features # 2. 数据标准化 def standardize_data(X): 标准化数据 # 由于数据中有0值使用StandardScaler scaler StandardScaler() X_scaled scaler.fit_transform(X) # 检查标准化后的数据 X_scaled_df pd.DataFrame(X_scaled, columnsX.columns) print(\n标准化后的数据统计:) print(X_scaled_df.describe()) return X_scaled, scaler # 3. 聚类分析无监督方法 def perform_clustering(X_scaled, n_clusters3): 使用多种聚类算法 clustering_results {} # 1. KMeans聚类 kmeans KMeans(n_clustersn_clusters, random_state42, n_init10) kmeans_labels kmeans.fit_predict(X_scaled) clustering_results[KMeans] { model: kmeans, labels: kmeans_labels, centers: kmeans.cluster_centers_ } # 2. 层次聚类 hierarchical AgglomerativeClustering(n_clustersn_clusters) hierarchical_labels hierarchical.fit_predict(X_scaled) clustering_results[Hierarchical] { model: hierarchical, labels: hierarchical_labels } # 3. DBSCAN聚类自动确定簇数 dbscan DBSCAN(eps0.5, min_samples5) dbscan_labels dbscan.fit_predict(X_scaled) clustering_results[DBSCAN] { model: dbscan, labels: dbscan_labels } return clustering_results # 4. 评估聚类结果 def evaluate_clustering(X_scaled, clustering_results): 评估不同聚类算法的效果 evaluation {} for name, result in clustering_results.items(): labels result[labels] # 跳过DBSCAN的噪声点标签为-1 if name DBSCAN: valid_mask labels ! -1 if sum(valid_mask) 0: X_valid X_scaled[valid_mask] labels_valid labels[valid_mask] if len(np.unique(labels_valid)) 1: silhouette silhouette_score(X_valid, labels_valid) db_index davies_bouldin_score(X_valid, labels_valid) else: silhouette -1 db_index 10 else: silhouette -1 db_index 10 else: silhouette silhouette_score(X_scaled, labels) db_index davies_bouldin_score(X_scaled, labels) n_clusters len(np.unique(labels[labels ! -1])) if name DBSCAN else len(np.unique(labels)) evaluation[name] { 轮廓系数: silhouette, DB指数: db_index, 簇数: n_clusters } return evaluation # 5. 分类算法如果有标签 def perform_classification(X, y, algorithmsNone): 使用多种分类算法 if algorithms is None: algorithms { 随机森林: RandomForestClassifier(n_estimators100, random_state42), 梯度提升: GradientBoostingClassifier(random_state42), K近邻: KNeighborsClassifier(n_neighbors5), 逻辑回归: LogisticRegression(max_iter1000, random_state42), SVM: SVC(kernelrbf, probabilityTrue, random_state42) } # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy ) # 标准化特征 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) results {} for name, model in algorithms.items(): # 训练模型 model.fit(X_train_scaled, y_train) # 预测 y_pred model.predict(X_test_scaled) y_pred_train model.predict(X_train_scaled) # 计算R²分数 r2_test r2_score(y_test, y_pred) r2_train r2_score(y_train, y_pred_train) # 交叉验证R² cv_scores cross_val_score(model, X_train_scaled, y_train, cv5, scoringr2) results[name] { 模型: model, 测试集R²: r2_test, 训练集R²: r2_train, 交叉验证R²均值: np.mean(cv_scores), 交叉验证R²标准差: np.std(cv_scores), 预测值: y_pred, 真实值: y_test } print(f\n{name}:) print(f 测试集R²: {r2_test:.4f}) print(f 训练集R²: {r2_train:.4f}) print(f 交叉验证R²: {np.mean(cv_scores):.4f} (±{np.std(cv_scores):.4f})) return results, (X_train_scaled, X_test_scaled, y_train, y_test) # 6. 可视化函数 def visualize_results(data, X, X_scaled, clustering_results, classification_resultsNone): 可视化结果 # 1. 原始数据分布 fig, axes plt.subplots(2, 3, figsize(15, 10)) # 原始数据分布 for i, col in enumerate(X.columns): axes[0, i].hist(X[col], bins30, alpha0.7, colorskyblue, edgecolorblack) axes[0, i].set_title(f{col}分布) axes[0, i].set_xlabel(值) axes[0, i].set_ylabel(频数) # 2. 特征相关性 correlation X.corr() im axes[1, 0].imshow(correlation, cmapcoolwarm, vmin-1, vmax1) axes[1, 0].set_title(特征相关性热图) axes[1, 0].set_xticks(range(len(X.columns))) axes[1, 0].set_yticks(range(len(X.columns))) axes[1, 0].set_xticklabels(X.columns, rotation45) axes[1, 0].set_yticklabels(X.columns) plt.colorbar(im, axaxes[1, 0]) # 3. 三维散点图如果使用聚类 if clustering_results: from mpl_toolkits.mplot3d import Axes3D # 使用KMeans结果 labels clustering_results.get(KMeans, {}).get(labels, None) if labels is not None: # 使用PCA降维到2D用于可视化 pca PCA(n_components2) X_pca pca.fit_transform(X_scaled) axes[1, 1].scatter(X_pca[:, 0], X_pca[:, 1], clabels, cmapviridis, alpha0.6) axes[1, 1].set_title(KMeans聚类结果 (PCA降维)) axes[1, 1].set_xlabel(主成分1) axes[1, 1].set_ylabel(主成分2) # 4. 各算法R²比较如果有分类结果 if classification_results: ax axes[1, 2] algorithms list(classification_results.keys()) r2_scores [classification_results[alg][测试集R²] for alg in algorithms] bars ax.bar(algorithms, r2_scores, color[skyblue, lightgreen, lightcoral, gold, violet]) ax.set_title(各分类算法R²分数比较) ax.set_ylabel(R²分数) ax.set_ylim(0, 1) ax.set_xticklabels(algorithms, rotation45, haright) # 在柱子上添加数值 for bar, score in zip(bars, r2_scores): height bar.get_height() ax.text(bar.get_x() bar.get_width()/2., height 0.01, f{score:.3f}, hacenter, vabottom, fontsize9) plt.tight_layout() plt.show() # 5. 聚类中心可视化 if KMeans in clustering_results: kmeans_result clustering_results[KMeans] centers kmeans_result[centers] fig, axes plt.subplots(1, 3, figsize(15, 4)) # 对每个特征显示聚类中心 for i, col in enumerate(X.columns): cluster_means centers[:, i] axes[i].bar(range(len(cluster_means)), cluster_means, color[red, green, blue][:len(cluster_means)]) axes[i].set_title(f{col} - 聚类中心值) axes[i].set_xlabel(聚类) axes[i].set_ylabel(标准化值) axes[i].set_xticks(range(len(cluster_means))) axes[i].set_xticklabels([f聚类{j} for j in range(len(cluster_means))]) plt.tight_layout() plt.show() # 7. 生成最终结果报告 def generate_report(data, X, clustering_eval, classification_resultsNone): 生成分析报告 print( * 60) print(新闻热度分析报告) print( * 60) print(f\n1. 数据概况:) print(f 样本数量: {len(data)}) print(f 特征数量: {len(X.columns)}) print(f 使用的特征: {list(X.columns)}) print(f\n2. 数据统计:) for col in X.columns: print(f {col}: 均值{X[col].mean():.2f}, 中位数{X[col].median():.2f}, f最小值{X[col].min():.2f}, 最大值{X[col].max():.2f}) print(f\n3. 聚类算法评估:) for algo, metrics in clustering_eval.items(): print(f {algo}:) print(f 轮廓系数: {metrics[轮廓系数]:.4f} (越大越好-1到1)) print(f DB指数: {metrics[DB指数]:.4f} (越小越好)) print(f 簇数: {metrics[簇数]}) if classification_results: print(f\n4. 分类算法R²分数比较:) # 按测试集R²排序 sorted_results sorted(classification_results.items(), keylambda x: x[1][测试集R²], reverseTrue) for name, result in sorted_results: print(f {name}:) print(f 测试集R²: {result[测试集R²]:.4f}) print(f 训练集R²: {result[训练集R²]:.4f}) print(f 交叉验证R²: {result[交叉验证R²均值]:.4f} (±{result[交叉验证R²标准差]:.4f})) # 推荐最佳算法 best_algo sorted_results[0][0] print(f\n5. 推荐算法: {best_algo}) print(f 理由: 在测试集上获得最高的R²分数 ({classification_results[best_algo][测试集R²]:.4f})) print(f\n6. 建议:) print(f - 如果数据量较大且特征间有复杂关系推荐使用随机森林或梯度提升) print(f - 如果数据量较小推荐使用逻辑回归或K近邻) print(f - 如果追求可解释性推荐使用逻辑回归) print(f - 如果追求最高准确率推荐使用梯度提升) # 8. 主函数 def main(): 主函数 # 请替换为您的数据文件路径 file_path news_data.csv # 请修改为您的文件路径 try: # 1. 加载和准备数据 print(步骤1: 加载和准备数据) data, X, features load_and_prepare_data(file_path) # 2. 标准化数据 print(\n步骤2: 标准化数据) X_scaled, scaler standardize_data(X) # 3. 聚类分析 print(\n步骤3: 进行聚类分析) clustering_results perform_clustering(X_scaled, n_clusters3) # 4. 评估聚类 print(\n步骤4: 评估聚类结果) clustering_evaluation evaluate_clustering(X_scaled, clustering_results) # 5. 使用KMeans聚类结果作为伪标签进行分类算法比较 print(\n步骤5: 基于聚类结果进行分类算法比较) # 使用KMeans聚类结果作为标签 kmeans_labels clustering_results[KMeans][labels] # 映射标签到热度等级 (假设0:低, 1:中, 2:高) # 可以根据聚类中心的值调整映射 centers clustering_results[KMeans][centers] # 计算每个聚类的平均得分 cluster_scores [] for i in range(centers.shape[0]): # 对三个特征取平均值作为热度得分 score centers[i].mean() cluster_scores.append((i, score)) # 按得分排序确定热度等级 cluster_scores.sort(keylambda x: x[1]) label_mapping {} for rank, (cluster_idx, _) in enumerate(cluster_scores): label_mapping[cluster_idx] rank # 0:低, 1:中, 2:高 y np.array([label_mapping[label] for label in kmeans_labels]) # 检查标签分布 unique, counts np.unique(y, return_countsTrue) print(f\n热度等级分布:) for level, count in zip(unique, counts): level_name {0: 低, 1: 中, 2: 高}[level] percentage (count / len(y)) * 100 print(f 热度{level_name}: {count}条 ({percentage:.1f}%)) # 6. 使用多种分类算法 print(\n步骤6: 使用多种分类算法) classification_results, split_data perform_classification(X_scaled, y) # 7. 可视化结果 print(\n步骤7: 生成可视化结果) visualize_results(data, X, X_scaled, clustering_results, classification_results) # 8. 生成报告 print(\n步骤8: 生成分析报告) generate_report(data, X, clustering_evaluation, classification_results) # 9. 保存结果 print(\n步骤9: 保存结果) data[热度等级] y data[热度等级名称] data[热度等级].map({0: 低, 1: 中, 2: 高}) # 保存到新文件 output_file news_with_heat_level.csv data.to_csv(output_file, indexFalse, encodingutf-8-sig) print(f结果已保存到: {output_file}) # 显示前几条结果 print(f\n前10条新闻的热度等级:) result_sample data[[标题] features [热度等级名称]].head(10) print(result_sample.to_string(indexFalse)) except FileNotFoundError: print(f错误: 找不到文件 {file_path}) print(请确保文件路径正确或者使用以下示例数据:) # 创建示例数据 np.random.seed(42) n_samples 100 # 生成示例数据 example_data pd.DataFrame({ 标题: [f新闻{i1} for i in range(n_samples)], 评论: np.random.poisson(50, n_samples) np.random.randint(0, 20, n_samples), 收藏: np.random.poisson(30, n_samples) np.random.randint(0, 15, n_samples), 转发: np.random.poisson(20, n_samples) np.random.randint(0, 10, n_samples) }) # 添加一些异常值 example_data.loc[0:5, 评论] [200, 180, 160, 0, 0, 5] example_data.loc[0:5, 收藏] [100, 90, 80, 0, 0, 3] example_data.loc[0:5, 转发] [80, 70, 60, 0, 0, 2] # 保存示例数据 example_data.to_csv(example_news_data.csv, indexFalse, encodingutf-8-sig) print(f已生成示例数据: example_news_data.csv) print(请修改代码中的文件路径为 example_news_data.csv 并重新运行) # 运行主函数 if __name__ __main__: main()
返回列表