当前位置: 首页 > news >正文

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)

相关文章:

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

预测模型主要分为两大类&#xff1a; 回归模型&#xff1a;当你的目标变量是连续的数值时&#xff0c;你会使用回归模型进行预测。回归模型试图找到输入特征和连续输出之间的关联。一些常见的回归模型包括&#xff1a; 线性回归&#xff08;Linear Regression&#xff09;岭回归…...

【MA35D1】buildroot 编译使用经验

文章目录 芯片介绍Buildroot开发Linux实践环境搭建代码获取编译执行步骤&#xff08;仅适用于我公司产品&#xff09; 后续有需要更改的输出文件目录 芯片介绍 NuMicro MA35D1系列为一颗异核同构的多核心微处理器&#xff0c;适用于高端 Edge IIoT Gateway。它是基于双核 64 位…...

排查 MyBatis XML 配置中的 IF 语句与传值名称不匹配的 Bug

文章目录 本文档只是为了留档方便以后工作运维&#xff0c;或者给同事分享文档内容比较简陋命令也不是特别全&#xff0c;不适合小白观看&#xff0c;如有不懂可以私信&#xff0c;上班期间都是在得 前言&#xff0c;在改一个bug得时候发现一个有意思得问题&#xff0c;就是myb…...

数字证书与公钥基础设施

关注这个证书的其他相关笔记&#xff1a;NISP 一级 —— 考证笔记合集-CSDN博客 0x01&#xff1a;数字证书 数字证书是由第三方可信机构&#xff08;一般是证书服务器&#xff09;颁发的数字证书&#xff0c;可以证明身份的可信度。 数字证书具有以下特点以及性质&#xff1a…...

拥抱数智化,JNPF低代码平台如何推动企业转型升级

随着信息技术的飞速发展&#xff0c;企业面临的市场竞争日益激烈&#xff0c;传统的业务流程和管理模式已经难以满足快速变化的市场需求。数智化转型成为企业持续发展的必由之路。在这一过程中&#xff0c;低代码开发平台扮演了至关重要的角色。本文将探讨JNPF低代码平台如何助…...

Linux shell脚本 (十二)case语句_linux awk case语句

​ case工作方式如上所示。取值后面必须为关键字 in&#xff0c;每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后&#xff0c;其间所有命令开始执行直至 ;;。;; 与其他语言中的 break 类似&#xff0c;意思是跳到整个 case 语句的最后。​ 取值将…...

【二等奖成品论文】2024年数学建模国赛B题25页成品论文+完整matlab代码、python代码等(后续会更新)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 【全网最全】2024年数学建模国赛B题31页完整建模过程25页成品论文matlab/python代码等&#xff08;后续会更新「首先来看看目前已有的资料&#xff0c;还会…...

国内快速高效下载 HuggingFace上的各种大语言模型

预先安装&#xff1a; apt install aria2 # sudo apt install aria2apt install git-lfs # sudo apt install git-lfs下载hfd wget https://hf-mirror.com/hfd/hfd.shchmod ax hfd.sh设置环境变量 Linux export HF_ENDPOINThttps://hf-mirror.comWindows $env:HF_ENDPOINT…...

linux proxy 【linux 代理】

服务端 略 客户端 proxy_url"http://192.168.21.101:7890" export no_proxy"192.168.21.2,10.0.0.0/8,192.168.0.0/16,localhost,127.0.0.0/8,.coding.net,.tencentyun.com,.myqcloud.com" # proxy settings enable_proxy() {export http_proxy"${…...

AcWing907. 区间覆盖

参考的视频讲解&#xff1a;↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【贪心算法08-区间问题03-区间覆盖】 每次贪心就是选择左端点里面&#xff1c;起始端点里面右边界最大的&#xff0c;这样就是保证了最少区间个数! 然后每次迭代都会更新一次起始端点st&#xff0c;反复运用本算法…...

Unity TMP (TextMeshPro) 更新中文字符集

