杂记

scikit-learn实现ebay数据分析

 

 

 

一、课程介绍

内容简介

风风火火的双十一过去了,今年的你又给某宝剁了多少手,拔了多少草呢。本节课程我们将介绍另外一个国际贸易门户--ebay,一个致力于为中国商家开辟海外网络直销渠道的平台。我们可以在这个平台上充当买家或是卖家。与淘宝不同的是,这个平台不是一口价交易,而是设置一个开始竞投的价格后开始拍卖。

这节课程我们就是要利用ebay上的历史拍卖数据,用机器学习的方法来训练一个模型,以预测一项拍卖是否会成功,和成功的交易最终的成交价格。

课程知识点

  • 学习如何用scikit-learn的机器学习算法
  • scikit-learn 做数据分析
  • 数据分析结果可视化

课程流程

本次课程我们将按照下面的流程实现数据分析的任务:

  1. ebay 在线拍卖数据初步分析
  2. 利用数据预测拍卖是否会成功
  3. 预测拍卖最终成交价格

二、ebay 在线拍卖数据初步分析

2.1 ebay在线拍卖数据

此次课程我们运用的ebay 在线拍卖数据数据集为EbayData Set,这个数据是由Jay Grossman提供的。这个数据集是由一个为运动爱好者提供资讯的平台SportsCollector

数据集raw.tar.gz数据中包括TrainingSet.csvTestSet.csvTrainingSubset.csv TestSubset.csv,下表中列出了这四个文件的内容简介:

数据名

数据描述

数据量

Training Set

20134月的所有拍卖

258588

Test Set

20135月第一个周的所有拍卖

37460

Training Subset

20134月成功交易的所有拍卖

7,9732

Test Subset

20135月第一周成功交易的所有拍卖

9392

表示数据的特征向量中的特征名及其对应性质:

特征名

特征描述

Price

最终交易金额

StartingBid

拍卖的最低交易金额

BidCount

此项拍卖获得的投标数

Title

交易标题

QuantitySold

成功销售的数量01表示)

SellerRating

卖家在ebay上的评级

StartDate

拍卖开始的日期

EndDate

拍卖结束的日期

PositiveFeedbackPercent

卖方收到的正反馈百分比(占所有反馈)

HasPicture

