datawhale-动手学数据分析task5笔记
datawhale-动手学数据分析task5笔记
模型搭建和评估--建模
模型搭建前的准备
-
引入所需的库与数据。
-
对数据进行特征工程:从原始数据中提取有用的特征,以便机器学习算法能够更有效地进行学习和预测。
-
数据集导致模型在拟合数据时发生变化的常见差异:
-
特征差异
-
样本数量与分布差异
-
噪声与异常值
-
目标变量差异
-
数据划分差异
-
时间序列数据的时序差异
-
数据预处理与清洗
-
模型搭建
sklearn的算法选择路径图:

切割训练集和测试集
-
划分数据集的方法:
-
简单随机抽样(Simple Random Sampling):
从总体中随机选择样本,每个样本被选中的概率是相等的。
适用于没有先验知识或特定结构的数据集。 -
分层抽样(Stratified Sampling):
根据某个或多个特征将数据分成不同的层或子集,然后从每层中随机抽取样本。
常用于确保每个类别的样本在训练集、验证集和测试集中都有合适的比例。 -
时间序列划分:
对于时间序列数据,通常按照时间顺序划分数据集,如使用前80%的数据作为训练集,接下来的10%作为验证集,最后的10%作为测试集。
这种划分方式有助于保持数据的时间依赖性,并防止未来数据泄露到训练集中。 -
K折交叉验证(K-fold Cross-validation):
将数据集分成K个不相交的子集,每次使用K-1个子集作为训练集,剩下的一个子集作为验证集。
这个过程重复K次,每次使用不同的子集作为验证集。
最后,对K次验证的结果取平均值,得到模型的性能估计。 -
留出法(Hold-out):
将数据集随机划分为两个互斥的子集,一个作为训练集,另一个作为测试集。
训练集用于训练模型,测试集用于评估模型的性能。
这种方法简单且易于实现,但可能由于随机性导致性能评估的不稳定。 -
自助法(Bootstrapping):
采用有放回的随机抽样方式从原始数据集中抽取样本形成训练集,剩余的样本作为测试集。
由于是有放回的抽样,自助法允许同一个样本在训练集中出现多次,或在训练集和测试集中同时出现。
自助法产生的数据集改变了原始数据集的分布,因此在估计模型误差时可能引入偏差。
-
-
分层抽样法的优点:
-
可以保持比例的代表性。
-
使得样本分布更加均匀,提高估计的精度。
-
确保每个类别在样本中都有足够的代表,可以减少抽样的误差。
-
-
随机抽样或分层抽样切割数据集的方法:
train_test_split()。''' 参数说明: - train_data是所要划分的样本特征集 - train_target是所要划分的样本结果 - test_size=[0,1]/int,样本占比,如果是整数的话就是样本的数量,None时默认0.25 - train_size,同上,test_size可替代,None时默认0.75 - random_state=int/None,随机数种子,不同随机数种子划分的结果不同,None时每次种子随机 - shuffle=Bool,如果True则会先将数据打乱顺序然后再进行划分 - stratify=list/None,保持split前类的分布,也就是分层抽样的分层依据,如果想要依据train_target分类,可直接使stratify=train_target,None时随机抽样 ''' # 以下有具体值的为默认值 from sklearn.model_selection import train_test_split x_train,x_test, y_train,y_test = train_test_split(train_data, train_target, test_size=None, train_size=None, random_state=None, shuffle=True, stratify=None) -
不用进行随机选取情况:
-
时间序列数据:随机打乱数据会破坏数据的时间依赖性和顺序性。
-
特定顺序的数据:有些数据项之间可能存在特定的逻辑或物理顺序,例如图像中的连续帧。
-
类别分布不平衡的数据:不同类别的样本数量差距可能很大,直接随机选取会导致某些类别样本在数据集中过少或过多。
-
有特定结构的数据:数据可能具有特定的结构或模型,例如社交网络中的图或网络。
-
模型创建
Logistic Regression
-
逻辑回归(Logistic Regression)模型是线性模型的分类模型,不是回归模型,与LinearRegression混淆。
-
Logistic Regression通过建立概率模型,将线性回归的输出结果通过逻辑函数(通常是sigmoid函数)转换为概率形式,从而进行分类预测(解决二分类问题)。
-
创建基于线性模型的分类模型(逻辑回归)的流程:
# 引入LogisticRegression类 from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score # 划分数据集 x_train, x_test, y_train, y_test = train_test_split(x, y, stratify=y) # 创建LogisticRegression类的示例(以下为默认参数) logreg = LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, l1_ratio=None, max_iter=100, multi_class='auto', n_jobs=None, penalty='l2', random_state=None, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False) # 拟合模型 logreg.fit(x_train, y_train) # 预测与评估准确度 y_pred = logreg.predict(y_test) accuracy = accuracy_score(y_test, y_pred) logreg.score(x_test, y_test) # 评测数据与标签,y是y_test的教师标签 -
LogisticRegression类的参数说明:


