期末作业——基于机器学习算法的LOL比赛预测(求高分,拜托拜托)_深度学习 预测 lol比赛-程序员宅基地

前言2018年5月2日,各大高校男生宿舍不约而同的爆发出尖叫和呼喊声。难道是“单身少年们”集体受到刺激,而引发的集体抗议吗?在这一切的背后究竟隐藏着怎样的秘密?

其实真相是:


一、题目背景

  近年来,随着科技的不断进步和人们传统思想的不断改变,电子竞技正在飞速发展。刚刚,亚奥理事会公布了亚运电子体育表演赛的六个项目:《英雄联盟》、《实况足球》、《炉石传说》、《星际争霸2》、《Arena of Valor》(王者荣耀国际版)和《皇室战争》。它们将作为电子竞技携手奥运的排头兵,出现在八月举行的雅加达亚运会赛场上。而我本人对英雄联盟(LOL)这门赛事比较感兴趣,于是自选了这个题目。

二、样本来源

本人选用的样本数据来源于英雄联盟官网 http://lpl.qq.com/es/lpl/2018/


三、数据可视化及数据预处理

    在我们拿到原始数据后,需要对数据进行预处理,提高数据质量,从而提高挖掘结果的质量。通过刚才的网页数据我们可以发现,其官方网站上所给出的信息非常多。但实际上我们在预测的过程中并不需要那么多的数据。


  所以选择合适的特征就显得更加重要!

  通过做出数据可视化,来观察其特征对最后结果的影响:

  由此看见,无论是插眼还是上单对于最后结果的影响都举足轻重,后边的数据可视化我就不一一展示了。当然,除了运用这种直观的方式观察和比对特征值对于最后结果的影响之外,我还采用了经验法(其实就是问大神)。这种方法的好处就是除了提供的特征外,我们还可以自己发掘一些隐藏关系,建立新的特征并验算新的特征值对于结果的影响。

  最后我选取了队伍十个特征,作为预测的基础。他们分别是:上单差距、中单差距、打野差距、下路差距、协作能力差距、平均小龙数差距、平均大龙数差距、场均插眼差距、场均击杀差距和场均死亡差距。

  首先对特征做一个简单的介绍,前四条差距代表了战队出战选手个人能力的差距,我们都知道一个选手的好坏无疑影响着最后的结果,尾大不掉的现象是确确实实存在的。除此之外,协作能力的差距这一个特征并没有体现在官方所提供的数据中,因此我自己拟定了一个函数:

   这代表着击杀对方一名选手所需要的己方人手。而场均大龙小龙则代表着队伍对于地图公共资源的争夺意识,场均插眼差距可以反映队伍对于地图信息量的把握,只有时时刻刻掌握敌方动向,才能知己知彼,百战不殆。

  将我们所需要的数据收集后,按照所选定的十个特征值整理成表格的形式,保存,作为数据库。

四、算法选择

4.1使用Adaboost算法预测

4.1.1 boost前提介绍

  提升(Boost)简单地来说,提升就是指每一步我都产生一个弱预测模型,然后加权累加到总模型中,然后每一步弱预测模型生成的的依据都是损失函数的负梯度方向,这样若干步以后就可以达到逼近损失函数局部最小值的目标。boosting分类的结果是基于所有分类器的加权求和结果的,分类器每个权重代表的是其对应分类器在上一轮迭代中的成功度。而bagging中的分类器权重是相等的。其中Adaboost就是boosting方法中一个极具代表性的分类器。

 4.1.2 Adaboost训练算法介绍

  AdaBoost(adaptiveboosting):训练数据中的每个样本,并赋予其一个权重,这些权重构成了向量D。一开始,这些权重都初始化成相等值。首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在同一数据集上再次训练弱分类器。重新调整每个样本的权重,第一次分对的样本的权重将会降低,分错的样本的权重将会提高。AdaBoost为每个分类器都分配了一个权重值alpha,其基于每个弱分类器的错误率进行计算的。错误率的定义:

AdaBoost算法的流程图:



对权重向量D更新,如果某个样本被正确分类,那么该样本的权重改为:


计算出D后,AdaBoost继续迭代重复训练调整权重,直到训练错误率为0或者弱分类器的数据达到用户指定值为止。

4.1.3 完整AdaBoost算法实现