是否有实物图(01

MemberSince

卖家创建其在ebay上账户的日期

HasStore

卖家是否有ebay店铺(01

SellerCountry

卖家所在的国家

BuyitNowPrice

立即购买该商品的价格

HighBidderFeedbackRating

出价最高的投标者的ebay评级

ReturnsAccepted

是否接受退货01表示)

HasFreeShipping

是否包邮(01表示)

IsHOF

卖家是否是名人堂中的玩家(01表示)

IsAuthenticated

是否受到了工会的认证(01表示)

HasInscription

拍卖项目是否有登记过(01表示)

AvgPrice

库存中关于这款商品的平均价格

MedianPrice

库存中这款商品价格的中位数

AuctionCount

库存中拍卖的总数

SellerSaleToAveragePriceRatio

这项拍卖商品的价格占平均价格的比例

StateDayOfWeek

拍卖开始时是周几

EndDayOfWeek

拍卖结束时是周几

AuctionDuration

拍卖持续的天数

StartingBidPercent

该商品投标底线占平均交易价格的比例

SellerClosePercent

一个卖家成功交易的拍卖数占所有在线拍卖数的比例

ItemAuctionSellPercent

成功交易的拍卖数占所有在线拍卖数的比例

2.2 数据准备及环境配置

进入Code目录中创建目录shiyanlou_cs714并进入,之后的所有代码及训练文件都在此文件夹下创建,通过wget命令获取本次数据分析的ebay拍卖数据raw.tar.gz

$ cd Code

$ mkdir shiyanlou_cs714&& cd shiyanlou_cs714

$ wgethttp://labfile.oss.aliyuncs.com/courses/714/raw.tar.gz

通过tar zxvf命令解压文件raw.tar.gz,并创建文件dataAnalysis.py

安装本次实验所需的Python安装包pandas,matplotlib, numpy, sklearn, seaborn及相关依赖包:

$ sudo pip installpandas

$ sudo pip installmatplotlib

$ sudo pip install numpy

$ sudo pip installsklearn

$ sudo pip installseaborn

$ sudo apt-get installpython-tk

安装包的官方文档:

2.3 数据可视化

编辑源码文件dataAnalysis.py,导入相关的包:

import pandas as pd

from pandas import DataFrame

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

读入数据:

test_set = pd.read_csv('raw/TestSet.csv')

train_set = pd.read_csv('raw/TrainingSet.csv')

test_subset =pd.read_csv('raw/TestSubset.csv')

train_subset =pd.read_csv('raw/TrainingSubset.csv')

输出查看train_set的数据:

train_set.info()

可查看到train_set的数据信息:

可看到总共有25,8588条数据,与我们上面的描述相符,在上面的代码中加入print函数。打印出前三条数据,查看属性值

print(train_set[:3])

第一列属性EbayID为每条拍卖记录的ID号,与预测拍卖是否成功没有联系,因此在模型训练时将该特征去除。QuantitySold属性为1时代表拍卖成功,为0时代表拍卖失败,其中SellerName拍卖卖方的名字与预测拍卖是否成功时没有多大的关系,因此在训练时也将该特征去除

train = train_set.drop(['EbayID','QuantitySold','SellerName'], axis=1)

train_target =train_set['QuantitySold']

 

# 获取总特征数

_, n_features =train.shape

可视化数据,取出一部分特征,量量组成对看数据在这个2维平面上的分布情况:

# isSold拍卖成功为1拍卖失败为0

df = DataFrame(np.hstack((train,train_target[:,None])), columns=range(n_features) + ["isSold"])

_ = sns.pairplot(df[:50], vars=[2,3,4,10,13], hue="isSold", size=1.5)

从第3,9,12,16维特征的散列图及柱状图可看出,这几个维度并不是有很好地区分度,横纵坐标的值分别代表不同维度之间的正负相关性,为了查看数据特征之间的相关性,及不同特征与类别isSold之间的关系,我们可以利用seaborn中的热度图来显示其两两组队之间的相关性

plt.figure(figsize=(10,10))

 

# 计算数据的相关性矩阵

corr = df.corr()

 

# 产生遮挡出热度图上三角部分的mask,因为这个热度图为对称矩阵,所以只输出下三角部分即可

mask =np.zeros_like(corr,dtype=np.bool)

mask[np.triu_indices_from(mask)]= True

 

# 产生热度图中对应的变化的颜色

cmap =sns.diverging_palette(220, 10, as_cmap=True)

 

# 调用seanborn中的heat创建热度图

sns.heatmap(corr,mask=mask, cmap=cmap, vmax = .3,

                square=True, xticklabels=5, yticklabels=2,

                linewidths=.5, cbar_kws={"shrink":.5})

 

# yticks旋转至水平方向,方便查看

plt.yticks(rotation=0)

 

plt.show()

运行结果图:

上幅图中,颜色越偏向红色的相关性越大,越偏向蓝色的相关性越小且负相关,白色即两个特征之间没有多大的关联,通过最后一行可看出,不同维的属性与类别isSold之间的关系,其中第3,9,12,16维特征与拍卖是否会成功有很强的 正相关性其中3,9,12,16分别对应属性SellerClosePercentHitCountSellerSaleAvgPriceRatioBestOffer,表示当这些属性的值越大时越有可能使拍卖成功,其中第6维特征StartingBid与成功拍卖isSold之间的呈现较大的负相关性,可看出当拍卖投标的底线越高则这项拍卖的成功性就越低。

通过这幅热度图的第一列我们还可以看出不同特征与价格Price之间的相关性。同样的我们可以根据这些相关性,选出比较有利于我们实现本次课程的第二个任务—— 拍卖价格预测 的特征。

三、利用数据预测拍卖是否会成功

由于我们的数据量比较大,且特征维度也不是特别少,因此我们一开始做baseline时,就不利用SVM 支持向量机 这些较简单的模型,因为当数据量比较大,且维度较高时,有些简单的机器学习算法就并不是很高效,且可能训练到最后都不收敛并耗时。

根据scikit-learn提供的机器学习算法使用图谱

scikit-learn官方介绍

我们根据图谱推荐先使用SGDClassifier,其全称为Stochastic Gradient Descent 随机梯度下降,通过梯度下降法在训练过程中优化目标函数使得预测值与真实值之间的误差loss最小化。SGDClassifier每次训练过程没有用到所有的训练样本,而是随机的从训练样本中选取一部分进行训练。而且SGD对特征值的大小比较敏感,而通过上面的数据展示,可以知道在我们的数据集里有数值较大的数据,如:Category。因此我们可以先用sklearn.preprocessing中提供的StandardScaler对数据进行预处理,使其每个属性的波动幅度不要太大,有助于训练时函数收敛。

以下就是我们使用sklearn中的SGDClassifier实现拍卖是否成功的模型训练代码(创建isSold_pred.py文件存放):

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

from sklearn.linear_modelimport SGDClassifier

fromsklearn.preprocessing import StandardScaler

 

# prepare data

test_set = pd.read_csv('raw/TestSet.csv')

train_set = pd.read_csv('raw/TrainingSet.csv')

 

train = train_set.drop(['EbayID','QuantitySold','SellerName'], axis=1)

train_target =train_set['QuantitySold']

 

n_trainSamples, n_features= train.shape

 

# 画出训练过程中SGDClassifier利用不同的mini_batch学习的效果

defplot_learning(clf,title):

 

    plt.figure()

    # 记录上一次训练结果在本次batch上的预测情况

    validationScore = []

    # 记录加上本次batch训练结果后的预测情况

    trainScore = []

    # 最小训练批数

    mini_batch = 1000

 

    for idx inrange(int(np.ceil(n_trainSamples / mini_batch))):

        x_batch = train[idx * mini_batch:min((idx + 1) * mini_batch, n_trainSamples)]

        y_batch = train_target[idx *mini_batch: min((idx + 1) * mini_batch, n_trainSamples)]

 

        if idx > 0:

           validationScore.append(clf.score(x_batch, y_batch))

        clf.partial_fit(x_batch, y_batch,classes=range(5))

        if idx > 0:

           trainScore.append(clf.score(x_batch, y_batch))

    plt.plot(trainScore, label="train score")

    plt.plot(validationScore, label="validationsocre")

    plt.xlabel("Mini_batch")

    plt.ylabel("Score")

    plt.legend(loc='best')

    plt.grid()

    plt.title(title)

 

# 对数据进行归一化

scaler =StandardScaler()

train =scaler.fit_transform(train)

# 创建SGDClassifier

clf =SGDClassifier(penalty='l2', alpha=0.001)

plot_learning(clf,"SGDClassifier")

 

plt.show()

训练结果如下图,由于SGDClassifier是在所有的训练样本中抽取一部分作为本次的训练集,因此在这里不适用交叉验证

可看到SGDClassifier的训练效果还不错,我们也可以通过scikit-learn中封装的一些降维方法,将数据可视化,这里我们使用的三种方法进行降维 ———— Random ProjectionPCA T-SNE embedding。在isSold_pred.py中加入以下代码:

from sklearn import (manifold,decomposition, random_projection)

from matplotlib import offsetbox

from time import time

 

# image[0]为数字0表示某条数据的isSold0

images= []

images.append([[  0. ,   0. ,   5.13. ,   9. ,   1. ,   0. ,   0. ],

 0. ,   0.13.15.10.15. ,   5. ,   0. ],

 0. ,   3.15. ,   2. ,   0.11. ,   8. ,   0. ],

 0. ,   4.12. ,   0. ,   0. ,   8. ,   8. ,   0. ],

 0. ,   5. ,   8. ,   0. ,   0. ,   9. ,   8. ,   0. ],

 0. ,   4.11. ,   0. ,   1.12. ,   7. ,   0. ],

 0. ,   2.14. ,   5.10.12. ,   0. ,   0. ],

 0. ,   0. ,   6.13.10. ,   0. ,   0. ,   0. ]])

