当前位置: 首页 > 工具软件 > GraphLab > 使用案例 >

Graphlab Create入门:一个简单的回归例子

周良弼
2023-12-01

数据的预处理

导入数据

因为邮政编码zipcode虽然是数值,但是不具有数值的含义,所以我们在导入数据的时候需要将其指派为字符串类型。

事实上,Graphlab Create在训练模型的时候,对于非数值型的数据,比如说str类型的,它会自动进行形如one-hot的dummy操作,并不需要我们自己来完成这个步骤。Graphlab Create在回归模块使用了简单编码,同时使用字符串功能训练模型。

在这个问题中,我们将zipcode转为字符串类型,无需进行任何特殊的预处理。str类型的所有SFrame列都会自动转换为分类变量。所以,这时候如果你做完模型,使用get('coefficients')方法列出系数,你会发现系数的数量和特征的数量并不相同。就是因为str类型特征使用这种编码一分为多个。

import graphlab
import numpy as np
sales = graphlab.SFrame.read_csv('home_data.csv', column_type_hints={'zipcode':str});
sales.remove_column('id');#去掉id列
sales.remove_column('date');#去掉id列,结果会变好
#sales.remove_column('zipcode')
#sales

数据可视化

通过分析每一列的数据,我们发现date和zipocde两列是str类型的变量,id只是一个编号,可以作为索引,我认为没有太大的信息。在选择特征的时候,我们可以不考虑它。在测试结果的时候,我们可以选择选择加不加入id,date等,看结果有没有变好。

#sales['price'].apply(np.log1p)
print sales.column_names()
sales.show
sales.show(view="Scatter Plot", x="sqft_living", y="price")

数据的标准化

我们知道,特征重新缩放会对准确性产生巨大影响。所以在拿到数据的时候,我们往往要做一些标准化的处理。所谓的标准化就是将每个特征进行缩放和平移。特征重新缩放是将各个特征缩放到相同比例的过程。当特征在其范围内变化很大时,该过程特别有用。

但是,很幸运的是,我们使用GraphLab Create时,默认情况下,它会自行做一定程度的标准化,以确保每个特征都具有相同的L2范数。但是,它并没有平移数据,也就是说每列数据未被中心化使每列平均值为零。关于这个,我自己也写了形如

def normalized(col):
    m = col.mean()
    s = col.std()
    y = (col - m)/s
    return y
sales['price'] = sales['price'].apply(np.log1p)

的标准化和GraphLab Create内置的标准化做比较,发现结果相去不大。既然这样,我不防就使用GraphLab Create标准化的方式。

当然,通过设置,我们也可以禁用其默认的特征缩放,设置参数为: feature_rescaling = False。从这个意义上来讲,GraphLab Create确实比scikit-learn要做得好。

数据集分割

我们将数据集按一定的比率随机分割为训练集和测试集,设置随机种子为一个固定的数字,确保每个人run这份代码都能有相同的结果。

train_data,test_data = sales.random_split(.8,seed=0)

建立模型

在不考虑数据处理的前题下,我们建立模型可以考虑选择不同的特征建立同一个模型,也可以建立不同的模型。参数的选择手动尝试,选了一个比较好的。

在这个问题中,我考虑使用不同特征的线性回归模型,和使用全部特征的决策树以及基于集成的boosting和随机森林模型,最后取结果的平均或者其它方式作为最后的结果,我们挑结果最好的一个。做到的比较好的结果是11万多的RMSE。

模型建立

  • 模型sqft_model是选取面积为单个特征的线性回归模型
  • 模型my_features_model是选取部分特征的线性回归模型
  • 模型advanced_features_model是选取更多特征的线性回归模型
  • 模型m1是选取除ID外所有特征的线性回归模型
  • 模型m2是选取除ID外所有特征的决策树模型
  • 模型m3是选取除ID外所有特征的boosting模型
  • 模型m4是选取除ID外所有特征的随机森林模型
sqft_model = graphlab.linear_regression.create(train_data, target='price', features=['sqft_living'],validation_set=None)