伪代码 

对每次迭代:  利用buildStump()函数找到最佳的单层决策树  将最佳单层决策树加入到单层决策树数组  计算alpha  计算新的权重向量D  更新累计类别估计值  如果错误率等于0.0,则退出循环

函数大致包括以下几个:

1、基于单层决策树的Adaboost训练过程

2、Adaboost分类函数

如果我们需要在一个较为复杂的数据集中使用adaboost,最好还加上一个自适应数据加载函数。(注:代码均在本文结尾处统一放置

4.1.4 实际应用

  在这里需要注意的是AdaBoost 需要确保标签类别是+1和-1而非1和0,且自适应数据加载函数假定最后一个特征是类别标签,所以在这里可以通过修改数据的txt文档或者是修改自适应数据加载函数来使得程序正常运行。(注:书中默认程序所限制所有数据应均为浮点数,所以在导入任何数据库的时候都应转换成浮点数

结果:


ROC曲线:


  由最终结果可以看出,对于结果的预测可以达到75%的正确率,所以使用adaboost算法是一个比较合适的选择。

4.2 运用BP神经网络模型

 4.2.1 模型简介

  BP(Back Propagation)神经网络是一种具有三层或者三层以上的多层神经网络,每一层都由若干个神经元组成,它的左、右各层之间各个神经元实现全连接,即左层的每一个神经元与右层的每个神经元都由连接,而上下各神经元之间无连接。BP神经网络按有导师学习方式进行训练,当一对学习模式提供给神经网络后,其神经元的激活值将从输入层经各隐含层向输出层传播,在输出层的各神经元输出对应于输入模式的网络响应。然后,按减少希望输出与实际输出误差的原则,从输出层经各隐含层,最后回到输入层(从右到左)逐层修正各连接权。由于这种修正过程是从输出到输入逐层进行的,所以称它为“误差逆传播算法”。随着这种误差逆传播训练的不断修正,网络对输入模式响应的正确率也将不断提高。

4.2.2 神经网络的概念

  BP神经网络是一种多层的前馈神经网络,其主要的特点是:信号是前向传播的,而误差是反向传播的。具体来说,对于如下的只含一个隐层的神经网络模型:


  BP神经网络的过程主要分为两个阶段,第一阶段是信号的前向传播,从输入层经过隐含层,最后到达输出层;第二阶段是误差的反向传播,从输出层到隐含层,最后到输入层,依次调节隐含层到输出层的权重和偏置,输入层到隐含层的权重和偏置。

在知道了BP神经网络的特点后,我们需要依据信号的前向传播和误差的反向传播来构建整个网络。

4.2.3神经网络的流程

    假设输入层的节点个数为,隐含层的节点个数为,输出层的节点个数为。输入层到隐含层的权重,隐含层到输出层的权重为,输入层到隐含层的偏置为,隐含层到输出层的偏置为。学习速率为,激励函数为。其中激励函数为取Sigmoid函数。形式为:


    如上面的三层BP网络所示,隐含层的输出

    输出层的输出为

    我们取误差公式为:

其中为期望输出。我们记,则可以表示为

以上公式中,
    权值的更新公式为:

   再判断算法是否已经收敛,常见的有指定迭代的代数,判断相邻的两次误差之间的差别是否小于指定的值等等。

4.2.4 程序实现

  因为我对python运用还不算十分熟悉,在运用神经网络的时候,我使用的是MATLAB程序,运行结果如下:


 可以看出虽然拟合的结果不错,但仍然有些比较大的偏差,为此,我又在此基础上尝试了两外一种神经网络的拟合。

4.3 广义回归神经网络

4.3.1 基本简介

  GRNN神经网络 广义回归神经网络(GRNN)是Donald FSpecht在1991年提出的。GRNN是一种正则化的径向基网络,通常用来实现函数逼近。广义回归神经网络是建立在数理统计基础上的径向基函数网络,其理论基础是非线性回归分析。广义回归神经网络对x的回归定义不同于径向基函数的对高斯权值的最小二乘法叠加,他是利用密度函数来预测输出。特点:训练速度快,非线性映射能力强。

4.3.2 算法流程

 GRNN 在结构上由四层构成,分别为输入层、模式层、 求和层和输出层。

1.输入层为向量,维度为m,样本个数为n,线性函数为传输函数。

2.隐藏层与输入层全连接,层内无连接,隐藏层神经元个数与样本个数相等,也就是n,传输函数为径向基函数。

3.加和层中有两个节点,第一个节点为每个隐含层节点的输出和,第二个节点为预期的结果与每个隐含层节点的加权和。

4.输出层输出是第二个节点除以第一个节点。


4.3.3 模型实践

  GRNN神经网络训练效果:红色网络输出数据  蓝色实际数据

  从最后的结果可以看出相比于BP神经网络而言,广义回归网络更适合这个数据集。

五、总结及心得

  这是我真正意义上第一次选择一个从未有过的数据集进行预测,从最开始原始数据的查找和分析,到数据可视化和特征值的选择,对我来说都是不小的考验。在今年进行学习的《机器学习》这门课程中我学到最多的并不是与机器学习相关的内容,而是接受了一种全新的自学模式。我想这种学习模式对于我们的求知欲和创造性的激发是正常上课所给与不了的,也和国外的教学模式不谋而合。这个学期我曾经无数次的为了弄明白一个程序段所包含的意义不眠不休,但是最后看到预测结果的合理的时候让我局的一切的辛苦都是值得的。在今后的学习中,我可能会出国读研转换学习方向重点学习人工智能这一专业,有了这一学期的入门和铺垫,我会更加快速地适应这门科学。最后,我要感谢老师和助教不厌其烦给我帮助和解答,感谢!


参考资料:

CSDN——Adaboost 2.24号:ROC曲线的绘制和AUC计算函数

CSDN——AdaBoost--从原理到实现

中国邮电出版社——《机器学习实战》

CSDN——神经网络学习笔记(六) 广义回归神经网络 https://blog.csdn.net/cyhbrilliant/article/details/52694943

CSDN——【通俗讲解】BP神经网络  https://blog.csdn.net/guomutian911/article/details/78635617


代码实现:
from numpy import *
import matplotlib.pyplot as plt

def loadSimpData():
    datMat = matrix([[ 1. ,  2.1],
        [ 2. ,  1.1],
        [ 1.3,  1. ],
        [ 1. ,  1. ],
        [ 2. ,  1. ]])
    classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]
    return datMat,classLabels

def loadDataSet(fileName):      #general function to parse tab -delimited floats
    numFeat = len(open(fileName).readline().split('\t')) #get number of fields 
    dataMat = []; labelMat = []
    fr = open(fileName)
    for line in fr.readlines():
        lineArr =[]
        curLine = line.strip().split('\t')
        for i in range(numFeat-1):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelMat.append(float(curLine[-1]))
    return dataMat,labelMat
    

def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):#just classify the data
    retArray = ones((shape(dataMatrix)[0],1))
    if threshIneq == 'lt':
        retArray[dataMatrix[:,dimen] <= threshVal] = -1.0
    else:
        retArray[dataMatrix[:,dimen] > threshVal] = -1.0
    return retArray
    

