唯品会 一家专门做特卖的网站,电商平台怎么加入,自己做的网站能上传吗,做电影网站被告版权文章目录 #x1f9e1;#x1f9e1;实验内容#x1f9e1;#x1f9e1;#x1f9e1;#x1f9e1;数据预处理#x1f9e1;#x1f9e1;代码缺失值处理特征探索相关性分析文本数据标签编码数值型数据标准化划分数据集 #x1f9e1;#x1f9e1;线性回归#x1f9e1;实验内容数据预处理代码缺失值处理特征探索相关性分析文本数据标签编码数值型数据标准化划分数据集 线性回归闭合形式参数求解原理梯度下降参数求解原理代码运行结果 总结 实验内容 基于California Housing Prices数据集完成关于房价预测的线性回归模型训练、测试与评估。 数据预处理
代码
数据预处理import pandas as pd
import numpy as np
import matplotlib.pyplot as pltdfpd.read_csv(data/housing.csv)
df.info()### 填充缺失值
print(df.isna().sum())
median_bedrooms df[total_bedrooms].median()
df[total_bedrooms].fillna(median_bedrooms, inplaceTrue)### 特征探索
df.hist(bins50,figsize(20,15),edgecolorblack)
plt.show()### 相关性分析
corr_matrixdf.corr()
corr_matrix[median_house_value].sort_values(ascendingFalse)### 组合特征
df[population_per_household]df[population]/df[households] # 每家有几个人
df[rooms_per_household]df[total_rooms]/df[households] # 每家有几个房屋
df[bedrooms_per_room]df[total_bedrooms]/df[total_rooms] # 每个房屋有几个卧室
# corr_matrixdf.corr()
# corr_matrix[median_house_value].sort_values(ascendingFalse)
df.drop([population,households,total_rooms,total_bedrooms],axis1,inplaceTrue)### 文本型数据独热编码
df pd.get_dummies(df, columns[ocean_proximity])### 连续型数据标准化
df[income_copy]df[median_income] # 留着后面分层抽样
con_cols[longitude,latitude,housing_median_age,median_income,population_per_household,rooms_per_household,bedrooms_per_room,median_house_value]
from sklearn.preprocessing import StandardScaler
scaler StandardScaler()
df[con_cols] scaler.fit_transform(df[con_cols])
df划分数据集### 划分数据集分层抽样
# 将median_income这个连续数据映射分级放到新属性income_cat中
df[income_cat] pd.cut(df[income_copy],bins[0, 1.5, 3.0, 4.5, 6, np.inf],labels[1, 2, 3, 4, 5])
df[income_cat].hist(edgecolorblack, bins11, gridFalse)# 分层抽样——按照income_cat属性中比例分层它最接近符合正态分布
from sklearn.model_selection import StratifiedShuffleSplit
ssStratifiedShuffleSplit(n_splits1, test_size0.2, random_state42)
for train_idx, test_idx in ss.split(df, df[income_cat]):train_stratdf.loc[train_idx]test_stratdf.loc[test_idx]print(ftrain_len: {len(train_strat)}, test_len: {len(test_strat)})
print(train 和 test 中 income_cat 比例: \n, train_strat[income_cat].value_counts()/len(train_strat))# 删除无用特征
df.drop([latitude,longitude,median_house_value,income_copy,income_cat],axis1,inplaceTrue)
train_strat.drop([income_cat,income_copy,latitude,longitude],axis1,inplaceTrue)
test_strat.drop([income_cat,income_copy,latitude,longitude],axis1,inplaceTrue)# 划分train和test
y_traintrain_strat[median_house_value].values # .values转array
x_traintrain_strat.drop(median_house_value,axis1).values
y_testtest_strat[median_house_value].values
x_testtest_strat.drop(median_house_value,axis1).values缺失值处理 如下图统计出total_bedrooms出现207个空值而总样本数为20640个大约占1%因此可以考虑直接剔除也可以替代这里这个特征属于连续型变量采用中位数替代。 特征探索 对数据集中的连续型特征绘制其直方图总结出一些处理建议 前两幅图为房地的经纬度因此数值比较分散不呈正态分布情有可原total_rooms、total_bedrooms、population、households这几幅图很类似同时考虑到其表达的含义比较相似可以对它们考虑进行特征组合后述。另外它们都呈现较偏左边的正态分布右半部分比较空缺可以考虑通过采样优化其分布后述。median_income比较接近理想的正态分布在划分数据集时可以考虑以它为基准进行分层抽样这样也能保证total_rooms等特征分布呈较为合理的正态分布。 相关性分析 各个特征与房价median_house_value的相关性分析如下图越接近1和-1越相关0表示没有线性关系。可以看出收入median_income与房价呈很强的正相关关系househols、total_bedrooms、popultion这几个特征对于房价来说相关性很小结合前面特征探索中可以将其组合出新的特征。例如 对于地区家庭数目households和总房屋数目total_rooms组合成“每个家庭的房屋数量”更具有代表性。对于地区卧室总数目total_bedrooms和总房屋总数目total_rooms显然单知道两者数目比较空泛现实生活中更看重“房间卧室的占比”是一个衡量房价的重要指标对于地区总人口和总家庭数目可以尝试组合成“每个家庭有多少人”可能可以从侧面反应出房间大小进而体现房价。 组合新特征出如下图可以看到新组合出的特征rooms_per_households和bedrooms_per_rom比原特征对于房价的相关性要更大显然房间卧室的占比越小房价越贵符合事实。 文本数据标签编码 对于地区举例海洋的距离ocean_proximity这个特征虽然印象里认为“离海越近房价越高”毕竟海景房更招人喜欢考虑使用标签编码是不错的选择但是这个特征值表示的仅是与海的距离分级离海越接近不一定代表有更多客户青睐毕竟能稍微远一点也能看到海景还不用担心极端天气海边发生突发状况。综合以上可能存在的不确定的主观因素以及对于现实情况还不够太了解我选择独热编码让机器自行训练自行分辨。 数值型数据标准化 采用z-score标准化对于每一列特征均处理成X-均值 / 方差。 划分数据集 前面特征探索流程中观察得出收入median_income最接近合理的正态分布并且它与房价的相关性程度最大因此依据不同收入median_income的等级比例来进行分层抽样。首先将连续型的收入median_income依据大小映射成不同的收入等级income_cat并统计不同等级比例然后依据这个等级比例分层抽样划分出训练集和测试集即不管是在训练集和测试集中数据比例满足收入等级对应的比例。 线性回归
闭合形式参数求解原理 主要是通过最小化残差平方和来找到最优的回归系数 设要求的函数为 其中X为样本θ为参数向量 代价函数表示为最小化残差平方和预测值和真实值的误差 对代价函数求导 令导数为0 得到如上线性回归模型的闭合形式解能够直接计算出最优的回归系数然而其中(XT*X)-1有时很难求解。 梯度下降参数求解原理 通过迭代优化逐步调整回归系数以最小化损失函数从而得到较优值对应的回归系数。 确定损失函数 计算梯度 梯度下降负梯度方向 其中α为下降的步幅学习率需提前设定。 重复计算梯度并且更新系数直到达到预先设定的迭代次数或者损失函数收敛至某个阈值本实验中通过设定每两次迭代中损失函数变化不超过1e-8则认为损失函数收敛至某个阈值。 代码
### 指标评估函数
def mean_absolute_error(y_true, y_pred):return np.mean(np.abs(y_pred - y_true))def mean_squared_error(y_true, y_pred):return np.mean((y_pred - y_true) ** 2)def root_mean_squared_error(y_true, y_pred):return np.sqrt(mean_squared_error(y_true, y_pred))def r_squared(y_true, y_pred):y_mean np.mean(y_true)ss_total np.sum((y_true - y_mean) ** 2)ss_residual np.sum((y_true - y_pred) ** 2)r2 1 - (ss_residual / ss_total)return r2def goodness_of_fit(y_true, y_pred):return np.sqrt(r_squared(y_true, y_pred))### 求解
import time## 闭合式求解法
def close_solve(X,Y):# np.linalg.inv求矩阵的逆 .T求矩阵的转置thetanp.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)return thetastart_time time.time() # 记录程序开始时间
print(闭合式求解)
thetaclose_solve(x_train, y_train)
print(ftheta: {theta})
y_prednp.dot(x_test,theta)
print(MAE:, mean_absolute_error(y_test, y_pred)) # 平均绝对误差
print(MSE:, mean_squared_error(y_test, y_pred)) # 均方误差
print(RMSE:, root_mean_squared_error(y_test, y_pred)) # 均方根误差
print(R方:, r_squared(y_test, y_pred)) # R方
print(拟合优度:, goodness_of_fit(y_test, y_pred)) # 拟合优度
print(f运行时间{time.time()-start_time} 秒\n)## 梯度下降法求解
# 定义损失函数
def loss_func(y_true, y_pred):return (1/2)*mean_squared_error(y_true,y_pred) # 1/2 MSEdef gradient_descent(x_train, y_train, lr):n,mx_train.shape # 样本数目thetanp.zeros(m)while True:# 计算误差error和损失lossy_prednp.dot(x_train, theta)errory_pred - y_trainlossloss_func(y_train, y_pred)# 计算梯度、更新参数gradient 2 * np.dot(x_train.T, error) / ntheta-lr*gradientif len(loss_histroy)!0 and abs( loss - loss_histroy[-1]) 1e-8: #结束条件breakloss_histroy.append(loss)return thetastart_time time.time() # 记录程序开始时间
loss_histroy[]
print(梯度下降法求解)
thetagradient_descent(x_train, y_train, lr0.01)
print(ftheta: {theta})
y_prednp.dot(x_test,theta)
print(MAE:, mean_absolute_error(y_test, y_pred)) # 平均绝对误差
print(MSE:, mean_squared_error(y_test, y_pred)) # 均方误差
print(RMSE:, root_mean_squared_error(y_test, y_pred)) # 均方根误差
print(R方:, r_squared(y_test, y_pred)) # R方
print(拟合优度:, goodness_of_fit(y_test, y_pred)) # 拟合优度
print(f运行时间{time.time()-start_time} 秒\n)
plt.plot(loss_histroy)
plt.xlabel(iter)
plt.ylabel(loss)## print特征对应的参数
for f,t in zip(df.columns,theta):print(f{f}\t{t})运行结果 通过闭合式求解和梯度下降法求解并用MAE、MSE、RMSE、R方、拟合优度等来比较两种求解方式的求解效果如下 可以看见两种方法得出的结果差别不大总体来看闭合式求解的误差MAE、MSE、RMSE相对小拟合效果R方、拟合优度相对大因此在本次实验中闭合式求解的效果整体优于梯度下降法。 另外能明显从运行时间看出两者的计算速度差异闭合式由于只需计算结果公式(XT*X)-1X^TY而梯度下降法中需要不断迭代更新theta很多次才能得到较优解所以一般来说闭合式会快得多但本实验中特征维度还算不多闭合式会比较快如若特征维度增多闭合式的求解效率会变得很艰难而梯度下降法在高纬度中仍然能以很快的速度求解出较优值。 总结来说 闭合式求解法在可解的情况下一定能求解出全局最优解但计算速度受维度影响大当维度较大时可能出现不可解的情况。梯度下降法不一定能求解出最优解但在高维度时计算速度仍然有可观的效果。 总结 讨论实验结果分析各个特征与目标预测值的正负相关性 - 呈负相关性的特征 对于population_per_household实验结果表明平均家庭人口越少可能意味着住房拥挤家庭成员较多时每个人的居住空间和私密性可能会减少进而可能会间接降低该地区的房价但相关性很小只有0.03接近0因此可以认为这个特征实际上对于房价影响不大改进实验时应该不再组合这个新特征。 对于ocean_proximity_INLAND实验结果表明靠近内陆的地区房价会越低且相关性程度达0.42结合实际内陆地区由于缺乏海洋景观等吸引力因素房价则相对较低。 - 呈正相关性的特征 相关性程度较大的主要是收入median_income高达0.68结合实际考虑高收入人群通常更愿意支付更高的房价因此高收入区域的房价往往更高。其次主要是与海洋远近的特征结合实际考虑靠近海湾和靠近海洋的地区往往景色优美、气候宜人因此房价会相应较高。 剩余特征如房龄housing_median_age、卧室占比bedrooms_per_room等等对房价的影响程度较小。