机器学习实战 | 逻辑回归应用之“Kaggle房价预测”

简介: 基于kaggle网站所提供的爱荷华州埃姆斯的住宅数据信息,预测每间房屋的销售价格,数据的标签SalePrice是连续性数据,因此可以判定这是一个回归问题。

本文转自丹妍,https://blog.csdn.net/z_mawkish/article/details/106335627


640.png


Competition Description


1. 问题描述:


基于kaggle网站所提供的爱荷华州埃姆斯的住宅数据信息,预测每间房屋的销售价格,数据的标签SalePrice是连续性数据,因此可以判定这是一个回归问题。


最终目标:预测每一个房屋的销售价格。对于测试集中的每个ID,预测SalePrice变量的值


判定标准:根据预测值的对数与观察到的销售价格的对数之间的均方根误差(RMSE)评估提交的内容(采取对数意味着预测昂贵房屋和廉价房屋的错误将同等影响结果).


2. 数据描述:


数据来源于kaggle网站。数据分为训练数据集和测试数据集。两个数据集都包括每栋房⼦的特征,如街道类型、建造年份、房顶类型、地下室状况等特征值。这些特征值有连续的数字、离散的标签甚⾄是缺失值“na”。只有训练数据集包括了每栋房⼦的价格,也就是标签。


训练数据和测试数据分别各有1460条,数据的特征列有79个,期中35个是数值类型的,44个类别类型


640.png


原题链接:https://www.kaggle.com/c/house-prices-advanced-regression-techniques


总体的步骤为:


640.png


导入各种包


import torch
import torch.nn as nn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns 
from scipy.stats import norm
from scipy import stats
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l
print(torch.__version__)
torch.set_default_tensor_type(torch.FloatTensor)


读取数据


##训练集
train_data=pd.read_csv(open('D:/Desktop/深度学习基础/期中论文/数据/train.csv'))
##测试集
test_data=pd.read_csv(open('D:/Desktop/深度学习基础/期中论文/数据/test.csv'))


数据可视化


#查看自变量与因变量的相关性
fig = plt.figure(figsize=(14,8))
abs(train_data.corr()['SalePrice']).sort_values(ascending=False).plot.bar()
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)


640.png


由上图可以发现有10个变量与因变量的相关性大于0.5,分别是:


  • OverallQual 房屋设施的完整性
  • GrLivArea 居住面积
  • GarageCars  车库
  • GarageArea  车库面积
  • TotalBsmtSF 地下室大小
  • 1stFlrSF 1楼面积
  • FullBath 厕所面积
  • TotRmsAbvGrd 地面上的房间数量
  • YearBuilt 建造年份
  • YearRemodAdd 重建年份


#查看因变量是否符合正态分布
sns.distplot(train_data['SalePrice'],fit=norm)
sns.distplot(np.log(train_data['SalePrice']),fit=norm)#取对数后的

640.png


取对数后发现基本符合正态分布,可以进行线性回归建模,但在这里先不做处理,建模的时候在取对数。


数据预处理


/

#异常值处理
figure=plt.figure()
sns.pairplot(x_vars=['OverallQual','GrLivArea','YearBuilt','TotalBsmtSF'],
             y_vars=['SalePrice'],data=train_data,dropna=True)
plt.show()

640.png


通过上面的散点图我们可以观察到训练数据存在一些离群点(异常值)比如:


  1. OverallQual:总体质量评分小于5,销售价格却大于200000
  2. GrLivArea:居住面积大于4000,销售价格却小于300000,根据我们的常识可以得知,一般来说居住面积越大,销售价格应该越高。
  3. YearBuilt:建造年份在1900年之前的销售价格还可以大于400000
  4. TotalBsmtSF:地下室总面积大于6000,销售价格还低于200000.


综合以上分析,我们将删除这些异常值。


#删除异常值
train_data = train_data.drop(train_data[(train_data['OverallQual']<5) &
                                        (train_data['SalePrice']>200000)].index)
