DAY 18 推断聚类后簇的类型

发布于:2025-07-27 ⋅ 阅读:(15) ⋅ 点赞:(0)

@浙大疏锦行聚类后的分析:推断簇的类型
知识点回顾:
1.推断簇含义的2个思路:先选特征和后选特征
2.通过可视化图形借助ai定义簇的含义
3.科研逻辑闭环:通过精度判断特征工程价值
作业:参考示例代码对心脏病数据集采取类似操作,并且评估特征工程后模型效果有无提升。
 

# 先运行之前预处理好的代码
import pandas as pd
import pandas as pd  # 用于数据处理和分析,可处理表格数据。
import numpy as np  # 用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt  # 用于绘制各种类型的图表
import seaborn as sns  # 基于matplotlib的高级绘图库,能绘制更美观的统计图形。
import warnings

warnings.filterwarnings("ignore")

# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号
data = pd.read_csv('data.csv')  # 读取数据

# 先筛选字符串变量
discrete_features = data.select_dtypes(include=['object']).columns.tolist()
# Home Ownership 标签编码
home_ownership_mapping = {
    'Own Home': 1,
    'Rent': 2,
    'Have Mortgage': 3,
    'Home Mortgage': 4
}
data['Home Ownership'] = data['Home Ownership'].map(home_ownership_mapping)

# Years in current job 标签编码
years_in_job_mapping = {
    '< 1 year': 1,
    '1 year': 2,
    '2 years': 3,
    '3 years': 4,
    '4 years': 5,
    '5 years': 6,
    '6 years': 7,
    '7 years': 8,
    '8 years': 9,
    '9 years': 10,
    '10+ years': 11
}
data['Years in current job'] = data['Years in current job'].map(years_in_job_mapping)

# Purpose 独热编码,记得需要将bool类型转换为数值
data = pd.get_dummies(data, columns=['Purpose'])
data2 = pd.read_csv("data.csv")  # 重新读取数据,用来做列名对比
list_final = []  # 新建一个空列表,用于存放独热编码后新增的特征名
for i in data.columns:
    if i not in data2.columns:
        list_final.append(i)  # 这里打印出来的就是独热编码后的特征名
for i in list_final:
    data[i] = data[i].astype(int)  # 这里的i就是独热编码后的特征名

# Term 0 - 1 映射
term_mapping = {
    'Short Term': 0,
    'Long Term': 1
}
data['Term'] = data['Term'].map(term_mapping)
data.rename(columns={'Term': 'Long Term'}, inplace=True)  # 重命名列
continuous_features = data.select_dtypes(include=['int64', 'float64']).columns.tolist()  # 把筛选出来的列名转换成列表

# 连续特征用中位数补全
for feature in continuous_features:
    mode_value = data[feature].mode()[0]  # 获取该列的众数。
    data[feature].fillna(mode_value, inplace=True)  # 用众数填充该列的缺失值,inplace=True表示直接在原数据上修改。

# 最开始也说了 很多调参函数自带交叉验证,甚至是必选的参数,你如果想要不交叉反而实现起来会麻烦很多
# 所以这里我们还是只划分一次数据集
from sklearn.model_selection import train_test_split

X = data.drop(['Credit Default'], axis=1)  # 特征,axis=1表示按列删除
y = data['Credit Default']  # 标签
# # 按照8:2划分训练集和测试集
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns

# 标准化数据(聚类前通常需要标准化)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# X_scaled
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score, calinski_harabasz_score, davies_bouldin_score
import matplotlib.pyplot as plt
import seaborn as sns

# 评估不同 k 值下的指标
k_range = range(2, 11)  # 测试 k 从 2 到 10
inertia_values = []
silhouette_scores = []
ch_scores = []
db_scores = []

for k in k_range:
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans_labels = kmeans.fit_predict(X_scaled)
    inertia_values.append(kmeans.inertia_)  # 惯性(肘部法则)
    silhouette = silhouette_score(X_scaled, kmeans_labels)  # 轮廓系数
    silhouette_scores.append(silhouette)
    ch = calinski_harabasz_score(X_scaled, kmeans_labels)  # CH 指数
    ch_scores.append(ch)
    db = davies_bouldin_score(X_scaled, kmeans_labels)  # DB 指数
    db_scores.append(db)
    print(f"k={k}, 惯性: {kmeans.inertia_:.2f}, 轮廓系数: {silhouette:.3f}, CH 指数: {ch:.2f}, DB 指数: {db:.3f}")
