kaggle比赛---房价预测

# kaggle比赛---房价预测

题目介绍

image-20220228231511522

基本操作

​ 该操作可以归结为先进行数据清洗,再用TensorFlow给定的线型模型去跑训练集,属于基础操作。

​ 思路:数据探索,做一点点的修改-->数据清洗(空值的填充)-->数据预处理(数据的归一化,标准化等)-->模型构建-->训练预测--->保存提交

​ 但是其中的数据清洗的学问值得一看

代码部分

导入相应的包

#导入相应的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns #数据可视化 类似Matplotlib
import pandas_profiling as ppf#进行数据探索性分析
import warnings#忽略警告
warnings.filterwarnings("ignore")
%matplotlib inline
plt.style.use("ggplot")

原始数据导入---这里的数据都是在比赛的官网下载得到的

train = pd.read_csv("data_set/train.csv")#读取训练数据
test = pd.read_csv("data_set/test.csv")#读取测试集数据

train.head()#默认显示前五行 该函数是显示数据表的函数

数据探索性分析---EDA

​ 由pandas_profiling库提供的数据探索性分析,可以对数据进行预先的分析,寻找数据之间的相关性

# ppf.ProfileReport(train)#  主要是查看特征之间的相关性--Correlations   分析的时候才会用这段代码

该图就是数据探索性分析生成的数据相关性图

image-20220228235819893

下面也可以通过绘制箱型图来看两个属性之间的关系

#属于探索性数据分析
plt.figure(figsize=(15,8))
sns.boxplot(train.YearBuilt,train.SalePrice)#统计数据可视化,绘制箱型图  看建造年份和房价之间的关系
#箱型图是看异常值的,找出离群的点

image-20220228232854330

下面是散点图,用来判断是否有线性关系的

其实当我们拿到这个房价预测问题的时候,就知道他是一个线性回归的问题(因为它是连续值)

#matplotlib绘制图像的库
plt.figure(figsize=(12,6))
plt.scatter(x=train.GrLivArea,y=train.SalePrice)#散点图用来观察是否存在线性的关系
plt.xlabel("GrLivArea",fontsize=13)
plt.ylabel("SalePrice",fontsize=13)
plt.ylim(0,800000)

image-20220228233132282

从图中可以看出,存在一些过于偏离直线的点,所以说需要对其进行裁剪
****所以得删除GrLivArea大于4000的点,即删除了右下角的点----删除训练集里面不大好的数据

#删除表中的某一行或者某一列更明智的方法是使用drop,它不改变原有的df中的数据,而是返回另一个dataframe来存放删除后的数据

##凡是会对原数组作出修改并返回一个新数组的,往往都有一个 inplace可选参数。
#如果手动设定为True(默认为False),那么原数组直接就被替换。也就是说,采用inplace=True之后,原数组名(如2和3情况所示)对应的内存值直接改变;

train.drop(train[
    (train["GrLivArea"]>4000)&(train["SalePrice"]<300000)
].index,inplace=True)#index为数组的自带的索引即行号    pandas里面的条件删除
full = pd.concat([train,test],ignore_index=True)#合并数组---为了把train和test里面的脏数据一起处理了
full.drop("Id",axis=1,inplace=True)#删除第一列Id  

数据清洗 (空值的填充、空值的删除、不处理)

寻找空值

##查看缺失值
miss = full.isnull().sum()#统计有多少个空值  返回的的类型为pandas.core.series.Series 是一种带标签的一维数组 类似字典

#把[miss>0]当一种限定条件看
miss[miss>0].sort_values(ascending=False)#把miss>0的数据,从大到小排序

#这里虽然知道是空,但是不知道空的是字符类型的值还是数字类型的值,
# 所以下面就得进行分类填充 通过full.info()查看数据类型,下面就进行分类填充
# full.info()

空值的填充

字符串用NULL填充,数字类型可以用0也可以用别的均值,众数来填充,根据情况来

#对字符类型的进行填充
cols1 = ["PoolQC" , "MiscFeature", "Alley", "Fence", "FireplaceQu", "GarageQual", "GarageCond", "GarageFinish", "GarageYrBlt", "GarageType", "BsmtExposure", "BsmtCond", "BsmtQual", "BsmtFinType2", "BsmtFinType1", "MasVnrType"]
for col in cols1:
    full[col].fillna("None",inplace=True)
#对数值类型的进行填充
cols=["MasVnrArea", "BsmtUnfSF", "TotalBsmtSF", "GarageCars", "BsmtFinSF2", "BsmtFinSF1", "GarageArea"]
for col in cols:
    full[col].fillna(0, inplace=True)
#对lotfrontage的空值进行填充(用这一列的均值)
full["LotFrontage"].fillna(np.mean(full["LotFrontage"]),inplace=True)
#对这些列进行众数填充  这里的也是object类型
cols2 = ["MSZoning", "BsmtFullBath", "BsmtHalfBath", "Utilities", "Functional", "Electrical", "KitchenQual", "SaleType","Exterior1st", "Exterior2nd"]
#full[col].mode()[0] 众数
for col in cols2:
    full[col].fillna(full[col].mode()[0], inplace=True)
    
