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.mzph.cn/bicheng/53448.shtml

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

相关文章

学不会虚拟列表?10分钟带你实现高度固定的Vue虚拟列表方案及原理

前言 本文主要介绍长列表的一种优化方案&#xff1a;虚拟列表。本文主要是对传统的虚拟列表方案进行更加详尽的刨析&#xff0c;以便我们能够更加深入理解虚拟列表的原理。 虚拟列表目录 1、为什么需要使用虚拟列表2、什么是虚拟列表与懒加载的区别(重要) 3、实现思路4、通过节…

SAP PO附件上传报错 输入时错

SAP PO附件上传报错 场景&#xff1a; 在SAP采购订单上传附件时&#xff0c;出现了SO424报错 Error occurred during import(输入时错)&#xff0c;报错界面如下图所示&#xff1a; 分析&#xff1a; 输入事务代码SLG1&#xff0c;在User处输入自己的用户名并运行报表。本案例…

统计学习方法与实战——统计学习方法之感知机

感知机 感知机三要素分析模型策略损失函数选择 算法原始形式对偶形式 相关问题 例子iris数据集分类实战数据集查看 显示结果sklearn 实战感知机 习题解答习题2.1解题步骤反证法 习题2.2习题2.3凸壳线性可分线性可分证明凸壳不相交证明充分性&#xff1a;凸壳不相交\Rightarrow⇒…

Jenkins 通过 Version Number Plugin 自动生成和管理构建的版本号

步骤 1&#xff1a;安装 Version Number Plugin 登录 Jenkins 的管理界面。进入 “Manage Jenkins” -> “Manage Plugins”。在 “Available” 选项卡中搜索 “Version Number Plugin”。选中并安装插件&#xff0c;完成后可能需要重启 Jenkins。 步骤 2&#xff1a;配置…

ultralytics实现DeepSort目标追踪算法之特征提取网络

文章目录 DeepSort基本流程DeepSort特征提取网络Market-1501数据集目录结构命名规则 数据集划分 网络模型训练过程参数设置数据集加载特征提取网络定义预训练模型加载损失函数与优化器定义mian函数调用训练过程验证过程平均指标与结果 DeepSort基本流程 DeepSort&#xff08;D…

数据结构栈和队列

系统栈 程序运行中使用的栈&#xff0c;由操作系统维护 栈区&#xff1a;1&#xff0c;保存局部变量 2&#xff0c;函数的形参的返回值 3&#xff0c;函数的调用关系 函数中调用函数时会把调用函数的下一条指定的首地址保存在栈区。 &#xff08;保护现…

Steam游戏截图方法

Steam游戏截图方法 截图快捷键 Steam游戏自带截图功能&#xff0c;在游戏中无需复杂的快捷键&#xff0c;仅需按下F12快捷键便可立即截图&#xff0c;官方说明如下。下文介绍使用方法。 查看截图 退出游戏后&#xff0c;在Steam界面点击查看 - 截图&#xff0c;即可查看截…

JAVA—反射

学习Java中关于反射的知识&#xff0c;以理解框架 目录 1.认识反射 2.获取类 3.获取构造器 4.获取成员变量​编辑 5.获取成员方法 6.作用 应用场景 1.认识反射 反射 加载类 并允许以编程的方式解刨类中的各种成分&#xff08;成员变量 方法 构造器&#xff09; 学习反射…

【Hadoop|HDFS篇】HDFS的读写流程

1. HDFS的写流程 1.1 剖析文件的写入 副本存储节点的选择问题&#xff1a; 第一个副本在Client所在的节点上&#xff0c;如果客户端在集群外&#xff0c;随机选一个。第二个副本在另一个机架的随机一个节点上。第三个副本在第二个副本所在的机架的随机节点上。 2. HDFS的写流…

机器学习和物联网驱动技术在加工过程中监测工具磨损:一项全面的综述

这篇论文的标题是《Machine-Learning and Internet-of-Things-Driven Techniques for Monitoring Tool Wear in Machining Process: A Comprehensive Review》&#xff0c;由 Sudhan Kasiviswanathan、Sakthivel Gnanasekaran、Mohanraj Thangamuthu 和 Jegadeeshwaran Rakkiya…