train_data = train_data.drop(train_data[(train_data['GrLivArea']>4000) &
                                        (train_data['SalePrice']<300000)].index)
train_data = train_data.drop(train_data[(train_data['YearBuilt']<1900) &
                                        (train_data['SalePrice']>400000)].index)
train_data = train_data.drop(train_data[(train_data['TotalBsmtSF']>6000) &
                                        (train_data['SalePrice']<200000)].index)


#检查是否还存在异常值
figure=plt.figure()
sns.pairplot(x_vars=['OverallQual','GrLivArea','YearBuilt','TotalBsmtSF'],
             y_vars=['SalePrice'],data=train_data,dropna=True)
plt.show()


异常值处理后发现数据没有其他明显的异常值


合并数据


#去掉Id和SalePrice,将训练集和测试集的79个特征按样本连接
all_features=pd.concat((train_data.iloc[:,1:-1],test_data.iloc[:,1:]))


分析数据得知,79列数据中有34列数据存在缺失值,但是大部分缺失值都在10%以下,而有5列数据缺失值接近或超过50%。分别是:


  1. PoolQC 游泳池情况,取值有Excellent,Good,Fair,空值表示没有游泳池。
  2. MiscFeature 房屋有的其他设施,取值有Shed(小屋),Othr(其他),Gar2(第二个车库),TenC(乒乓球桌),空值代表没有其他设施
  3. Alley 小巷道路类型,取值有Grvl(碎石),paved(铺切面)。空值代表没有小巷
  4. Fence 围墙类型,取值有GdPrv(Good Privacy),MnPrv(Minimum Privacy),GdWo(Good Wood),MnWw(Minimum Wood),空值代表没有围墙
  5. FireplaceQu,壁炉类型,取值有Ex(Excellent),Gd(Good),
  6. Fa(Fair),Po(Poor),TA(Average),空值代表没有壁炉。


对于这些列,空值是有特别意义的,因此这些缺失值不可以删除。


#将列表中数值型的数据索引出来
numeric_features=all_features.dtypes[all_features.dtypes!='object'].index
#对数据进行标准化
all_features[numeric_features]=all_features[numeric_features].apply(
        lambda x:(x-x.mean())/(x.std()))
#标准化后,每个数值特征的均值变为0,可以直接用0来替换缺失值
all_features[numeric_features]=all_features[numeric_features].fillna(0)
#离散数值转成指示特征
all_features=pd.get_dummies(all_features,dummy_na=True)#通过转换将特征数从79增加到了330


数值型的数据,我们直接采用0来填充缺失值.


非数值型的数据,我们采用独热编码的方式转换成指示特征。比如,特征MSZoning里面有两个不同的离散值RL和RM,那么这一步将去掉MSZoning特征,并新加两个特征MSZoning_RL和MSZoning_RM,其值为0或者1.如果一个样本在原来MSZoning里的值为RL,那么MSZoning_RL=1且MSZoning_RM=0.


模型建立和训练


640.png


#先把合并的数据集重新分割为训练集和测试集
n_train=train_data.shape[0]
#通过values属性得到Numpy格式的数据,并转成Tensor方便后面的训练
#训练样本特征
train_features=torch.tensor(all_features[:n_train].values,dtype=torch.float)
#测试样本特征
test_features=torch.tensor(all_features[n_train:].values,dtype=torch.float)
#训练样本标签
train_labels=torch.tensor(train_data.SalePrice.values,dtype=torch.float).view(-1,1)


#定义均方误差损失函数
loss=torch.nn.MSELoss()


#定义线性回归模型
def get_net(feature_num):
    net=nn.Sequential(
            d2l.FlattenLayer(),
            nn.Linear(feature_num,256),
            nn.ReLU(),
            nn.Linear(256,1),
            )
    #模型参数初始化
    for param in net.parameters():
        nn.init.normal_(param,mean=0,std=0.01)
    return net


