面向人工智能: 对红酒数据集进行分析 (实验四)

由于直接提供截图是不切实际的,我将详细解释如何使用scikit-learn(通常称为sk-learn)自带的红酒数据集进行葡萄酒数据的分析与处理。这包括实验要求的分析、数据的初步分析(完整性和重复性)以及特征之间的关联关系分析。

1. 分析实验要求

实验的主要目标是使用scikit-learn中的红酒数据集(通常是UCI机器学习库中的Wine Recognition dataset)来分析葡萄酒的化学成分与葡萄酒类型或质量之间的关系。通常,该数据集包含多种葡萄酒的化学成分(如酒精度、苹果酸含量等)以及葡萄酒的类别或质量评分。

2. 初步分析数据

2.1 加载数据

首先,你需要加载红酒数据集。在scikit-learn中,这可以通过load_wine函数完成。

# 导入必要的库  
from sklearn.datasets import load_wine  
import pandas as pd  
import matplotlib.pyplot as plt  
import seaborn as sns  
  
# 加载红酒数据集  
wine_data = load_wine()  
  
# 将数据转换为Pandas DataFrame  
df = pd.DataFrame(wine_data.data, columns=wine_data.feature_names)  
df['class'] = wine_data.target  # 将目标变量(葡萄酒的类别)添加到DataFrame中  
2.2 检查数据的完整性和重复性
  • 完整性:通过检查数据的形状(shape)和特征名称(feature_names)来验证数据是否完整。
# 检查数据的形状  
print("Data shape:", df.shape)  # 查看样本数量和特征数量 
  • 重复性:在大多数情况下,UCI数据集不会包含重复的样本。然而,为了确认,你可以使用Pandas库检查数据的唯一性。
# 检查是否有重复的行  
print("Number of duplicate rows:", df.duplicated().sum())  # 如果输出为0,则表示没有重复行

3. 分析实验数据各特征之间的关联关系

3.1 使用统计方法

使用Pandas的describe函数查看特征的统计描述,包括均值、标准差等,这些可以帮助你了解数据的分布情况。

print(df.describe())

3.2 绘制直方图和箱线图

绘制特征的直方图和箱线图,以观察特征的分布和可能的异常值。

# 绘制直方图  
df.iloc[:, :-1].hist(bins=30, figsize=(15, 10), layout=(4, 4)) 
plt.tight_layout()  
plt.show()  
  
# 使用subplots=True让matplotlib自动处理布局  
# df.iloc[:, :-1].hist(bins=30, figsize=(15, 15), layout=None, subplots=True)  
# plt.tight_layout()  # 尝试调整子图参数, 以便子图之间的重叠最小化  
# plt.show() 

# 绘制箱线图  
plt.figure(figsize=(10, 8))  
sns.boxplot(data=df.iloc[:, :-1])  
plt.title('Boxplot of Wine Dataset Features')  
plt.show()  

 subplots是一个用来控制自动处理布局的参数,但在这里是不适用的,因为hist 方法在 pandas 的 DataFrame 中并没有 subplots 参数。 subplots=True 是不适用于 pandas 的 hist 方法的,这是 matplotlib 中某些函数(如 subplot_mosaic 或在创建多个子图时)的参数。

为了在 pandas 中绘制多个特征的直方图,并且让 pandas 自动处理子图的布局,应该使用 subplots=True 的方式,但这不是通过 hist 方法的参数来实现的。相反,你需要调整 figsize 来确保图形足够大,以容纳所有特征的直方图。由于 pandas 的 hist 方法不直接支持复杂的子图布局,它通常会将所有直方图绘制在一个连续的网格中,或者可以通过迭代每列来手动创建子图。

为了简化这个过程,我们可以使用 pandas 的 hist 方法,并接受它自动选择的布局,或者我们可以使用 matplotlib 的子图功能来更精细地控制布局。

以下是使用 pandas hist 方法并调整 figsize 的示例:

(figsize:指定figure的宽和高,单位为英寸)

# 绘制特征分布的直方图  
fig, axes = plt.subplots(nrows=4, ncols=4, figsize=(15, 15))  # 假设4x4布局,但会有些空白  
axes = axes.flatten()  # 将二维数组转换为一维,以便迭代  
  
# 注意:如果特征数量不是16个,则以下循环将不会为所有特征绘制直方图  
# 或者,你可以根据特征数量动态调整nrows和ncols  
for i, feature in enumerate(df.columns[:-1]):  # 遍历除'class'之外的所有特征  
    if i < len(axes):  # 确保索引不会超出axes的长度  
        df[feature].hist(ax=axes[i], bins=30)  
        axes[i].set_title(feature)  
    else:  
        # 如果特征数量超过16个,你可以在这里添加代码来处理额外的特征  
        # 例如,创建一个新的图形或调整布局  
        break  
  
