特征缩放和转换以及自定义Transformers(Machine Learning 研习之九)

特征缩放和转换

您需要应用于数据的最重要的转换之一是功能扩展。除了少数例外,机器学习算法在输入数值属性具有非常不同的尺度时表现不佳。住房数据就是这种情况:房间总数约为6至39320间,而收入中位数仅为0至15间。如果没有任何缩放,大多数模型将倾向于忽略收入中位数,而更多地关注房间数。

有两种常见的方法使所有属性具有相同的尺度:最小-最大尺度和标准化。

与所有估计器一样,重要的是仅将标量拟合到训练数据:永远不要对训练集以外的任何对象使用fit()或fit_transform()。一旦你有了一个训练好的定标器,你就可以用它来变换()任何其他的集合,包括验证集、测试集和新的数据。请注意,虽然培训集值将始终缩放到指定的范围,但如果新的数据包含异常值,则这些值最终可能会缩放到该范围之外。如果要避免这种情况,只需将剪辑超参数设置为True即可。

最小-最大缩放(许多人称之为标准化)是最简单的:对于每个属性,值被移位和重新缩放,以便它们最终的范围从0到1。这是通过减去最小值并除以最小值和最大值之间的差来实现的。Scikit-Learn为此提供了一个名为MinMaxScaler的转换器。它有一个feature_range超参数,如果出于某种原因,不希望0-1(例如,神经网络在零均值输入下工作得最好,所以最好在-1到1的范围内工作)。是相当好用的:

from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler(feature_range=(-1, 1))
housing_num_min_max_scaled = min_max_scaler.fit_transform(housing_num)

标准化是不同的:首先它减去平均值(所以标准化值有一个零均值),然后它除以标准差(所以标准-化值的标准差等于1)。不像最小最大缩放,标准化化不会将值限制在特定的范围内。然而,标准化受到离群值的影响要小得多。例如,假设一个地区的收入中位数等于100(误打误撞),而不是通常的0-15。将最小最大值缩放到0-1范围会将这个离群值映射到1并将所有其他值压缩到0-0.15,而标准化不会受到太大影响。Scikit-Learn提供了一个名为StandardScaler的转换器用于标准化:

from sklearn.preprocessing import StandardScaler
std_scaler = StandardScaler()
housing_num_std_scaled = std_scaler.fit_transform(housing_num)

