24/9/6算法笔记 kaggle 房屋价格

预测模型主要分为两大类:

  1. 回归模型:当你的目标变量是连续的数值时,你会使用回归模型进行预测。回归模型试图找到输入特征和连续输出之间的关联。一些常见的回归模型包括:

    • 线性回归(Linear Regression)
    • 岭回归(Ridge Regression)
    • LASSO回归(LASSO Regression)
    • 弹性网回归(Elastic Net Regression)
    • 决策树回归(Decision Tree Regression)
    • 随机森林回归(Random Forest Regression)
    • 梯度提升回归(Gradient Boosting Regression)
    • XGBoost和LightGBM等基于树的模型
    • 支持向量回归(Support Vector Regression)
  2. 分类模型:当你的目标变量是离散的类别时,你会使用分类模型进行预测。分类模型试图找到输入特征和离散标签之间的关联。一些常见的分类模型包括:

    • 逻辑回归(Logistic Regression)
    • K最近邻分类(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,(j+1)*fold_size)  #创建一个切片对象,用于选取第 j 个折的数据。X_part,y_part = X[idx,:],y[idx]if j==i: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], xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')print(f'fold {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], xlabel='epoch', ylabel='log rmse', xlim=[1, num_epochs], yscale='log')print(f'train 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']], axis=1)submission.to_csv('submission.csv', index=False)# 调用函数
train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size)

以下是使用k折交叉验证来评估神经网络模型的一般步骤:

  1. 准备数据:确保你的数据集已经被加载并且准备好用于训练。

  2. 定义神经网络模型:创建一个神经网络模型类或函数。

  3. 初始化评估指标:选择一个或多个评估指标,如准确率、均方误差等。

  4. k折循环

    • 将数据集分成k个子集。
    • 对于每一个子集:
      • 使用剩下的k-1个子集作为训练集来训练模型。
      • 使用当前的子集作为验证集来评估模型。
      • 记录评估指标。
  5. 计算平均评估指标:计算所有k次迭代的平均评估指标。

  6. 分析结果:分析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',fontsize=13)
plt.xlabel('GrLivArea',fontsize=13)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,ax=ax[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'],plot=ax[1])
plt.show()

QQ 图,又称为量-量图(Quantile-Quantile plot),是一种用于比较两个数据集是否来自同一分布的可视化工具。它通过将两个数据集的分位数进行一一对应的方式,将它们的分布进行比较。

在QQ 图中,通常将一个数据集的分位数(纵轴)与另一个数据集的对应分位数(横轴)进行比较。如果两个数据集来自同一分布,那么点应该沿着一条直线排列。如果数据集的分布存在差异,QQ 图中的点会偏离这条直线。

QQ 图可以帮助我们判断一个数据集是否符合某种特定的分布假设,比如正态分布。如果在QQ 图中,点几乎在一条直线上,那么数据集很可能符合正态分布。如果点在直线上方或下方有明显的偏离,说明数据集分布与正态分布有所不同。

saleprice 分布呈正偏态,而线性回归模型要求因变量服从正态分布,我们对其做对数变换,让数据接近正态分布

#对数变换,将目标变量正太化
train["SalePrice"] = np.log1p(train["SalePrice"]) #np.log1p(x) 计算的是 log(1+x),
这个函数对于处理正偏斜度(右偏)的数据非常有用,
因为它可以帮助我们减小数据的偏斜度,使其更接近正态分布#查看转换后数据分布
#分布图
fig,ax = plt.subplots(nrows = 2,figsize = (6,10))
sns.distplot(train['SalePrice'],fit = norm,ax=ax[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'],plot=ax[1])
plt.show()

缺失值处理

把训练测试集整合,方便处理

all_data = pd.concat((train,test)).reset_index(drop = True)
all_data.drop(['SalePrice'],axis=1,inplace=True)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(ascending=False)
missing_data = pd.DataFrame({'Missing Ratio':all_data_na})
missing_data.head(10)

#缺失率条形图
fig,ax = plt.subplots(figsize = (15,8))
sns.barplot(x=missing_data.index,y=all_data_na)
plt.xticks(rotation=90)
plt.xlabel('Features',fontsize=15)
plt.ylabel('Percent of missing values',fontsize=15)
plt.title('Percent missing data by feature',fontsize=15)

填补缺失值

不同的缺失值,用不同方法填补

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'],axis=1)

最好缺人缺失值是否已经处理完毕

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,vmax=0.9,square=True)

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)

构造更多的特征是特征工程中一个重要的步骤,它可以帮助模型更好地理解数据、提取数据中的模式,并最终提升机器学习模型的性能。以下是构造更多特征的几个原因:

  1. 捕捉数据间的非线性关系:一些机器学习模型,特别是线性模型,难以捕获数据之间的复杂关系和非线性关系。通过构造交互项、多项式特征等,可以帮助模型更好地学习数据之间的非线性关系。

  2. 增加模型的表达能力:更多的特征可以增加模型的表达能力,使其能够更准确地拟合数据。这样可以降低模型的偏差,提高模型的准确性。

  3. 提高模型的泛化能力:构造更多特征可以帮助模型从训练数据中学到更多有用的信息,有助于提高模型的泛化能力,即在未见过的数据上表现良好。

  4. 减少过拟合:在某些情况下,增加更多特征可以减少模型的过拟合风险。通过添加更多特征,可以使模型更难以记住训练数据的细节,从而更好地泛化到新数据。

  5. 提高模型对异常值的鲁棒性:通过构造更多特征,可以使模型更加鲁棒,降低异常值对模型的影响。

总的来说,构造更多特征是一种优化模型性能的重要手段,可以帮助模型更好地理解数据、增加灵活性、降低过拟合风险,并提高预测的准确性和稳定性。

# 构造更多的特征
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(ascending=False)
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)在机器学习中用于衡量模型在预测任务中的性能和准确度。它是通过对比模型的预测结果与真实标签或目标变量之间的差异来进行评估的。