def buildStump(dataArr,classLabels,D):
    dataMatrix = mat(dataArr); labelMat = mat(classLabels).T
    m,n = shape(dataMatrix)
    numSteps = 10.0; bestStump = {}; bestClasEst = mat(zeros((m,1)))
    minError = inf #init error sum, to +infinity
    for i in range(n):#loop over all dimensions
        rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max();
        stepSize = (rangeMax-rangeMin)/numSteps
        for j in range(-1,int(numSteps)+1):#loop over all range in current dimension
            for inequal in ['lt', 'gt']: #go over less than and greater than
                threshVal = (rangeMin + float(j) * stepSize)
                predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)#call stump classify with i, j, lessThan
                errArr = mat(ones((m,1)))
                errArr[predictedVals == labelMat] = 0
                weightedError = D.T*errArr  #calc total error multiplied by D
                #print "split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)
                if weightedError < minError:
                    minError = weightedError
                    bestClasEst = predictedVals.copy()
                    bestStump['dim'] = i
                    bestStump['thresh'] = threshVal
                    bestStump['ineq'] = inequal
    return bestStump,minError,bestClasEst


def adaBoostTrainDS(dataArr,classLabels,numIt=40):
    weakClassArr = []
    m = shape(dataArr)[0]
    D = mat(ones((m,1))/m)   #init D to all equal
    aggClassEst = mat(zeros((m,1)))
    for i in range(numIt):
        bestStump,error,classEst = buildStump(dataArr,classLabels,D)#build Stump
        alpha = float(0.5*log((1.0-error)/max(error,1e-16)))#calc alpha, throw in max(error,eps) to account for error=0
        bestStump['alpha'] = alpha  
        weakClassArr.append(bestStump)                  #store Stump Params in Array
        expon = multiply(-1*alpha*mat(classLabels).T,classEst) #exponent for D calc, getting messy
        D = multiply(D,exp(expon))                              #Calc New D for next iteration
        D = D/D.sum()
        #calc training error of all classifiers, if this is 0 quit for loop early (use break)
        aggClassEst += alpha*classEst
        aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T,ones((m,1)))
        errorRate = aggErrors.sum()/m
        print ("total error: ",errorRate)
        if errorRate == 0.0: break
    return weakClassArr,aggClassEst

