Python3里 print(1.2-1.0==0.2)输出为 False

有朋友问我,为何 print(1.2 -1.0 ==0.2)输出为 False,今天来一探究竟~

自己先来验证下:

>>>print(1.2-1.0==0.2)
False                   #还真滴是False

这是为啥呢???先来看看它的类型是啥

>>> type(1.2-1.0)
<class 'float'>      #呦呵是浮点型的

继续向下验证,我们直接进行减

>>> 1.2-1.0
0.19999999999999996

阔以看到,结果并不是我们所认知的0.2,而是0.1好多,近似等于0.2。

到这基本上就知道为何是False了,原因如下:

1、1.2-1.0在Python中的运算结果是浮点数,其结果数值是个近似值。

2、"=="是进行比较两个对象的内容是不是一样,内存地址可以不一样,内容一样就行了。

3、还有个原因那就是运算的优先级,左边是浮点数,是不可能相等的。

4、最后就是计算机底层的进制问题了。

所以呢,需要进行精确计算的时候就要注意这个问题啦~

``` import pandas as pd import numpy as np import matplotlib.pyplot as plt plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] plt.rcParams[&#39;axes.unicode_minus&#39;] = False import seaborn as sns from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.feature_selection import SelectKBest, f_classif from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report, roc_curve, auc, confusion_matrix import statsmodels.api as sm from sklearn.metrics import precision_score, roc_curve plt.style.use(&#39;ggplot&#39;) # 读取数据 file_path = r&#39;C:\Users\29930\Desktop\插补数据.csv&#39; data = pd.read_csv(file_path,encoding=&#39;GBK&#39;) data[&#39;性别&#39;] = data[&#39;性别&#39;].map({&#39;男&#39;: 0, &#39;女&#39;: 1}) # 编码性别列 arr = data.to_numpy() # 转换为NumPy数组 # 查看前几行数据 print(data.head()) # 检查是否有缺失值 print(data.isnull().sum()) # 填充缺失值(如果有的话) data.ffill(inplace=True) # 分离特征和目标变量 X = data.drop(columns=[&#39;慢阻肺&#39;]) # 假设第一列为COPD标签 y = data[&#39;慢阻肺&#39;].map({&#39;否&#39;: 0, &#39;是&#39;: 1}) # 关键修改 # 标准化数值型特征 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 将标准化后的数据转回DataFrame格式以便后续操作 X_scaled_df = pd.DataFrame(X_scaled, columns=X.columns) # 使用SelectKBest进行单变量选择 selector = SelectKBest(score_func=f_classif, k=&#39;all&#39;) # 先全部选出来查看得分情况 fit = selector.fit(X_scaled_df, y) # 打印每个特征的重要性评分 feature_scores = pd.DataFrame(list(zip(X_scaled_df.columns, fit.scores_)), columns=[&#39;Feature&#39;,&#39;Score&#39;]) feature_scores.sort_values(by=&#39;Score&#39;, ascending=False, inplace=True) print(feature_scores) # 绘制特征重要性图 plt.figure(figsize=(10, 6)) sns.barplot(x="Score", y="Feature", data=feature_scores) plt.title(&#39;特征重要性评分&#39;) plt.xlabel(&#39;ANOVA F值&#39;) plt.ylabel(&#39;特征名称&#39;) plt.show() # 选择最重要的几个特征 selected_features = feature_scores[feature_scores.Score >= feature_scores.Score.quantile(0.75)].Feature.tolist() # 选取前75%分位数以上的特征 X_selected = X_scaled_df[selected_features] # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X_selected, y, test_size=0.2, random_state=42) # 定义逻辑回归模型 logreg = LogisticRegression(solver=&#39;liblinear&#39;) # 超参数调优 -我们只对正则化强度C做网格搜索 param_grid = {&#39;C&#39;: [0.01, 0.1, 1, 10, 100]} grid_search = GridSearchCV(logreg, param_grid, cv=5, scoring=&#39;accuracy&#39;) grid_search.fit(X_train, y_train) # 输出最佳参数组合及对应的成绩 best_logreg = grid_search.best_estimator_ print("Best parameters:", grid_search.best_params_) print("Best CV Score:", grid_search.best_score_) # 在测试集上应用最优模型 y_pred = best_logreg.predict(X_test) # 计算性能指标 acc = accuracy_score(y_test, y_pred) report = classification_report(y_test, y_pred) conf_mat = confusion_matrix(y_test, y_pred) print(f"Accuracy: {acc:.4f}") print(report) # 绘制混淆矩阵热力图 plt.figure(figsize=(8, 6)) sns.heatmap(conf_mat, annot=True, fmt=&#39;d&#39;, cmap=&#39;Blues&#39;) plt.title(&#39;分类结果混淆矩阵&#39;) plt.xlabel(&#39;预测类别&#39;) plt.ylabel(&#39;真实类别&#39;) plt.show() # ROC曲线 fpr, tpr, _ = roc_curve(y_test, best_logreg.decision_function(X_test)) roc_auc = auc(fpr, tpr) plt.figure(figsize=(8, 6)) plt.plot(fpr, tpr, color=&#39;darkorange&#39;, lw=2, label=f&#39;ROC Curve (area = {roc_auc:.2f})&#39;) plt.plot([0, 1], [0, 1], color=&#39;navy&#39;, lw=2, linestyle=&#39;--&#39;) plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel(&#39;False Positive Rate&#39;) plt.ylabel(&#39;True Positive Rate&#39;) plt.title(&#39;ROC曲线(AUC = %0.2f)&#39; % roc_auc) plt.legend(loc="lower right") plt.show() # 添加常数项 X_const = sm.add_constant(X_selected) # 构建OLS线性回归模型(用于展示线性关系) model = sm.Logit(y, X_const).fit() print(model.summary()) # 获取最终模型方程 coefs = list(best_logreg.coef_[0]) + [best_logreg.intercept_[0]] features_with_intercept = [&#39;const&#39;] + selected_features formula_parts = [] for coef, feat in zip(coefs, features_with_intercept): formula_parts.append(f"{coef:+.4f}*{feat}") final_formula = " + ".join(formula_parts) print("\nFinal Early Screening Formula:") print(final_formula.replace(&#39;+&#39;, &#39; + &#39;).replace(&#39;-&#39;, &#39; - &#39;))```将特征重要性图,混淆矩阵热力图,和ROC曲线画的更精美
03-29
<think>嗯,用户希望将他们的Python代码中的三个图表——特征重要性图、混淆矩阵热力图和ROC曲线——画得更精美。我需要仔细分析他们现有的代码,然后找出可以优化的地方。首先,我应该回忆一下matplotlib和seaborn的高级定制方法,看看有哪些参数可以调整来提升图表的美观度。 特征重要性图现在用的是seaborn的barplot,可能可以调整颜色、字体大小、添加更多的标签信息,或者改变背景样式。比如,使用更现代的颜色渐变,增加标题的字体大小,或者调整坐标轴的标签位置。另外,特征重要性可能需要排序,让最重要的特征排在前面,不过原代码已经按分数排序了,所以这点可能已经处理好了。 混淆矩阵热力图,用户现在用的是sns.heatmap,可能需要添加更多的注释,比如百分比而不仅仅是数量,或者调整颜色映射,使其更清晰。另外,可以设置更合适的图例位置,或者调整单元格的大小,让图表看起来更专业。 至于ROC曲线,当前的代码已经绘制了曲线和虚线参考线,但可能需要调整线条的粗细、颜色,或者添加阴影效果来突出AUC值。坐标轴的标签字体、图例的位置和样式也可以优化,比如使用更大的字体,或者将图例放在更合适的位置。 接下来,我需要检查用户现有的代码,看看哪些参数已经设置,哪些可以进一步调整。例如,在特征重要性图中,是否使用了合适的调色板?是否添加了数据标签?在混淆矩阵中,是否对数值进行了标准化,以便更直观地显示比例? 另外,用户可能希望图表在学术论文或报告中展示,所以需要更高的分辨率和更清晰的输出。可能需要调整plt.figure的参数,比如dpi,或者保存为矢量图格式如PDF或SVG。 在代码层面,可能需要为每个图表单独设置不同的样式,比如使用sns.set_style来改变背景网格,或者调整字体类型。同时,要确保中文字体正确显示,用户已经设置了SimHei,但可能需要检查是否在所有图表中都应用了该设置。 对于特征重要性图,可以考虑使用水平条形图,并给每个条形添加数值标签,这样更易读。在seaborn中,可以通过annotate函数或者修改barplot的参数来实现。 混淆矩阵方面,除了数量,还可以显示每个类别的百分比,特别是在数据不平衡的情况下,这样更直观。可以通过计算百分比矩阵来实现,并在热力图中显示。 ROC曲线方面,可以填充曲线下的面积,增加AUC值的显示位置,调整线条样式,或者添加阈值标签,但可能过于复杂。保持简洁的同时提升视觉效果是关键。 最后,要确保所有修改后的代码与用户现有的代码兼容,不会引起错误。例如,数据预处理步骤是否正确,特征选择是否影响了后续的模型训练等。需要逐步测试每个图表的代码调整,确保输出正确无误。 总结一下,优化方向包括:调整颜色和样式、添加数据标签、优化布局和字体、调整坐标轴和标题、使用更专业的图表元素。需要逐一针对每个图表进行这些调整,并在回答中详细说明修改的代码部分及其作用。</think>我将分步骤说明如何优化这三个图的绘制效果,并提供修改后的代码段: 一、特征重要性图优化方案(增强可读性与美观度) ```python plt.figure(figsize=(12, 8), dpi=120) # 提高分辨率和尺寸 sns.set_style("whitegrid") # 使用白色网格背景 # 创建渐变色条 bar_plot = sns.barplot(x="Score", y="Feature", data=feature_scores, palette="viridis_r", edgecolor="0.2", linewidth=1.5) # 添加数据标签 for index, value in enumerate(feature_scores.Score): bar_plot.text(value + 0.05, index, f&#39;{value:.1f}&#39;, va=&#39;center&#39;, fontsize=10, color=&#39;#2d3436&#39;) plt.title(&#39;特征重要性评分(ANOVA F值)&#39;, fontsize=16, pad=20, fontweight=&#39;bold&#39;) # 增加标题格式 plt.xlabel(&#39;ANOVA F值&#39;, fontsize=12, labelpad=15) # 调整标签间距 plt.ylabel(&#39;特征名称&#39;, fontsize=12, labelpad=15) plt.xticks(fontsize=10) plt.yticks(fontsize=10, rotation=0) # 添加参考线 plt.axvline(x=np.mean(feature_scores.Score), color=&#39;#e74c3c&#39;, linestyle=&#39;--&#39;, linewidth=1.5, alpha=0.7) # 添加图例说明 plt.text(np.mean(feature_scores.Score)+0.5, 0.5, f&#39;平均得分: {np.mean(feature_scores.Score):.1f}&#39;, color=&#39;#e74c3c&#39;, fontsize=10) plt.tight_layout() # 自动调整边距 plt.show() ``` 二、混淆矩阵热力图优化方案(增强信息量和可视化效果) ```python plt.figure(figsize=(10, 8), dpi=120) sns.set(font_scale=1.2) # 统一字体缩放比例 # 计算百分比矩阵 conf_mat_perc = conf_mat.astype(&#39;float&#39;) / conf_mat.sum(axis=1)[:, np.newaxis] # 自定义注释标签 annot_labels = np.array([["{0:0.0f}\n({1:.1%})".format(num,perc) for num, perc in zip(row, per_row)] for row, per_row in zip(conf_mat, conf_mat_perc)]) # 创建热力图 heatmap = sns.heatmap(conf_mat, annot=annot_labels, fmt=&#39;&#39;, # 使用自定义格式 cmap=&#39;YlGnBu&#39;, # 更换色系 linewidths=2, linecolor=&#39;grey&#39;, cbar_kws={&#39;label&#39;: &#39;样本数量&#39;}, annot_kws={&#39;size&#39;:14, &#39;color&#39;:&#39;#2d3436&#39;, &#39;va&#39;:&#39;center&#39;}) plt.title(&#39;分类结果混淆矩阵\n&#39;, fontsize=16, fontweight=&#39;bold&#39;) plt.xlabel(&#39;预测类别&#39;, fontsize=12) plt.ylabel(&#39;真实类别&#39;, fontsize=12) # 优化颜色条 cbar = heatmap.collections[0].colorbar cbar.ax.tick_params(labelsize=10) cbar.ax.set_ylabel(&#39;样本数量&#39;, rotation=270, labelpad=20, fontsize=12) # 调整刻度标签 heatmap.set_xticklabels([&#39;非慢阻肺&#39;, &#39;慢阻肺&#39;], fontsize=12) heatmap.set_yticklabels([&#39;非慢阻肺&#39;, &#39;慢阻肺&#39;], fontsize=12, rotation=0) plt.tight_layout() plt.show() ``` 三、ROC曲线优化方案(提升专业展示效果) ```python plt.figure(figsize=(10, 8), dpi=120) plt.style.use(&#39;seaborn-darkgrid&#39;) # 使用深色网格样式 # 绘制主曲线 plt.plot(fpr, tpr, color=&#39;#3498db&#39;, lw=3, alpha=0.8, label=f&#39;ROC曲线 (AUC = {roc_auc:.2f})&#39;) # 填充曲线下方区域 plt.fill_between(fpr, tpr, alpha=0.15, color=&#39;#3498db&#39;) # 绘制参考线 plt.plot([0, 1], [0, 1], linestyle=&#39;--&#39;, lw=2, color=&#39;#e74c3c&#39;, alpha=0.7, label=&#39;随机猜测&#39;) # 标注最佳阈值点 optimal_idx = np.argmax(tpr - fpr) plt.scatter(fpr[optimal_idx], tpr[optimal_idx], s=100, color=&#39;#f1c40f&#39;, edgecolor=&#39;#2d3436&#39;, zorder=3, label=f&#39;最佳阈值点\n(FPR={fpr[optimal_idx]:.2f}, TPR={tpr[optimal_idx]:.2f})&#39;) # 坐标轴设置 plt.xlim([-0.02, 1.02]) plt.ylim([-0.02, 1.02]) plt.xticks(np.arange(0, 1.1, 0.1), fontsize=10) plt.yticks(np.arange(0, 1.1, 0.1), fontsize=10) # 标签和标题 plt.xlabel(&#39;False Positive Rate (1 - Specificity)&#39;, fontsize=12, labelpad=15) plt.ylabel(&#39;True Positive Rate (Sensitivity)&#39;, fontsize=12, labelpad=15) plt.title(&#39;ROC曲线 - 慢阻肺筛查模型&#39;, fontsize=16, pad=20, fontweight=&#39;bold&#39;) # 图例设置 plt.legend(loc=&#39;lower right&#39;, frameon=True, fontsize=10, framealpha=0.9, edgecolor=&#39;#2d3436&#39;) # 添加网格线 plt.grid(True, alpha=0.3, linestyle=&#39;--&#39;) plt.tight_layout() plt.show() ``` 主要优化点说明(使用无序列表表示): - 特征重要性图 - 添加渐变色系(`viridis_r`)增强视觉层次 - 精确到小数点后1位的数据标签 - 红色虚线标出平均分参考线 - 调整字体大小和边距提升可读性 - 混淆矩阵 - 同时显示绝对数量和百分比 - 使用蓝绿色系(`YlGnBu`)更符合医疗主题 - 添加单元格边框线增强结构感 - 优化颜色条说明文字 - ROC曲线 - 填充曲线下方区域增强表现力 - 标注最佳阈值点提供决策参考 - 使用深色网格背景提升对比度 - 添加详细的轴刻度(0.1间隔) - 专业级的图例排版和标签说明 建议在代码前添加以下样式初始化: ```python # 全局样式设置 plt.style.use(&#39;seaborn&#39;) sns.set_palette("husl") # 使用统一色板 plt.rcParams[&#39;font.family&#39;] = &#39;SimHei&#39; # 确保中文显示 plt.rcParams[&#39;axes.titlepad&#39;] = 20 # 标题间距 ``` 这些修改通过以下方式提升专业性: 1. 增加信息密度(如同时显示数值和百分比) 2. 优化色彩对比度(使用科学可视化常用色系) 3. 增强可解释性(添加参考线和阈值点) 4. 统一视觉风格(字体、间距、边距) 5. 提高输出分辨率(dpi=120) 6. 添加辅助决策信息(如最佳阈值点)
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值