西安房价在下个月内什么地方最值得买?——中篇

本文详细介绍了在预测西安房价过程中如何选择对价格影响最大的特征,包括房源和楼盘数据的处理,利用过滤法、包装法和嵌入法进行特征选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  接“西安房价在下个月内什么地方最值得买?——上篇”。上回我们说到选择对价格影响最大的特征。只说了房源的数据,这回我们接着说楼盘的数据。

第三步:选择对价格影响最大的特征

3.2 楼盘的处理

  我们像上节一样先分析数据,然后用一些特殊的方法去选择特征。  

3.2.1 均价的总体情况

sns.set(color_codes=True)
sns.distplot(loupan['average'], fit=stats.t);
fig = plt.figure()
res = stats.probplot(loupan['average'], sparams=(10,0),dist=stats.t,plot=plt);

  我们还是观察distplot和proplot生成的图像:


这里写图片描述

  我们可以看出这个均价几乎完美符合t分布。但是很显然它线性拟合地不好:

这里写图片描述

  这里算出的偏度是:2.31543220483。说明数据右偏,且不是很符合正态分布了(绝对值超过2,就不是正态分布了)。这也侧面证明了我们上面调参调出来的t分布的正确性。
  峰度是:9.51434946559。说明我们的分布比正态分布要陡峭。这一点从图中也能看出来。9.5左右不是很大,所以我们的数据相对集中,取得极端值的概率小。
  在实际的问题中,数据一般都不会是线性的,非线性的居多,所以在后面我们建立模型来预测房价时,要建立非线性的模型。

3.3 特征的选择

  3.1节我们把影响房源总价的特征选出来了。现在我们不用画图,用一些特征选择的方法来选择影响楼盘均价的特征。因为一共有10几个特征,画图虽然直观但是速度不快。
  
  一般提取特征有三种方法:

  • 过滤法(Filter):过滤法可以分为方差过滤,相关系数过滤,卡方检验,信息增益等。本质就是找到一种能度量特征的重要性的方法。其原理就是按照一定的值(设定的阈值或是算出的相关系数等值)来选择和我们目标(这里指我们的均价)关系最大的几个特征。
  • 包装法(Wrapper):一般都使用递归消除特征法:使用一个“基模型”来进行多轮训练,每轮训练后,消除若干权值系数的特征(将其删除),再基于新的特征集进行下一轮训练。
  • 嵌入法(Embedded): 基于一些机器学习的模型,得到各个特征的权重系数。再根据权重系数来选择特征。有点类似于过滤法。

  这里 有一个基于鸢尾花数据集的特征选择的实例,感兴趣的小伙伴可以去看看。

3.3.1 过滤法

  • 方差过滤:根据设定的阈值来筛选特征。

      阈值的选择决定了特征选几个。因为我们这里后面17个特征都是分类属性的特征值,所以只有0和1两个值。此时计算方差意义不大,所以这里把阈值选的小一些,以便能选择更多的特征。个人觉得这个方法有点鸡肋。因为这个阈值得自己设定,到底设定多少合适谁也说不清,到底选择几个也是看心情= =,完全没个啥可靠的依据。所以我以后可能不会用这种方法。

from sklearn.feature_selection import VarianceThreshold
feature =np.array(loupan[['region','Sale','mark','trian_bus','food','square','park','Vegetable_market','low_price','bank','south','livingroom','low_density','three_room','decoration','kindergarten','Brand_developers']])
feature1 = VarianceThreshold(threshold=0.01).fit_transform(feature)

  我们运行这段程序之后,feature1就是一个矩阵(因为我们前面把表格转化为矩阵了),由于矩阵都是数字,我们根本就不知道哪个特征被摘出去了。feature1.shape出来的也只是现在还有几个特征。所以我们得输出所有的值之后,人工统计一下。通过人工比对可以得知,特征删除了“square”。现在我们还剩下16个特征。
  

  • 相关系数法:这里我们选择皮尔逊系数

      皮尔逊系数一般都表示两个数据集的“线性”关系。 但在实际工作中,两个数据集分布不可能是线性的,所以这个结果值只能做一个参考,最终选择特征还是要根据经验来做一个权衡。pearsonr系数会输出一个二元组(评分,p值)。
      【评分】一般都是在-1和+1之间变化,0表示没有相关性。 -1或+1的相关性意味着精确的线性关系。 正相关意味着随着x的增加,y也随之增加。 负相关意味着随着x增加,y减少。
      【p值】是一个概率值。表示其他不相关的数据集与现在你指定的这个数据集产生具有Pearson相关性的概率。 p值不完全可靠,但对于大于500左右的数据集可能是合理的。
      我将根据皮尔逊的评分高低来选择16个特征。  

from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr
array=[(0,0),]
for i in range(1,17):
    coefc= pearsonr(loupan.iloc[:,i],loupan['average'])
    array.append(coefc)
array.sort(reverse=True)