# 如果特征数量少于16个,可以移除多余的子图(可选)  
for ax in axes[len(df.columns[:-1]):]:  
    ax.remove()  
  
plt.tight_layout()  
plt.show()

上面的代码在特征数量不是16个时会留下空白的子图。一个更灵活的方法是使用 GridSpec 或类似的方法来动态地创建子图网格。不过,对于简单的用例,可能只需要调整 figsize 并接受 pandas hist 方法的默认布局。

如果只是想让 pandas 自动处理布局,并希望图形足够大以清晰显示所有直方图,可以这样做:

# 绘制特征分布的直方图,让pandas自动处理布局  
df.iloc[:, :-1].hist(bins=30, figsize=(15, 20))  # 调整figsize的高度以容纳更多直方图  
plt.tight_layout()  # 尝试调整子图参数,但效果可能有限  
plt.show()
3.3 计算特征之间的相关性

使用Pandas的corr函数计算特征之间的相关系数(如皮尔逊相关系数),以分析它们之间的线性关系。

# 计算特征之间的相关系数矩阵  
correlation_matrix = df.iloc[:, :-1].corr()  # 排除'class'列  
  
# 打印相关系数矩阵  
print("Correlation Matrix:")  
print(correlation_matrix)  
  
# 绘制热力图以更直观地查看相关性  
plt.figure(figsize=(10, 8))  
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')  
plt.title('Correlation Heatmap of Wine Dataset Features')  
plt.show()  

注意:

  1. pandas用于数据处理,matplotlib.pyplotseaborn用于数据可视化。
  2. 使用load_wine函数加载了红酒数据集,并将其转换为pandas.DataFrame以便于处理。
  3. 在分析特征之间的关联关系时,排除了目标变量'class'列,只计算了特征之间的相关系数。
  4. 绘制直方图和箱线图时,layout参数要根据特征数目进行相应的调整。如果特征数量不是3的倍数,可能需要调整layout参数或使用plt.subplots来更灵活地控制子图的布局。
  5. seabornheatmap函数用于绘制相关系数矩阵的热力图,它提供了直观的视觉表示来查看哪些特征之间存在强相关性

结果:

4.决策树模型:

(使用准确度和AUC指标进行模型评估)

准确度指标:
# 划分数据集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)  

# 训练模型  
clf = DecisionTreeClassifier(random_state=42)  
clf.fit(X_train, y_train)

# 预测测试集  
y_pred = clf.predict(X_test)  
  
# 评估模型(准确度)  
accuracy = accuracy_score(y_test, y_pred)  
print(f"Accuracy: {accuracy:.2f}")  
 AUC指标:
y_scores = clf.predict_proba(X_test)  # 获取每个类别的概率  
auc = roc_auc_score(y_test, y_scores, multi_class='ovr', average='macro')  
print(f"Macro-average AUC: {auc:.2f}")  
  • clf:这是一个已经训练好的分类器对象,在这个例子中,它是一个DecisionTreeClassifier实例。
  • .predict_proba(X_test):这是clf对象的一个方法,用于对给定的测试集X_test中的样本进行预测,但它不直接给出类标签(即预测结果所属的类别),而是给出每个样本属于各个类别的概率。这个方法返回一个二维数组,其中每一行对应X_test中的一个样本,每一列对应一个类别,元素值是该样本属于对应类别的概率。
  • y_scores:这个变量接收了.predict_proba(X_test)方法的返回值,即测试集中每个样本属于各个类别的概率。

第二行代码用于计算ROC曲线下的面积(AUC):

  • y_test:这是测试集的真实标签,即每个样本的实际类别。
  • y_scores:这是通过.predict_proba(X_test)得到的预测概率。
  • multi_class='ovr':这个参数指定了如何将多分类问题转换为多个二分类问题以计算AUC。'ovr'代表“一对一”(One-vs-Rest),即对于每个类别,都将其视为正类,其余所有类别视为负类,然后计算每个类别的ROC AUC,最后通过某种方式(如平均)汇总这些AUC值。
  • average='macro':这个参数指定了如何汇总每个类别的AUC值。'macro'意味着简单地计算所有类别AUC的未加权平均值。

AUC(Area Under the Curve)通常用于评估二分类问题的ROC曲线下的面积,但葡萄酒数据集是一个多分类问题。对于多分类问题,我们可以计算加权平均AUC(通过roc_auc_scoremulti_class参数设置为ovrovo),但更常见的做法是使用准确度、F1分数、混淆矩阵等指标。 

如果数据集是高度不平衡的,使用精确度-召回率曲线可能更加合适,因为它能更好地反映模型在少数类上的性能 。

结果:

5.随机森林:

# 划分数据集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)  
  
  
# 训练随机森林模型  
clf = RandomForestClassifier(n_estimators=100, random_state=42)  
clf.fit(X_train, y_train)  # 注意:ravel()将y_train从二维数组转换为一维数组  
  