# 提示用户选择 k 值
selected_k = 3 # 这里选择3后面好分析,也可以根据图选择最佳的k值

# 使用选择的 k 值进行 KMeans 聚类
kmeans = KMeans(n_clusters=selected_k, random_state=42)
kmeans_labels = kmeans.fit_predict(X_scaled)
X['KMeans_Cluster'] = kmeans_labels

# 使用 PCA 降维到 2D 进行可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# KMeans 聚类结果可视化
plt.figure(figsize=(6, 5))
sns.scatterplot(x=X_pca[:, 0], y=X_pca[:, 1], hue=kmeans_labels, palette='viridis')
plt.title(f'KMeans Clustering with k={selected_k} (PCA Visualization)')
plt.xlabel('PCA Component 1')
plt.ylabel('PCA Component 2')
plt.show()

# 打印 KMeans 聚类标签的前几行
print(f"KMeans Cluster labels (k={selected_k}) added to X:")
print(X[['KMeans_Cluster']].value_counts())






















print(X.columns)

x1= X.drop('KMeans_Cluster',axis=1) # 删除聚类标签列
y1 = X['KMeans_Cluster']
# 构建随机森林,用shap重要性来筛选重要性
import shap
import numpy as np
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
model = RandomForestClassifier(n_estimators=100, random_state=42)  # 随机森林模型
model.fit(x1, y1)  # 训练模型,此时无需在意准确率 直接全部数据用来训练了
#通过随机森林模型和 SHAP 值来分析哪些特征对聚类结果(簇)的区分最关键
#假设你已经用 K-Means 完成了聚类,给每个样本打上了 “簇标签”(存在X的KMeans_Cluster列中,比如 0、1、2 代表不同簇)。现在想知道:哪些原始特征最能解释这些簇的差异?
#SHAP 是一种解释模型的工具,能量化每个特征对 “区分簇” 的影响程度。比如计算后发现 “消费金额” 的 SHAP 值最高,说明这个特征最能解释不同簇的差异。
#通过这种方式,从所有原始特征中筛选出对聚类结果(簇)最关键的特征,后续就用这些特征来解释簇的含义(比如 “簇 0 的特点是消费金额高、购买频率低”)。
#让模型告诉我们 “哪些特征最能区分这些簇”,从而帮我们给簇起名字、赋予含义
shap.initjs()
# 初始化 SHAP 解释器
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(x1) # 这个计算耗时
print(shap_values.shape) # 第一维是样本数,第二维是特征数,第三维是类别数
"""
前面已经让 “智能识别器”(随机森林模型)学习了 “哪些苹果特点决定了它们分到 A/B/C 堆”。现在这段代码就是让这个识别器 “说人话”,告诉我们具体每个特点有多重要。
shap.initjs():相当于给电脑装一个 “翻译器”,让它能把复杂的计算结果变成我们能看懂的图表(不然之后画不出图)。
explainer = shap.TreeExplainer(model):给 “智能识别器” 配一个 “解说员”(SHAP 解释器),专门负责解释这个识别器是怎么判断苹果该分到哪堆的。
shap_values = explainer.shap_values(x1):让 “解说员” 分析所有苹果的特点(x1),计算出 “每个特点对分堆的影响程度”,结果存在 shap_values 里。比如:
“苹果大小” 这个特点,对 A 堆的影响值是 + 3(越大越可能进 A 堆)
“苹果甜度” 这个特点,对 B 堆的影响值是 - 2(越甜越不可能进 B 堆)
(计算起来费时间,所以代码注释说 “这个计算耗时”)
shap_values.shape:查看这个 “影响程度表” 的结构。比如结果是 (100,5,3),就表示:
有 100 个苹果(样本数)
有 5 个分析的特点(特征数)
有 3 个堆(类别数:A/B/C)
简单说,这段代码就是让电脑算出 “每个苹果特点对分堆的具体影响”,为后续搞清楚 “到底是什么特点区分了不同的堆” 做准备。
"""
# --- 1. SHAP 特征重要性条形图 (Summary Plot - Bar) ---
print("--- 1. SHAP 特征重要性条形图 ---")
shap.summary_plot(shap_values[:, :, 0], x1, plot_type="bar",show=False)  #  这里的show=False表示不直接显示图形,这样可以继续用plt来修改元素,不然就直接输出了
plt.title("SHAP Feature Importance (Bar Plot)")
plt.show()