#查看哪些是还没填充好的,发现只有test数据集的没有SalePrice列
full.isnull().sum()[full.isnull().sum()>0]##至此我们已经把空值填充好了

数据预处理--字符变成数值型这是很重要的

将一些数字特征转换为类别特征。最好使用LabelEncoder和get_dummies来实现这些功能。

for col in cols2:
    full[col]=full[col].astype(str)##astype对cols2中的数据进行数据转换成字符串类型
#类别数据数字化 encoder 
#可以将数据集中的文本转化成0或1的数值
#例如存在 A B两种类型的str,直接将这两种转变成0或1
#A--0  B--1 将str转换成int
from sklearn.preprocessing import LabelEncoder

lab = LabelEncoder()

#将下列字符型数据都转换成数字型数据
full["Alley"] = lab.fit_transform(full.Alley)
full["PoolQC"] = lab.fit_transform(full.PoolQC)
full["MiscFeature"] = lab.fit_transform(full.MiscFeature)
full["Fence"] = lab.fit_transform(full.Fence)
full["FireplaceQu"] = lab.fit_transform(full.FireplaceQu)
full["GarageQual"] = lab.fit_transform(full.GarageQual)
full["GarageCond"] = lab.fit_transform(full.GarageCond)
full["GarageFinish"] = lab.fit_transform(full.GarageFinish)
full["GarageYrBlt"] = full["GarageYrBlt"].astype(str)
full["GarageYrBlt"] = lab.fit_transform(full.GarageYrBlt)
full["GarageType"] = lab.fit_transform(full.GarageType)
full["BsmtExposure"] = lab.fit_transform(full.BsmtExposure)
full["BsmtCond"] = lab.fit_transform(full.BsmtCond)
full["BsmtQual"] = lab.fit_transform(full.BsmtQual)
full["BsmtFinType2"] = lab.fit_transform(full.BsmtFinType2)
full["BsmtFinType1"] = lab.fit_transform(full.BsmtFinType1)
full["MasVnrType"] = lab.fit_transform(full.MasVnrType)
full["BsmtFinType1"] = lab.fit_transform(full.BsmtFinType1)

#对col2进行字符型数据转换成数字型数据
full["MSZoning"] = lab.fit_transform(full.MSZoning)
full["BsmtFullBath"] = lab.fit_transform(full.BsmtFullBath)
full["BsmtHalfBath"] = lab.fit_transform(full.BsmtHalfBath)
full["Utilities"] = lab.fit_transform(full.Utilities)
full["Functional"] = lab.fit_transform(full.Functional)
full["Electrical"] = lab.fit_transform(full.Electrical)
full["KitchenQual"] = lab.fit_transform(full.KitchenQual)
full["SaleType"] = lab.fit_transform(full.SaleType)
full["Exterior1st"] = lab.fit_transform(full.Exterior1st)
full["Exterior2nd"] = lab.fit_transform(full.Exterior2nd)

#这里会发现仍然存在字符类型的数据
full.head()

# 将大表变成训练时候的输入X  线性回归模型 函数y=k*x
full.drop("SalePrice",axis=1,inplace=True)##删除  

# 将离散型特征使用one-hot编码,
# 会让特征之间的距离计算更加合理
full2 = pd.get_dummies(full)##独热编码  

#处理好的数据
full2.shape

#可以看出都变成数字型了
full2.head()

数据集预处理--为模型构建做准备

from sklearn.preprocessing import RobustScaler, StandardScaler#去除异常值与数据标准化

n_train = train.shape[0]#行数
#划分数据集
#将其分为一个函数y=k*x  X是自变量 y是结果
X = full2[:n_train]#相当于取出X 行切分
y = train.SalePrice#取出训练集的标签 一列

#进行实例化 进行归一化和标准化 
# 目的:减少坐标直接的差异 让x的值在[0,1]之间
# 归一化是让不同维度之间的特征在数值上有一定比较性
std = StandardScaler()

X_scaled = std.fit_transform(X)

# y = np.log(y)#训练集的一个数据分布

test_x = full2[n_train:]#截取测试集部分 1461行之后的

#这里其实是不需要进行归一化和标准化的,归一化和标准化之后跑出来的结果有问题

模型构建

#导入线性回归模型
from sklearn.linear_model import LinearRegression #导入模型
#模型定义
model = LinearRegression()
#开始训练模型
# model1 = model.fit(X_scaled,y)
model1 = model.fit(X,y)

预测

predict = model1.predict(test_x)
result = pd.DataFrame({'Id':test.Id,'SalePrice':predict})
result.to_csv("submission1.csv",index=False)

最终结果

最终会生成的csv文件提交之后的成绩如下

image-20220228234901972

结果不是很好,毕竟只用了很简单的方法,但是这是一个很好的开端,后面将会接着进行学习,来改进这个方法。

思考

后面学了再说吧

posted @ 2022-03-01 00:01  PRINT王哲  阅读(297)  评论(0编辑  收藏  举报
Live2D