#预测测试集的概率
y_score = clf.predict_proba(X_test)  
  
# 评估模型(准确度)
# 预测测试集的标签  
y_pred = clf.predict(X_test)  # 注意:这里使用原始标签的索引进行预测  
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")  
  

auc = roc_auc_score(y_test, y_score, multi_class='ovr', average='macro')  
print(f"Macro-average AUC: {auc:.2f}") 

 结果:

(居然准确度和AUC指标都是1!!怀疑)

如果你得到的准确度和AUC都为1,这通常意味着你的模型在测试集上表现得非常完美,几乎没有任何错误。然而,这种情况在实际应用中是非常罕见的,特别是当使用随机森林这样的集成学习方法时,因为数据集通常包含一些噪声或难以预测的样本。

不放心搜了一下出现这种情况的原因,大家可以参考一下: 

以下是一些可能导致这种情况的原因:

  1. 过拟合:模型在训练集上表现得太好,以至于它学习到了训练数据中的噪声或特定模式,而这些模式在测试集中并不适用。然而,随机森林通常具有较好的抗过拟合能力,所以这可能是不太可能的原因,除非数据集非常小或非常特殊。

  2. 数据泄漏:在训练和测试集之间存在某种形式的重叠或信息泄漏。例如,如果测试集中的某些样本在无意中用于训练模型,或者如果特征和标签之间存在直接的依赖关系(这些依赖关系在训练集和测试集中都被保留了下来),那么模型可能会表现得异常好。

  3. 简单的数据集:数据集可能非常简单,以至于即使是随机猜测也能得到很好的结果。然而,由于你正在使用随机森林这样的复杂模型,并且通常预期它在更复杂的数据集上也能表现良好,所以这种情况也不太可能。

  4. 标签不平衡:如果测试集中的大多数样本都属于同一个类别,并且模型只是简单地预测这个最常见的类别,那么准确度可能会很高,但这并不意味着模型实际上能够区分不同的类别。然而,在这种情况下,AUC通常不会接近1,因为它考虑了所有类别的区分能力。

  5. 随机性:虽然你设置了random_state来确保结果的可重复性,但随机森林的每次运行都可能略有不同(尽管差异很小)。然而,这种随机性不太可能导致准确度和AUC都为1。

  6. 评估错误:可能你在评估模型时犯了某种错误。例如,你可能错误地将训练集用作测试集,或者你可能在计算AUC时使用了错误的参数或方法。

  7. 模型参数:在某些情况下,随机森林的参数(如n_estimators)可能被设置得非常高,导致模型过度拟合训练数据。然而,即使在这种情况下,通常也不会看到准确度和AUC都为1的完美结果。

为了诊断这个问题,可以尝试以下步骤:

  • 检查数据:确保训练集和测试集之间没有重叠,并且它们都正确地反映了你要解决的问题。
  • 检查标签:确保测试集的标签是正确的,并且没有误用训练集的标签。
  • 交叉验证:使用交叉验证来评估模型,这可以帮助你了解模型在不同测试集上的表现。
  • 简化模型:尝试使用更简单的模型(如决策树)来查看是否仍然得到相同的结果。
  • 检查AUC计算:确保你正确地计算了AUC,并且使用了适当的参数(如multi_class='ovr'average='macro')。如果你对二分类问题使用AUC,请确保你的问题是二分类的,或者你已经将多类问题转换为了多个二分类问题。
  • 查看预测结果:查看模型的预测结果,特别是那些被错误分类的样本,以了解模型可能存在的问题。
  • 调整模型参数:尝试调整随机森林的参数,如n_estimatorsmax_depth等,以查看是否对结果有影响。然而,请注意,过度调整参数可能会导致过拟合。

 6.调试

scaler = StandardScaler()  
X_train_scaled = scaler.fit_transform(X_train)  
X_test_scaled = scaler.transform(X_test);
param_grid = {  
    'n_estimators': [50, 100, 200],  
    'max_depth': [None, 10, 20, 30],  
    'min_samples_split': [2, 5, 10],  
    'min_samples_leaf': [1, 2, 4]  
}  
  
grid_search = GridSearchCV(clf, param_grid, cv=5, scoring='accuracy', verbose=2, n_jobs=-1)  
grid_search.fit(X_train_scaled, y_train)  
  
best_clf = grid_search.best_estimator_  
y_pred_best = best_clf.predict(X_test_scaled)  
print("Best Parameters:", grid_search.best_params_)  
print("Best Accuracy:", accuracy_score(y_test, y_pred_best))  
print("Classification Report with Best Parameters:\n", classification_report(y_test, y_pred_best))

结果:

结论

通过上述步骤,可以初步了解红酒数据集的完整性、重复性以及各特征之间的关联关系。这些数据分析步骤对于进一步的数据处理和建模(如分类或回归)至关重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

pranaa

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

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

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

打赏作者

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

抵扣说明:

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

余额充值