flash网站开发,php网站开发教程培训,网线制作心得,小程序平台推广方案预测模型主要分为两大类#xff1a; 回归模型#xff1a;当你的目标变量是连续的数值时#xff0c;你会使用回归模型进行预测。回归模型试图找到输入特征和连续输出之间的关联。一些常见的回归模型包括#xff1a; 线性回归#xff08;Linear Regression#xff09;岭回归… 预测模型主要分为两大类 回归模型当你的目标变量是连续的数值时你会使用回归模型进行预测。回归模型试图找到输入特征和连续输出之间的关联。一些常见的回归模型包括 线性回归Linear Regression岭回归Ridge RegressionLASSO回归LASSO Regression弹性网回归Elastic Net Regression决策树回归Decision Tree Regression随机森林回归Random Forest Regression梯度提升回归Gradient Boosting RegressionXGBoost和LightGBM等基于树的模型支持向量回归Support Vector Regression 分类模型当你的目标变量是离散的类别时你会使用分类模型进行预测。分类模型试图找到输入特征和离散标签之间的关联。一些常见的分类模型包括 逻辑回归Logistic RegressionK最近邻分类K-Nearest Neighbors Classification支持向量机分类Support Vector Machine Classification决策树分类Decision Tree Classification随机森林分类Random Forest Classification梯度提升分类Gradient Boosting Classification神经网络分类Neural Network Classification
常见的离散类别实例
性别男、女有些情况下会考虑更多性别类别。血型A型、B型、AB型、O型。产品类型手机、电脑、平板等。教育水平小学、中学、大学等。天气状况晴、阴、雨、雪等。
常见的连续数值实例
身高一个人身高可以是1.75米也可以是1.76米、1.75501米等等。温度温度计可以测量从绝对零度到几千度的任意温度值。时间时间可以精确到秒、毫秒、微秒等并且可以在两个整点之间取任意值。重量物体的重量可以在一定范围内取任意值如50.5千克、55.375千克等。价格商品的价格可以是连续的如99.99美元。
我一共用了两种方法
下面是我参考李沐大神写的算法以及理解他用的是神经网络和k折线
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import torch
from torch import nn
from d2l import torch as d2l
import numpy as np
train_data pd.read_csv(C:\\Users\\91144\\Desktop\\kaggle比赛数据\\房屋价格\\train.csv)
test_data pd.read_csv(C:\\Users\\91144\\Desktop\\kaggle比赛数据\\房屋价格\\test.csv)
print(train_data.shape)
print(test_data.shape) print(pd.DataFrame(train_data)) 我们先把无关的两列去掉ID和目标变量
#这通常是因为第一列是索引最后一列是目标变量。all_features pd.concat((train_data.iloc[:,1:-1],test_data.iloc[:,-1]))
标准化
#找到数字列
numeric_features all_features.dtypes[all_features.dtypes !object].index#这段代码的目的是对所有的数值特征进行标准化处理。标准化是一种常见的特征缩放方法它能够将特征的分布转变为均值为0标准差为1的标准正态分布。这样可以消除特征之间的尺度差异有利于模型的训练。
all_features[numeric_features] all_features[numeric_features].apply(lambda x: (x-x.mean())/(x.std()))#它会将DataFrame中所有的NaN值替换为括号里的值这里是0。
all_features[numeric_features] all_features[numeric_features].fillna(0)
处理离散值
all_features pd.get_dummies(all_features,dummy_na True)
all_features.shape print(all_features.dtypes)
#指定了要选择的数据类型。np.number 是NumPy的一个类表示所有的数值类型包括整数和浮点数。
print(all_features.dtypes)
#指定了要选择的数据类型。np.number 是NumPy的一个类表示所有的数值类型包括整数和浮点数。
all_features all_features.select_dtypes(include[np.number])#LabelEncoder 标签的编码是按照字母顺序进行的它可以将分类特征的标签转换为数值。
from sklearn.preprocessing import LabelEncoder
label_encoder LabelEncoder()
#将字符串类型转化为数字
for col in all_features.columns:if all_features[col].dtype object:all_features[col] label_encoder.fit_transform(all_features[col]) 数据通常被转化为张量tensor进行处理原因有以下几点
GPU 加速张量运算可以在 GPU 上进行这通常比在 CPU 上进行计算更快。这是因为 GPU 是专门为并行运算设计的能够同时处理大量的数据而深度学习中通常需要对大量的数据进行相同的运算。PyTorch 的张量Tensor和 TensorFlow 的张量都支持 GPU 加速。
统一的数据结构在深度学习框架中无论是输入数据、模型权重、偏置项、激活值还是梯度都是以张量的形式存在的。这样所有的运算都可以统一为张量运算简化了编程。
自动求导深度学习框架通常提供了自动求导的功能。在 PyTorch 和 TensorFlow 中只要张量的 requires_grad 属性被设置为 True那么在进行运算时就会自动构建计算图从而可以自动计算梯度。这对于深度学习中的反向传播算法非常有用。
批处理在机器学习和深度学习中通常会一次处理多个样本这被称为批处理。批处理可以提高计算效率并且可以使模型的更新更加平稳。张量很自然地支持批处理因为它是一个多维数组可以用一个维度来表示批次中的样本。
n_train train_data.shape[0]
train_features torch.tensor(all_features[:n_train].values, # 从 DataFrame 中选取前 n_train 行并转换为 numpy 数组dtype torch.float32)# 将 numpy 数组转换为 PyTorch 张量并指定数据类型为 float32
test_features torch.tensor(all_features[n_train:].values,dtype torch.float32) #将 numpy 数组转换为 PyTorch 张量并指定数据类型为 torch.float32。
train_labels torch.tensor(train_data[SalePrice].values.reshape(-1,1),dtype torch.float32)
loss nn.MSELoss() #定义了损失函数为均方误差Mean Squared Error, MSE
in_features train_features.shape[1] #获取训练数据的特征数量。#定义了一个简单的神经网络。这个网络只包含一个线性层nn.Linear输入特征的数量为 in_features输出一个值。nn.Sequential 是一个容器它按照顺序包含了一系列的模块。在这个例子中只有一个模块就是线性层。
def get_net():net nn.Sequential(nn.Linear(in_features,1))return net
#它实现了从输入特征到输出预测值的线性映射。
net(features) 就是在用神经网络模型 net 根据特征 features 来进行预测。这个预测的结果我们可以看作是模型对于每个输入样本的标签的预测值。然后我们可以将这个预测值和真实的标签进行比较计算出一个损失值loss这个损失值表示模型的预测结果和真实结果之间的差距。通过最小化这个损失值我们可以训练模型以使其预测结果更接近真实结果。 这种误差度量通常用于评估预测模型的性能特别是在预测正数连续值时例如销售量、价格等。RMSLE 是一种惩罚低估比高估更严重的损失函数。
def log_rmse(net,features,labels):clipped_preds torch.clamp(net(features),1,float(inf)) #torch.clamp
函数将预测值限制在 [1, ∞) 范围内。这是为了避免在下一步计算对数时出现问题
因为对数函数在 (0, ∞) 范围内是定义的。rmse torch.sqrt(loss(torch.log(clipped_preds),torch.log(labels))) #均方误差return rmse.item() def train(net,train_features,train_labels,test_features,test_labels,num_epochs,learning_rate,weight_decay,batch_size):train_ls,test_ls [],[]train_iter d2l.load_array((train_features,train_labels),batch_size) #d2l.load_array 函数将训练集的特征和标签加载到一个迭代器中这样就可以按照批量大小进行迭代。optimizer torch.optim.Adam(net.parameters(),lr learning_rate,weight_decay weight_decay)for epoch in range(num_epochs):for X,y in train_iter:optimizer.zero_grad() #梯度清零l loss(net(X),y) l.backward() #进行反向传播计算损失 l 对模型参数的梯度。optimizer.step() # 这行代码使用计算出的梯度更新模型的参数。train_ls.append(log_rmse(net,train_features,train_labels)) #计算训练集的对数均方根误差log RMSE并将其添加到 train_ls 列表中。if test_labels is not None:test_ls.append(log_rmse(net,test_features,test_labels))return train_ls,test_ls
k 折交叉验证是一种常用的模型验证技术它将数据集分为 k 个子集每次将其中一个子集作为验证集其余的子集作为训练集。这个过程重复 k 次每个子集都有一次机会作为验证集。
#k折交叉验证集的数据分割
def get_k_fold_data(k,i,X,y):assert k 1fold_size X.shape[0]//kX_train,y_train None,Nonefor j in range(k):idx slice(j*fold_size,(j1)*fold_size) #创建一个切片对象用于选取第 j 个折的数据。X_part,y_part X[idx,:],y[idx]if ji:X_valid,y_valid X_part,y_partelif X_train is None:X_train,y_train X_part,y_partelse:X_train torch.cat([X_train,X_part],0) #将当前折的特征添加到训练特征中。y_train torch.cat([y_train,y_part],0) #当前折的标签添加到训练标签中。return X_train,y_train,X_valid,y_valid
使用了 k 折交叉验证来训练和验证神经网络模型。
def k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay, batch_size):train_l_sum, valid_l_sum 0, 0fold 1epochs range(1, num_epochs 1)for i in range(k):data get_k_fold_data(k, i, X_train, y_train)net get_net()train_ls, valid_ls train(net, *data, num_epochs, learning_rate, weight_decay, batch_size)train_l_sum train_ls[-1]valid_l_sum valid_ls[-1]if i 0:epochs list(range(1, num_epochs 1))d2l.plot(epochs, [train_ls, valid_ls], xlabelepoch, ylabelrmse, xlim[1, num_epochs],legend[train, valid], yscalelog)print(ffold {fold}, train log rmse {float(train_ls[-1]):f}, valid log rmse {float(valid_ls[-1]):f})fold 1return train_l_sum / k, valid_l_sum / k
k,num_epochs,lr,weight_decay,batch_size 5,100,5,0,64
epochs list(range(1, num_epochs 1)) #创建了一个包含所有训练周期的列表。
train_l,valid_l k_fold(k,train_features,train_labels,num_epochs,lr, #使用 k 折交叉验证来训练和验证模型并获取训练损失和验证损失。weight_decay,batch_size)
print(f{k}-折验证平均训练log rmse:{float(train_l):f},f平均验证log rmse:{float(valid_l):f}) def train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size):net get_net()train_ls, _ train(net, train_features, train_labels, None, None, num_epochs, lr, weight_decay, batch_size)d2l.plot(np.arange(1, num_epochs 1), [train_ls], xlabelepoch, ylabellog rmse, xlim[1, num_epochs], yscalelog)print(ftrain log rmse {float(train_ls[-1]):f})preds net(test_features).detach().numpy()preds preds.flatten() # 将二维数组转换为一维数组test_data[SalePrice] pd.Series(preds)submission pd.concat([test_data[Id], test_data[SalePrice]], axis1)submission.to_csv(submission.csv, indexFalse)# 调用函数
train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size) 以下是使用k折交叉验证来评估神经网络模型的一般步骤 准备数据确保你的数据集已经被加载并且准备好用于训练。 定义神经网络模型创建一个神经网络模型类或函数。 初始化评估指标选择一个或多个评估指标如准确率、均方误差等。 k折循环 将数据集分成k个子集。对于每一个子集 使用剩下的k-1个子集作为训练集来训练模型。使用当前的子集作为验证集来评估模型。记录评估指标。 计算平均评估指标计算所有k次迭代的平均评估指标。 分析结果分析k折交叉验证的结果以确定模型的性能。 然后是根据讯飞的老师写的算法运用堆叠法
from scipy.stats import norm,skew#获取统计信息
from scipy import stats
import numpy as np
import pandas as pd
import seaborn as sns
color sns.color_palette() #创建了一个颜色调色板可以用于 seaborn 图形的颜色设置。
sns.set_style(darkgrid) #这行代码设置了 seaborn 图形的风格。
import matplotlib.pyplot as plt
%matplotlib inline #这行是 Jupyter Notebook 的魔术命令用于在 notebook 中内嵌显示图形。pd.set_option(display.float_format,lambda x:{:3f}.format(x))#限制浮点输出到小数点后3位
train pd.read_csv(C:\\Users\\91144\\Desktop\\kaggle比赛数据\\房屋价格\\train.csv)
test pd.read_csv(C:\\Users\\91144\\Desktop\\kaggle比赛数据\\房屋价格\\test.csv)
#检查样本和特征的数量
print(删除Id列前训练集大小{}.format(train.shape))
print(删除Id列前测试集大小{}.format(test.shape)) #保存Id列
train_ID train[Id]
test_ID test[Id]
#Id列用不到
#删除原数据的Id列
train.drop(Id,axis 1 ,inplace True)
test.drop(Id,axis 1,inplace True)
数据处理和特征工程
异常值处理
将数据可视化后可看见有几个点远离了将他们删除
#观察是否有离群值
plt.figure(figsize (14,4))plt.subplot(121)
plt.scatter(x train[GrLivArea],y train[SalePrice])
plt.ylabel(SalePrice,fontsize13)
plt.xlabel(GrLivArea,fontsize13)train train.drop(train[(train[GrLivArea]4000)(train[SalePrice]300000)].index)目标变量分析
看数据是否符合正态分布
#分布图
fig,ax plt.subplots(nrows 2,figsize (6,10))
sns.distplot(train[SalePrice],fit norm,axax[0])
(mu,sigma) norm.fit(train[SalePrice]) #正态分布
ax[0].legend([Normal dist.($\mu$ {:.2f} and $\sigma ${:.2f}).format(mu,sigma)],loc best)
ax[0].set_ylabel(Frequency)
ax[0].set_title(SalePrice distribution)
#QQ图 如果QQ图的点分布在一条直线上那说明数据近似正态分布斜率为标准差截距为均值
stats.probplot(train[SalePrice],plotax[1])
plt.show() QQ 图又称为量-量图Quantile-Quantile plot是一种用于比较两个数据集是否来自同一分布的可视化工具。它通过将两个数据集的分位数进行一一对应的方式将它们的分布进行比较。
在QQ 图中通常将一个数据集的分位数纵轴与另一个数据集的对应分位数横轴进行比较。如果两个数据集来自同一分布那么点应该沿着一条直线排列。如果数据集的分布存在差异QQ 图中的点会偏离这条直线。
QQ 图可以帮助我们判断一个数据集是否符合某种特定的分布假设比如正态分布。如果在QQ 图中点几乎在一条直线上那么数据集很可能符合正态分布。如果点在直线上方或下方有明显的偏离说明数据集分布与正态分布有所不同。 saleprice 分布呈正偏态而线性回归模型要求因变量服从正态分布我们对其做对数变换让数据接近正态分布
#对数变换将目标变量正太化
train[SalePrice] np.log1p(train[SalePrice]) #np.log1p(x) 计算的是 log(1x)
这个函数对于处理正偏斜度右偏的数据非常有用
因为它可以帮助我们减小数据的偏斜度使其更接近正态分布#查看转换后数据分布
#分布图
fig,ax plt.subplots(nrows 2,figsize (6,10))
sns.distplot(train[SalePrice],fit norm,axax[0])
(mu,sigma) norm.fit(train[SalePrice])
ax[0].legend([Normal dist.($\mu$ {:.2f} and $\sigma ${:.2f}).format(mu,sigma)],loc best)
ax[0].set_ylabel(Frequency)
ax[0].set_title(SalePrice sidtribution)
#QQ图 如果QQ图的点分布在一条直线上那说明数据近似正态分布斜率为标准差截距为均值
stats.probplot(train[SalePrice],plotax[1])
plt.show() 缺失值处理
把训练测试集整合方便处理
all_data pd.concat((train,test)).reset_index(drop True)
all_data.drop([SalePrice],axis1,inplaceTrue)print(all_data size is :{}.format(all_data.shape))
统计各特征缺失情况
all_data_na (all_data.isnull().sum()/len(all_data))*100
all_data_na all_data_na all_data_na.drop(all_data_na[all_data_na 0].index).sort_values(ascendingFalse)
missing_data pd.DataFrame({Missing Ratio:all_data_na})
missing_data.head(10) #缺失率条形图
fig,ax plt.subplots(figsize (15,8))
sns.barplot(xmissing_data.index,yall_data_na)
plt.xticks(rotation90)
plt.xlabel(Features,fontsize15)
plt.ylabel(Percent of missing values,fontsize15)
plt.title(Percent missing data by feature,fontsize15) 填补缺失值
不同的缺失值用不同方法填补
all_data[PoolQC] all_data[PoolQC].fillna(None)
all_data[MiscFeature] all_data[MiscFeature].fillna(None)
all_data[Alley] all_data[Alley].fillna(None)
all_data[Fence] all_data[Fence].fillna(None)
all_data[FireplaceQu] all_data[FireplaceQu].fillna(None)
all_data[MasVnrType] all_data[MasVnrType].fillna(None)
all_data[MasVnrArea] all_data[MasVnrArea].fillna(0)
for col in (GarageType, GarageFinish, GarageQual, GarageCond):all_data[col] all_data[col].fillna(None)
for col in (GarageYrBlt, GarageArea, GarageCars):all_data[col] all_data[col].fillna(0)
for col in (BsmtFinSF1, BsmtFinSF2, BsmtUnfSF, TotalBsmtSF, BsmtFullBath, BsmtHalfBath):all_data[col] all_data[col].fillna(0)
for col in (BsmtQual, BsmtCond, BsmtExposure, BsmtFinType1, BsmtFinType2):all_data[col] all_data[col].fillna(None)
对于缺失较少的离散型特征比如Electrical.可以用众数填补缺失值
all_data[MSZoning] all_data[MSZoning].fillna(all_data[MSZoning].mode()[0])
all_data[Electrical] all_data[Electrical].fillna(all_data[Electrical].mode()[0])
all_data[KitchenQual] all_data[KitchenQual].fillna(all_data[KitchenQual].mode()[0])
all_data[Exterior1st] all_data[Exterior1st].fillna(all_data[Exterior1st].mode()[0])
all_data[Exterior2nd] all_data[Exterior2nd].fillna(all_data[Exterior2nd].mode()[0])
all_data[SaleType] all_data[SaleType].fillna(all_data[SaleType].mode()[0])
LotFrontage:由于房屋到街道的距离最有可能与其附近其他房屋到街道的距离相同或相似因此我们可以用中位数填补缺失值
all_data[LotFrontage] all_data.groupby(Neighborhood)[LotFrontage].transform(lambda x:x.fillna(x.median()))
Functional:居家功能性数据描述说NA表示类型Typ,因此我们用其填充
all_data[Functional] all_data[Functional].fillna(Typ)
Utilities:设备可用性这特征对预测建模没有帮助因此我们可以安全地删除它
all_data all_data.drop([Utilities],axis1)
最好缺人缺失值是否已经处理完毕
all_data.isnull().sum().max() 特征相关性,相关性矩阵热图可以表现与目标值之间以及两两特征之间的相关程度对特征的处理有指导意义
#seaborn中函数heatmap()可以查看特征如何与SalePrice相关联
numeric_cols train.select_dtypes(include[np.number])
corrmat numeric_cols.corr()
plt.figure(figsize(12,9))
sns.heatmap(corrmat,vmax0.9,squareTrue)all_data[MSSubClass] all_data[MSSubClass].apply(str)#apply函数默认对列进行操作
all_data[YrSold] all_data[YrSold].apply(str)
all_data[MoSold] all_data[MoSold].apply(str)from sklearn.preprocessing import LabelEncoder
cols (FireplaceQu, BsmtQual, BsmtCond, GarageQual, GarageCond,ExterQual, ExterCond, HeatingQC, PoolQC, KitchenQual, BsmtFinType1,BsmtFinType2, Functional, Fence, BsmtExposure, GarageFinish, LandSlope,LotShape,PavedDrive, Street, Alley, CentralAir, MSSubClass, OverallCond,YrSold, MoSold)#处理列将标签编码应用于分类特征
for c in cols:lbe LabelEncoder()all_data[c] lbe.fit_transform(list(all_data[c].values))print(Shape all_dat a:{}.format(all_data.shape))Shape all_data:(2917, 78)
all_data.shape (2917, 78)
构造更多的特征是特征工程中一个重要的步骤它可以帮助模型更好地理解数据、提取数据中的模式并最终提升机器学习模型的性能。以下是构造更多特征的几个原因 捕捉数据间的非线性关系一些机器学习模型特别是线性模型难以捕获数据之间的复杂关系和非线性关系。通过构造交互项、多项式特征等可以帮助模型更好地学习数据之间的非线性关系。 增加模型的表达能力更多的特征可以增加模型的表达能力使其能够更准确地拟合数据。这样可以降低模型的偏差提高模型的准确性。 提高模型的泛化能力构造更多特征可以帮助模型从训练数据中学到更多有用的信息有助于提高模型的泛化能力即在未见过的数据上表现良好。 减少过拟合在某些情况下增加更多特征可以减少模型的过拟合风险。通过添加更多特征可以使模型更难以记住训练数据的细节从而更好地泛化到新数据。 提高模型对异常值的鲁棒性通过构造更多特征可以使模型更加鲁棒降低异常值对模型的影响。
总的来说构造更多特征是一种优化模型性能的重要手段可以帮助模型更好地理解数据、增加灵活性、降低过拟合风险并提高预测的准确性和稳定性。
# 构造更多的特征
all_data[TotalSF] all_data[TotalBsmtSF] all_data[1stFlrSF] all_data[2ndFlrSF] # 房屋总面积all_data[OverallQual_TotalSF] all_data[OverallQual] * all_data[TotalSF] # 整体质量与房屋总面积交互项
all_data[OverallQual_GrLivArea] all_data[OverallQual] * all_data[GrLivArea] # 整体质量与地上总房间数交互项
all_data[OverallQual_TotRmsAbvGrd] all_data[OverallQual] * all_data[TotRmsAbvGrd] # 整体质量与地上生活面积交互项
all_data[GarageArea_YearBuilt] all_data[GarageArea] * all_data[YearBuilt] # 车库面积与建造时间交互项#筛选出所有数值型特征
numeric_feats all_data.dtypes[all_data.dtypes ! object].index
#计算特征的偏度
numeric_data all_data[numeric_feats]
skewed_feats numeric_data.apply(lambda x:skew(x.dropna())).sort_values(ascendingFalse)
skewness pd.DataFrame({skew:skewed_feats})
skewness new_skewness skewness[skewness.abs() 0.75]
print(有{}个特征被Box-Cox变换.format(new_skewness.shape[0]))
有63个特征被Box-Cox变换
#Box-Cox变换是一种能够处理偏度问题的数学变换方法。
当你的数据不满足正态分布时Box-Cox变换可以使数据更接近正态分布
从而提高某些统计模型的效果例如许多机器学习算法都假设数据是
正态分布或至少是高斯分布的。
from scipy.special import boxcox1pskewed_features new_skewness.index
lam 0.15
for feat in skewed_features:all_data[feat] boxcox1p(all_data[feat],lam)#指定要平滑的列和需要平滑到的峰度
df pd.DataFrame({color:[红,蓝,黄]})
df lbl LabelEncoder()df[color] lbl.fit_transform(df[color])df 独热编码
df pd.DataFrame({color:[红,蓝,黄]})
pd.get_dummies(df) all_data pd.get_dummies(all_data)
print(all_data.shape) (2917, 224)
建模
from sklearn. linear_model import ElasticNet, Lasso
from sklearn. ensemble import GradientBoostingRegressor
from sklearn. kernel_ridge import KernelRidge
from sklearn. pipeline import make_pipeline
from sklearn. preprocessing import RobustScaler
from sklearn. base import BaseEstimator, TransformerMixin, RegressorMixin, clone
from sklearn. model_selection import KFold, cross_val_score, train_test_split
from sklearn. metrics import mean_squared_error
import xgboost as xgb
import lightgbm as lgb
y_train train.SalePrice.values
train all_data[:train.shape[0]]
test all_data[train.shape[0]:]
评价函数Evaluation function在机器学习中用于衡量模型在预测任务中的性能和准确度。它是通过对比模型的预测结果与真实标签或目标变量之间的差异来进行评估的。
评价函数的选择取决于具体的机器学习任务和目标。以下是几个常见的评价函数 均方误差Mean Squared ErrorMSE均方误差是回归任务中常用的评价函数它计算预测值与真实值之间的平方误差的平均值。均方误差越小表示模型的预测结果与真实值的拟合程度越好。 均方根误差Root Mean Squared ErrorRMSE均方根误差是均方误差的平方根它度量了回归模型预测结果的标准误差。与均方误差类似均方根误差越小表示模型的预测准确度越高。 平均绝对误差Mean Absolute ErrorMAE平均绝对误差是回归任务中另一种常见的评价函数它计算预测值与真实值之间的绝对误差的平均值。平均绝对误差越小表示模型的预测结果与真实值的距离越近。 准确率Accuracy准确率是分类任务中常用的评价函数它衡量模型正确分类的样本数与总样本数之间的比例。准确率越高表示模型在分类任务中的预测准确度越高。 召回率Recall 和 精确度Precision召回率和精确度是在不均衡分类问题中常用的评价函数。召回率衡量模型对正例样本的识别能力精确度衡量模型的预测结果中真正正例的比例。两者的取值范围都是0到1之间。
#评价函数
n_folds 5
def rmsle_cv(model):kf KFold(n_folds,shuffle True,random_state42).get_n_splits(train.values) #shuffle打乱#评估模型常用指标rmse np.sqrt(-cross_val_score(model,train.values,y_train,scoring neg_mean_squared_error,cvkf))return(rmse)
基本模型LASSO Regression(套索回归)
lasso make_pipeline(RobustScaler(),Lasso(alpha 0.0005,random_state 1))
核岭回归Kernel Ridge Regression是一种结合了岭回归Ridge Regression和核方法Kernel methods的回归算法。它在处理非线性问题时特别有效并且对数据中存在的噪声和共线性具有较强的鲁棒性。
下面简单介绍核岭回归的基本原理 岭回归Ridge Regression岭回归是一种线性回归的扩展形式它通过在损失函数中加入正则化项L2正则化来控制模型的复杂度防止过拟合。岭回归的目标是最小化损失函数和正则化项之和。 核方法Kernel methods核方法通过将数据映射到高维特征空间来解决非线性问题同时保持计算的高效性。其中核函数起到了至关重要的作用它可以将数据映射到高维空间并在该空间中进行线性操作避免了显式地进行高维计算。 核岭回归Kernel Ridge Regression核岭回归结合了岭回归的正则化思想和核方法的非线性特性。它在进行岭回归时采用核技巧将输入数据映射到特征空间中进行线性回归从而可以处理非线性关系。
在核岭回归中损失函数由两部分组成回归损失通常使用平方损失和正则化项。正则化项包含了控制模型复杂度的超参数以平衡拟合训练数据和避免过拟合的需求。
核岭回归的优点包括能够处理非线性关系、对噪声和共线性具有较强的鲁棒性以及较好的泛化能力。然而由于核方法的计算复杂度较高处理大规模数据时可能需要耗费较多的计算资源。因此在实际应用中需要根据数据的特点和问题的需求来选择是否使用核岭回归以及合适的核函数。
#核岭回归KRR KernelRidge(alpha 0.6,kernelpolynomial,degree2,coef0 2.5)
这段代码的作用是创建了一个机器学习管道其中包含数据标准化RobustScaler和Elastic Net回归ElasticNet两个步骤并使用了指定的参数配置。这个管道可以直接用于拟合数据并进行预测。
#lasticNet 是一种线性回归方法它结合了 LASSO最小绝对收缩和选择算子和岭回归Ridge Regression的特点。
ENet make_pipeline(RobustScaler(),ElasticNet(alpha0.0005,l1_ratio.9,random_state3))
#梯度提升回归,通过顺序地训练决策树来最小化损失函数并逐步改进模型的性能。
GBoost GradientBoostingRegressor(n_estimators 3000,learning_rate 0.05,max_depth 4,max_features sqrt,min_samples_leaf 15,min_samples_split10,losshuber,random_state 5)
#一种优化的分布式梯度增强库它设计用于速度和性能同时保持灵活性。
model_xgb xgb.XGBRegressor(colsample_bytree 0.5,gamma0.05,learning_rate 0.005,max_depth3,min_child_weight 1.8,n_estimators 2200,reg_alpha0.5,reg_lambda0.8,subsample0.5,random_state7,nthread-1)
#LightGBM,LightGBM 是一种基于梯度提升框架的高效、分布式、高性能机器学习算法
model_lgb lgb.LGBMRegressor(objectregression,num_leaves 5,learning_rate 0.05,n_estimators720,max_bin55,bagging_fraction0.8,bagging_freq5,feature_fraction0.2,feature_fraction_seed9,bagging_seed9,min_data_in_leaf6,min_sum_hessian_in_leaf11,verbose-1)
#基本模型效果评价
models {Lasso:lasso,ElasticNet:ENet,Kernel Ridge:KRR,Gradient Boosting:GBoost,XGBoost:model_xgb,LightGBM:model_lgb}
for model_name,model in models.items():score rmsle_cv(model)print({}:{:.4f}({:.4f})\n.format(model_name,score.mean(),score.std()))
Lasso:0.1114(0.0073)
ElasticNet:0.1115(0.0074)Kernel Ridge:0.1175(0.0081)Gradient Boosting:0.1168(0.0081)XGBoost:0.1191(0.0056)LightGBM:0.1161(0.0069)堆叠法
堆叠法Stacking是一种集成学习方法通过结合多个基础模型的预测结果来提高整体模型的泛化能力和性能。
在堆叠法中我们首先将原始数据集划分为训练集和测试集。接下来我们构建多个不同的基础模型并在训练集上对它们进行拟合。然后我们使用这些基础模型对测试集进行预测并将它们的预测结果作为新的特征。最后我们使用另一个模型通常称为元模型或者堆叠模型来基于这些新特征进行拟合和预测。
下面是堆叠法的基本步骤 第一层基础模型选择不同类型的基础模型例如决策树、支持向量机、随机森林等并在训练集上对它们进行拟合学习。每个基础模型都会产生一组预测结果。 创建新的特征使用基础模型对训练集的特征进行预测得到一组新的特征。这些新的特征在训练集上是基于基础模型的预测结果得到的。 第二层元模型将创建的新特征与原始特征合并并使用元模型通常是一个简单的线性模型如逻辑回归来训练整体模型。这个元模型使用之前得到的新特征作为输入并预测目标变量。
需要注意的是在训练期间基础模型和元模型通常都会使用交叉验证的方法来获得更可靠的效果评估。
堆叠法的优点包括能够利用多个基础模型的优势提高整体模型的泛化能力。通过结合不同模型的预测结果堆叠法可以有效地捕捉数据中的复杂关系和特征。
然而堆叠法也有一些需要注意的方面。它在构建过程中会引入更多的计算成本和复杂性。此外如果没有适当的模型选择和参数调整堆叠法可能导致过拟合的问题。
总的来说堆叠法是一种强大的集成学习方法通过结合多个模型的预测结果来提高模型的性能和鲁棒性。
class StackingAveragedModels(BaseEstimator,RegressorMixin,TransformerMixin):def __init__(self,base_models,meta_model,n_folds 5):self.base_models base_models#第一层模型self.meta_model meta_model#第二层模型self.n_folds n_folds#运用克隆的基本模型拟合数据def fit(self,X,y):self.base_models_ [list()for x in self.base_models]self.meta_model_ clone(self.meta_model)kfold KFold(n_splits self.n_folds,shuffleTrue,random_state 156)#训练克隆的第一层模型out_of_fold_predictions np.zeros((X.shape[0],len(self.base_models)))for i, model in enumerate(self.base_models):for train_index, holdout_index in kfold.split(X, y):instance clone(model)self. base_models_[i].append(instance)instance.fit(X[train_index], y[train_index])y_pred instance.predict(X[holdout_index])out_of_fold_predictions[holdout_index, i] y_pred#使用交叉验证预测的结果作为新特征来训练克隆的第二模型self.meta_model_.fit(out_of_fold_predictions,y)return selfdef predict(self,X):meta_features np.column_stack([np.column_stack([model.predict(X) for model in base_models]).mean(axis1)for base_models in self.base_models_])return self.meta_model_.predict(meta_features)
stacked_averaged_models StackingAveragedModels(base_models(ENet, GBoost, KRR), meta_modellasso)score rmsle_cv(stacked_averaged_models)
print (Stacking Averaged models score: {:.4f} ({:.4f}).format(score.mean(), score.std()))
Stacking Averaged models score: 0.1083 (0.0074)
#表示均方误差
def rmsle(y,y_pred):return np.sqrt(mean_squared_error(y,y_pred))
#stack模型
stacked_averaged_models.fit(train.values,y_train)
stacked_train_pred stacked_averaged_models.predict(train.values)
stacked_pred np.expm1(stacked_averaged_models.predict(test.values))
print(rmsle(y_train,stacked_train_pred))
0.0763193711203406 XGBoostExtreme Gradient Boosting是一种高效的梯度提升算法广泛应用于机器学习竞赛和实际问题中。它通过集成多个决策树模型来提高预测性能具有出色的准确性和速度。
#XGBoost
model_xgb.fit(train,y_train)
xgb_train_pred model_xgb.predict(train)
xgb_pred np.expm1(model_xgb.predict(test))
print(rmsle(y_train,xgb_train_pred))
0.09401726360646369 LightGBM 是一个基于梯度提升框架的快速、高效的机器学习库专注于处理大规模数据集和高维特征的问题。它在训练过程中采用了一种称为基于直方图的决策树算法具有快速训练速度和良好的准确性。
#LightGBM
model_lgb.fit(train,y_train)
lgb_train_pred model_lgb.predict(train)
lgb_pred np.expm1(model_lgb.predict(test.values))
print(rmsle(y_train,lgb_train_pred))
0.07158286128042535
print(集成模型的得分:{}.format(rmsle(y_train,stacked_train_pred*0.70 xgb_train_pred*0.15 lgb_train_pred*0.15)))
集成模型的得分:0.07605329200791791
生成最终预测模型
ensemble stacked_pred*0.70 xgb_pred*0.15lgb_pred*0.15
提交结果
sub pd.DataFrame()
sub[Id]test_ID
sub[SalePrice] ensemble
sub.to_csv(submission.csv,index False)