# 此时判断一下这几个特征是离散型还是连续型
import pandas as pd
selected_features = ['Purpose_debt consolidation', 'Bankruptcies',
                     'Number of Credit Problems', 'Purpose_other']

for feature in selected_features:
    unique_count = X[feature].nunique() # 唯一值指的是在某一列或某个特征中,不重复出现的值
    # 连续型变量通常有很多唯一值,而离散型变量的唯一值较少
    print(f'{feature} 的唯一值数量: {unique_count}')
    if unique_count < 10:  # 这里 10 是一个经验阈值,可以根据实际情况调整
        print(f'{feature} 可能是离散型变量')
    else:
        print(f'{feature} 可能是连续型变量')
"""
这段代码的作用是**判断几个特定的特征(变量)是离散型还是连续型**,用的是一种简单直观的方法:通过统计每个特征中“不重复的值”(唯一值)的数量来区分。

咱们用通俗的方式解释:

1. 首先选了4个要分析的特征:`Purpose_debt consolidation`、`Bankruptcies`、`Number of Credit Problems`、`Purpose_other`。

2. 对每个特征做两件事:
   - 统计它有多少个“不重复的值”(比如“性别”特征只有“男”和“女”,唯一值数量就是2)。
   - 根据唯一值数量判断类型:
     - 如果唯一值数量少于10个(经验值),就认为是“离散型变量”(比如性别、学历这类值有限的特征)。
     - 如果唯一值数量多于或等于10个,就认为是“连续型变量”(比如年龄、收入这类可以取很多不同值的特征)。

3. 最后会打印出每个特征的判断结果,比如:
   - 假设`Bankruptcies`(破产次数)的唯一值只有0、1、2这3个,就会显示“可能是离散型变量”。
   - 假设某个特征有20个不同的值,就会显示“可能是连续型变量”。

简单说,这段代码就是用“特征值的丰富程度”来快速区分变量类型,帮我们更好地理解数据——因为离散型和连续型变量在后续分析(比如建模、可视化)中的处理方式是不同的。
"""
# X["Purpose_debt consolidation"].value_counts() # 统计每个唯一值的出现次数
import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

# 绘制出每个簇对应的这四个特征的分布图
X[['KMeans_Cluster']].value_counts()
# 分别筛选出每个簇的数据
X_cluster0 = X[X['KMeans_Cluster'] == 0]
X_cluster1 = X[X['KMeans_Cluster'] == 1]
X_cluster2 = X[X['KMeans_Cluster'] == 2]
"""
X_cluster0 = X[X['KMeans_Cluster'] == 0]:从原始数据X中,筛选出所有 “簇标签为 0” 的样本,单独存到X_cluster0里(这就是第一簇的所有数据)。
X_cluster1 = X[X['KMeans_Cluster'] == 1]:同理,筛选出 “簇标签为 1” 的样本,存到X_cluster1里(第二簇的数据)。
X_cluster2 = X[X['KMeans_Cluster'] == 2]:筛选出 “簇标签为 2” 的样本,存到X_cluster2里(第三簇的数据)。
"""
# 先绘制簇0的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster0[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

# 绘制簇1的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster1[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

# 绘制簇3的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster2[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()

作业