这里写图片描述

  我们从上面的数据可以看出来,有一些特征是正相关的,一些特征是负相关的。这16个特征排序下来对应的顺序分别是:
   正相关: 17、4、15、12、13、3、2。只要房子附近有这些元素,房价就会变高。(影响力由大到小排列)即:’Brand_developers’(品牌开发商),’trian_bus’(轨交房),’decoration’(精装),’livingroom’(主卧套房),’low_density’(低密度),’mark’(热度),’Sale’(是否在售)
   负相关: 10、16、14、1、5、11、8、9。只要房子附近有这些元素,房价就会降低。(影响力由小到达排列)即:’bank’(银行),’kindergarten’(幼儿园),’three_room’(小三室),’region’(区域),’food’(美食街),’south’(朝南),’Vegetable_market’(菜市场),’low_price’(低价房)
  所以此处我们将两个特征:’Sale’(是否在售)和’bank’(银行)去掉。现在我们还有14个特征。

  • 卡方检验:看自变量与因变量的相关性。A代表某个类别的观察频数,E代表基于假设计算出的期望频数,A与E之差称为残差。考虑自变量等于i且因变量等于j的样本频数的残差,构建统计量。

    这里写图片描述
from sklearn.feature_selection import SelectKBest ,chi2
feature2 = SelectKBest(chi2, k=13).fit_transform(feature1, loupan['average'])

  我们这里取前13个特征。这里和上面一样,需要自己找删除掉了什么特征。万万没想到这卡方检验把“轨交房”这个特征删除了= =。但是根据实际的生活经验,是否交通便利,对房价会造成影响的,而且影响很大,所以我决定不删除这个特征。目前我们还是14个特征。
  信息增益和上面的都同理,不过是函数不一样,所以在这里不再详述。通过过滤法,我们选出了14个特征。

3.3.2 包装法

  给定了‘基模型’, 这里我选择逻辑回归模型。(原因就是前面我们 拟合时发现这是非线性的,所以不能用线性回归)及预测效果评价的方法,然后针对特征空间中的不同子集,计算每个子集的预测效果,效果最好的,即作为最终被挑选出来的特征子集,这个过程称为迭代,所以计算量很大。我们这里用递归消除特征法,即从包含所有特征值的集合出发,逐步删除特征,只要删除后模型预测效果提升,即说明删除动作有效,否则就还是保留原特征。用feature_selection库的RFE类来选择。

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
RFE(estimator=LogisticRegression(), n_features_to_select=13).fit_transform(feature1, a)

  这里还取13个值,我们查看后得知“park”这个特征被删除了,现在我们有13个特征。

3.3.3 嵌入法

  嵌入法通常我们用两个:基于惩罚项的特征选择法&基于树模型的特征选择法。第一个是基于逻辑回归的,第二个是基于GBDT(梯度下降决策树)的。(LR&GBDT算法过程此处不详述,网上有很多资料,可以自行百度)

  • 基于惩罚项的特征选择法
      我们这里的惩罚项指的是回归模型损失函数的惩罚项。一般有两种:L1和L2。这里 有一个对它们的直观理解,里面有相应的公式。如果不想看公式的话,只用理解:
    【1】L1正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择
    【2】L2正则化可以防止模型过拟合(overfitting)。

     【基于L1的LinearSVC选择特征

from sklearn.svm import LinearSVC
from sklearn.feature_selection import SelectFromModel
lsvc = LinearSVC(C=0.12, penalty="l1", dual=False).fit(loupan, a)
model = SelectFromModel(lsvc, prefit=True)
X_lsvc = model.transform(loupan)

  linearSVC:线性支持向量分类。其原理和SVM差不多,不过核函数用的是线性的。SVM网上资料很多,建议阅读
  C:目标函数的惩罚系数,用来平衡分类间隔margin和错分样本的,default C = 1.0。C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样对训练集测试时准确率很高。
   C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。对于我们的样本数据来说,c=0.13时,会排除1个特征;c=0.12时,会排除2个特征。c=0.1时,会排除3个特征。(这就是一个调参的过程)
  penalty:选择哪个惩罚项,L1 or L2?
  dual:当你的样本数量比特征数量多的时候,这个值就是False。用来解决优化问题的。

  【基于L1的LogisticRegression选择特征

from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
#带L1惩罚项的逻辑回归作为基模型的特征选择
SelectFromModel(LogisticRegression(penalty="l1",C=0.3)).fit_transform(loupan, a)

  如果基于LR模型的话,我们的参数C会不一样。C=0.5时就会排除一个特征,C=0.1时已经只剩下两个特征了。所以我们还是采用基于linearSVC的方法,调参C=0.13,排除一个特征,经查看,是“decoration”特征被排除了。现在我们还剩下12个特征。有时还要结合L2一起看,这个问题就比较复杂了,需要先建立一个新模型,我还没有研究。

  • 基于树的特征选择
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier

#GBDT作为基模型的特征选择
SelectFromModel(GradientBoostingClassifier()).fit_transform(loupan, a)

  天啦噜,这个训练过程能训练一年= =,我就这么点数据,跑了将近有半个小时了。可能是要生成树,还要进行合并,所以又占空间又占时间的。

3.4 总结

  至此,我们的特征选取就结束了,最终我们选择了12个特征去参加预测。相信准确率会有提升。其实特征的选择,还要牵扯到特征的融合,比如把几个特征合并,说不定能出现意想不到的结果。这一点还有待去尝试,目前我还没有做到这一步,但是我相信在实际的项目中,这么做是十分有价值的,毕竟再好的特征选取方法,也比不上业务的逻辑和长年累积的经验。

                       memoryjdch编辑于2017.8.9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值