【Python机器学习】回归——示例:预测乐高玩具套装的价格

用回归法预测乐高套装价格的基本步骤:

1、收集数据:用Google Shopping的API收集到的数据

2、准备数据:从返回的JSON数据中抽取价格

3、分析算法:可视化并观察数据

4、训练算法:构建不同的模型,采用逐步线性回归和直接的线性回归模型

5、测试算法:使用交叉验证来测试不同的模型,分析哪个效果更好

6、使用算法:目标就是生成数据模型

收集数据

Google为用户提供了一套购物的API来抓取价格,API将以JSON格式返回所需的产品信息。Python提供了JSON解析模块,我们可以从返回的JSON格式里整理出所需数据。

具体代码:

import json
from numpy import *
from time import sleep
import urllib.request

def searchForSet(retX,retY,setNum,yr,numPce,origPrc):
    sleep(5)
    myAPIstr='AIzaSyD2cR2KFyx12hXu6PFU-wrWot3NXvko8vY'
    searchURL='https://www.googleapis.com/shopping/search/v1/public/products?key=%s&country=US&q=lego+%d&alt=json'%(myAPIstr,setNum)
    pg=urllib.request.urlopen(searchURL)
    retDict=json.loads(pg.read())
    for i in range(len(retDict['items'])):
        try:
            currItem=retDict['item'][i]
            if currItem['product']['condition']=='new':
                newFlag=1
            else:
                newFlag=0
            listOfInv=currItem['product']['inventories']
            for item in listOfInv:
                sellingPrice=item['price']
                if sellingPrice>origPrc*0.5:
                    print(yr,numPce,newFlag,origPrc,sellingPrice)
                    retX.append([yr,numPce,newFlag,origPrc])
                    retY.append(sellingPrice)
        except:
            print('problem with item %d' % i)

def setDataCollect(retX,retY):
    searchForSet(retX,retY,8288,2006,800,49.99)
    searchForSet(retX,retY,10030,2002,3096,269.99)
    searchForSet(retX,retY,10179,2007,5195,499.99)
    searchForSet(retX,retY,10181,2007,3428,199.99)
    searchForSet(retX,retY,10189,2008,5922,299.99)
    searchForSet(retX,retY,10196,2009,3263,249.99)

上述代码中,第一个函数是searchForSet(),它调用Google购物API并保证数据抽取的正确性。这里需要导入的模块是time.sleep()、json、urllib3。接下来,拼接查询的URL字符串,添加API的key和待查询的套装信息,打开和解析操作通过json.loads()方法实现。完成后将得到一部字典,下面需要做的就是从中找出价格和其他信息。

部分返回结果的是一个产品的数组,我们将在这些产品上循环迭代,判断该产品是否是新产品并抽取它的价格。解析成功后的套装将在屏幕上显示出来并保存在list对象setX和retY中。

最后一个函数是setDataCollect(),它负责多次调用searchForSet()。函数searchForSet()的其他参数是从某网站收集来的,它们也一并输出到文件中。

执行结果:

lgX=[]
lgY=[]
setDataCollect(lgX,lgY)

训练算法:建立模型

上面收集了一些真实数据,下面依据这些数据构建模型。构建出的模型可以对售价做出预测,并帮助我们理解现有数据。

首先需要添加对应常数项的特征X0(X0=1),为此创建一个全1的矩阵,然后将原数据矩阵lgX复制到新数据矩阵lgX1的第一列到第5列:

lgX1=mat(ones((58,5)))
lgX1[:,1:5]=mat(lgX)

最后,在这个新数据集上进行回归处理:

ws=standRegres(lgX1,lgY)

下面使用缩减法的一种,即岭回归在进行一次试验:

def crossValidation(xArr,yArr,numVal=10):
    m=len(yArr)
    indexList=range(m)
    errorMat=zeros((numVal,30))
    for i in range(numVal):
        trainX=[]
        trainY=[]
        testX=[]
        testY=[]
        random.shuffle(indexList)
        for j in range(m):
            if j<m*0.9:
                trainX.append(xArr[indexList[j]])
                trainY.append(yArr[indexList[j]])
            else:
                testX.append(xArr[indexList[j]])
                testY.append(yArr[indexList[j]])
        wMat=ridgeTest(trainX,trainY)
        for k in range(30):
            #用训练时的参数将测试数据标准化
            matTestX=mat(testX)
            matTrainX=mat(trainX)
            meanTrain=mean(matTrainX,0)
            varTrain=var(matTrainX,0)
            matTestX=(matTestX-meanTrain)/varTrain
            yEst=matTestX*mat(wMat[k,:]+mean(trainY))
            errorMat[i,k]=rssError(yEst.T.A,array(testY))
    meanErrors=mean(errorMat,0)
    minMean=float(min(meanErrors))
    bestWeights=wMat[nonzero(meanErrors==minMean)]
    xMat=mat(xArr)
    yMat=mat(yArr).T
    meanX=mean(xMat,0)
    varX=var(xMat,0)
    unReg=bestWeights/varX
    print('岭回归下最好的模型是:',unReg)
    print(-1*sum(multiply(meanX,unReg))+mean(yMat))

上述代码中,函数crossValidation()有三个参数,前两个参数lgX和lgY存有数据集中的X值和Y值的list对象,默认lgX和lgY具有相同的长度。第三个参数numVal是算法中交叉验证的次数,如果该值没有指定,就取默认值10。函数crossValidation()首先计算数据点的个数m。创建好了训练集和测试集容器,之后创建了一个list并使用NumPy提供的random.shuffle()函数对其中的元素进行混洗,因此可以实现训练集或测试集的随机选取。将数据集的90%分割成训练集,其余10%为测试集,并将二者分别放入对应容器中。

一旦对数据点进行混洗之后,就建立了一个新的矩阵wMat来保存岭回归中的所有回归系数。接下来我们在上述测试集上用30组回归系数来循环测试回归效果。岭回归需要使用标准化后的数据,因此测试数据也需要与测试集相同的参数来执行标准化。之后用rssError()计算误差,并将结果草存在errorMat中。在所有交叉验证完成后,errorMat保存了ridgeTest()里每个\lambda对应的多个误差值。为了将得出的回归系数与standRegres()作对比,需要计算这些误差估计值的均值。有一点需要注意的是:岭回归使用了数据标准化,而standRegres()则没有,因此为了将上述比较可视化,还需要将数据还原。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值