#对数均方误差的实现
def log_rmse(net,features,labels):
    with torch.no_grad():
        #将小于1的值设成1,使的取对数时数值更稳定
        clipped_preds=torch.max(net(features),torch.tensor(1.0))
        rmse=torch.sqrt(loss(clipped_preds.log(),labels.log()))
    return rmse.item()


测试集中的数据量m不同,因为有累加操作,所以随着数据的增加 ,误差会逐渐积累;因此衡量标准和 m 相关。为了抵消掉数据量的形象,可以除去数据量,抵消误差。通过这种处理方式得到的结果叫做均方误差MSE(Mean Squared Error):均方误差MSE,定义如下:


640.png


上式中,yi为一个batch_size中第 i 个数据的正确答案,而为神经网络给出的预测值。


但是使用均方误差MSE受到量纲的影响。例如在衡量销售价格时,y的单位是(万元),那么衡量标准得到的结果是(万元平方)。为了解决量纲的问题,可以将其开方(为了解决方差的量纲问题,将其开方得到平方差)得到均方根误差RMSE(Root Mean Squarde Error)


640.png


即便为了解决均方误差受到量纲的影响,采用的均方根误差,仍然存在其他影响,比如预测过程中昂贵房屋和廉价房屋的错误会给结果带来不同的影响,因此为解决这一问题,又引进对数均方差根误差,采取对数意味着预测昂贵房屋和廉价房屋的错误将同等影响结果。对数均方根误差


640.png

def train(net,train_features,train_labels,test_features,test_labels,
          num_epochs,learning_rate,weight_decay,batch_size):
    train_ls,test_ls=[],[]
    #把dataset放入DataLoader
    dataset=torch.utils.data.TensorDataset(train_features,train_labels)
    train_iter=torch.utils.data.DataLoader(dataset,batch_size,shuffle=True)
    #这里使用了Adam优化算法
    optimizer=torch.optim.Adam(params=net.parameters(),lr=learning_rate,weight_decay=weight_decay)
    net=net.float()#将神经网络中的数据类型设置维浮点型
    for epoch in range(num_epochs):
        for X,y in train_iter:
            l=loss(net(X.float()),y.float())
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
        train_ls.append(log_rmse(net,train_features,train_labels))
        if test_labels is not None:
            test_ls.append(log_rmse(net,test_features,test_labels))
    return train_ls,test_ls
#K折交叉验证
def get_k_fold_data(k,i,X,y):
    assert k>1
    fold_size=X.shape[0]//k
    X_train,y_train=None,None
    for j in range(k):
        idx=slice(j*fold_size,(j+1)*fold_size)
        X_part,y_part=X[idx,:],y[idx]
        #划分出验证数据集
        if j==1:
            X_valid,y_valid=X_part,y_part
        elif X_train is None:
            X_train,y_train=X_part,y_part
        #划分出训练数据,剩下的进行合并
        else:
            X_train=torch.cat((X_train,X_part),dim=0)
            #dim=0按列合并
            y_train=torch.cat((y_train,y_part),dim=0)
    return X_train,y_train,X_valid,y_valid
def k_fold(k,X_train,y_train,num_epochs,
           learning_rate,weight_decay,batch_size):
    train_l_sum,valid_l_sum=0,0
    for i in range(k):
        data=get_k_fold_data(k,i,X_train,y_train)
        net=get_net(X_train.shape[1])
        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:
            d2l.semilogy(range(1,num_epochs+1),train_ls,
                         'epochs','rmse',
                         range(1,num_epochs+1),valid_ls,
                         ['train','valid'])
            #输出相应的结果:训练误差、验证误差
        print('fold%d,train rmse %f,valid rmse %f'%
              (i,train_ls[-1],valid_ls[-1]))
    return train_l_sum/k,valid_l_sum/k


模型选择