Decision Tree Classifier
-
分类决策树(DecisionTreeClassifier)是一种预测模型,主要用于解决分类问题,是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一个类别,基于这样的结构,根据样本的属性值进行逐步测试,最终将样本划分到某个叶节点,即某个类别中。
-
创建分类决策树的流程:
# 引入DecisionTreeClassifier类 from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score # 划分数据集 x_train, x_test, y_train, y_test = train_test_split(x, y, stratify=y) # 创建DecisionTreeClassifier类的示例(以下为默认参数) clf = DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, class_weight=None, ccp_alpha=0.0, monotonic_cst=None) # 拟合模型 clf.fit(x_train, y_train) # 预测与评估准确度 y_pred = clf.predict(y_test) accuracy = accuracy_score(y_test, y_pred) clf.score(x_test, y_test) # 评测数据与标签,y是y_test的教师标签 -
DecisionTreeClassifier类的参数说明:
参数 类型 描述 criterion可选值为'gini'或'entropy', default='gini' 特征选择标准,默认'gini'即CART算法。 splitter可选值为'best'或'random', default='best' 用于在每个节点选择划分特征的算法。'best'表示在全局选择最优划分,'random'表示随机局部选择最优划分。 max_depthint, default=None 树的最大深度。如果为None,则树会生长到所有叶子都是纯的,或者直到所有叶子包含少于 min_samples_split的样本。min_samples_splitint or float, default=2 拆分内部节点所需的最小样本数。如果是float,则表示的是占训练集样本总数的比例。 min_samples_leafint or float, default=1 一个叶子节点必须具有的最小样本数。如果是float,则它表示的是占训练集样本总数的比例。 min_weight_fraction_leaffloat, default=0.0 最小样本权重和,如果小于则会和兄弟节点一起被剪枝,这个参数用于处理带权重的样本。 max_featuresint, float, string or None, default=None 考虑用于查找最佳划分的特征数量。如果是int,则随机考虑 max_features个特征;如果是float,则max_features是特征总数的比例;如果是'sqrt',则max_features=sqrt(n_features);如果是'log2',则max_features=log2(n_features);如果是None,则max_features=n_features。random_stateint, RandomState instance or None, default=None 控制随机性的参数。对于 splitter='random'时尤为重要。max_leaf_nodesint or None, default=None 最大叶子节点数。如果为None,则不限制叶子节点的数量。 min_impurity_decreasefloat, default=0.0 如果一个分割点导致的不纯度减少小于这个值,则该分割点不会被考虑。 class_weightdict, list of dict or "balanced", default=None 类别权重。如果为None,则所有类别的权重相等。如果为'balanced',则类别权重与类频率成反比。也可以提供一个字典,指定每个类别的权重。 ccp_alphafloat, default=0.0 复杂度参数用于最小成本-复杂度剪枝。增加此参数的值会导致树更早停止生长。 monotonic_cstlist of bools or None, default=None 如果给出,布尔值的列表,其长度等于类的数量,表示是否应该强制决策树为单调的。请注意,单调性仅适用于单变量分割的决策树。
Random Forest Classifier
-
分类随机森林(RandomForestClassifier)是一种集成学习方法,基于构建并结合多个决策树来提高模型的预测性能。随机森林通过随机有放回地抽取数据样本集来训练多个决策树,并且每个决策树在构建过程中也随机抽取特征进行划分。
-
创建分类随机森林的流程:
# 引入RandomForestClassifier类 from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score # 划分数据集 x_train, x_test, y_train, y_test = train_test_split(x, y, stratify=y) # 创建RandomForestClassifier类的示例(以下为默认参数) clf = RandomForestClassifier(n_estimators=100, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1,min_weight_fraction_leaf=0.0, max_features='sqrt', max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None, monotonic_cst=None) # 拟合模型 clf.fit(x_train, y_train) # 预测与评估准确度 y_pred = clf.predict(y_test) accuracy = accuracy_score(y_test, y_pred) clf.score(x_test, y_test) # 评测数据与标签,y是y_test的教师标签 -
RandomForestClassifier类的参数说明:
参数名称 参数类型 描述 n_estimators int, optional default=100 随机森林里的树木数量。 criterion 可选值为"gini" 或 "entropy", str, optional default='gini' 用于测量分裂质量的函数。 max_depth int or None, optional default=None 树的最大深度。如果为 None,则节点将展开直到所有叶子都是纯净的或者直到所有叶子包含少于 min_samples_split 的样本。 min_samples_split int or float, optional default=2 分裂内部节点所需的最小样本数。 min_samples_leaf int or float, optional default=1 一个叶节点应该具有的最小样本数。 min_weight_fraction_leaf float, optional default=0.0 在叶子节点所有输入样本权重总和中的最小权重分数。 max_features str, int or None, optional default='sqrt' 寻找最佳分裂时要考虑的特征数量。 max_leaf_nodes int or None, optional default=None 最大叶节点数量。 min_impurity_decrease float, optional default=0.0 如果这种分裂导致不纯度的减少大于或等于此值,则节点将被分裂。 bootstrap bool, optional default=True 是否在构建树时使用自助法样本。 oob_score bool, optional default=False 是否使用袋外样本来估计泛化误差。 n_jobs int or None, optional default=None 用于运行的并行运行的线程数。如果为 -1,则使用所有可用的处理器。 random_state int, RandomState instance or None, optional default=None 控制随机性的参数。 verbose int, optional default=0 控制建树过程的日志输出的详细程度。 warm_start bool, optional default=False 当设置为 True 时,重用解决方案的上一次调用的解作为初始化,否则,只需擦除之前的解决方案。 class_weight dict, list of dict or "balanced", optional default=None 指定类别的权重。 ccp_alpha non-negative float, optional default=0.0 复杂度参数用来最小化损失函数的正则化项。 max_samples int or float, optional default=None 如果 bootstrap 为 True,则这是从 X 中抽取样本以构建每个基础学习器的样本数。 monotonic_cst list of lists or array-like or None, optional default=None 约束树中的每个特征的单调性。
输出模型预测结果
-
.predict()方法可以输出预测标签。 -
.predict_proba()可以输出标签概率。
predict_proba(X) 方法会返回一个数组,其形状为 (n_samples, n_classes),其中 n_samples 是输入样本的数量,n_classes 是目标变量的类别数。数组的每一个元素 [i, j] 表示第 i 个样本属于第 j 个类别的概率。 -
预测标签的概率可以用来调整阈值、估计不确定性、校准概率、指定调整决策等。
模型评估
模型评估的三种方法
-
模型评估是为了知道模型的泛化能力。
-
机器学习和数据科学中用于评估分类模型性能的三种工具方法:交叉验证、混淆矩阵和ROC曲线。
-
准确率(Precision)、召回率(Recall)和F-分数(F-score)是分类任务中常用的评估指标,它们可以帮助我们全面评估分类模型的性能。
-
准确率:
准确率表示模型预测为正样本的实例中,真正为正样本的比例。
\(Precision = \dfrac{TP}{TP + FP}\)
\(TP\)是真正例
\(FP\)是假正例
准确率越高,说明模型预测为正样本的实例中,错误预测的比例越低。 -
召回率
召回率表示实际为正样本的实例中,被模型预测为正样本的比例。
\(Recall = \dfrac{TP}{TP + FN}\)
\(FN\)是假负例
召回率越高,说明模型能够找到更多的正样本,减少漏报的情况。 -
f-分数
F-分数是准确率和召回率的调和平均值,用于综合评估模型的性能。
$F-score = \dfrac{2 * precision * recall}{precision + recall} $
F-分数越高,说明模型在准确率和召回率之间达到了较好的平衡。
-
交叉验证
-
交叉验证(cross-validation)是一种评估泛化性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面,主要用于防止模型过拟合。
-
交叉验证法的常见形式:
-
简单交叉验证(Hold-out Cross-validation):
将数据集分为训练集和测试集两部分。
使用训练集训练模型,并在测试集上评估其性能。
这种方法的优点是简单,但缺点是可能由于数据划分的随机性导致评估结果的不稳定。 -
K折交叉验证(K-fold Cross-validation):
将数据集分成K个大小相等的子集(或尽可能相等)。
每次选择K-1个子集作为训练集,剩下的一个子集作为验证集。
进行K次迭代,每次使用不同的子集作为验证集。
计算K次迭代的平均性能作为模型的最终评估结果。
这种方法的优点是评估结果较为稳定,能够充分利用数据集进行训练和验证。
-
留一交叉验证(Leave-one-out Cross-validation):
当数据集非常小时,可以使用留一交叉验证。
每次选择一个样本作为验证集,其余样本作为训练集。
对于数据集中的每个样本都进行这样的操作,最终计算所有迭代的平均性能。
这种方法的优点是评估结果非常稳定,但由于每次迭代只使用一个样本作为验证集,所以计算成本较高。 -
分层交叉验证(Stratified Cross-validation):
当数据集中各类别的样本数量不平衡时,可以使用分层交叉验证。
在划分数据集时,确保每个子集中各类别的样本比例与原始数据集中的比例相同。
这有助于避免由于类别不平衡导致的评估偏差。 -
时间序列交叉验证(Time-series Cross-validation):
适用于时间序列数据,其中数据的顺序非常重要。
将数据按照时间顺序划分成多个子集,并确保训练集总是在验证集之前。
这种方法有助于评估模型在时间序列预测任务中的性能。
-
-
k-交叉验证的示例:
# 引入cross_val_score函数 from sklearn.model_seleciton import cross_val_score from sklearn.linear_model import LogisticRegression # 划分数据集并处理模型 x_train, x_test, y_train, y_test = train_test_split(x, y, stratify=y) logreg = LogisticRegression() score = cross_val_score(logreg, x_train, y_train, cv=10) # k折交叉验证分数 print(f"score:{score}") # 平均交叉验证分数 print("Average cross-validation score: {:.2f}".format(scores.mean())) -
不需要显示拟合模型
.fit(),因为在交叉验证中会自动拟合模型。 -
K值越多,意味着每次用于训练和验证的数据子集越小,同时验证的次数也越多,当k折越多时的影响:
-
模型评估的稳定性增加
-
计算量增加
-
过拟合风险减小
-
超参数选择更精确
-