TMP更新中文字符集 1 字符集缺失说明2 字体的字符表2.1 字符表更新模式&#xff1a;动态2.2 字符表更新模式&#xff1a;静态 3 更新字符集步骤3.1 打开纹理更新面板3.1 导入文本文件3.3 关于警告处理 4 修改TMP默认字体设置 1 字符集缺失说明 使用TMP显示中文需要用到中文字体…...

Leetcode3259. 超级饮料的最大强化能量

Every day a Leetcode 题目来源&#xff1a;3259. 超级饮料的最大强化能量 解法1&#xff1a;记忆化搜索 本题的状态定义 dfs(i,j)。其中 j0,1&#xff0c;分别表示最后选的是 energyDrinkA[i] 还是 energyDrinkB[i]。 为方便实现&#xff0c;把 energyDrinkA 和 energyDri…...

Java题集(由入门到精通)03

此系列文章收录大量Java经典代码题&#xff08;也可以算是leetcode刷题指南&#xff09;&#xff0c;希望可以与大家一起努力学好Java。3、2、1&#xff0c;请看&#xff01; 目录 1.创建学生成绩表 2.冒泡排序 3.模拟彩票中奖 4.杨辉三角 1.创建学生成绩表 输入n个学生的…...

zblog自动生成文章插件(百度AI写作配图,图文并茂)

最近工作比较忙&#xff0c;导致自己的几个网站都无法手动更新&#xff0c;于是乎也想偷个懒把&#xff0c;让AI帮忙打理下自己的网站。我接触chatgpt等AI工具还是比较早了&#xff0c;从openai推出gpt3.5就一直在用&#xff0c;说实话&#xff0c;开始的时候用AI自动更新网站还…...

华为 HCIP-Datacom H12-821 题库 (4)

有需要题库的可以看主页置顶 V群仅进行学习交流 1.缺省情况下&#xff0c;广播型网络中运行 IS-IS 的路由器&#xff0c;DIS 发送 CSNP报文的周期为多少秒&#xff1f; A、10 B、3.3 C、30 D、40 答案&#xff1a;A 解析&#xff1a; 广播型网络中运行 IS-IS 的路由器&am…...

使用seq_file

在《使用procfs》一文的源码示例中有说到proc文件系统每次读取的数据只能是1个页,如果超过则需多次读取,这样的话会增加读取次数,增多系统调用次数,影响了整体的效率,故而才有seq file序列文件的出现,该项功能使得内核对于大文件的读取更加容易。 对于seq file,其结构…...

期货赫兹量化-种群优化算法:进化策略,(μ,λ)-ES 和 (μ+λ)-ES

进化策略&#xff08;Evolution Strategies, ES&#xff09;是一种启发式算法&#xff0c;旨在模仿自然选择的过程来解决复杂的优化问题&#xff0c;尤其在没有显式解、或搜索空间巨大的情况下表现良好。基于自然界的进化原理&#xff0c;进化策略通过突变、选择等遗传算子迭代…...

pytest实战演练

pytest实战演练 pycharm常见操作 创建项目使用虚拟环境 创建文件夹的时候建议使用的创建方式 这样创建是因为python3.0版本之后导包无区别&#xff0c;之前版本导包会报错的 _init_.py文件中建议为空不写内容 _all_[]的含义 是将列表中的方法或变量或类暴漏出去便于使用的生效…...

7、关于LoFTR

7、关于LoFTR LoFTR论文链接&#xff1a;LoFTR LoFTR的提出&#xff0c;是将Transformer模型的注意力机制在特征匹配方向的应用&#xff0c;Transformer的提取特征的机制&#xff0c;在自身进行&#xff0c;本文提出可以的两张图像之间进行特征计算&#xff0c;非常适合进行特…...

硬件工程师笔试面试知识器件篇——电感

目录​​​​​​​ 3、电感 3.1、基础 电感原理图 电感实物图 3.1.1、定义与单位 1)定义: 2) 单位: 3.1.2、物理原理 1)法拉第电磁感应定律: 2)楞次定律: 3.1.3、电感器的构造 3.1.4、类型 3.1.5、应用 3.1.6、特性 3.1.7、设计考虑 3.2、相关问题 3.…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...