超越传统:Reflection 70B如何革新AI语言处理

Reflection 70B&#xff1a;AI语言模型的新里程碑&#x1f680; AI领域迎来了革命性的变革&#xff0c;HyperWrite公司推出的开源AI大模型Reflection 70B&#xff0c;以其卓越的性能在多个基准测试中超越了GPT-4o和Llama 3.1。这款基于Meta的Llama 3.1 70B Instruct构建的模型…

为何iPhone 16系列的发布对苹果至关重要?

即将发布的iPhone 16系列对苹果来说将是至关重要的时刻&#xff0c;特别是在快速发展的AI智能手机市场背景下。随着Android制造商在集成先进AI功能方面领先一步&#xff0c;苹果正处于一个关键的转折点——赶上竞争对手不仅仅是选择&#xff0c;而是必须完成的任务。 AI竞赛&am…

上交2024最新-《动手学大模型》实战教程及ppt分享!

本课介绍 今天分享一个上海交大的免费的大模型课程&#xff0c;有相关教程文档和Slides&#xff0c;目前是2.2K星标&#xff0c;还是挺火的&#xff01; 《动手学大模型》系列编程实践教程&#xff0c;由上海交通大学2024年春季《人工智能安全技术》课程&#xff08;NIS3353&…

传统CV算法——基于harris检测算法实现角点检测

角点 角点是图像中的一个特征点&#xff0c;指的是两条边缘交叉的点&#xff0c;这样的点在图像中通常表示一个显著的几角。在计算机视觉和图像处理中&#xff0c;角点是重要的特征&#xff0c;因为它们通常是图像中信息丰富的区域&#xff0c;可以用于图像分析、对象识别、3D…

如何在极狐GitLab中添加 SSH Key?

本文分享如何生成 SSH Key 并添加到极狐GitLab 中&#xff0c;然后用 SSH Key 进行代码拉取。 极狐GitLab 是 GitLab 在中国的发行版&#xff0c;可以私有化部署&#xff0c;对中文的支持非常友好&#xff0c;是专为中国程序员和企业推出的企业级一体化 DevOps 平台&#xff0…

43. 1 ~ n 整数中 1 出现的次数【难】

comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9843.%201%EF%BD%9En%E6%95%B4%E6%95%B0%E4%B8%AD1%E5%87%BA%E7%8E%B0%E7%9A%84%E6%AC%A1%E6%95%B0/README.md 面试题 43. 1 &#xff5e; n 整数中 1 …

C#游戏服务器开发框架设计与架构详解

我一直在思考一个问题&#xff0c;什么样的服务端框架最好用&#xff0c;最适合? 经过这些年的项目经验&#xff0c;其实最好用&#xff0c;最适合的游戏服务端框架就是自己结合公司项目需求,团队特点与技术能力,自己整合的游戏框架是最好用的。 很多新手会担心自己整合的框架…

JS生成二维码QRCode代码

JavaScript是一种广泛使用的前端编程语言&#xff0c;它不仅用于网页交互&#xff0c;还可以实现许多实用功能&#xff0c;如生成二维码。本篇文章将深入探讨如何使用JavaScript生成二维码&#xff0c;以及如何确保这种生成的二维码在各种浏览器和手机端都能正常工作&#xff0…

找不同-第15届蓝桥省赛Scratch初级组真题第4题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第183讲。 如果想持续关注Scratch蓝桥真题解读&#xff0c;可以点击《Scratch蓝桥杯历年真题》并订阅合集&#xff0c;…

GAMES101(0~1作业)

搭建虚拟机环境 安装Oracle VM VirtualBox虚拟机&#xff0c;安装虚拟硬盘&#xff0c;配置Linux Ubuntu-64 bit系统&#xff0c;启动虚拟机&#xff0c;发生冲突错误&#xff1a; 将Vmware虚拟设备取消挂起状态&#xff0c;关机确保 Hyper-V 完全关闭&#xff1a;bcdedit /se…