评价函数的选择取决于具体的机器学习任务和目标。以下是几个常见的评价函数:

  1. 均方误差(Mean Squared Error,MSE):均方误差是回归任务中常用的评价函数,它计算预测值与真实值之间的平方误差的平均值。均方误差越小,表示模型的预测结果与真实值的拟合程度越好。

  2. 均方根误差(Root Mean Squared Error,RMSE):均方根误差是均方误差的平方根,它度量了回归模型预测结果的标准误差。与均方误差类似,均方根误差越小,表示模型的预测准确度越高。

  3. 平均绝对误差(Mean Absolute Error,MAE):平均绝对误差是回归任务中另一种常见的评价函数,它计算预测值与真实值之间的绝对误差的平均值。平均绝对误差越小,表示模型的预测结果与真实值的距离越近。

  4. 准确率(Accuracy):准确率是分类任务中常用的评价函数,它衡量模型正确分类的样本数与总样本数之间的比例。准确率越高,表示模型在分类任务中的预测准确度越高。

  5. 召回率(Recall) 和 精确度(Precision):召回率和精确度是在不均衡分类问题中常用的评价函数。召回率衡量模型对正例样本的识别能力,精确度衡量模型的预测结果中真正正例的比例。两者的取值范围都是0到1之间。

#评价函数
n_folds = 5
def rmsle_cv(model):kf = KFold(n_folds,shuffle = True,random_state=42).get_n_splits(train.values)  #shuffle打乱#评估模型常用指标rmse = np.sqrt(-cross_val_score(model,train.values,y_train,scoring = "neg_mean_squared_error",cv=kf))return(rmse)

基本模型LASSO Regression(套索回归)

lasso = make_pipeline(RobustScaler(),Lasso(alpha = 0.0005,random_state = 1))

核岭回归(Kernel Ridge Regression)是一种结合了岭回归(Ridge Regression)和核方法(Kernel methods)的回归算法。它在处理非线性问题时特别有效,并且对数据中存在的噪声和共线性具有较强的鲁棒性。

下面简单介绍核岭回归的基本原理:

  1. 岭回归(Ridge Regression):岭回归是一种线性回归的扩展形式,它通过在损失函数中加入正则化项(L2正则化)来控制模型的复杂度,防止过拟合。岭回归的目标是最小化损失函数和正则化项之和。

  2. 核方法(Kernel methods):核方法通过将数据映射到高维特征空间来解决非线性问题,同时保持计算的高效性。其中,核函数起到了至关重要的作用,它可以将数据映射到高维空间,并在该空间中进行线性操作,避免了显式地进行高维计算。

  3. 核岭回归(Kernel Ridge Regression):核岭回归结合了岭回归的正则化思想和核方法的非线性特性。它在进行岭回归时采用核技巧,将输入数据映射到特征空间中进行线性回归,从而可以处理非线性关系。

