• [干货汇总] 机器学习实践:基于支持向量机算法对鸢尾花进行分类
    【摘要】 @[toc] 一.前言 1.1 本文原理支持向量机(SVM)是一种二元分类模型。它的基本模型是在特征空间中定义最大区间的线性分类器,这使它不同于感知器;支持向量机还包括核技术,这使得它本质上是一个非线性分类器。支持向量机的学习策略是区间最大化,它可以形式化为求解凸二次规划的问题,等价于正则化铰链损失函数的最小化。支持向量机的学习算法是求解凸二次规划的优化算法。Scikit learn(skl...本文分享自华为云社区《支持向量机算法之鸢尾花特征分类【机器学习】》,作者:上进小菜猪。一.前言1.1 本文原理支持向量机(SVM)是一种二元分类模型。它的基本模型是在特征空间中定义最大区间的线性分类器,这使它不同于感知器;支持向量机还包括核技术,这使得它本质上是一个非线性分类器。支持向量机的学习策略是区间最大化,它可以形式化为求解凸二次规划的问题,等价于正则化铰链损失函数的最小化。支持向量机的学习算法是求解凸二次规划的优化算法。Scikit learn(sklearn)是机器学习中常见的第三方模块。它封装了常见的机器学习方法,包括回归、降维、分类、聚类等。1.2 本文目的List item使用scikit-learn机器学习包的支持向量机算法,使用全部特征对鸢尾花进行分类;使用scikit-learn机器学习包的支持向量机算法,设置SVM对象的参数,包括kernel、gamma和C,分别选择一个特征、两个特征、三个特征,写代码对鸢尾花进行分类;使用scikit-learn机器学习包的支持向量机算法,选择特征0和特征2对鸢尾花分类并画图,gamma参数分别设置为1、10、100,运行程序并截图,观察gamma参数对训练分数(score)的影响,请说明如果错误调整gamma参数会产生什么问题?二.实验过程2.1 支持向量机算法SVM实例的特征向量(以2D为例)映射到空间中的一些点,如下图中的实心点和空心点,它们属于两个不同的类别。支持向量机的目的是画一条线来“最好”区分这两类点,这样,如果将来有新的点,这条线也可以很好地进行分类。2.2List item使用scikit-learn机器学习包的支持向量机算法,使用全部特征对鸢尾花进行分类;首先引入向量机算法svm模块:from sklearn import svm还是老样子,使用load_iris模块,里面有150组鸢尾花特征数据,我们可以拿来进行学习特征分类。如下代码:from sklearn.datasets import load_iris iris = load_iris() X = iris.data print(X.shape, X) y = iris.target print(y.shape, y)下面使用sklearn.svm.SVC()函数。C-支持向量分类器如下:svm=svm.SVC(kernel='rbf',C=1,gamma='auto')使用全部特征对鸢尾花进行分类svm.fit(X[:,:4],y)输出训练得分:print("training score:",svm.score(X[:,:4],y)) print("predict: ",svm.predict([[7,5,2,0.5],[7.5,4,7,2]]))使用全部特征对鸢尾花进行分类训练得分如下:2.3 使用scikit-learn机器学习包的支持向量机算法,设置SVM对象的参数,包括kernel、gamma和C,分别选择一个特征、两个特征、三个特征,写代码对鸢尾花进行分类;2.3.1 使用一个特征对鸢尾花进行分类上面提过的基础就不再写了。如下代码:使用一个特征对鸢尾花进行分类,如下代码:svm=svm.SVC() svm.fit(X,y)输出训练得分:print("training score:",svm.score(X,y)) print("predict: ",svm.predict([[7,5,2,0.5],[7.5,4,7,2]]))使用一个特征对鸢尾花进行分类训练得分如下:2.3.2 使用两个特征对鸢尾花进行分类使用两个特征对鸢尾花进行分类,如下代码:svm=svm.SVC() svm.fit(X[:,:1],y)输出训练得分:print("training score:",svm.score(X[:,:1],y)) print("predict: ",svm.predict([[7],[7.5]]))使用两个特征对鸢尾花进行分类训练得分如下:2.3.3 使用三个特征对鸢尾花进行分类使用三个特征对鸢尾花进行分类,如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='auto') svm.fit(X[:,1:3],y)输出训练得分:print("training score:",svm.score(X[:,1:3],y)) print("predict: ",svm.predict([[7,5],[7.5,4]]))使用三个特征对鸢尾花进行分类训练得分如下:2.3.4 可视化三个特征分类结果使用plt.subplot()函数用于直接指定划分方式和位置进行绘图。x_min,x_max=X[:,1].min()-1,X[:,1].max()+1 v_min,v_max=X[:,2].min()-1,X[:,2].max()+1 h=(x_max/x_min)/100 xx,vy =np.meshgrid(np.arange(x_min,x_max,h),np.arange(v_min,v_max,h)) plt.subplot(1,1,1) Z=svm.predict(np.c_[xx.ravel(),vy.ravel()]) Z=Z.reshape(xx.shape)绘图,输出可视化。如下代码plt.contourf(xx,vy,Z,cmap=plt.cm.Paired,alpha=0.8) plt.scatter(X[:, 1], X[:, 2], c=y, cmap=plt.cm.Paired) plt.xlabel('Sepal width') plt.vlabel('Petal length') plt.xlim(xx.min(), xx.max()) plt.title('SVC with linear kernel') plt.show()可视化三个特征分类结果图:2.4使用scikit-learn机器学习包的支持向量机算法,选择特征0和特征2对鸢尾花分类并画图,gamma参数分别设置为1、10、100,运行程序并截图,观察gamma参数对训练分数(score)的影响,请说明如果错误调整gamma参数会产生什么问题?2.4.1当gamma为1时:讲上文的gamma='auto‘ 里的auto改为1,得如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='1') svm.fit(X[:,1:3],y)运行上文可视化代码,得如下结果:2.4.2当gamma为10时:讲上文的gamma='auto‘ 里的auto改为10,得如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='10') svm.fit(X[:,:3:2],y)运行上文可视化代码,得如下结果:2.4.3当gamma为100时:讲上文的gamma='auto‘ 里的auto改为100,得如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='100') svm.fit(X[:,:3:2],y)运行上文可视化代码,得如下结果:2.4.4 结论参数gamma主要是对低维的样本进行高度度映射,gamma值越大映射的维度越高,训练的结果越好,但是越容易引起过拟合,即泛化能力低。通过上面的图可以看出gamma值越大,分数(score)越高。错误使用gamma值可能会引起过拟合,太低可能训练的结果太差。
  • [技术干货] 人脸识别:使用Scikit-Learn构建人脸识别系统
    什么是人脸识别人脸识别是将未知个体的人脸与存储记录数据库中的图像进行比较的任务。映射可以是一对一或一对多,这取决于我们是在运行人脸验证还是人脸识别。在本教程中,我们感兴趣的是构建一个面部识别系统,该系统将验证图像(通常称为探测图像)是否存在于预先存在的面部数据库(通常称为评估集)中。直觉建立这样一个系统涉及四个主要步骤:1.检测图像中的人脸可用的人脸检测模型包括MTCNN、FaceNet、Dlib等。2.裁剪和对齐人面OpenCV库提供了此步骤所需的所有工具。3.查找每个面的向量表示由于程序不能直接处理jpg或png文件,我们需要某种方法将图像转换为数字。在本教程中,我们将使用Insightface模型为人脸创建多维(512-d)嵌入,从而封装与人脸相关的有用语义信息。要使用单个库处理所有三个步骤,我们将使用insightface。特别是,我们将使用Insightface的ArcFace模型。InsightFace是一个开源的深度人脸分析模型,用于人脸识别、人脸检测和人脸对齐任务。4.比较嵌入一旦我们将每个唯一的人脸转换成一个向量,比较特征就归结为比较相应的嵌入。我们将利用这些嵌入来训练scikit-learn模型。另外,如果你想继续,代码可以在Github上找到:https://github.com/V-Sher/Face-Search。安装程序创建虚拟环境(可选):python3 -m venv face_search_env激活此环境:source face_search_env/bin/activate此环境中的必要安装:pip install mxnet==1.8.0.post0pip install -U insightface==0.2.1pip install onnx==1.10.1pip install onnxruntime==1.8.1更重要的是,完成pip安装insightface后:从onedrive下载antelope模型版本。(它包含两个预训练的检测和识别模型)。把它放在*~/.insightface/models/下,所以在~/.insightface/models/antelope.onnx*上有onnx模型。这是正确完成设置后的外观:如果你查看antelope目录,你会发现用于人脸检测和识别的两个onnx模型:注意:自从上周insightface 0.4.1的最新版本发布以来,安装并不像我希望的那样简单(至少对我来说)。因此,我将在本教程中使用0.2.1。将来,我将相应地更新Github上的代码。如果你被卡住了,请看这里的说明。数据集我们将使用Kaggle上提供的Yale人脸数据集,该数据集包含15个人的大约165张灰度图像(即每个人大概11张唯一图像)。这些图像由各种表情、姿势和照明组成。获得数据集后,继续将其解压缩到项目中新创建的数据目录中(请参阅Github上的项目目录结构)开始如果你想继续,可以在Github上找到Jupyter笔记本:https://github.com/V-Sher/Face-Search/blob/main/notebooks/face-search-yale.ipynb。导入import osimport pickleimport numpy as npfrom PIL import Imagefrom typing import Listfrom tqdm import tqdmfrom insightface.app import FaceAnalysisfrom sklearn.neighbors import NearestNeighbors加载Insightface模型安装insightface后,我们必须调用app=FaceAnalysis(name="model_name")来加载模型。由于我们将onnx模型存储在antelope目录中:app = FaceAnalysis(name="antelope")app.prepare(ctx_id=0, det_size=(640, 640))生成Insightface嵌入使用insightface模型为图像生成嵌入非常简单。例如:# 为图像生成嵌入img_emb_results = app.get(np.asarray(img))img_emb = img_emb_results[0].embeddingimg_emb.shape------------OUTPUT---------------(512,)数据集在使用此数据集之前,我们必须修复目录中文件的扩展名,使文件名以.gif结尾。(或.jpg、.png等)。例如,以下代码段将文件名subject01.glasses更改为subject01_glasses.gif。# 修复扩展名YALE_DIR = "../data/yalefaces"files = os.listdir(YALE_DIR)[1:]for i, img in enumerate(files):# print("original name: ", img)new_ext_name = "_".join(img.split(".")) + ".gif"# print("new name: ",  new_ext_name)os.rename(os.path.join(YALE_DIR, img), os.path.join(YALE_DIR, new_ext_name))接下来,我们将数据分为评估集和探测集:每个受试者90%或10张图像将成为评估集的一部分,每个受试者剩余的10%或1张图像将用于探测集中。为了避免采样偏差,将使用名为create_probe_eval_set的辅助函数随机选择每个对象的探测图像。它将包含属于特定主题的11个图像(文件名)的列表作为输入,并返回长度为1和10的两个列表。前者包含用于探测集的文件名,而后者包含用于评估集的文件名。def create_probe_eval_set(files: List):# 选择0和len(files)-1之间的随机索引random_idx = np.random.randint(0,len(files))probe_img_fpaths = [files[random_idx]]eval_img_fpaths = [files[idx] for idx in range(len(files)) if idx != random_idx]return probe_img_fpaths, eval_img_fpaths生成嵌入create_probe_eval_set返回的两个列表都按顺序送到名为generate_embs的助手函数。对于列表中的每个文件名,它读取灰度图像,将其转换为RGB,计算相应的嵌入,最后返回嵌入以及图像标签。def generate_embs(img_fpaths: List[str])embs_set = list()embs_label = list()for img_fpath in img_fpaths:  # 读取灰度图       img = Image.open(os.path.join(YALE_DIR, img_fpath))       img_arr = np.asarray(img)         # 将灰度转换为RGB       im = Image.fromarray((img_arr * 255).astype(np.uint8))       rgb_arr = np.asarray(im.convert('RGB'))            # 生成Insightface嵌入       res = app.get(rgb_arr)                 # 将emb添加到eval set       embs_set.append(res)                 # 添加标签到eval_label set       embs_label.append(img_fpath.split("_")[0])          return embs_set, embs_label现在我们有了一个生成嵌入的框架,让我们继续使用generate_embs()为探测和评估集创建嵌入。# 排序文件files = os.listdir(YALE_DIR)files.sort()eval_set = list()eval_labels = list()probe_set = list()probe_labels = list()IMAGES_PER_IDENTITY = 11for i in tqdm(range(1, len(files), IMAGES_PER_IDENTITY), unit_divisor=True): # 忽略在files[0]的README.txt文件# print(i)probe, eval = create_probe_eval_set(files[i:i+IMAGES_PER_IDENTITY])# 存储eval embs和标签eval_set_t, eval_labels_t = generate_embs(eval)eval_set.extend(eval_set_t)eval_labels.extend(eval_labels_t)# 存储探测embs和标签probe_set_t, probe_labels_t = generate_embs(probe)probe_set.extend(probe_set_t)probe_labels.extend(probe_labels_t)需要考虑的几件事:os.listdir返回的文件是完全随机的,因此第3行的排序很重要。不带排序和带排序的os.listdir输出:[可选]如果我们使用sklearn提供的分层训练测试功能,我们本可以替换create_probe_eval_set函数,去掉forloop,并简化上述代码段中的几行。然而,在本教程中,我将清晰性置于代码简单性之上。通常情况下,insightface无法检测到人脸,并随后为其生成空嵌入。这解释了为什么probe_setor eval_set列表中的某些条目可能为空。重要的是我们要过滤掉它们,只保留非空值。为此,我们创建了另一个名为filter_empty_embs的助手函数:def filter_empty_embs(img_set: List, img_labels: List[str]):# 在insightface无法生成嵌入的地方过滤filtering where insightface could not generate an embeddinggood_idx = [i for i,x in enumerate(img_set) if x]if len(good_idx) == len(img_set):       clean_embs = [e[0].embedding for e in img_set]       clean_labels = img_labels       else:       # 保留good_idx       clean_labels = np.array(img_labels)[good_idx]       clean_set = np.array(img_set, dtype=object)[good_idx]       # 生成embs       clean_embs = [e[0].embedding for e in clean_set]return clean_embs, clean_labels它将图像集(probe_set或eval_set)作为输入,并删除insightface无法生成嵌入的元素(参见第6行)。随后,它还会更新标签(probe_labels或eval_labels)(请参见第7行),以使集合和标签具有相同的长度。最后,对于评估集和探测集中,我们可以获得512维嵌入:evaluation_embs, evaluation_labels = filter_empty_embs(eval_set, eval_labels)probe_embs, probe_labels = filter_empty_embs(probe_set, probe_labels)assert len(evaluation_embs) == len(evaluation_labels)assert len(probe_embs) == len(probe_labels)有了这两套设备,我们现在可以使用Sklearn库中实现的一种流行的无监督学习方法来构建人脸识别系统。创建人脸识别系统我们使用.fit训练最近邻模型,评估嵌入为X。这是一种用于无监督最近邻学习的简洁技术。注:一般来说,距离可以是任何度量单位,如欧几里德、曼哈顿、余弦、闵可夫斯基等。# 最近邻学习方法nn = NearestNeighbors(n_neighbors=3, metric="cosine")nn.fit(X=evaluation_embs)# 保存模型到磁盘filename = 'faceID_model.pkl'with open(filename, 'wb') as file:pickle.dump(nn, file)# 过了一段时间…# 从磁盘加载模型# with open(filename, 'rb') as file:#     pickle_model = pickle.load(file)因为我们正在实施一种无监督的学习方法,请注意,我们没有将任何标签传递给fit方法,即评估标签。我们在这里所做的就是将评估集中的人脸嵌入映射到一个潜在空间中。为什么??简单回答:通过提前将训练集存储在内存中,我们可以在推理过程中加快搜索最近邻的速度。它是如何做到这一点的?简单回答:在内存中以优化的方式存储树是非常有用的,尤其是当训练集很大并且搜索新点的邻居时,计算成本会很高。基于邻域的方法被称为非泛化机器学习方法,因为它们只是“记住”其所有训练数据推理对于每个新的探测图像,我们可以通过使用nn.neights方法搜索其前k个邻域来确定它是否存在于评估集中。例如,# 测试图像的实例推理dists, inds = nn.kneighbors(X = probe_img_emb.reshape(1,-1),                           n_neighbors = 3,                           return_distances = True                           )如果评估集中返回索引(IND)处的标签与图像的原始/真实标签完全匹配,则我们知道我们在验证系统中找到了自己的脸。我们已经将上述逻辑包装到print_ID_results方法中。它将探测图像路径、评估集标签和详细标志作为输入,以指定是否应显示详细结果。def print_ID_results(img_fpath: str, evaluation_labels: np.ndarray, verbose: bool = False):   img = Image.open(img_fpath)img_emb = app.get(np.asarray(img))[0].embedding# 从KNN获取预测dists, inds = nn.kneighbors(X=img_emb.reshape(1,-1), n_neighbors=3, return_distance=True)# 获取邻居的标签pred_labels = [evaluation_labels[i] for i in inds[0]]# 检查dist是否大于0.5,如果是,打印结果no_of_matching_faces = np.sum([1 if d <=0.6 else 0 for d in dists[0]])if no_of_matching_faces > 0:       print("Matching face(s) found in database! ")       verbose = Trueelse:       print("No matching face(s) not found in database!")       # 打印标签和相应的距离 if verbose:       for label, dist in zip(pred_labels, dists[0]):print(f"Nearest neighbours found in the database have labels {label} and is at a distance of {dist}")这里需要注意的几个重要事项:IND包含评估标签集中最近邻的索引(第6行)。例如,inds=[[2,0,11]]意味着评估中索引=2处的标签被发现最靠近探测图像,然后是索引=0处的标签。因为对于任何图像,nn.neighbors都会返回非空响应。我们要过滤一些,如果返回的距离小于或等于0.6(行12),我们只考虑这些结果。(请注意,0.6的选择完全是任意的)。例如,继续上面的例子,其中Inds= [[2,0,11 ] ]和例子= [[ 0.4,0.6,0.9 ] ],我们将只考虑在索引=2和索引=0,因为最后一个邻居的距离太大。作为一个快速的健康检查,让我们看看当我们输入婴儿的脸作为探测图像时系统的响应。正如所料,它显示没有找到匹配的脸!但是,我们将verbose设置为True,因此我们可以在数据库中看到其伪近邻的标签和距离,所有这些都非常大(>0.8)。人脸识别系统的评价测试此系统是否良好的方法之一是查看前k个邻居中存在多少相关结果。相关结果是真实标签与预测标签匹配的结果。该度量通常称为k处的精确度,其中k是预先确定的。例如,从探测集中选择一个图像(或者更确切地说是一个嵌入),其真实标签为“subject01”。如果nn.Neighers为该图像返回的前两个pred_labels为['subject01','subject01'],则表示k处的精度(p@k)k=2时为100%。类似地,如果pred_labels中只有一个值等于“subject05”,p@k将是50%,依此类推…dists, inds = nn.kneighbors(X=probe_embs_example.reshape(1, -1),n_neighbors=2, return_distance=True)pred_labels = [evaluation_labels[i] for i in inds[0] ]pred_labels----- OUTPUT ------['002', '002']让我们继续计算整个探测集上p@k的平均值:# 探测集上的推理dists, inds = nn.kneighbors(X=probe_embs, n_neighbors=2, return_distance=True)# 计算平均p@kp_at_k = np.zeros(len(probe_embs))for i in range(len(probe_embs)):true_label = probe_labels[i]pred_neighbr_idx = inds[i]pred_labels = [evaluation_labels[id] for id in pred_neighbr_idx]pred_is_labels = [1 if label == true_label else 0 for label in pred_labels]p_at_k[i] = np.mean(pred_is_labels)p_at_k.mean()------ OUTPUT --------0.990%!还可以,但肯定可以继续改进。
  • [问题求助] Atlas 200dk安装scikit-image报错
    通过pip3 install--user scikit-image安装的时候,报错FileNotFoundError:[Errno 2] No useble temporary directory found in ['/tmp','var/tmp','usr/tmp','home/HwHiAiUser']用pip3 install  scikit-image安装的时候,报错OSError:[Error 30]Read-only file system:请问想用pip安一些包要怎么办
  • [其他] Scikit-learn的新特性学习
    自 2007 年发布以来,Scikit-learn 已经成为 Python 领域非常重要的机器学习库,支持分类、回归、降维和聚类四大机器学习算法,还包括了特征提取、数据处理和模型评估三大模块。总的来说,Scikit-learn 有以下优点:完善的文档,上手容易;丰富的 API,在学术界颇受欢迎;封装了大量的机器学习算法,包括 LIBSVM 和 LIBINEAR 等;内置了大量数据集,节省了获取和整理数据集的时间。和其他众多的开源项目一样,Scikit-learn 目前主要由社区成员自发进行维护。可能是由于维护成本的限制,Scikit-learn 相比其他项目要显得更为保守。但在刚刚到来的 2021 年,Scikit-learn 0.24.0 版本更新了,让我们看看新版本有哪些值得关注的新特性。1. 选择超参数更快的方法HalvingGridSearchCV 和 HalvingRandomSearchCV 将 GridSearchCV 和 RandomizedSearchCV 合并为超参数调优家族中资源密集度较低的成员。新类使用锦标赛方法(tournament approach)选择最佳超参数。它们在观测数据的子集上训练超参数组合,得分最高的超参数组合会进入下一轮。在下一轮中,它们会在大量观测中获得分数。比赛一直持续到最后一轮。确定传递给 HalvingGridSearchCV 或 halvingAndomSearchCV 的超参数需要进行一些计算,你也可以使用合理的默认值。HalvingGridSearchCV 使用所有超参数组合。RandomGridSearchCV 使用随机子集,就如 RandomizedSearchCV 一样。一些建议:如果没有太多的超参数需要调优,并且 pipeline 运行时间不长,请使用 GridSearchCV;对于较大的搜索空间和训练缓慢的模型,请使用 HalvingGridSearchCV;对于非常大的搜索空间和训练缓慢的模型,请使用 HalvingRandomSearchCV。在使用之前,这些类需要从 experimental 模块导入:from sklearn.experimental import enable_halving_search_cvfrom sklearn.model_selection import HalvingRandomSearchCV from sklearn.model_selection import HalvingGridSearchCV2. ICE 图Scikit-learn 0.23 版本引入了部分依赖图(PDP),PDP 对显示平均特征非常重要。而 Scikit-learn 0.24 版本则提供了显示个体条件期望(ICE)图的选项。与 PDP 一样,ICE 图显示了目标和输入特征之间的依赖关系。不同之处在于, ICE 图显示了对每个样本特征的预测依赖性——每个样本一行。特征的平均 ICE 为 PDP。通过将关键字参数 kind='individual'传递给 plot_partial_dependency 函数可以查看 ICE 图。而 PDP 和 ICE 则可以通过关键字参数 kind='both'进行查看。来自 scikit-learn gapminder 数据集的 PDP 和 ICE 图。3. 直方图 boosting 改进受 LightGBM 启发, HistGradientBoostingRegressor 和 HistGradientBoostingClassifier 现在有一个 categorical_features 参数,可用来提供分类特征支持。因为基于直方图的 booster 支持连续特征,这是一个不错的选择。与 one-hot 编码相比,它节省了训练时间,并且性能优于其他编码选项。但是,模型的输入特征需要是数值型的。如果分类特征不是数值型的,可以使用 OrdinalEncoder 进行数字编码。然后通过传递一个布尔掩码或一个整数数组来告诉 booster 哪些特征是用来分类的。例如:model = HistGradientBoostingRegressor( categorical_features=[True, False])在 scikit-learn 0.24 版本中,直方图 boosting 算法在速度和内存使用方面得到了改进。在 2020 年末,HistGradientBoostingClassifier 的基准拟合速度(benchmark fit speed)下降了近 75%。此外,请注意,基于直方图的估计器支持缺失值,因此,如果你不需要填充缺失值,则无需进行插补。这些估计器还处于试验阶段,因此启用估计器需要从 sklearn.experimental 导入。4. 前向选择用于特征选择选择特征子集时,SequentialFeatureSelector 从无特征开始,通过前向选择,逐渐添加特征,首先添加第一个最有价值的特征,然后添加第二个最有价值的特征,依此类推,直到到达选择的停止点。不同于特征选择转换器 RFE 和 SelectFromModel,SequentialFeatureSelector 不需要底层模型来公开 coef_或 feature_importances_属性。但是,SequentialFeatureSelector 可能比 RFE 和 SelectFromModel 这两个选项慢,因为它使用交叉验证来评估模型。5. 多项式特征展开的快速逼近PolynomialFeatures 转换器创建交互项和特征的高阶多项式。然而,这会让模型训练变得非常缓慢。来自 kernel_approximation 命名空间的 PolynomialCountSketch 核近似函数提供了一种更快的方法来训练具有预测优势的线性模型,该模型可以使用 PolynomialFeatures 进行近似。或者,你可以将 PolynomialCountSketch 视为具有径向基函数核的支持向量机的更快版本,只是在预测方面,性能差一点。PolynomialFeatures 返回平方特征和交互项(如果需要,还可以返回高阶多项式)。相反,PolynomialCountSketch 返回在 n_components 参数中指定的特征数。默认值为 100,建议文档字符串(docstring)中包含的特征数量是原始特征数量的 10 倍。这些特征表示多项式特征展开近似,但不能直接解释。6. 用于半监督学习的 SelfTrainingClassifierSelfTrainingClassifier 是一个新的用于半监督学习的元分类器。它允许所有可以预测属于目标类的样本概率的监督分类器作为半监督分类器,从未标记的观测结果中学习。请注意,y_train 中未标记值必须为 - 1,不能设置为 null。7. 平均绝对百分比误差 (MAPE)mean_absolute_percentage_error 函数现已被添加为回归问题评分指标。和 R-squared 一样,MAPE 在不同的回归问题中提供了一些比较值。你可以使用 np.mean(np.abs((y_test — preds)/y_test)) 手动计算 MAPE,但总体来说,这个函数还是非常有用的。8. OneHotEncoder 支持缺失值scikit-learn 0.24 版本的 OneHotEncoder 可以处理缺失值。如果在 X_train 中有一个 null 值,那么在转换后的列中将有一个列来表示缺失值。9. OrdinalEncoder 可以处理测试集中的新值你是否有存在于测试集中、但在训练集中没有的类别?如果有这种情况的话,将 handle_unknown='use_encoded_value' 关键字参数和新的 unknown_value 参数一起使用。你可以将 unknown_value 参数设置为未出现在序数编码值中的整数或 np.nan。这使得 OrdinalEncoder 更易于使用。10. 递归式特征消除(RFE)接受一定比例的特征保留向 n_features_to_select 传递一个 0 到 1 之间的浮点数,以控制要选择特性的百分比。这种添加使得以编程方式消除部分特征变得更容易。(本文转载自机器之心)