#作业
import pandas as pd
import pandas as pd  # 用于数据处理和分析,可处理表格数据。
import numpy as np  # 用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt  # 用于绘制各种类型的图表
import seaborn as sns  # 基于matplotlib的高级绘图库,能绘制更美观的统计图形。
import warnings
from sklearn.preprocessing import MinMaxScaler
warnings.filterwarnings("ignore")
# 显示所有列(解决列显示不全)
pd.set_option('display.max_columns', None)
# 显示所有行(如果数据行数不多,可开启;行数太多建议按需设置,比如 500)
pd.set_option('display.max_rows', None)
# 扩大每列的显示宽度(避免内容被截断)
pd.set_option('display.max_colwidth', 100)
# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号
data = pd.read_csv('heart.csv')  # 读取数据

# 先筛选字符串变量
discrete_features = data.select_dtypes(include=['object']).columns.tolist()
print(discrete_features)
continuous_features = []
for i in data.columns:
    if data[i].dtype != 'object':
        continuous_features.append(i)
print(continuous_features)
missing_values = data.isnull().sum()

from sklearn.ensemble import RandomForestClassifier #随机森林分类器

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 用于评估分类器性能的指标
from sklearn.metrics import classification_report, confusion_matrix #用于生成分类报告和混淆矩阵
import warnings #用于忽略警告信息
warnings.filterwarnings("ignore") # 忽略所有警告信息
from sklearn.model_selection import train_test_split

features = ['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg', 'thalach', 'exang', 'oldpeak', 'slope', 'ca', 'thal', 'target']

# 初始化归一化器
scaler = MinMaxScaler()

# 对选定列进行归一化
data[features] = scaler.fit_transform(data[features])

# 检查归一化后的数据
print(data.head())
from sklearn.model_selection import train_test_split

X = data.drop(['target'], axis=1)  # 特征,axis=1表示按列删除
y = data['target']  # 标签
# # 按照8:2划分训练集和测试集
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns

#KMeans 是基于距离的算法,如果特征的尺度差异大(比如一个特征是 “年龄”(0-100),另一个是 “收入”(0-10000)),距离会被大尺度特征主导,导致聚类结果失真。
#StandardScaler会把所有特征转换为 “均值 0、标准差 1” 的分布,让每个特征对距离的影响平等。
# 标准化数据(聚类前通常需要标准化)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# X_scaled

import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score, calinski_harabasz_score, davies_bouldin_score
import matplotlib.pyplot as plt
import seaborn as sns
# 评估不同 k 值下的指标
k_range = range(2, 11)  # 测试 k 从 2 到 10
#作用:测试聚类数k从2到10,因为k=1无意义。
inertia_values = []
silhouette_scores = []
ch_scores = []
db_scores = []
#作用:用于存储每个k值对应的评估结果,后续绘图用。

for k in k_range:
    kmeans = KMeans(n_clusters=k, random_state=42)
    kmeans_labels = kmeans.fit_predict(X_scaled)
    inertia_values.append(kmeans.inertia_)  # 惯性(肘部法则)
    silhouette = silhouette_score(X_scaled, kmeans_labels)  # 轮廓系数
    silhouette_scores.append(silhouette)
    ch = calinski_harabasz_score(X_scaled, kmeans_labels)  # CH 指数
    ch_scores.append(ch)
    db = davies_bouldin_score(X_scaled, kmeans_labels)  # DB 指数
    db_scores.append(db)
    print(f"k={k}, 惯性: {kmeans.inertia_:.2f}, 轮廓系数: {silhouette:.3f}, CH 指数: {ch:.2f}, DB 指数: {db:.3f}")
# 提示用户选择 k 值
selected_k = 3

# 使用选择的 k 值进行 KMeans 聚类
kmeans = KMeans(n_clusters=selected_k, random_state=42)
kmeans_labels = kmeans.fit_predict(X_scaled)
X['KMeans_Cluster'] = kmeans_labels

# 使用 PCA 降维到 2D 进行可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# KMeans 聚类结果可视化
plt.figure(figsize=(6, 5))
sns.scatterplot(x=X_pca[:, 0], y=X_pca[:, 1], hue=kmeans_labels, palette='viridis')
plt.title(f'KMeans Clustering with k={selected_k} (PCA Visualization)')
plt.xlabel('PCA Component 1')
plt.ylabel('PCA Component 2')
plt.show()