在核岭回归中,损失函数由两部分组成:回归损失(通常使用平方损失)和正则化项。正则化项包含了控制模型复杂度的超参数,以平衡拟合训练数据和避免过拟合的需求。

核岭回归的优点包括能够处理非线性关系、对噪声和共线性具有较强的鲁棒性,以及较好的泛化能力。然而,由于核方法的计算复杂度较高,处理大规模数据时可能需要耗费较多的计算资源。因此,在实际应用中,需要根据数据的特点和问题的需求来选择是否使用核岭回归以及合适的核函数。

#核岭回归KRR = KernelRidge(alpha = 0.6,kernel='polynomial',degree=2,coef0 = 2.5)

这段代码的作用是创建了一个机器学习管道,其中包含数据标准化(RobustScaler)和Elastic Net回归(ElasticNet)两个步骤,并使用了指定的参数配置。这个管道可以直接用于拟合数据,并进行预测。

#lasticNet 是一种线性回归方法,它结合了 LASSO(最小绝对收缩和选择算子)和岭回归(Ridge Regression)的特点。
ENet = make_pipeline(RobustScaler(),ElasticNet(alpha=0.0005,l1_ratio=.9,random_state=3))
#梯度提升回归,通过顺序地训练决策树来最小化损失函数,并逐步改进模型的性能。
GBoost = GradientBoostingRegressor(n_estimators = 3000,learning_rate = 0.05,max_depth = 4,max_features = 'sqrt',min_samples_leaf = 15,min_samples_split=10,loss='huber',random_state = 5)
#一种优化的分布式梯度增强库,它设计用于速度和性能,同时保持灵活性。
model_xgb = xgb.XGBRegressor(colsample_bytree = 0.5,gamma=0.05,learning_rate = 0.005,max_depth=3,min_child_weight = 1.8,n_estimators = 2200,reg_alpha=0.5,reg_lambda=0.8,subsample=0.5,random_state=7,nthread=-1)
#LightGBM,LightGBM 是一种基于梯度提升框架的高效、分布式、高性能机器学习算法
model_lgb = lgb.LGBMRegressor(object='regression',num_leaves = 5,learning_rate = 0.05,n_estimators=720,max_bin=55,bagging_fraction=0.8,bagging_freq=5,feature_fraction=0.2,feature_fraction_seed=9,bagging_seed=9,min_data_in_leaf=6,min_sum_hessian_in_leaf=11,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)是一种集成学习方法,通过结合多个基础模型的预测结果来提高整体模型的泛化能力和性能。

在堆叠法中,我们首先将原始数据集划分为训练集和测试集。接下来,我们构建多个不同的基础模型,并在训练集上对它们进行拟合。然后,我们使用这些基础模型对测试集进行预测,并将它们的预测结果作为新的特征。最后,我们使用另一个模型(通常称为元模型或者堆叠模型)来基于这些新特征进行拟合和预测。

下面是堆叠法的基本步骤:

  1. 第一层(基础模型):选择不同类型的基础模型,例如决策树、支持向量机、随机森林等,并在训练集上对它们进行拟合(学习)。每个基础模型都会产生一组预测结果。

  2. 创建新的特征:使用基础模型对训练集的特征进行预测,得到一组新的特征。这些新的特征在训练集上是基于基础模型的预测结果得到的。

  3. 第二层(元模型):将创建的新特征与原始特征合并,并使用元模型(通常是一个简单的线性模型,如逻辑回归)来训练整体模型。这个元模型使用之前得到的新特征作为输入,并预测目标变量。

需要注意的是,在训练期间,基础模型和元模型通常都会使用交叉验证的方法来获得更可靠的效果评估。

堆叠法的优点包括能够利用多个基础模型的优势,提高整体模型的泛化能力。通过结合不同模型的预测结果,堆叠法可以有效地捕捉数据中的复杂关系和特征。

然而,堆叠法也有一些需要注意的方面。它在构建过程中会引入更多的计算成本和复杂性。此外,如果没有适当的模型选择和参数调整,堆叠法可能导致过拟合的问题。

