PCA降维后做不出列线图(诺曼图)
基本情况就是我做了个二分类python,T检验之后做的lasso,得到特征后,发现模型准确率不好,然后又进一步在lasso基础上做的PCA降维,发现准确率好了,统计发现两类病人的年龄具有统计学差异,所以想请人做一个列线图(诺曼图)来反应患某个病的概率.前面的代码都写好了.就是做诺曼图需要计算影像组学标签公式进而推出得分,加上年龄,一起来预测得病概率.需要年龄和组学标签来进行预测
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
iris = load_iris()
X = iris.data
y = iris.target
print(pd.DataFrame(X))
# 调用PCA
pca = PCA(n_components=2) # 实例化 此处使用2代表降维到2个特征值,也可取mle让程序使用最大似然估计自己找寻最合适的降维超参数
pca = pca.fit(X) # 拟合模型
X_dr = pca.transform(X) # 获取新矩阵
# X_dr = PCA(2).fit_transform(X) # 同上两步
print(X_dr.shape)
plt.figure()
colors = ['red', 'black', 'orange']
for i in range(0, 3):
# 画点图
plt.scatter(X_dr[y==i, 0], X_dr[y==i, 1]
, alpha=.7 # 透明度设置
, c=colors[i], label=iris.target_names[i])
plt.legend()
plt.title('PCA of IRIS dataset')
plt.show()
# 查看降维后每个新特征向量上所带的信息量大小,即方差大小
print(pca.explained_variance_)
# 查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比
# 又叫可解释性方差贡献率
print(pca.explained_variance_ratio_)
print(pca.explained_variance_ratio_.sum())
# 累计可解释方差贡献率曲线来选择最好的n_components
pca_line = PCA().fit(X)
plt.plot([1, 2, 3, 4], np.cumsum(pca_line.explained_variance_ratio_))
plt.xticks([1, 2, 3, 4]) # 限制坐标轴显示为整数
plt.xlabel("number of components after dimension reduction")
plt.ylabel("cumulative explained variance")
plt.show()
题主可以将所写的代码也贴出来,根据代码如有什么问题,在问题处标明出来。
pca对数据进行降维处理的过程:
from numpy import *;
def loadDataSet(fileName,delim='\t'):
# 打开文件
fr=open(fileName);
"""
>>> line0=fr.readlines();
>>> type(line0)
<class 'list'>
>>> line0[0]
'10.235186\t11.321997\n'
"""
stringArr=[line.strip().split(delim) for line in fr.readlines()];
# map函数作用于给定序列的每一个元素,并用一个列表来提供返回值
datArr=[list(map(lambda x:float(x),line)) for line in stringArr];
dataMat=mat(datArr);
return dataMat;
def pcaFun(dataMat,topNfeat=9999999):
# 计算每列的平均值axis=0,计算每行的平均值axis=1
meanVals=mean(dataMat,axis=0);
# 去平均值,shape(dataMat)=(1000, 2),shape(meanVals)=(1, 2)
meanRemoved=dataMat-meanVals;# 可以直接对两个维度不同的矩阵进行运算
# 计算协方差矩阵shape(covMat)=(2, 2)
covMat=cov(meanRemoved,rowvar=0);
# 计算协方差矩阵的特征值和特征向量
eigVals,eigVects=linalg.eig(mat(covMat));
# 对特征值按升序排序
eigValInd=argsort(eigVals);
# 对特征值进行逆序排序
eigValInd=eigValInd[:-(topNfeat+1):-1];
# 计算最大特征值对应的特征向量
redEigVects=eigVects[:,eigValInd];
# 计算降维之后的数据集
lowDDataMat=meanRemoved*redEigVects;
# 重构原始数据
reconMat=(lowDDataMat*redEigVects.T)+meanVals;
return lowDDataMat,reconMat;
import matplotlib.pyplot as plt;
# 绘图,绘出原始数据和降维后的数据
def plotData(dataMat,reconMat):
# import matplotlib;
# import matplotlib.pyplot as plt;
fig=plt.figure();
ax=fig.add_subplot(111);
ax.scatter(dataMat[:,0].flatten().A[0],dataMat[:,1].flatten().A[0],marker='^',s=90);
ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0],marker='o',s=50,c='red');
plt.show();
上面代码中lowDDataMat为降维后的数据集,reconMat为重构的数据集;你调一下你的参数试试
组学标签计算参考:
https://zhuanlan.zhihu.com/p/47112755
matplotlib绘图基础:
https://zhuanlan.zhihu.com/p/47112755
看看这个对你有帮助麽
还望博主发下代码
https://blog.csdn.net/qq_40985985/article/details/119738620
这个链接有python 画诺曼图详细说明,可以参考一下。
R绘制Nomogram图_banlucainiao的博客-CSDN博客_诺曼图分析
这个链接有R 画诺曼图详细说明,和你的问题极为相似,可以参考一下。
没太理解你的问题到底是个啥,是有数据不会画图,还是预测的那步计算不出来。
题主您可以详细描述一下您的数据的格式,或者简单贴一小部分数据出来,而且最好是将代码也贴出来
二分类为啥不用深度学习呢,深度学习效果好。而且简单二分类训练也不复杂
你是组学标签计算不出来,还是图不会画?
就一个二分类直接使用pytorch 弄几层神经网络 就行搞什么pca呢
画列线图的例子:
# 绘制列线图
import matplotlib.pyplot as plt
from matplotlib import ticker
import matplotlib
# 注意注释掉此句,才可以plt.show()看到效果图
# 设置此才可保存图片到本地,plt.savefig将保存结果图,但同时plt.show()将不在起作用
# matplotlib.use("Agg")
# 设置展示的刻度
# 设置刻度轴位置
# 刻度起始值、结束值、刻度最小精度、刻度间隔
# 文字位置
def setup(ax, title, minx, maxx, major, minor, position="bottom"):
# 只显示底部脊椎
ax.yaxis.set_major_locator(ticker.NullLocator())
ax.spines['right'].set_color('none')
ax.spines['left'].set_color('none')
if (position == "bottom"):
ax.spines['top'].set_color('none')
elif (position == "top"):
ax.spines['bottom'].set_color('none')
# 定义刻度最大最小精度
ax.xaxis.set_major_locator(ticker.MultipleLocator(major))
ax.xaxis.set_minor_locator(ticker.MultipleLocator(minor)) # 最小刻度精度
# 定义刻度位置
ax.xaxis.set_ticks_position(position)
ax.set_xlim(minx, maxx)
ax.text(-0.5, -0.3, title, transform=ax.transAxes,
fontsize=9, fontname='Monospace', color='black')
fig, axs = plt.subplots(9, 1, figsize=(8, 6))
# fig.suptitle("Nomogram demo") # 设置标题
setup(axs[0], title="Points", position="top", minx=0, maxx=100, major=10, minor=2.5)
axs[0].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[1], title="Age", minx=35, maxx=85, major=5, minor=5)
axs[1].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[2], title="Blood Glucose", minx=100, maxx=50, major=10, minor=10)
axs[2].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[3], title="Gender", minx=1, maxx=0, major=1, minor=1)
axs[3].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[4], title="TotalPoints", minx=0, maxx=260, major=20, minor=4)
axs[4].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[5], title="Linear Predictor", minx=-0.8, maxx=0.8, major=0.2, minor=0.1)
axs[5].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[6], title="1-yearSurvival Probability", minx=0.85, maxx=0.5, major=0.05, minor=0.05)
axs[6].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[7], title="3-yearSurvival Probability", minx=0.5, maxx=0.05, major=0.05, minor=0.05)
axs[7].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
setup(axs[8], title="5-yearSurvival Probability", minx=0.25, maxx=0.05, major=0.05, minor=0.05)
axs[8].xaxis.set_major_formatter(ticker.ScalarFormatter(useMathText=True))
fig.tight_layout()
plt.show()
# 保存图片
# plt.savefig('nomogram.jpg')
参考:
https://matplotlib.org/stable/gallery/ticks_and_spines/tick-formatters.html#sphx-glr-gallery-ticks-and-spines-tick-formatters-py
https://matplotlib.org/stable/gallery/ticks_and_spines/tick-locators.html#sphx-glr-gallery-ticks-and-spines-tick-locators-py
代码贴一下,我们才能帮你分析问题,还有就是报错或者异常也贴一下,如果代码不方便的话,可以放简略版的,你的问题具体一点,容易解决,目前即时会的,也只能给你个泛泛的答案,你可能应用上去还是不能解决问题
https://download.csdn.net/download/weixin_38738977/12855098?spm=1001.2101.3001.5697
有错误吗,代码贴一下