# image[1]为数字1表示某条数据的isSold1

images.append([[  0. ,   0. ,   0.12.13. ,   5. ,   0. ,   0. ],

 0. ,   0. ,   0.11.16. ,   9. ,   0. ,   0. ],

 0. ,   0. ,   3.15.16. ,   6. ,   0. ,   0. ],

 0. ,   7.15.16.16. ,   2. ,   0. ,   0. ],

 0. ,   0. ,   1.16.16. ,   3. ,   0. ,   0. ],

 0. ,   0. ,   1.16.16. ,   6. ,   0. ,   0. ],

 0. ,   0. ,   1.16.16. ,   6. ,   0. ,   0. ],

 0. ,   0. ,   0.11.16.10. ,   0. ,   0. ]])

 

# 这里只选取了1000条数据进行数据可视化展示

show_instancees = 1000

# define the drawingfunction

defplot_embedding(X, title=None):

    x_min, x_max = np.min(X, 0), np.max(X, 0)

    X = (X - x_min) / (x_max - x_min)

 

    plt.figure()

    ax = plt.subplot(111)

    for i in range(X.shape[0]):

        plt.text(X[i,0], X[i,1],str(train_target[i]),

                color=plt.cm.Set1(train_target[i] / 2.),

                 fontdict={'weight':'bold','size':9})

 

    if hasattr(offsetbox, 'AnnotationBbox'):

        shown_images = np.array([[1., 1.]])  # just something big

    for i inrange(show_instancees):

        dist = np.sum((X[i] - shown_images) ** 2, 1)

        if np.min(dist) < 4e-3:

            # don't show points thatare too close

            continue

        shown_images = np.r_[shown_images,[X[i]]]

        auctionbox = offsetbox.AnnotationBbox(

           offsetbox.OffsetImage(images[train_target[i]], cmap=plt.cm.gray_r),X[i])

        ax.add_artist(auctionbox)

    plt.xticks([]), plt.yticks([])

    if title isnotNone:

        plt.title(title)

 