def adaClassify(datToClass,classifierArr):
    dataMatrix = mat(datToClass)#do stuff similar to last aggClassEst in adaBoostTrainDS
    m = shape(dataMatrix)[0]
    aggClassEst = mat(zeros((m,1)))
    for i in range(len(classifierArr)):
        classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],\
                                 classifierArr[i]['thresh'],\
                                 classifierArr[i]['ineq'])#call stump classify
        aggClassEst += classifierArr[i]['alpha']*classEst
        print (aggClassEst)
    return sign(aggClassEst)

def plotROC(predStrengths, classLabels):
    import matplotlib.pyplot as plt
    cur = (1.0,1.0) #cursor
    ySum = 0.0 #variable to calculate AUC
    numPosClas = sum(array(classLabels)==1.0)
    yStep = 1/float(numPosClas); xStep = 1/float(len(classLabels)-numPosClas)
    sortedIndicies = predStrengths.argsort()#get sorted index, it's reverse
    fig = plt.figure()
    fig.clf()
    ax = plt.subplot(111)
    #loop through all the values, drawing a line segment at each point
    for index in sortedIndicies.tolist()[0]:
        if classLabels[index] == 1.0:
            delX = 0; delY = yStep;
        else:
            delX = xStep; delY = 0;
            ySum += cur[1]
        #draw line from cur to (cur[0]-delX,cur[1]-delY)
        ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY], c='b')
        cur = (cur[0]-delX,cur[1]-delY)
    ax.plot([0,1],[0,1],'b--')
    plt.xlabel('FALSE Positiverate'); plt.ylabel('TRUE Positive rate')
    plt.title('ROC curve for WINE')
    ax.axis([0,1,0,1])
    plt.show()
    print ("the Area Under the Curve is: ",ySum*xStep)


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/AmbiRF/article/details/80978168

智能推荐

HTML5 Web SQL 数据库_方式准则的定义-程序员宅基地

文章浏览阅读1k次。1、HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。如果你是一个 Web 后端程序员,应该很容易理解 SQL 的操作。Web SQL 数据库可以在最新版的 Safari, Chrome 和 Opera 浏览器中工作。2、核心方法 以下是规范中定义的三个_方式准则的定义

spring Boot 中使用线程池异步执行多个定时任务_springboot启动后自动开启多个线程程序-程序员宅基地

文章浏览阅读4.1k次,点赞2次,收藏6次。spring Boot 中使用线程池异步执行多个定时任务在启动类中添加注解@EnableScheduling配置自定义线程池在启动类中添加注解@EnableScheduling第一步添加注解,这样才会使定时任务启动配置自定义线程池@Configurationpublic class ScheduleConfiguration implements SchedulingConfigurer..._springboot启动后自动开启多个线程程序

Maven编译打包项目 mvn clean install报错ERROR_mvn clean install有errors-程序员宅基地

文章浏览阅读1.1k次。在项目的target文件夹下把之前"mvn clean package"生成的压缩包(我的是jar包)删掉重新执行"mvn clean package"再执行"mvn clean install"即可_mvn clean install有errors

navacate连接不上mysql_navicat连接mysql失败怎么办-程序员宅基地