#模型选择
k,num_epochs,lr,weight_decay,batch_size=8,100,0.1,300,64
train_l,valid_l=k_fold(k,train_features,train_labels,num_epochs,lr,weight_decay,batch_size)
print('%d-fold validation:avg trian rmse %f,avg valid rmse %f'%
      (k,train_l,valid_l))


经过不断的调整参数,最后选择的最优参数为:


参数
k
Num_epochs
lr
weight_decaye
batch_siz
数值
8
100
0.1
300
64
训练误差
0.082840
测试误差
0.107597


640.png

                                  训练误差图


模型预测


#模型预测
def train_and_pred(train_features,test_features,train_labeld,test_data,
                   num_epochs,lr,weight_decay,batch_size):
    net=get_net(train_features.shape[1])
    #第二个变量(测试误差)缺省,用_代替
    train_ls,_=train(net,train_features,train_labels,None,None,
                     num_epochs,lr,weight_decay,batch_size)
    d2l.semilogy(range(1,num_epochs+1),train_ls,'epochs','rmse')
    print('train rmse %f'%train_ls[-1])
    preds=net(test_features).detach().numpy()
    test_data['SalePrice']=pd.Series(preds.reshape(1,-1)[0])
    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)

640.png

640.png训练误差图640.png


640.png

640.png

MaiweiE-com|WeChat ID:Yida_Zhang2

640.png