# 随机投影 Random Projection

start_time = time()

rp =random_projection.SparseRandomProjection(n_components=2, random_state=42)

rp.fit(train[:show_instancees])

train_projected =rp.transform(train[:show_instancees])

plot_embedding(train_projected,"Random Projection of the auction (time: %.3fs" % (time() -start_time))

 

# 主成分提取 PCA

start_time = time()

train_pca =decomposition.TruncatedSVD(n_components=2).fit_transform(train[:show_instancees])

plot_embedding(train_pca,"Pricincipal components projection of the auction (time: %.3fs" % (time() -start_time))

 

# t-sne 降维

start_time = time()

tsne =manifold.TSNE(n_components=2, init='pca', random_state=0)

train_tsne =tsne.fit_transform(train[:show_instancees])

plot_embedding(train_tsne,"T-SNE embedding of the auction (time: %.3fs" % (time() -start_time))

随机投影效果:

PCA降维效果:

t-sne降维效果:

从以上三幅图中,我们可以根据数字01的重叠情况,判读出我们的数据可区分度并不是特别大。因此我们的训练效果也没有达到特别好,从这方面也可以看出我们这里用来训练分类器的特征并不是利用得特别好。有兴趣的同学可以多了解下特征工程,或者根据我们上面绘制的热度图挑选一些特征进行分类器训练,查看训练效果。

分类器训练结束后,可查看分类器在测试集上的测试效果:

# 导入相关包

from sklearn.metrics import (precision_score,recall_score, f1_score)

# 首先也是准备好测试数据,进行归一化处理

test = test_set.drop(['EbayID','QuantitySold','SellerName'],axis=1)

test_target = test_set['QuantitySold']

test = scaler.fit_transform(test)

 