如果你想缩放一个稀疏矩阵而不首先将其转换为稠密矩阵,你可以使用一个标准缩放器,它的with_mean超参数设置为False它只会除以标准差,而不会减去均值(因为这会破坏稀疏性

当特征的分布具有重尾时(即,当远离平均值的值不是指数罕见时),最小-最大缩放和标准化都会将大多数值压缩到一个小范围内。 机器学习模型通常根本不喜欢这种情况,因此,在缩放特征之前,您应该首先对其进行变换以缩小重尾,并且如果可能的话,使分布大致对称。 例如,对于右侧有重尾部的正特征,执行此操作的常见方法是用其平方根替换特征(或将特征提高到 0 到 1 之间的幂)。 如果该特征具有非常长且重的尾部,例如幂律分布,则用其对数替换该特征可能会有所帮助。 例如,人口特征大致遵循幂律:拥有 10,000 名居民的地区的出现频率仅比拥有 1,000 名居民的地区低 10 倍,而不是呈指数级下降。 下图 显示了当你计算它的对数时这个特征看起来有多好:它非常接近高斯分布(即钟形)。

在这里插入图片描述

另一种处理重尾特征的方法是对特征进行反向转换。这意味着将其分布切割成大致相等大小的桶,并将每个特征值替换为它所属的桶的索引,就像我们创建收入猫特征一样(尽管我们只在分层抽样时使用它)。例如,您可以将每个值替换为其百分位数。使用相同大小的bucket处理会产生一个几乎均匀分布的特性,因此不需要进一步的缩放,或者您可以只除以bucket的数目来强制值到0-1的范围。

当一个特征具有多峰分布(即,有两个或两个以上清晰的峰值,称为模式)时,例housing_median_age特征,对它进行bucket ization也是有帮助的,但这次将bucket ID作为类别处理,而不是作为数值。这意味着必须对桶索引进行编码,例如使用OneHotEncoder(所以你通常不想用太多桶)。这种方法将允许回归模型更容易地为该特征值的不同范围学习不同的规则。例如,也许35年前建造的房子有一种独特的风格,已经过时了,因此它们比它们的年龄更便宜。

转换多峰分布的另一种方法是为每个模式(至少是主要模式)添加一个特征,表示住房中位年龄和该特定模式之间的相似性。相似性度量通常使用径向基函数(RBF)来计算–任何只依赖于输入值与不动点之间距离的函数。最常用的RBF是高斯RBF,其输出值随着输入值远离固定点而呈指数衰减。例如,高斯RBF相似度与房龄x和35由方程exp (-y (x-35)2)给出。超参数y(gamma)确定当x远离35时相似性度量衰减的速度。使用Scikit-Learn的rbf_kernel()函数,您可以创建一个新的高斯RBF特征来测量房屋中位年龄和35:

from sklearn.metrics.pairwise import rbf_kernel
age_simil_35 = rbf_kernel(housing[["housing_median_age"]], [[35]], gamma=0.1)

下图显示了这一新特征作为住房中位数年龄的函数(实线)。它还显示了如果使用较小的gamma值,该功能将是什么样子。如图所示,新的年龄相似性特征在35岁时达到峰值,正好在住房中位年龄分布的峰值附近:如果这个特定的年龄组与较低的价格有很好的相关性,那么这个新特征将有很好的机会发挥作用。

在这里插入图片描述

到目前为止,我们只看了输入特性,但是目标值可能也需要转换。例如,若目标分布具有较重的尾部,您可以选择将目标替换为其对数。但是,如果你这样做,回归模型现在将预测的房屋价值中位数的对数,而不是房屋价值中位数本身。如果您想要预测的房屋中值,则需要计算模型预测的指数值。

幸运的是,大多数Scikit-Learn的转换器都有一个inverse_transform()方法,这使得计算转换的逆运算变得很容易。例如,下面的代码示例显示了如何使用StandardScaler缩放标签(就像我们对输入所做的那样),然后在缩放后的标签上训练一个简单的线性回归模型,并使用它对一些新数据进行预测,然后使用经过训练的缩放器的inverse_transform()方法将这些数据转换回原始尺度。请注意,我们将标签从Pandas Series转换为DataFrame,因为标准Scaler期望2D输入。此外,为了简单起见,在本示例中,我们仅使用单个原始输入特征(中值收入)对模型进行训练:

from sklearn.linear_model import LinearRegression
target_scaler = StandardScaler()
scaled_labels = target_scaler.fit_transform(housing_labels.to_frame())
model = LinearRegression()
model.fit(housing[["median_income"]], scaled_labels)
some_new_data = housing[["median_income"]].iloc[:5] # pretend this is new data
scaled_predictions = model.predict(some_new_data)
predictions = target_scaler.inverse_transform(scaled_predictions)

这工作得很好,但更简单的选择是使用TransformedTargetRegressor。我们只需要构造它,给它回归模型和标签转换器,然后使用原始的未缩放标签将其拟合到训练集上。它将自动使用转换器缩放标签,并在缩放后的标签上训练回归模型,就像我们之前所做的那样。然后,当我们想要进行预测时,它将调用回归模型的predict()方法,并使用scaler的inverse_trans form()方法生成预测:

from sklearn.compose import TransformedTargetRegressor
model = TransformedTargetRegressor(LinearRegression(),
transformer=StandardScaler())
model.fit(housing[["median_income"]], housing_labels)
predictions = model.predict(some_new_data)

自定义Transformers

虽然Scikit-Learn提供了许多有用的转换器,但您需要编写自己的任务,如自定义转换、清理操作或组合特定属性。

对于不需要任何训练的转换,您可以只编写一个函数,该函数接受NumPy数组作为输入,并输出转换后的数组。例如,如前一节所述,通过将具有重尾分布的特征替换为它们的对数(假设特征为正数且尾部位于右侧),通常是一个好主意。让我们创建一个log-transformer,并将其应用于人口特征:

from sklearn.preprocessing import FunctionTransformer
log_transformer = FunctionTransformer(np.log, inverse_func=np.exp)
log_pop = log_transformer.transform(housing[["population"]])

inverse_func参数是可选的。它允许您指定一个逆变换函数,例如,如果您计划在
TransformedTargetRegressor中使用您的转换器。转换函数可以接受超参数作为附加参数。例如,以下是如何创建一个转换器,计算与前面相同的高斯RBF相似性度量:

rbf_transformer = FunctionTransformer(rbf_kernel,
kw_args=dict(Y=[[35.]], gamma=0.1))
age_simil_35 = rbf_transformer.transform(housing[["housing_median_age"]]

注意,RBF核没有反函数,因为在距离一个固定点的给定距离上总是有两个值(距离0除外)。还要注意rbf_kernel()不会单独处理这些特性。如果你给它传递一个有两个特征的数组,它会测量二维距离(欧几里得)来测量相似性。例如,以下是如何添加一个功能,该功能将测量每个区和旧金山之间的地理相似性:

sf_coords = 37.7749, -122.41
sf_transformer = FunctionTransformer(rbf_kernel,
kw_args=dict(Y=[sf_coords], gamma=0.1))
sf_simil = sf_transformer.transform(housing[["latitude", "longitude"]])

自定义transformers对于组合功能也很有用。例如,这里有一个FunctionTransformer,它计算输入特征0和1之间的比率:

在这里插入图片描述

FunctionTransformer非常方便,但是如果您希望您的转换器是可训练的,在fit()方法中学习一些参数,然后在transform()方法中使用它们,那该怎么办呢?为此,您需要编写一个自定义类。Scikit-Learn依赖于duck类型,所以这个类不必从任何特定的基类继承。它只需要三个方法:fit()(必须返回self)、
transform () 和fit_transform()。

只需添加TransformerMixin作为基类,就可以免费获得fit_transform():默认实现将只调用fit(),然后再调用transform()。如果将BaseEstimator添加为基类(并避免使用*args和**kwargs),您还将获得两个额外的方法:get_params ()和set_params()。这些对于自动超参数调优非常有用。

例如,这里有一个自定义 transformer,其行为与StandardScaler非常相似:

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.utils.validation import check_array, check_is_fitted
class StandardScalerClone(BaseEstimator, TransformerMixin):
    def __init__(self, with_mean=True): # no *args or **kwargs!
    	self.with_mean = with_mean
    def fit(self, X, y=None): # y is required even though we don't use it
        X = check_array(X) # checks that X is an array with finite float values
        self.mean_ = X.mean(axis=0)
        self.scale_ = X.std(axis=0)
        self.n_features_in_ = X.shape[1] # every estimator stores this in fit()
        return self # always return self!
    def transform(self, X):
        check_is_fitted(self) # looks for learned attributes (with trailing _)
        X = check_array(X)
        assert self.n_features_in_ == X.shape[1]
        if self.with_mean:
        X = X - self.mean_
        return X / self.scal

这里有几点需要注意:

  • sklearn.utils.validation包包含几个我们可以用来验证输入的函数。为了简单起见,我们将在本书的其余部分跳过这样的测试,但是产品代码应该有这些测试。
  • Scikit-Learn管道要求fit()方法有两个参数X和y,这就是为什么我们需要y=没有参数,即使我们不使用y。
  • 所有Scikit-Learn估计器都在fit()方法中设置n_features_in_,并且它们确保传递给transform()或predict()的数据具有此数量的特征。_
  • .fit ()方法必须返回self。
  • 这个实现不是100%完成的:所有的估算器都应该在拟合中设置feature_
    names_in_ ()方法时,它们被传递一个DataFrame。此外,所有的转换器都
    应该提供get_feature_names_out()方法,以及当它们的转换可以被逆转时
    的inverse_transform()方法。更多细节请参见本章最后一个练习。

自定义转换器可以(而且经常)在其实现中使用其他估计器。例如,以下代码演示了自定义转换器,该转换器在fit()方法中使用KMeans聚类器来识别训练数据中的主要聚类,然后在transform()方法中使用rbf
kernel ()来衡量每个样本与每个聚类中心的相似程度:

from sklearn.cluster import KMeans
class ClusterSimilarity(BaseEstimator, TransformerMixin):
    def __init__(self, n_clusters=10, gamma=1.0, random_state=None):
        self.n_clusters = n_clusters
        self.gamma = gamma
        self.random_state = random_state
    def fit(self, X, y=None, sample_weight=None):
        self.kmeans_ = KMeans(self.n_clusters, random_state=self.random_state)
        self.kmeans_.fit(X, sample_weight=sample_weight)
        return self # always return self!
    def transform(self, X):
    	return rbf_kernel(X, self.kmeans_.cluster_centers_, gamma=self.gamma)
    def get_feature_names_out(self, names=None):
    	return [f"Cluster {i} similarity" for i in range(self.n_clusters)]

k-means是一种在数据中定位聚类的聚类算法。它搜索的数量由n_clusters超参数控制。训练后,可以通过cluster_centers_属性使用聚类中心。KMeans的fit()方法支持一个可选参数sample_weight,该参数允许用户指定样本的相对权重。K-means是一种随机算法,这意味着它依赖随机性来定位聚类,因此若您想要可重现的结果,则必须设置random_state参数。正如您所看到的,尽管任务很复杂,但代码相当简单。现在让我们使用这个自定义的变压器:

cluster_simil = ClusterSimilarity(n_clusters=10, gamma=1., random_state=42)
similarities = cluster_simil.fit_transform(housing[["latitude", "longitude"]],
sample_weight=housing_labels)

这段代码创建一个ClusterSimilarity转换器,将集群数设置为10.然后调用fit_transform(),输入训练集中每个区的纬度和经度,并根据每个区的房屋中值对每个区进行加权。变压器采用k-均值定位聚类,
然后测量每个区域与所有10个聚类中心之间的高斯RBF相似性。结果是一个矩阵,每个区有一行,每个集群有一列。先看前三行,四舍五入到小数点后两位:

在这里插入图片描述

下图显示了通过k-means找到的10个聚类中心。根据它们与最近的集群中心的地理相似性,对这些区域进行着色。正如您所看到的,大多数集群都位于人口密集且价格昂贵的地区。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/162205.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

anaconda安装依赖报错ERROR: Cannot unpack file C:\Users\33659\AppData\Loca...|问题记录

执行命令: # 安装matplotlib依赖 pip install matplotlib-i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com出现问题: ERROR: Cannot unpack file C:\Users\33659\AppData\Local\Temp\pip-unpack-0au_blfq\simple (downloa…

Redis面经

Redis使用场景 1、缓存: 缓存三兄弟(穿透、击穿、雪崩) 、双写一致、持久化、数据过期策略,数据淘汰策略 2、分布式锁 setnx、redisson 3、消息队列 4、延迟队列 何种数据类型(list、zset) 缓存三兄弟 缓存穿透 缓存穿透…

【RH850芯片】RH850U2A芯片平台Spinlock的底层实现

目录 前言 正文 1.RH850U2A上的原子操作 1.1 Link 1.2 Link generation 1.3 Success in storing 1.4 Failure in storing 1.5 Condition for successful storing 1.6 Loss of the link 1.7 示例代码 2.Spinlock代码分析 2.1 尝试获取Spinlock 2.2 释放Spinlock …

Web前端—移动Web第二天(空间转换、动画、综合案例:全名出游)

版本说明 当前版本号[20231118]。 版本修改说明20231118初版 目录 文章目录 版本说明目录移动 Web 第二天01-空间转换空间转换简介平移视距旋转左手法则rotate3d-了解立体呈现案例-3d导航缩放 02-动画动画实现步骤animation复合属性animation拆分写法案例-走马灯精灵动画多组…

一款带数字传输信号的OVP芯片

基本概述 今天给大家介绍的一款芯片是OVP,相比于传统的OVP芯片来说,这款芯片新增了数字信号控制,可以进行10Mbps的一个通信,通过外部的GPIO口进行控制,达到输入与输出信号的产生。 YHM2009这款OVP芯片具有较低的导通…

图像分类(一) 全面解读复现AlexNet

解读 论文原文:http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf Abstract-摘要 翻译 我们训练了一个庞大的深层卷积神经网络,将ImageNet LSVRC-2010比赛中的120万张高分辨率图像分为1000个不…

如何实现一个下班倒计时程序

shigen日更文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。 Hello伙伴们,好几天不见啦。最近也是晚上打球太累,加上一直在研究mybatis的多租户问题&…

LM(大模型)应用开发利器之LangChain,带你走进AI世界

原文:LLM(大模型)应用开发利器之LangChain,带你走进AI世界 - 简书 LangChain组件图 LangChain 是什么 首先 LangChain 是一个框架,这个框架是用来让开发者进行 LLMs (大语言模型)应用开发的。…

【Unity】单例模式及游戏声音管理类应用

【Unity】单例模式及游戏声音管理类应用 描述 在日常游戏项目开发中,单例模式是一种常用的设计模式,它允许在应用程序的生命周期中只创建一个对象实例,并提供对该实例的全局访问点。通过使用单例模式,可以提高代码的可维护性和可…

【18年扬大真题】定义一个类Student记录学生计算机课程的成绩。要求使用静态成员变量或静态成员函数计算全班学生计算机课程的总成绩和平均成绩

【18年扬大真题】 定义一个类Student记录学生计算机课程的成绩。要求使用静态成员变量或静态成员函数计算全班学生计算机课程的总成绩和平均成绩 #include<stdio.h> #define n 5;//假设5个学生 typedef struct {char name[10];float score; }stu;int main() {printf(&qu…

LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字

上一节实现了 LangChain 实现给动物取名字&#xff0c; 实际上每次给不同的动物取名字&#xff0c;还得修改源代码&#xff0c;这周就用模块化template来实现。 1. 添加promptTemplate from langchain.llms import OpenAI # 导入Langchain库中的OpenAI模块 from langchain.p…

数据结构详细笔记——图

文章目录 图的定义图的存储邻接矩阵法邻接表法邻接矩阵法与邻接表法的区别 图的基本操作图的遍历广度优先遍历&#xff08;BFS&#xff09;深度优先遍历&#xff08;DFS&#xff09;图的遍历和图的连通性 图的定义 图G由顶点集V和边集E组成&#xff0c;记为G(V,E)&#xff0c;…

首发|PS 2024 正式版来袭,内置AI神经滤镜,支持Win/Mac

前言 Photoshop 2024应用程序发布了生成式AI绘图&#xff0c;这是世界上第一个创意和设计工作流程的软件&#xff0c;为用户提供了一种神奇的新工作方式。生成式AI绘图由Adobe Firefly提供支持&#xff0c;Adobe的创意生成AI模型系列。 正文简介 Photoshop 2024正式版 支持…

【Linux从入门到放弃】环境变量

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《Linux从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 文…

torch.stack

看网上看多没讲的不是很明白&#xff0c;我来试试空间上的理解 # 假设是时间步T1的输出 T1 torch.tensor([[1, 2, 3],[4, 5, 6],[7, 8, 9]]) # 假设是时间步T2的输出 T2 torch.tensor([[10, 20, 30],[40, 50, 60],[70, 80, 90]])输出&#xff1a; print(torch.stack((T1,T2…

Spring Boot中配置文件生效位置

1. 配置文件位置 首先小伙伴们要明白&#xff0c;Spring Boot 默认加载的配置文件是 application.properties 或者 application.yaml&#xff0c;properties优先级高于yaml。默认的加载位置一共有五个&#xff0c;五个位置可以分为两类&#xff1a; 从 classpath 下加载&…

设计模式-行为型模式-责任链模式

一、什么是责任链模式 责任链模式是一种设计模式。在责任链模式里&#xff0c;很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递&#xff0c;直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求&…

【数据分享】2023年我国省市县三级的专精特新“小巨人”企业数量(Excel/Shp格式)

企业是经济活动的参与主体。一个城市的企业数量决定了这个城市的经济发展水平&#xff01;比如一个城市的金融企业较多&#xff0c;那这个城市的金融产业肯定比较发达&#xff1b;一个城市的制造业企业较多&#xff0c;那这个城市的制造业肯定比较发达。 之前我们给大家分享了…

【数据结构】10道经典面试题目带你玩转链表

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.移除链表元素 二.反转链表 三.链表的中间结点 四.链表中倒数第K个结点 五.合并两个有序链表 六.链表分割 七.链表的回文结构 八.相交链表 九.环形链表 一.移…

国内优质企业网盘推荐:满足您的文件存储与共享需求

企业网盘是主要用于企业工作过程中给的文件存储、共享以及协作。很多用户在挑选文件协作工具时更偏爱国内的工具&#xff0c;原因是使用上可能更贴合国人的使用习惯&#xff01; 那么现在国内做的比较好的企业网盘有什么&#xff1f; Zoho Workdrive企业网盘&#xff0c;ZOHO…