相关文章
|
23小时前
|
机器学习/深度学习 运维 自然语言处理
探索机器学习在金融欺诈检测中的应用
【5月更文挑战第3天】 随着金融科技的迅猛发展,机器学习作为其核心推动力之一,正逐渐改变着我们对金融服务安全与效率的理解。本文将深入探讨机器学习技术在金融欺诈检测领域内的应用现状与前景。通过分析多种算法和实际案例,我们揭示了如何利用机器学习提高识别欺诈行为的准确率,降低金融机构的风险损失。同时,文章还将讨论在此过程中遇到的挑战及未来的发展趋势,为读者提供一个全面而深入的视角。
|
1天前
|
机器学习/深度学习 自然语言处理 算法
机器学习算法原理与应用:深入探索与实战
【5月更文挑战第2天】本文深入探讨机器学习算法原理,包括监督学习(如线性回归、SVM、神经网络)、非监督学习(聚类、PCA)和强化学习。通过案例展示了机器学习在图像识别(CNN)、自然语言处理(RNN/LSTM)和推荐系统(协同过滤)的应用。随着技术发展,机器学习正广泛影响各领域,但也带来隐私和算法偏见问题,需关注解决。
|
2天前
|
机器学习/深度学习 算法 自动驾驶
探索机器学习在图像识别中的应用
【5月更文挑战第1天】 随着人工智能技术的飞速发展,机器学习已成为其最活跃的分支之一。特别是在图像识别领域,机器学习技术已展现出强大的能力与广泛的应用前景。本文将深入探讨机器学习在图像识别中的关键作用,从基础原理到实际应用案例,剖析其背后的算法和模型。同时,我们将讨论当前面临的挑战和未来的发展趋势,为读者提供一个全景式的技术分享。
10 3
|
3天前
|
机器学习/深度学习 数据采集 人工智能
探索机器学习在金融欺诈检测中的应用
【4月更文挑战第30天】 随着金融科技的迅猛发展,机器学习技术在金融行业中的应用变得日益广泛。特别是在金融欺诈检测领域,机器学习以其强大的数据处理能力和智能识别功能,正逐渐成为防范和打击金融欺诈的重要工具。本文将深入探讨机器学习在金融欺诈检测中的关键作用,分析其优势及面临的挑战,并提出未来发展趋势。
|
3天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习在图像识别中的应用与挑战探索机器学习中的自然语言处理技术
【4月更文挑战第30天】 随着人工智能技术的飞速发展,深度学习已经成为计算机视觉领域的核心动力。本文将探讨深度学习在图像识别任务中的关键技术、应用实例以及面临的主要挑战。我们将重点讨论卷积神经网络(CNN)的架构优化、数据增强技术以及迁移学习的策略,并通过具体案例分析其在医疗影像、自动驾驶和面部识别等领域的应用成效。同时,我们也将指出当前模型泛化能力不足、对抗性攻击以及算力资源需求等挑战,并提出潜在的解决方向。 【4月更文挑战第30天】 在人工智能领域,自然语言处理(NLP)是赋予机器理解和响应人类语言能力的关键技术。本文将深入探讨NLP的发展历程、核心技术及其在不同领域的应用案例。我们将从
|
3天前
|
机器学习/深度学习 数据采集 算法
【Python 机器学习专栏】机器学习在医疗诊断中的前沿应用
【4月更文挑战第30天】本文探讨了机器学习在医疗诊断中的应用,强调其在处理复杂疾病和大量数据时的重要性。神经网络、决策树和支持向量机等方法用于医学影像诊断、疾病预测和基因数据分析。Python作为常用工具,简化了模型构建和数据分析。然而,数据质量、模型解释性和伦理法律问题构成挑战,需通过数据验证、可解释性研究及建立规范来应对。未来,机器学习将更深入地影响医疗诊断,带来智能和精准的诊断工具,同时也需跨学科合作推动其健康发展。
|
3天前
|
机器学习/深度学习 自然语言处理 搜索推荐
【Python机器学习专栏】迁移学习在机器学习中的应用
【4月更文挑战第30天】迁移学习是利用已有知识解决新问题的机器学习方法,尤其在数据稀缺或资源有限时展现优势。本文介绍了迁移学习的基本概念,包括源域和目标域,并探讨了其在图像识别、自然语言处理和推荐系统的应用。在Python中,可使用Keras或TensorFlow实现迁移学习,如示例所示,通过预训练的VGG16模型进行图像识别。迁移学习提高了学习效率和性能,随着技术发展,其应用前景广阔。
|
3天前
|
机器学习/深度学习 传感器 自动驾驶
【Python机器学习专栏】深度学习在自动驾驶中的应用
【4月更文挑战第30天】本文探讨了深度学习在自动驾驶汽车中的应用及其对技术发展的推动。深度学习通过模拟神经网络处理数据,用于环境感知、决策规划和控制执行。在环境感知中,深度学习识别图像和雷达数据;在决策规划上,学习人类驾驶行为;在控制执行上,实现精确的车辆控制。尽管面临数据需求、可解释性和实时性挑战,但通过数据增强、规则集成和硬件加速等方法,深度学习将持续优化自动驾驶性能,并在安全性和可解释性上取得进步。
|
3天前
|
机器学习/深度学习 自然语言处理 PyTorch
【Python 机器学习专栏】自然语言处理中的深度学习应用
【4月更文挑战第30天】本文探讨了深度学习在自然语言处理(NLP)中的应用,包括文本分类、情感分析和机器翻译等任务。深度学习的优势在于自动特征学习、强大的表达能力和处理大规模数据的能力。常见模型如RNN、LSTM、GRU、CNN和注意力机制在NLP中发挥作用。Python的TensorFlow、PyTorch、NLTK和SpaCy等工具支持NLP研究。然而,数据稀缺、模型解释性和计算资源需求高等挑战仍待解决。随着技术进步,未来深度学习将进一步推动NLP发展,实现更智能的语言交互。
|
3天前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习专栏】金融数据分析中的机器学习应用
【4月更文挑战第30天】本文探讨了机器学习在金融数据分析中的应用,如股价预测、信用评分、欺诈检测、算法交易和风险管理,并以Python为例展示了如何进行股价预测。通过使用机器学习模型,金融机构能更准确地评估风险、识别欺诈行为并优化交易策略。Python结合scikit-learn库简化了数据分析过程,助力金融从业者提高决策效率。随着技术发展,机器学习在金融领域的影响力将持续增强。

热门文章

最新文章