文章浏览阅读974次。Navicat连接mysql数据库时,不断报1405错误,下面是针对这个的解决办法:MySQL服务器正在运行,停止它。如果是作为Windows服务运行的服务器,进入计算机管理--->服务和应用程序------>服务。如果服务器不是作为服务而运行的,可能需要使用任务管理器来强制停止它。创建1个文本文件(此处命名为mysql-init.txt),并将下述命令置于单一行中:SET PASSW..._nvarchar链接不上数据库

Python的requests参数及方法_python requests 参数-程序员宅基地

文章浏览阅读2.2k次。Python的requests模块是一个常用的HTTP库,用于发送HTTP请求和处理响应。_python requests 参数

近5年典型的的APT攻击事件_2010谷歌网络被极光黑客攻击-程序员宅基地

文章浏览阅读2.7w次,点赞7次,收藏50次。APT攻击APT攻击是近几年来出现的一种高级攻击,具有难检测、持续时间长和攻击目标明确等特征。本文中,整理了近年来比较典型的几个APT攻击,并其攻击过程做了分析(为了加深自己对APT攻击的理解和学习)Google极光攻击2010年的Google Aurora(极光)攻击是一个十分著名的APT攻击。Google的一名雇员点击即时消息中的一条恶意链接,引发了一系列事件导致这个搜_2010谷歌网络被极光黑客攻击

随便推点

微信小程序api视频课程-定时器-setTimeout的使用_微信小程序 settimeout 向上层传值-程序员宅基地

文章浏览阅读1.1k次。JS代码 /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { setTimeout( function(){ wx.showToast({ title: '黄菊华老师', }) },2000 ) },说明该代码只执行一次..._微信小程序 settimeout 向上层传值

uploadify2.1.4如何能使按钮显示中文-程序员宅基地

文章浏览阅读48次。uploadify2.1.4如何能使按钮显示中文博客分类:uploadify网上关于这段话的搜索恐怕是太多了。方法多也试过了不知怎么,反正不行。最终自己想办法给解决了。当然首先还是要有fla源码。直接去管网就可以下载。[url]http://www.uploadify.com/wp-content/uploads/uploadify-v2.1.4...

戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)_vmware-vcsa-all-6.7.0-8169922.iso-程序员宅基地

文章浏览阅读9.6k次,点赞5次,收藏36次。戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)一、前期准备1、下载镜像下载esxi6.7镜像:VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso这里推荐到戴尔官网下载,Baidu搜索“戴尔驱动下载”,选择进入官网,根据提示输入服务器型号搜索适用于该型号服务器的所有驱动下一步选择具体类型的驱动选择一项下载即可待下载完成后打开软碟通(UItraISO),在“文件”选项中打开刚才下载好的镜像文件然后选择启动_vmware-vcsa-all-6.7.0-8169922.iso

百度语音技术永久免费的语音自动转字幕介绍 -程序员宅基地

文章浏览阅读2k次。百度语音技术永久免费的语音自动转字幕介绍基于百度语音技术,识别率97%无时长限制,无文件大小限制永久免费,简单,易用,速度快支持中文,英文,粤语永久免费的语音转字幕网站: http://thinktothings.com视频介绍 https://www.bilibili.com/video/av42750807 ...

Dyninst学习笔记-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏9次。Instrumentation是一种直接修改程序二进制文件的方法。其可以用于程序的调试,优化,安全等等。对这个词一般的翻译是“插桩”,但这更多使用于软件测试领域。【找一些相关的例子】Dyninst可以动态或静态的修改程序的二进制代码。动态修改是在目标进程运行时插入代码(dynamic binary instrumentation)。静态修改则是直接向二进制文件插入代码(static b_dyninst

在服务器上部署asp网站,部署asp网站到云服务器-程序员宅基地

文章浏览阅读2.9k次。部署asp网站到云服务器 内容精选换一换通常情况下,需要结合客户的实际业务环境和具体需求进行业务改造评估,建议您进行服务咨询。这里仅描述一些通用的策略供您参考,主要分如下几方面进行考虑:业务迁移不管您的业务是否已经上线华为云,业务迁移的策略是一致的。建议您将时延敏感型,有快速批量就近部署需求的业务迁移至IEC;保留数据量大,且需要长期稳定运行的业务在中心云上。迁移方法请参见如何计算隔离独享计算资源..._nas asp网站