数据挖掘实战-基于LDA主题分析+文本分析的医学论文分类研究
本实验数据集来源于Kaggle,原始数据集为医学相关的论文,共有8000条,3列,分别为title:论文题目author:论文作者abstract:论文摘要在本次医学类论文摘要分析实验中,我们采取了多元化的分析方法,以深入探索和理解文本的内在结构和语义信息。通过综合运用LDA主题分析和K-means聚类算法,我们有效地对文本数据进行了主题识别和类别划分。首先,我们应用了LDA主题分析技术,该技术成
🤵♂️ 个人主页:@艾派森的个人主页
✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+
目录
1.项目背景
在当今信息爆炸的时代,医学领域的知识体系以前所未有的速度扩展,每年发表的医学论文数量激增。这些论文涵盖了从基础医学研究到临床试验、药物开发、疾病诊断与治疗等多个方面,为医学进步提供了丰富的数据与见解。然而,如此庞大的信息量也带来了挑战:如何高效地组织、检索和理解这些文献,以支持科研工作者快速定位所需知识,加速科研进程,成为了一个亟待解决的问题。
在此背景下,文本挖掘与自然语言处理技术(NLP)的发展为医学文献的智能化处理提供了可能。特别是潜在狄利克雷分配(Latent Dirichlet Allocation, LDA)模型,作为一种强大的主题建模工具,能够在不预先定义主题的情况下,从大量文本数据中自动发现隐藏的主题结构。LDA模型通过假设每篇文档是多个主题的混合,而每个主题又是多个词汇的概率分布,从而有效地揭示了文本集合中的主题信息。
将LDA主题分析应用于医学论文分类研究,不仅有助于实现对海量医学文献的高效组织与管理,还能进一步促进跨领域知识的融合与发现。具体而言,通过LDA模型提取出的主题信息,可以揭示不同研究领域的热点与趋势,为科研人员提供有价值的参考;同时,基于主题的论文分类结果,能够优化搜索引擎的性能,提高文献检索的准确性和效率,加快科研成果的转化与应用。
此外,结合文本分析技术,如关键词提取、情感分析等,可以进一步挖掘医学论文中的深层次信息,如疾病特征描述、治疗效果评价等,为临床决策支持、药物研发策略制定等提供更加全面和深入的依据。这种综合性的分析方法,不仅丰富了医学文献分析的手段,也为医学研究的创新与发展注入了新的活力。
综上所述,基于LDA主题分析+文本分析的医学论文分类研究,旨在利用先进的信息技术手段,应对医学文献爆炸式增长带来的挑战,推动医学知识的有效组织与利用,促进医学研究的持续进步与发展。
2.数据集介绍
本实验数据集来源于Kaggle,原始数据集为医学相关的论文,共有8000条,3列,分别为
title:论文题目
author:论文作者
abstract:论文摘要
3.技术工具
Python版本:3.9
代码编辑器:jupyter notebook
4.实验过程
4.1导入数据
首先导入本次实验的第三方库并加载数据集
查看数据大小
可以看出数据集共有8000行,3列
查看数据的基本信息
可以看到本数据集各列的名称、有多少个非空值以及数据类型
查看数据的描述性统计
在数据的描述性统计结果中,我们可以看到各变量的总数、唯一值个数、出现最高频率的值以及出现的次数。
4.2数据预处理
在现实生活问题中,我们得到的原始数据往往非常混乱、不全面,机器学习模型往往无法从中有效识别并提取信息。数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已,真实的训练数据总是存在各种各样的问题:各特征(变量)的尺度(量纲)和数量级差异大、存在噪声:包含错误和异常值、存在缺失值、存在冗余特征(变量)等问题,存在上述问题的数据有时也称为“脏数据”,这些“脏数据”会影响机器学习模型预测的有效性(有时会得到相反的结论)、可重复性和泛化能力,从而影响模型的质量。因此在采集完数据后,机器学习建模的首要步骤以及主要步骤便是数据预处理。
数据预处理就是一种数据挖掘技术,本质就是为了将原始数据转换为可以理解的格式或者符合我们挖掘的格式。它可以改进数据的质量,从而有助于提高其后的挖掘过程的准确率和效率,得到高质量的数据。
统计数据缺失值情况
可以看到数据集中各列均不存在缺失值
统计数据重复值情况
可以看到数据集中并不存在重复值
这里我们自定义一个英文分词函数,用于删除句子中的标点符号。分词并去除停用词
对数据集中的摘要变量进行分词处理
4.3LDA主题分析
Tomotopy简介
tomotopy 是 tomoto(主题建模工具)的 Python 扩展,它是用 C++ 编写的基于 Gibbs 采样的主题模型库。支持的主题模型包括 LDA、DMR、HDP、MG-LDA、PA 和 HPA, 利用现代 CPU 的矢量化来最大化速度。
首先使用主题一致性来确定最佳的主题个数
从图中我们可以看出最佳的主题个数应为4个(图线最低点)
构建主题数为4的LDA模型,并输出每个主题的前20个主题词
4.4LDA主题可视化
打印模型信息
在模型信息中,我们看出最后一栏的Topics
<Topics>
| #0 (207682) : study patients development energy cells
| #1 (163974) : data art stateoftheart study model
| #2 (155477) : energy system model proposed method
| #3 (211992) : stateoftheart proposed method methods image
现在,我们根据关键词来分析每个主题可能代表的含义:
- #0 (207682) : study patients development energy cells
- 这个主题可能与医学研究和发展有关,特别是与细胞和能量相关的研究。关键词“study”表明这是一个研究领域的主题,“patients”可能与临床试验或患者研究有关,“development”可能指的是疾病的发展、药物或治疗方法的开发,而“energy”和“cells”可能指向生物能量学或细胞层面的研究。
- #1 (163974) : data art stateoftheart study model
- 这个主题可能与使用数据驱动的模型和方法来研究医学领域的最新技术(state-of-the-art)有关。“data”和“model”这两个词表明这个主题涉及数据分析和建模,“stateoftheart”意味着研究的是当前最前沿的技术或方法,“study”则表明这是一个研究过程。
- #2 (155477) : energy system model proposed method
- 这个主题似乎聚焦于能量系统和相关模型的提出或改进。“energy system”可能指的是生物能量系统或与医疗相关的能量机制,“model”和“proposed method”则表明这个主题是关于新方法或模型的提出和应用。
- #3 (211992) : stateoftheart proposed method methods image
- 这个主题可能与图像处理或医学影像技术的最新发展有关。“stateoftheart”表明研究的是当前最前沿的技术,“proposed method”和“methods”表明有新方法或技术的提出,“image”很可能指的是医学影像,如X光片、MRI扫描等。
总的来说,这四个主题涵盖了医学研究的不同方面,从细胞层面的能量研究到最前沿的医学影像技术。每个主题都通过其关键词集合展示了该领域的研究焦点和方法。
4.5文本聚类
TruncatedSVD是一种常见的降维方法,它属于奇异值分解(Singular Value Decomposition,简称SVD)的一种变种。SVD是一种矩阵分解技术,可以将一个复杂的矩阵分解为三个更简单的矩阵的乘积,这些矩阵描述了原矩阵的重要特性。具体来说,SVD将一个矩阵A分解为U、Σ和V^T三个矩阵的乘积,其中U和V是正交矩阵,Σ是对角矩阵,对角线上的元素称为奇异值。
在TruncatedSVD中,这个分解过程被截断,即只保留Σ矩阵中的前k个最大的奇异值及其对应的奇异向量,从而得到降维后的数据表示。这种方法通过减少数据的维度来降低存储和计算的复杂度,同时在一定程度上避免了维度灾难。降维后的数据矩阵保留了原始数据的主要特征,因此可以用于各种机器学习任务,如文本挖掘、推荐系统等。
TruncatedSVD的具体步骤如下:
- 对原始数据矩阵A进行SVD分解,得到U、Σ和V^T三个矩阵。
- 保留Σ矩阵中的前k个最大奇异值及其对应的奇异向量,得到新的Σ'矩阵和对应的奇异向量矩阵U'和V'^T。
- 将降维后的矩阵A'计算为A' = U'Σ'V'^T,这就是降维后的数据表示。
通过这个过程,我们可以将高维数据降低到低维空间,从而减少数据的复杂度,同时保留数据的主要特征。这种方法在文本挖掘、图像处理、推荐系统等领域都有广泛的应用。
首先对分词后的摘要文本进行降维处理,降到5000维
TF-IDF(Term Frequency-Inverse Document Frequency)是一种用于信息检索和文本挖掘的权重计算方法,它反映了一个词在特定文档中的重要性。TF-IDF是Term Frequency(词频)和Inverse Document Frequency(逆文档频率)的乘积。这个方法有助于调整一个词在特定文档中的权重,同时考虑到该词在所有文档集中的罕见程度。
1. Term Frequency (TF):
词频(TF)表示一个词在文档中出现的频率。计算公式通常为:
(TF(t) = \frac{词t在文档中出现的次数}{文档中的总词数})
2. Inverse Document Frequency (IDF):
逆文档频率(IDF)用于衡量一个词在所有文档集中的重要性。如果一个词在很多文档中都出现,那么它的IDF值会较低,因为它不够特定;反之,如果一个词只在少数文档中出现,那么它的IDF值会较高。IDF的计算公式通常为:
(IDF(t) = \log{\frac{N}{df(t)}})
其中,(N) 是文档集中的文档总数,(df(t)) 是包含词 (t) 的文档数量。
3. TF-IDF:
TF-IDF是TF和IDF的乘积,用于表示一个词在特定文档中的重要性。其计算公式为:
(TF-IDF(t, d) = TF(t, d) \times IDF(t))
其中,(t) 表示一个词,(d) 表示一个文档。
TF-IDF在文本挖掘、自然语言处理和信息检索中非常有用,因为它可以帮助我们找到在特定文档中重要而在整个文档集中相对罕见的词。这些词往往携带着更多的信息,对于文档的分类、聚类和检索等任务非常关键。
在实际应用中,为了避免除数为零或对数中的零值问题,通常会进行一些平滑处理,例如对词频加1,或在计算IDF时使用 (1 + \log{\frac{N}{df(t)}}) 等。此外,很多文本处理库(如scikit-learn、NLTK等)都提供了现成的TF-IDF计算功能,可以方便地应用在实际项目中。
接着使用TF-IDF模型
接着使用肘部法则和轮廓系数确定聚类个数K
肘部法则(Elbow Method)是一种常用于确定KMeans聚类算法中参数K的方法。该方法通过绘制不同K值对应的聚类误差(通常是SSE,Sum of Squared Errors)的折线图,来寻找一个“肘点”,该点对应的K值即为较为合适的聚类数。
以下是使用肘部法则确定K的步骤:
选择一定范围的K值:首先,确定一个K值的范围,一般从较小的K开始,例如1到10或者更大的范围,具体根据问题的复杂程度而定。
计算聚类误差(SSE):对于每一个K值,使用KMeans算法进行聚类,并计算每个数据点到其所属簇中心的距离之和的平方,即SSE。SSE是衡量聚类效果的指标,表示样本点与其所属簇中心的紧密程度。
绘制肘部法则图:将不同K值对应的SSE绘制成折线图(K-SSE曲线图)。横坐标为K值,纵坐标为对应的SSE值。
寻找“肘点”:观察K-SSE曲线图,通常会出现一个明显的拐点,即曲线从下降阶段转为平缓下降或持平阶段的位置。这个拐点所对应的K值,即为肘部法则确定的较为合适的聚类数。
请注意,肘部法则并不是一个绝对准确的方法,有时候K-SSE曲线可能没有明显的肘点,或者存在多个肘点。在实际应用中,我们可以结合领域知识和业务需求,综合考虑选择最合适的K值。另外,还可以尝试其他聚类评估指标(如轮廓系数、DBI等)来辅助确定最佳的K值。
肘部法则看出转折点在3附近
轮廓系数(Silhouette Coefficient)是一种用于评估聚类质量的指标,可以帮助确定KMeans聚类算法中最佳的聚类数K。它结合了聚类的紧密度(簇内样本距离平均值)和分离度(不同簇之间样本距离平均值),从而提供一个综合的聚类效果评估。
轮廓系数的计算过程如下:
对于每个数据点,首先计算它与同簇其他数据点的平均距离,称为a(簇内紧密度)。
然后,对于每个数据点,计算它与其他簇中所有数据点的平均距离,找到其中最近的一个平均距离,称为b(簇间分离度)。
计算每个数据点的轮廓系数:s = (b - a) / max(a, b)
对于整个数据集,计算所有数据点的轮廓系数的平均值,作为整个聚类的轮廓系数。
轮廓系数的取值范围在-1到1之间:
如果轮廓系数接近于1,则表示簇内样本紧密度高,簇间分离度较好,聚类效果较好。
如果轮廓系数接近于-1,则表示簇内样本紧密度较低,簇间分离度不好,聚类效果较差。
如果轮廓系数接近于0,则表示簇内外样本的距离相差不大,聚类效果一般。
通常来说,较高的轮廓系数意味着更好的聚类效果。在使用轮廓系数确定K值时,我们可以尝试不同的K值,计算对应的轮廓系数,选择轮廓系数最大的K值作为最佳的聚类数。但是,需要注意的是,轮廓系数也有一定的局限性,特别是在数据分布不均匀或者聚类间有重叠的情况下,可能不适用于评估聚类效果。因此,综合考虑多种评估指标和领域知识,能够更全面地确定最佳的聚类数。
结合肘部法则和轮廓系数,我们可以确定最佳主题个数为4,与前面的LDA主题分析吻合。
构建Kmeans聚类模型,并训练
将聚类结果保存为excel文件
聚类结果可视化
从图中可以看出共有四种颜色,模型拟合效果还不错,但还有待提高。
4.6文本分类
准备建模数据,并将数据集拆分为训练集和测试集,其中测试集比例为0.2
构建逻辑回归模型
构建SVM支持向量机模型
构建决策树模型
构建随机森林模型
构建XGBoost模型
在构建的五个分类模型中,我们发现XGBoost模型的准确率最高,为0.97875,故我们最终选择其作为最终的模型。
模型预测
我们随机抽取10个模型预测结果与真实值进行对比,可以发现10个全部预测正确,模型效果很不错。
5.实验总结
在本次医学类论文摘要分析实验中,我们采取了多元化的分析方法,以深入探索和理解文本的内在结构和语义信息。通过综合运用LDA主题分析和K-means聚类算法,我们有效地对文本数据进行了主题识别和类别划分。
首先,我们应用了LDA主题分析技术,该技术成功地揭示了隐藏在大量医学论文摘要中的主要主题。这不仅帮助我们快速把握了数据集的整体内容,还为后续的聚类分析提供了有价值的背景信息。
紧接着,我们利用K-means聚类算法对文本数据进行了聚类处理,设定聚类个数为4。通过聚类,我们将相似的论文摘要归为一类,进一步揭示了数据集中的内在结构和分组情况。聚类结果的可视化展示使我们能够直观地评估模型的效果,虽然表现尚可,但仍有一定的提升空间。
为了充分利用聚类分析的结果,我们进一步利用聚类得到的标签构建了分类模型。在模型选择阶段,我们构建了五个不同的分类模型,包括逻辑回归、SVM支持向量机、决策树、随机森林和XGBoost。通过对这些模型的训练和评估,我们发现XGBoost模型在准确率上表现最佳,达到了0.97875的高准确率。
XGBoost模型的优异表现得益于其基于梯度提升的决策树集成算法,该算法在处理结构化数据时具有显著的优势。通过不断调整模型的参数和优化设置,我们成功地将XGBoost模型调整为最适合当前数据集的配置,从而实现了如此高的准确率。
总的来说,本次实验在医学类论文摘要分析方面取得了显著的成果。通过综合运用LDA主题分析和K-means聚类算法,我们有效地理解了数据集的内在结构和主题内容。同时,通过构建和比较多个分类模型,我们找到了最适合当前数据集的XGBoost模型,并实现了高达0.97875的准确率。这些成果不仅展示了我们在文本分析领域的专业能力,也为后续的医学研究和应用提供了有力的支持。
展望未来,我们将继续探索和优化文本分析技术,以更好地服务于医学研究和相关领域的应用。通过不断改进模型算法和引入更多的特征工程手段,我们相信能够进一步提高文本分析的准确性和效率,为医学研究和临床实践提供更加精准和有价值的信息支持。
源代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
df = pd.read_csv('medical_thesis.csv')
df.head()
df.shape
df.info()
df.describe()
df.isnull().sum()
df.duplicated().sum()
import string
def english_word_cut(mytext):
# 删除标点符号
punctuations =string.punctuation
mytokens = ''.join(word for word in mytext if word not in punctuations)
# 文本分词
seg_list_exact = mytokens.split(' ')
result_list = []
# 读取停用词库
with open('stopwords.txt', encoding='utf-8') as f: # 可根据需要打开停用词库,然后加上不想显示的词语
con = f.readlines()
stop_words = set()
for i in con:
i = i.replace("\n", "") # 去掉读取每一行数据的\n
stop_words.add(i)
# 去除停用词
for word in seg_list_exact:
if word.lower() not in stop_words:
result_list.append(word)
return ' '.join(result_list)
df['abstract_cutted'] = df['abstract'].apply(english_word_cut)
df['abstract_cutted']
import tomotopy as tp
def find_k(docs, min_k=1, max_k=20, min_df=2):
# min_df 词语最少出现在2个文档中
scores = []
for k in range(min_k, max_k):
mdl = tp.LDAModel(min_df=min_df, k=k, seed=555)
for words in docs:
if words:
mdl.add_doc(words)
mdl.train(20)
coh = tp.coherence.Coherence(mdl)
scores.append(coh.get_score())
plt.plot(range(min_k, max_k), scores)
plt.xlabel("number of topics")
plt.ylabel("coherence")
plt.show()
find_k(docs=df['abstract_cutted'], min_k=3, max_k=10, min_df=4)
# 初始化LDA
mdl = tp.LDAModel(k=4, min_df=4, seed=555)
for words in df['abstract_cutted']:
#确认words 是 非空词语列表
if words:
mdl.add_doc(words=words.split())
#训 练
mdl.train()
# 查看每个topic feature words
for k in range(mdl.k):
print('Top 20 words of topic #{}'.format(k))
print(mdl.get_topic_words(k, top_n=20))
print('\n')
# 查看话题模型信息
mdl.summary()
import pyLDAvis
import numpy as np
# 在notebook显示
pyLDAvis.enable_notebook()
# 获取pyldavis需要的参数
topic_term_dists = np.stack([mdl.get_topic_word_dist(k) for k in range(mdl.k)])
doc_topic_dists = np.stack([doc.get_topic_dist() for doc in mdl.docs])
doc_topic_dists /= doc_topic_dists.sum(axis=1, keepdims=True)
doc_lengths = np.array([len(doc.words) for doc in mdl.docs])
vocab = list(mdl.used_vocabs)
term_frequency = mdl.used_vocab_freq
prepared_data = pyLDAvis.prepare(
topic_term_dists,
doc_topic_dists,
doc_lengths,
vocab,
term_frequency,
start_index=0, # tomotopy话题id从0开始,pyLDAvis话题id从1开始
sort_topics=False # 注意:否则pyLDAvis与tomotopy内的话题无法一一对应。
)
# 可视化结果存到html文件中
pyLDAvis.save_html(prepared_data, 'ldavis.html')
# notebook中显示
pyLDAvis.display(prepared_data)
文本聚类
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import Normalizer
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.pipeline import make_pipeline
vectorizer = CountVectorizer()
svd = TruncatedSVD(5000) # 降到5000维
normalizer = Normalizer(copy=False) # 标准化
lsa = make_pipeline(svd,normalizer)
X = lsa.fit_transform(vectorizer.fit_transform(df['abstract_cutted']))
X.shape
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X)
tfidf_weight = tfidf.toarray()
tfidf_weight
from sklearn.cluster import KMeans
# 肘部法则
loss = []
for i in range(2,10):
model = KMeans(n_clusters=i).fit(tfidf_weight)
loss.append(model.inertia_)
plt.plot(range(2,10),loss)
plt.xlabel('k')
plt.ylabel('loss')
plt.show()
# 轮廓系数
from sklearn.metrics import silhouette_score
score = []
for i in range(2,10):
model = KMeans(n_clusters=i).fit(tfidf_weight)
score.append(silhouette_score(tfidf_weight, model.labels_, metric='euclidean'))
plt.plot(range(2,10),score)
plt.xlabel('k')
plt.ylabel('silhouette_score')
plt.show()
# 指定分成4个类
kmeans = KMeans(n_clusters=4)
kmeans.fit(tfidf_weight)
# 打印出各个簇的中心点
print("中心点坐标:")
print(kmeans.cluster_centers_)
for index, label in enumerate(kmeans.labels_, 1):
print("index: {}, label: {}".format(index, label))
# 样本距其最近的聚类中心的平方距离之和,用来评判分类的准确度,值越小越好
# k-means的超参数n_clusters可以通过该值来评估
print("效果评估值:")
print("inertia: {}".format(kmeans.inertia_))
# 保存结果至excel
df['label'] = kmeans.labels_
df.to_excel("data_labeled.xlsx",index=False)
# 使用T-SNE算法,对权重进行降维,准确度比PCA算法高,但是耗时长
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2)
decomposition_data = tsne.fit_transform(tfidf_weight)
x = []
y = []
for i in decomposition_data:
x.append(i[0])
y.append(i[1])
fig = plt.figure(figsize=(10, 10))
ax = plt.axes()
plt.scatter(x, y, c=kmeans.labels_, marker="x")
plt.xticks(())
plt.yticks(())
plt.show()
文本分类
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report,ConfusionMatrixDisplay,confusion_matrix
# 准备建模数据
X = tfidf_weight
y = df['label']
# 拆分数据集为训练集和测试集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=2024)
# 构建逻辑回归模型
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
model = LogisticRegression()
model.fit(X_train,y_train)
y_pred = model.predict(X_test)
print('模型准确率:',accuracy_score(y_pred,y_test))
print('模型分类报告:','\n',classification_report(y_pred,y_test))
ConfusionMatrixDisplay(confusion_matrix(y_test,y_pred),display_labels=[0,1,2,3]).plot()
plt.show()
# 构建svm支持向量机模型
from sklearn.svm import SVC
svc = SVC()
svc.fit(X_train,y_train)
y_pred = svc.predict(X_test)
print('模型准确率:',accuracy_score(y_pred,y_test))
print('模型分类报告:','\n',classification_report(y_pred,y_test))
ConfusionMatrixDisplay(confusion_matrix(y_test,y_pred),display_labels=[0,1,2,3]).plot()
plt.show()
# 构建决策树模型
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier()
tree.fit(X_train,y_train)
y_pred = tree.predict(X_test)
print('模型准确率:',accuracy_score(y_pred,y_test))
print('模型分类报告:','\n',classification_report(y_pred,y_test))
ConfusionMatrixDisplay(confusion_matrix(y_test,y_pred),display_labels=[0,1,2,3]).plot()
plt.show()
# 构建随机森林模型
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier()
forest.fit(X_train,y_train)
y_pred = forest.predict(X_test)
print('模型准确率:',accuracy_score(y_pred,y_test))
print('模型分类报告:','\n',classification_report(y_pred,y_test))
ConfusionMatrixDisplay(confusion_matrix(y_test,y_pred),display_labels=[0,1,2,3]).plot()
plt.show()
# 构建XGBoost模型
from xgboost import XGBClassifier
xgb = XGBClassifier()
xgb.fit(X_train,y_train)
y_pred = xgb.predict(X_test)
print('模型准确率:',accuracy_score(y_pred,y_test))
print('模型分类报告:','\n',classification_report(y_pred,y_test))
ConfusionMatrixDisplay(confusion_matrix(y_test,y_pred),display_labels=[0,1,2,3]).plot()
plt.show()
# 模型预测
res = pd.DataFrame()
res['真实值'] = y_test
res['预测值'] = y_pred
res.sample(10) # 随机抽取10个
资料获取,更多粉丝福利,关注下方公众号获取
更多推荐
所有评论(0)