# 利用训练好的分类器进行预测

test_pred =clf.predict(test)

 

print("SGDClassifiertraining performance on testing dataset:" )

print("\tPrecision:%1.3f " % precision_score(test_target, test_pred))

print("\tRecall:%1.3f" % recall_score(test_target, test_pred))

print("\tF1: %1.3f\n" % f1_score(test_target, test_pred))

测试结果:

四、预测拍卖最终成交价格

由于在价格的分布是在一个连续的区间上,因此这与预测拍卖是否会成功是不同的,预测价格是一个回归预测,而判断拍卖是否会成功是一个分类任务。

同样根据机器学习算法使用图谱,在这里我们采取SGDRegressor,其他使用情况与预测拍卖是否成功时差不多,创建Price_pred.py, 代码如下:

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

from sklearn.linear_modelimport SGDRegressor

import random

fromsklearn.preprocessing import MinMaxScaler

 

# prepare data

test_subset =pd.read_csv('raw/TestSubset.csv')

train_subset =pd.read_csv('raw/TrainingSubset.csv')

 

# 训练集

train =train_subset.drop(['EbayID','Price','SellerName'],axis=1)

train_target =train_subset['Price']

 

scaler = MinMaxScaler()

train =scaler.fit_transform(train)

n_trainSamples,n_features = train.shape

 

# ploting example fromscikit-learn

defplot_learning(clf,title):

 

    plt.figure()

    validationScore = []

    trainScore = []

    mini_batch = 500

    # define the shuffle index

    ind = list(range(n_trainSamples))

    random.shuffle(ind)

 

    for idx inrange(int(np.ceil(n_trainSamples / mini_batch))):

        x_batch = train[ind[idx * mini_batch:min((idx + 1) * mini_batch, n_trainSamples)]]

        y_batch = train_target[ind[idx *mini_batch: min((idx + 1) * mini_batch, n_trainSamples)]]

 

        if idx > 0:

           validationScore.append(clf.score(x_batch, y_batch))

        clf.partial_fit(x_batch, y_batch)

        if idx > 0:

           trainScore.append(clf.score(x_batch, y_batch))

 

    plt.plot(trainScore, label="trainscore")

    plt.plot(validationScore, label="validationsocre")

    plt.xlabel("Mini_batch")

    plt.ylabel("Score")

    plt.legend(loc='best')

    plt.title(title)

 

sgd_regresor =SGDRegressor(penalty='l2',alpha=0.001)

plot_learning(sgd_regresor,"SGDRegressor")

 

# 准备测试集查看测试情况

test =test_subset.drop(['EbayID','Price','SellerName'],axis=1)

test =scaler.fit_transform(test)

test_target =test_subset['Price']

 

print("SGD regressorprediction result on testing data: %.3f" %sgd_regresor.score(test,test_target))

 

plt.show()

训练过程:

在测试集上的测试结果:

由于SGDRegressor的回归效果还不错,因此我们没有在进一步的选择其他的模型进行尝试,有兴趣的同学可以在这方面在多改进参数,或者尝试其他的方法看预测效果如何。

五、总结

本次课程我们学习了如何使用scikit-learn进行数据分析,其实在数据分析过程中,运用到机器学习的算法进行模型训练并不是最主要的,很多时候是如何在前期进行数据预处理。这过程中包括数据的筛选,和特征工程等,在进行一项数据挖掘任务时,我们可能会花更多的时间在数据预处理特征工程上,但是这些准备工作做好后,可使得我们之后的模型训练过程事半功倍。在scikit-learn官方文档中也有许多数据库和算法实现例子,并且有很多数据可视化的例子,运用这些例子也能帮助我们快速入门机器学习这个领域。

本次课程所有代码可通过以下地址获得:

wgethttp://labfile.oss.aliyuncs.com/courses/714/dataAnalysis.py

wgethttp://labfile.oss.aliyuncs.com/courses/714/isSold_pred.py

wgethttp://labfile.oss.aliyuncs.com/courses/714/Price_pred.py

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值