总的来说,堆叠法是一种强大的集成学习方法,通过结合多个模型的预测结果来提高模型的性能和鲁棒性。

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,shuffle=True,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(axis=1)for base_models in self.base_models_])return self.meta_model_.predict(meta_features)
stacked_averaged_models =StackingAveragedModels(base_models=(ENet, GBoost, KRR), meta_model=lasso)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
  1. XGBoost(Extreme 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
  1. 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.15+lgb_pred*0.15

提交结果

sub = pd.DataFrame()
sub['Id']=test_ID
sub['SalePrice'] = ensemble
sub.to_csv('submission.csv',index = False)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FFmpeg 7.0 版本 “Dijkstra”的特点概述

FFmpeg 7.0 FFmpeg 官网:https://ffmpeg.org/FFmpeg 官网更新日志,2024.4.5 号发布代号"Dijkstra"的 7.0 版本的 FFmpeg,如下截图: 为什么叫 Dijkstra“Dijkstra” 指的是艾兹格戴克斯特拉(Edsger Wybe Dijkstra),他是一位荷兰计算机科学家,对计算机科学领域…

C#使用TCP-S7协议读写西门子PLC(一)

之前本人发布西门子S7协议的报文 西门子PLC的S7协议报文解析说明_西门子报文详解-CSDN博客 西门子PLC的S7协议是西门子公司在ModbusTcp协议的基础上自定义的一种协议,仅支持西门子PLC,S7协议本质仍然属于TCP协议的一种自定义具体实现 第一步,准备工作。VS2022中新建窗体应…

Redis学习Day3——项目工程开发

扩展阅读推荐&#xff1a; 黑马程序员Redis入门到实战教程_哔哩哔哩_bilibili 一、项目介绍及其初始化 学习Redis的过程&#xff0c;我们还将遇到各种实际问题&#xff0c;例如缓存击穿、雪崩、热Key等问题&#xff0c;只有在实际的项目实践中解决这些问题&#xff0c;才能更好…

教师节特辑:AI绘制的卡通人物,致敬最可爱的人‍

【编号&#xff1a;9】教师节到了&#xff0c;今天我要分享一组由AI绘制的教师节主题卡通人物插画&#xff0c;每一幅都充满了对老师的敬意和爱戴。让我们一起用这些可爱的卡通形象&#xff0c;向辛勤的园丁们致敬&#xff01; &#x1f393;【教师形象】 这…

域名证书,泛域名证书,sni

文章目录 前言一、证书1.全域名证书2.泛域名证书 二、域名证书的使用1、浏览器请求域名证书流程对全域名证书的请求流程对泛域名证书的请求流程ssl client-hello携带server name 报文 2、浏览器对证书的验证流程 三、域名证书和sni 前言 本文介绍了泛域名证书和全域名证书的区别…

JavaWeb【day12】--(SpringBootWeb登录认证)

案例-登录认证 在前面的课程中&#xff0c;我们已经实现了部门管理、员工管理的基本功能&#xff0c;但是大家会发现&#xff0c;我们并没有登录&#xff0c;就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的&#xff0c;所以我们今天的主题就是登录认证。 最终我们…

【32单片机篇】项目:智能台灯

一、项目需求 1. 红外传感器检测是否有人&#xff0c;有人的话实时检测距离&#xff0c;过近则报警&#xff1b;同时计时&#xff0c;超过固定时间则报警&#xff1b; 2. 按键 1 切换工作模式&#xff1a;智能模式、按键模式、远程模式&#xff1b; 3. 智能模式下&#xff0c;…

UML之类图详解

犬余&#x1f436; “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 零、什么是类图 类图&#xff08;Class Diagram&#xff09;是面向对象系统建模中最常用和最重要的图&#xff0c;它通过图形化的方式展示系统中的…

Conda安装R环境并在Jupyter Lab中运行

说明&#xff1a; Conda 安装 R 环境&#xff0c;并在 Jupyter Lab 中运行 R 脚本。 1. 创建环境并安装r-base 创建环境&#xff1a;conda create -n [环境名] 激活环境&#xff1a;conda activate [环境名] 安装 Jupyter Lab&#xff1a;conda install -c conda-forge jupy…

Promise详解、自定义

这里写目录标题 一、.Promise对象详解1. Promise是什么2. Promise的优点3. 异步编程4. then(onFulfilled, onRejected)&#xff1a;5. util.promisify 方法&#xff1a;6. promise的状态改变7.Promise 对象的值8. Promise的基本执行流程9. Promise的API10. Promise中的关键问题…

怎么修复松下相机死机视频只有0字节(0KB)的MDT文件【实测可修复】

死机后视频文件大小仅为0字节 松下S5相机录像死机&#xff0c;关机重新开机后有一个视频文件变成MDT&#xff0c;大小为0KB&#xff0c;录了30多分钟&#xff0c;本应为MOV格式的视频。0字节文件可以修复吗&#xff1f;怎么修复0字节的MDT文件为视频&#xff1f; 数据提取与视…

四款免费视频剪辑工具使用感受与优劣势总结

在如今这个视频内容如火如荼的时代&#xff0c;如何快速高效地完成视频剪辑成为许多人关心的问题&#xff1b;今天&#xff0c;我们就来轻松愉快地聊一聊本人常用的四款免费的视频剪辑工具&#xff1b;这四款工具各有千秋&#xff0c;让我们一起来看看它们的使用感受和优劣势吧…

数据结构(并查集) How did you do it? 怎么做到的!!!

一、前言 并查集的历史 1964年&#xff0c; Bernard A. Galler 和 Michael J. Fischer 首次描述了不相交的并查集&#xff0c;1975 年&#xff0c;Robert Tarjan 是第一个证明O(ma(n))&#xff08;逆阿克曼函数 (opens new window)&#xff09;算法时间复杂度的上限&#xff…

C语言深入了解指针一(14)

文章目录 前言一、内存和地址内存究竟该如何理解编址 二、指针变量和地址取地址操作符&解引用操作符*指针变量的大小 总结 前言 终于来到指针啦&#xff01;如前篇末尾总结所说&#xff0c;这是你们马上要下大功夫的地方   但是&#xff0c;就像我们上初中的时候&#xf…

【开发工具】IntelliJ IDEA插件推荐:Json Helper——让JSON处理更高效

导语&#xff1a;在Java开发过程中&#xff0c;JSON作为一种轻量级的数据交换格式&#xff0c;被广泛应用于前后端数据交互。今天&#xff0c;我要为大家介绍一款IntelliJ IDEA插件——Json Helper&#xff0c;帮助开发者更高效地处理JSON数据。 一、什么是Json Helper&#x…

智能优化算法-樽海鞘优化算法(SSA)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 樽海鞘优化算法 (Salp Swarm Algorithm, SSA) 虽然名称中提到的是“樽海鞘”&#xff0c;但实际上这个算法是基于群体智能的一种元启发式优化算法&#xff0c;它模拟了樽海鞘&#xff08;Salps&#xff09;在海…

C语言:刷题日志(3)

一.猴子选大王 一群猴子要选新猴王。新猴王的选择方法是&#xff1a;让N只候选猴子围成一圈&#xff0c;从某位置起顺序编号为1~N号。从第1号开始报数&#xff0c;每轮从1报到3&#xff0c;凡报到3的猴子即退出圈子&#xff0c;接着又从紧邻的下一只猴子开始同样的报数。如此不…

阿里云镜像报错 [Errno 14] HTTP Error 302 - Found 问题解决记录

1、问题背景和解决思路 在本地安装 CentOS7 后&#xff0c;网络已调通可正常上网&#xff0c;但切换阿里云镜像后&#xff0c;使用 yum 安装软件时出现 “[Errno 14] HTTPS Error 302 - Found Trying other mirror.” 报错&#xff0c;原因是 yum 源配置问题。给出了详细的解决…

苹果首款AI手机发布!iPhone 16全新AI功能体验感拉满

苹果于2024年秋季盛大发布iPhone 16系列&#xff0c;带来前所未有的AI智能体验。iPhone 16系列不仅硬件全面升级&#xff0c;更融入了尖端的AI技术&#xff0c;为用户带来更加智能化的生活体验。 在科技春晚的舞台上&#xff0c;苹果不负众望地揭开了iPhone 16系列的神秘面纱。…

ubuntu20.04 Qt6引用dcmtk库实现dicom文件读取和字符集转换

1 环境问题 安装完Qt6&#xff0c;新建Qt/QtQuick CMake工程编译出现如下错误: Found package configuration file: Qt6Config.cmake but it set Qt6 FOUND to FALSE so package "Qt6" is considered to be NOT FOUND. 原因&#xff1a; 这是因为系统中缺少OpenG…