# 打印 KMeans 聚类标签的前几行
print(f"KMeans Cluster labels (k={selected_k}) added to X:")
print(X[['KMeans_Cluster']].value_counts())
print(X.columns)
x1= X.drop('KMeans_Cluster',axis=1) # 删除聚类标签列
y1 = X['KMeans_Cluster']
# 构建随机森林,用shap重要性来筛选重要性
import shap
import numpy as np
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
model = RandomForestClassifier(n_estimators=100, random_state=42)  # 随机森林模型
model.fit(x1, y1)  # 训练模型,此时无需在意准确率 直接全部数据用
shap.initjs()
# 初始化 SHAP 解释器
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(x1) # 这个计算耗时
shap_values.shape # 第一维是样本数,第二维是特征数,第三维是类别数
# --- 1. SHAP 特征重要性条形图 (Summary Plot - Bar) ---
print("--- 1. SHAP 特征重要性条形图 ---")
shap.summary_plot(shap_values[:, :, 0], x1, plot_type="bar",show=False)  #  这里的show=False表示不直接显示图形,这样可以继续用plt来修改元素,不然就直接输出了
plt.title("SHAP Feature Importance (Bar Plot)")
plt.show()
# 此时判断一下这几个特征是离散型还是连续型
import pandas as pd
selected_features = ['age','thalach','slope','sex']

for feature in selected_features:
    unique_count = X[feature].nunique() # 唯一值指的是在某一列或某个特征中,不重复出现的值
    # 连续型变量通常有很多唯一值,而离散型变量的唯一值较少
    print(f'{feature} 的唯一值数量: {unique_count}')
    if unique_count < 10:  # 这里 10 是一个经验阈值,可以根据实际情况调整
        print(f'{feature} 可能是离散型变量')
    else:
        print(f'{feature} 可能是连续型变量')
# X["Purpose_debt consolidation"].value_counts() # 统计每个唯一值的出现次数
import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()
print(X[['KMeans_Cluster']].value_counts())
# 分别筛选出每个簇的数据
X_cluster0 = X[X['KMeans_Cluster'] == 0]
X_cluster1 = X[X['KMeans_Cluster'] == 1]
X_cluster2 = X[X['KMeans_Cluster'] == 2]
# 先绘制簇0的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster0[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()
# 绘制簇1的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster1[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()
# 绘制簇2的分布图

import matplotlib.pyplot as plt

# 总样本中的前四个重要性的特征分布图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.flatten()

for i, feature in enumerate(selected_features):
    axes[i].hist(X_cluster2[feature], bins=20)
    axes[i].set_title(f'Histogram of {feature}')
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('Frequency')

plt.tight_layout()
plt.show()
cluster_onehot = pd.get_dummies(X['KMeans_Cluster'], prefix='Cluster')
X_original = X.drop('KMeans_Cluster', axis=1)
X_new = pd.concat([X_original, cluster_onehot], axis=1)
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
from sklearn.metrics import accuracy_score, classification_report

# 1. 划分训练集和测试集(用包含目标变量y的数据)
# 假设y是你要预测的标签(比如心脏病target)
X_train_new, X_test_new, y_train, y_test = train_test_split(X_new, y, test_size=0.2, random_state=42)

# 2. 训练“加了新特征”的随机森林模型
rf_new = RandomForestClassifier(n_estimators=100, random_state=42)
rf_new.fit(X_train_new, y_train)  # 用包含簇特征的数据训练

# 3. 预测并评估精度
y_pred_new = rf_new.predict(X_test_new)
new_accuracy = accuracy_score(y_test, y_pred_new)
print(f"加新特征后的精度:{new_accuracy:.4f}")

X_train_old, X_test_old, _, _ = train_test_split(X_original, y, test_size=0.2, random_state=42)
rf_old = RandomForestClassifier(n_estimators=100, random_state=42)
rf_old.fit(X_train_old, y_train)

# 评估基准模型精度
y_pred_old = rf_old.predict(X_test_old)
old_accuracy = accuracy_score(y_test, y_pred_old)
print(f"不加新特征的精度:{old_accuracy:.4f}")























网站公告

今日签到

点亮在社区的每一天
去签到