my_features = ['bedrooms', 'bathrooms', 'sqft_living', 'sqft_lot', 'floors', 'zipcode']
#my_features = ['bedrooms', 'bathrooms', 'sqft_living', 'sqft_lot', 'floors']
my_features_model = graphlab.linear_regression.create(train_data,target='price',features=my_features,validation_set=None)

advanced_features=['bedrooms','bathrooms','sqft_living','sqft_lot','floors','zipcode', 'waterfront','view','condition','grade', 'yr_built']
#advanced_features=['bedrooms','bathrooms','sqft_living','sqft_lot','floors', 'waterfront','view','condition','grade', 'yr_built']
advanced_features_model = graphlab.linear_regression.create(train_data,target='price',features=advanced_features,validation_set=None)

all_features = sales.column_names().remove('price')
m1 = graphlab.linear_regression.create(train_data,target='price',features=all_features,validation_set=None)

m2= graphlab.decision_tree_regression.create(train_data, target='price', max_depth =  8)

m2= graphlab.decision_tree_regression.create(train_data, target='price', max_depth =  8)

m3 = graphlab.boosted_trees_regression.create(train_data, target='price',
                                           max_iterations=100,
                                           max_depth =  5)
m4 = graphlab.random_forest_regression.create(train_data, target='price',
                                           max_iterations=100,
                                           max_depth =  8)
sqft_model.get('coefficients');
my_features_model.get('coefficients');
advanced_features_model.get('coefficients');
m1.get('coefficients');

模型可视化

我们除了使用GraphLab的可视化工具外,还可以使用matplotlib.pyplot帮助我们绘图。

import matplotlib.pyplot as plt
plt.plot(test_data['sqft_living'],test_data['price'],'.',
        test_data['sqft_living'],sqft_model.predict(test_data),'-')

模型评价和比较

不同种类的模型具有不同的优点。决策树模型非常擅长处理具有数字特征的表格数据,或具有少于几百个类别的分类特征。与线性模型不同,决策树能够捕获特征与目标之间的非线性的一个关系。

一个重要的注意事项是,基于树的模型不适用于非常稀疏的特征。当处理稀疏输入数据(例如具有大维度的分类特征)时,我们可以预处理稀疏特征以生成新的统计量,或者切换到更适合这种情况的线性模型。

print sqft_model.evaluate(test_data)
print my_features_model.evaluate(test_data)
print advanced_features_model.evaluate(test_data)
print m1.evaluate(test_data)
print m2.evaluate(test_data)#似乎决策树的结果很糟糕
print m3.evaluate(test_data)#似乎梯度提升的结果也不是很行,多迭代几次好多了
print m4.evaluate(test_data)#随机森林的结果不是太好

一个预测例子

我们选比尔盖茨的房子,输入其特征,来看看最后他的房子可以值多少钱。从结果中可以看出,m2、m3、m4三个结果应该是过拟合了。所以这个问题用线性回归来做还是比较理想的。

bill_gates = {'bedrooms':[8], 
              'bathrooms':[25], 
              'sqft_living':[50000], 
              'sqft_lot':[225000],
              'floors':[4], 
              'zipcode':['98039'], 
              'condition':[10], 
              'grade':[10],
              'waterfront':[1],
              'view':[4],
              'sqft_above':[37500],
              'sqft_basement':[12500],
              'yr_built':[1994],
              'yr_renovated':[2010],
              'lat':[47.627606],
              'long':[-122.242054],
              'sqft_living15':[5000],
              'sqft_lot15':[40000]}
print sqft_model.predict(graphlab.SFrame(bill_gates))
print my_features_model.predict(graphlab.SFrame(bill_gates))
print advanced_features_model.predict(graphlab.SFrame(bill_gates))
print m1.predict(graphlab.SFrame(bill_gates))
print m2.predict(graphlab.SFrame(bill_gates))
print m3.predict(graphlab.SFrame(bill_gates))
print m4.predict(graphlab.SFrame(bill_gates))
 类似资料: