一、数据清洗
1、数据数值处理
(1)数据集主要问题
1.数据缺失
2.数据不一致
3.存在“脏”数据
4.数据不规范
数据整体较为规整,但仍存在以下问题:数据缺失,存在某些数据等于0
(2)删除重复数据
(a)新建一个工作表house_prices_new.csv执行数据清洗,方便和原始数据区分开来,选中需要处理的数据。
(b)选择数据——重复项——删除重复项
(c)利用唯一标识house_id,删除重复值
未发现重复项
(3)升序排列
选择排序——升序
(4)缺失值处理
通过人工手动补全,适合与缺失值比较少
删除缺失数据
用列表平均值代替缺失值
用统计模型计算出来的值代替缺失值
本题删除所有值为0的,缺失值所在行
(a)选中地址列的数据区域即bedrooms所在的列
(b)采用选择菜单:点击数据——自动筛选——图中下拉三角形
(c)筛选值为0
(d)选中删除bedrooms值为0的所有行
(e)以同样的方法删除bathrooms值为0的行
结果如下
2.非数值数据处理
线性回归中经常会遇到非数值型数据,即分类型数据,比如性别、所属省份、专业类型等等
分类型数据无法量化,一般会采用哑数据进行处理
如某个数据分为A、B、C三类,即可采用两个哑数据a,b
类型为A时,a=1,b=0
类型为B时,a=0,b=1
类型为C时,a=0,b=0
不使用a,b,c三个哑数据,是因为如果哑数据个数与分类数相同时,恒有a+b+c=1,会存在多重共线性问题
在数据中neighborhood和style栏是非数值数据,在neighborhood一栏中将A,B,C以二进制编码表示为10,01,00,也就是十进制的2,1,0。
在style一栏中同理可得ranch,victorian,lodge为2,1,0。
3.使用Excel实现回归
根据表中数据得到回归方程
y=-9109.9x1+345.41x2-1645.87x3+7907.17x4+4524.79x5
r²=0.622195
通过P-value一栏可以得到房屋面积和价格的相关性最强。
三.用Sklearn库做房价预测线性回归
代码
#导入相关库
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split #这里是引用了交叉验证
from sklearn.linear_model import LinearRegression #线性回归
from sklearn.linear_model import Lasso, Ridge, LinearRegression as LR
from sklearn.metrics import r2_score, explained_variance_score as EVS, mean_squared_error as MSE
from sklearn.model_selection import train_test_split, cross_val_score
from pandas.core.accessor import register_dataframe_accessor
#读入数据
data=pd.read_csv('D:/house_prices.csv')
x = data[['neighborhood','area','bedrooms','bathrooms','style']]# 特征数据,自变量
y= data['price']# 标签值,因变量
#以8:2的比例分成训练集与测试集
x_train, x_test, y_train, y_test = train_test_split(
x, y, test_size=0.2, random_state=1)
reg = LR().fit(x_train, y_train) # 训练模型
yhat = reg.predict(x_test) # 基于测试集x去预测标签
print("r² = ",r2_score(y_test,yhat))#判定系数R²
f = open("多元线性回归.txt", 'w+', encoding='utf8')
f.write("参数为:" + str(reg.coef_)+"\t\n") # 得到各个特征的系数
f.write("截距为:" + str(reg.intercept_)+"\t\n") # 得到截距,常数c
f.write("均方差为:" + str(MSE(y_test, yhat))+"\t\n") # 均方差(绝对值)
f.write('平均误差相对于样本真实值平均值的比例为:'+str(np.sqrt(MSE(y_test, yhat)) /y_test.mean())+"\t\n") # 平均误差相对于样本真实值平均值的比例
f.write("判定系数R²为:"+str(r2_score(y_test,yhat))+"\t\n")
#print("R²的均值为:",r²_score(y_test,yhat))
f.write(("可解释方差为:"+str(cross_val_score(reg, x, y, cv=5, scoring="explained_variance")) ))
f.close()
得出r²=0.6123538857467424
参数为:[-4100.19318121 345.25308485 2966.20096372 3932.51688274
4200.13783087]
截距为:-5118.2579364771955
均方差为:94832750958.33032
平均误差相对于样本真实值平均值的比例为:0.3801539086677292
判定系数R²为:0.6123538857467424
可解释方差为:[0.60892115 0.63216779 0.61917468 0.61916186 0.62563534]
模型优化:
# 设置虚拟变量
# 以名义变量 neighborhood 街区为例
nominal_data = df['neighborhood']
# 设置虚拟变量
dummies = pd.get_dummies(nominal_data)
dummies.sample() # pandas 会自动帮你命名
# 每个名义变量生成的虚拟变量中,需要各丢弃一个,这里以丢弃C为例
dummies.drop(columns=['C'], inplace=True)
dummies.sample()
# 将结果与原数据集拼接
results = pd.concat(objs=[df, dummies], axis='columns') # 按照列来合并
results.sample(3)
# 对名义变量 style 的处理可自行尝试
import statsmodels.api as sm
from statsmodels.formula.api import ols # ols 为建立线性回归模型的统计学库
from statsmodels.stats.anova import anova_lm
# 再次建模
lm = ols('price ~ area + bedrooms + bathrooms + A + B', data=results).fit()
lm.summary()
四.总结
基于统计分析库statsmodels实现的线性回归的r²稍大于Excel和Sklearn库实现的线性回归。模型优化后,r²大大提高。了解了多元回归模型的相关概念。