用一些简单的数据挖掘(机器学习)模型预测2018TGA最佳游戏

一、背景

The Game Awards颁奖典礼,是由索尼、微软、任天堂以及维尔福赞助的新活动,取代了以往的VGA以及VGX,The Game Awards被喻为游戏界的奥斯卡。(来自百度百科)

The Game Awards 2018

TGA的的提名几天前已经公布。今年最佳游戏的提名包括《刺客信条:奥德赛》、《蔚蓝》、《战神》、《漫威蜘蛛侠》、《怪物猎人:世界》以及《荒野大镖客2》。


刺客信条:奥德赛

蔚蓝

战神

蜘蛛侠

怪物猎人:世界

荒野大镖客2

目前来看,呼声较高的应当是《荒野大镖客2》,虽然此前金摇杆奖颁给了《堡垒之夜》,但是毕竟金摇杆更来自玩家投票,基数大是有优势的。可能从媒体的角度,大部分人还是认为大表哥有较大几率斩获今年的最佳游戏。那么通过前几年的数据能否预测出今年的最佳游戏呢,这里尝试用一些基本的模型做一个预测。

当然,我只是个学社科类专业的,并不是学CS的,文章里所用的模型都是以前旁听的课程或者现在学的数学统计课里学到的,所以肯定有诸多问题,这个只是完成一个课程作业的尝试,仅供自己记录用。

解决思路大概是这样的,收集数据--基本的数据描述--随机森林选择属性--使用模型进行预测(KNN、决策树、随机森林、逻辑斯蒂回归LR、支持向量机SVM、朴素贝叶斯NB、神经网络、XGBoost)--综合所有模型投票结果,得到最终预测。


游戏数据预测The Game Awards奖项

结果剧透:
Red Dead: Redemption 2> Monster Hunter: World =Celeste
中间都是废话,结果直接拉到最后。

二、数据

由于14年开始TGA才叫这个名字,有的属性也不太好收集,所以我们的训练集就用14到17,四年的数据,其实有一些问题,之后也能看出来。

下图展示了部分数据。


数据概览

属性

Year:就是获奖的年份,只有2014到2018年这个范围。
Platform:游戏运行的平台,但是数据太少了,也没分太清,如果同时上了Xbox和PS就当他是全平台吧。也许有写错平台的。
Developer:开发商,我们都知道好的开发商大概率做出好的游戏。不过由于数据量较少,所以出现过两次以上的开发商并不多。
Publisher:发行商,有时候开发商和发行商就一个,育碧、任天堂、暴雪有几款游戏就是这样。
Gamerankings:GameRankings是一个著名的电子游戏评分网站GameRankings综合其他电子游戏评分网站对每一款电子游戏的评分,并且收集各玩家对每一款游戏的意见及批评。(来自百度百科)如果一个游戏有多平台的得分,选评论数最多的得分作为该属性的值。

Gamerankings评分

Rank of Gamerankings:其实是游戏在该平台的排行,比如大表哥在PS4平台排名第一,马里奥奥德赛在NS平台排第一。
Metacritic-Metascore:Metacritic是专门收集对于电影、电视节目、音乐专辑、游戏的评论的网站,网站会整合每个评价的分数再做出一个总评分做为这个项目的评分。metascore是下图左侧的评分,来自媒体评分整合。
Metacritic-Userscore:这部分评分来源于用户,是下图右侧评分。在记录的时候已将用户评分转换为了百分制。

Metacritic评分

Sales:主要是游戏当年的销量,并不是累计到现在的销量。当然,这个数据只是个大概的数据,并不完全准确。
Type:游戏类型,但是目前随着游戏发展,类型越来越有融合的感觉,我自己对类型也没有很好的研究,ARPG,JRPG,或者传统RPG,没有做太多区分,另外其他类型可能也标得不完全正确。但是从评奖上看,很多奖项是倾向RPG的。
Awardornot:这是得没得奖的标签。

初步统计

平台

先来看看平台。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
df_gamedata=pd.read_csv('data.csv', encoding='gb18030')
df_train = df_gamedata[:-6]
df_test = df_gamedata[-6:]
ax = sns.countplot(x = "Platform", data = df_train)

提名游戏平台分布

ax = sns.barplot(x = "Platform", y = "Awardornot", data = df_train)
获奖游戏平台分布

由于就四年数据,所以就四个最佳游戏,这问题挺严重的,14年最佳《龙腾世纪:审判》是全平台的,15年最佳《巫师3:狂猎》也是全平台的,16年最佳《守望先锋》,我们还是当它是PC平台的吧,17年《塞尔达传说:荒野之息》是NS平台的。当然这个图给的包含了误差线,数据量太少,所以误差挺大的。另外可以发现,PS独占的游戏是没有获奖的。

类型

整体上看,提名游戏大多是角色扮演和动作冒险游戏,这和普遍的认识相吻合。
ax = sns.countplot(x = "Type", data = df_train)

提名游戏类型分布

获奖的游戏,因为比较少,只有RPG和FPS类游戏获奖。
ax = sns.barplot(x = "Type", y = "Awardornot", data = df_train)
获奖游戏类型分布

销量

其实,之前的两个属性都算是硬伤,如果可能把VGA的提名数据也加进来,可能会使情况好转。
从销量上看,大部分游戏当年的销量都集中在1000万以内。
sns.distplot(df_train['Sales'])

提名游戏销量分布

值得一提的是,训练集中超过2000万销量的其实是《守望先锋》,比较非典型吧。而今年大表哥发售到开奖期间也可能有2000万销量,这对比其实也不太对等。

评分

评分主要统计了Gamerankings的一个评分,Metacritic的两个评分,考察分布时,使用的值是这三个评分的加和。

scorelist = np.array([])
for i in range(len(df_train)):
    score = df_train.ix[i].values[5] + df_train.ix[i].values[7] + df_train.ix[i].values[8]
    scorelist = np.append(scorelist, score)
sns.distplot(scorelist)
提名游戏得分分布
scorelist = np.array([])
for i in range(len(df_train)):
    if df_train.ix[i].values[11] == 1:
        score = df_train.ix[i].values[5] + df_train.ix[i].values[7] + df_train.ix[i].values[8]
        scorelist = np.append(scorelist, score)
sns.distplot(scorelist)
获奖游戏得分分布

获奖游戏的综合评分在250-280这个区间,得分最高的没获奖主要还是因为去年神仙打架的结果,而每年游戏的水平其实是不均衡的,所以年份需要做更好的区分。

从以上的结果看获奖游戏在平台、游戏类型、评分等方面有一定特点。不过需要承认的是,确实数据量比较少。

随机森林选取属性

我们先用随机森林选一下属性,以免分不出来类,本来就这么少的属性。直观来看,虽然我们都认为有的开发商游戏质量应该是比较过硬的,比如任天堂的第一方、暴雪(不朽?),但是数据量就这么多,游戏厂商工作室太多也不能年年都有提名,所以可能没那么重要。

from sklearn.ensemble import RandomForestClassifier
label = df_train["Awardornot"]
train = df_gamedata.iloc[:, 1:-1]
#train.head()
X = pd.get_dummies(train)[:-6]
y = label
X = X.values
y = y.values
rnd_clf = RandomForestClassifier(max_features=7,n_jobs=-1, n_estimators=40, bootstrap=True, random_state=42)
rnd_clf.fit(X, y)
f_importance=rnd_clf.feature_importances_
indices = np.argsort(f_importance)[::-1]
print("Feature ranking:")
for f in range(X.shape[1]):
    print("%d. feature %d (%f)" % (f + 1, indices[f], f_importance[indices[f]]))
plt.figure(figsize=(20,8))
plt.title("Feature importances")
plt.bar(range(X.shape[1]), f_importance[indices], color="r", align="center")
plt.xticks(range(X.shape[1]), indices)
plt.xlim([-1, X.shape[1]])
plt.show()

调参过程没有展示。结果如下。


参数重要性

对于文本属性的数据,使用的是one-hot编码。参考这一结果,确定模型使用的属性是"Name","Year", "Platform", "Gamerankings", "Metacritic-Metascore", "Metacritic-Userscore", "Sales", "Type", "Awardornot"这几个。虽然的确最佳游戏每年只有一个,不过Year是否真的会产生影响,值得考虑,经过测试,有没有这个属性,结果是一样的。

三、模型运用

sgamedata = df_gamedata[["Name","Year", "Platform", "Gamerankings", "Metacritic-Metascore", "Metacritic-Userscore", "Sales", "Type", "Awardornot"]]

KNN

KNN参考:https://blog.csdn.net/qq_36330643/article/details/77532161

from sklearn.preprocessing import scale
from sklearn.cross_validation import KFold
from sklearn.cross_validation import train_test_split
import numpy as np
from sklearn.metrics import accuracy_score, classification_report
from sklearn.neighbors import KNeighborsClassifier
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
#train.head()
X = pd.get_dummies(train)[:-6]
y = label
X = scale(X.values)
y = y.values

#交叉验证测准确率
def cv_estimate(k, X, y, kfold=10):
    score = 0
    total_num = 100
    for xloop in range(0, total_num):
        cv = KFold(n = X.shape[0], n_folds = kfold)
        clf = KNeighborsClassifier(n_neighbors=k,metric='euclidean')
        for train, test in cv:
            clf.fit(X[train], y[train])
            y_pred = clf.predict(X[test])
            score=score + accuracy_score(y[test], y_pred)
    score=score / (kfold * total_num)
    return score

#普通的循环测准确率
def normal_estimate(k, X, y):
    score = 0
    total_num = 100
    clf = KNeighborsClassifier(n_neighbors=k,metric='euclidean')
    for i in range(total_num):
        clf.fit(X, y)
        y_pred = clf.predict(X)
        score = score + accuracy_score(y, y_pred)
    score = score / total_num
    return score

#选K值
X_train, X_test, y_train, y_test = train_test_split(X,y, stratify=y,test_size=0.20)
k_range = range(1,13)
test_accuracy = []
for k in k_range:
    test_accuracy.append(cv_estimate(k,X_train,y_train,kfold=10))

plt.plot(k_range, test_accuracy)
plt.xlabel("Value of K for KNN")
plt.ylabel("Average Accuracy of Kfold CV")
plt.show()
K和准确率
#所以选个4吧
clf = KNeighborsClassifier(n_neighbors=4,metric='euclidean')
clf.fit(X, y)
test = pd.get_dummies(train)[-6:]
result = clf.predict(test)
result
-----------------------------------------------------------------------------------------------
result: array([0., 0., 0., 0., 0., 0.])

KNN觉得今年六个都不配。

决策树

决策树参考:https://blog.csdn.net/jiaoyangwm/article/details/79525237

from sklearn.model_selection import validation_curve
from sklearn.tree import DecisionTreeClassifier
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
X = pd.get_dummies(train)[:-6]
y = label
X = X.values
y = y.values
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2,stratify=y, random_state=42)
dtc=DecisionTreeClassifier() 
train_score,validation_score=validation_curve(dtc,X_train,y_train,param_name='max_depth',cv=7,param_range=np.arange(1,21,1)) 
x_axis=np.linspace(1,20,20)  
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')
my_y_ticks = np.arange(0, 20, 1)
plt.xticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()  
决策树选参
dtc = DecisionTreeClassifier(max_depth=10)
dtc.fit(X, y)
test = pd.get_dummies(train)[-6:]
result = dtc.predict(test)
R.append(result)
result
----------------------------------------------------------------------------------------------
result: array([0., 1., 0., 0., 0., 1.])

这个array对应的游戏顺序是提名的排序。即《刺客信条:奥德赛》、《蔚蓝》、《战神》、《漫威蜘蛛侠》、《怪物猎人:世界》、《荒野大镖客2》。决策树认为《蔚蓝》和《荒野大镖客2》有可能获奖。

随机森林

随机森林参考:https://www.cnblogs.com/maybe2030/p/4585705.html

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import validation_curve
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
X = pd.get_dummies(train)[:-6]
y = label
X = X.values
y = y.values
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2,stratify=y, random_state=42)
rnd_clf = RandomForestClassifier(max_features=7,n_jobs=-1, bootstrap=True, random_state=42)
train_score,validation_score=validation_curve(rnd_clf,X_train,y_train,param_name='n_estimators',cv=5,param_range=np.arange(10,101,10)) 
x_axis=np.linspace(10,100,10)  
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')  
my_y_ticks = np.arange(0.7, 1, 0.02)
plt.yticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()  
随机森林选参

将n_estimators设置为50。

rnd_clf = RandomForestClassifier(max_features=7,n_jobs=-1, n_estimators=50, bootstrap=True, random_state=42)
rnd_clf.fit(X, y)
test = pd.get_dummies(train)[-6:]
result = rnd_clf.predict(test)
result
---------------------------------------------------------------------
result: array([0., 0., 0., 0., 0., 1.])

随机森林认为今年的最佳游戏是《荒野大镖客2》

Logistic回归

LR参考:https://www.cnblogs.com/alfred2017/p/6627824.html

from sklearn.linear_model import LogisticRegressionCV, LogisticRegression
from sklearn.model_selection import validation_curve
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
X = pd.get_dummies(train)[:-6]
y = label
X = scale(X.values)
y = y.values
lr = LogisticRegressionCV(fit_intercept=True,class_weight = "balanced", cv=10,tol=0.001)
lr.fit(X, y)
test = pd.get_dummies(train)[-6:]
t = scale(test.values)
result = lr.predict(t)
R.append(result)
result
-------------------------------------------------------------------------
result: array([0., 0., 0., 0., 0., 1.])

自带交叉验证的认为最佳应该是《荒野大镖客2》

lr=LogisticRegression()  
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2,stratify=y, random_state=42)
train_score,validation_score=validation_curve(lr,X_train,y_train,param_name='C',cv=10,param_range=np.arange(1,25,1)) 
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
x_axis=np.linspace(0,25,24)  
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')
my_y_ticks = np.arange(0, 25, 1)
plt.xticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()  
逻辑回归选参

C就选2吧。

lr = LogisticRegression(fit_intercept=True,class_weight = "balanced",C=2,tol=0.001)
lr.fit(X, y)
test = pd.get_dummies(train)[-6:]
t = scale(test.values)
result = lr.predict(t)
result
-------------------------------------------------------------------------
result: array([0., 0., 0., 0., 0., 1.])

结果没有太大变化。

SVM

SVM参考:https://cuijiahua.com/blog/2017/11/ml_8_svm_1.html

linear

SVM kernel参考:https://blog.csdn.net/aspirinvagrant/article/details/45306783

from sklearn.svm import SVC
from sklearn.grid_search import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.svm import LinearSVC
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
#train.head()
X = pd.get_dummies(train)[:-6]
y = label
X = scale(X.values)
y = y.values
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2,stratify=y, random_state=42)
params={'gamma':list(np.arange(0.01,0.04,0.005)), 'C':list(np.arange(0.1,5,0.1))}
svm_clf = SVC(kernel="linear")
grid = GridSearchCV(svm_clf, params, cv=3, scoring="accuracy")
grid.fit(X_train,y_train)
#print('网格搜索-最佳度量值:',grid.best_score_) 
#print('网格搜索-最佳模型:',grid.best_estimator_)
print('网格搜索-最佳参数:',grid.best_params_)  
---------------------------------------------------------------------------
网格搜索-最佳参数: {'C': 0.1, 'gamma': 0.01}
svm_clf = SVC(class_weight = "balanced", gamma=0.01, C=0.1, kernel="linear")
svm_clf.fit(X,y)
test = pd.get_dummies(train)[-6:]
t = scale(test.values)
result = svm_clf.predict(t)
R.append(result)
result
---------------------------------------------------------------------------
array([0., 0., 0., 0., 0., 1.])

线性kernel预测《荒野大镖客2》为年度最佳。

rbf

svm_clf = SVC(kernel="rbf")
grid = GridSearchCV(svm_clf, params, cv=3, scoring="accuracy")
grid.fit(X_train,y_train)
#print('网格搜索-最佳度量值:',grid.best_score_)
#print('网格搜索-最佳模型:',grid.best_estimator_)
print('网格搜索-最佳参数:',grid.best_params_)  
---------------------------------------------------------------------------
网格搜索-最佳参数: {'C': 0.1, 'gamma': 0.01}
svm_clf = SVC(class_weight = "balanced", gamma=0.01, C=0.1, kernel="rbf")
svm_clf.fit(X,y)
test = pd.get_dummies(train)[-6:]
t = scale(test.values)
result = svm_clf.predict(t)
R.append(result)
result
---------------------------------------------------------------------------
array([0., 1., 0., 0., 1., 1.])

rbf kernel认为《蔚蓝》、《怪物猎人:世界》、《荒野大镖客2》都有可能是年度最佳。

sigmod

svm_clf = SVC(kernel="sigmoid")
grid = GridSearchCV(svm_clf, params, cv=3, scoring="accuracy")
grid.fit(X_train,y_train)
#print('网格搜索-最佳度量值:',grid.best_score_)
#print('网格搜索-最佳模型:',grid.best_estimator_)
print('网格搜索-最佳参数:',grid.best_params_)  
svm_clf = SVC(class_weight = "balanced", gamma=0.01, C=0.1, kernel="sigmoid")
svm_clf.fit(X,y)
test = pd.get_dummies(train)[-6:]
t = scale(test.values)
result = svm_clf.predict(t)
R.append(result)
result
---------------------------------------------------------------------------
array([0., 1., 0., 0., 1., 1.])

sigmod kernel分出来的结果也是《蔚蓝》、《怪物猎人:世界》、《荒野大镖客2》。

朴素贝叶斯

NB参考:https://blog.csdn.net/moxigandashu/article/details/71480251?locationNum=16&fps=1

from sklearn.naive_bayes import MultinomialNB
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
#train.head()
X = pd.get_dummies(train)[:-6]
y = label
X = X.values
y = y.values
nb_clf = MultinomialNB()
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2,stratify=y, random_state=42)
train_score,validation_score=validation_curve(nb_clf,X,y,param_name='alpha',cv=5,param_range=np.arange(0,0.51,0.01)) 
x_axis=np.linspace(0,0.5,51)  
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')  
my_y_ticks = np.arange(0.70, 0.85, 0.02)
plt.yticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()
alpha选择
nb_clf = MultinomialNB(alpha = 0.1, class_prior=[1,5])
nb_clf.fit(X,y)
test = pd.get_dummies(train)[-6:]
result = nb_clf.predict(test)
R.append(result)
result
---------------------------------------------------------------------------
array([0., 1., 0., 0., 1., 1.])

NB分出来的结果同样也是《蔚蓝》、《怪物猎人:世界》、《荒野大镖客2》。

神经网络

理解神经网络:
https://www.cnblogs.com/charlotte77/p/5629865.html
https://blog.csdn.net/roguesir/article/details/79383122
不太熟,只是调包。(其实都是调包)

import tensorflow as tf
from sklearn.preprocessing import scale
df_gamedata=pd.read_csv('data.csv', encoding='gb18030')
df_train = df_gamedata[:-6]
df_test = df_gamedata[-6:]
sgamedata = df_gamedata[["Name","Year", "Platform", "Gamerankings", "Metacritic-Metascore", "Metacritic-Userscore", "Sales", "Type", "Awardornot"]]
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
x = pd.get_dummies(train)[:-6]
y = label
x = scale(x.values)
Y = list()
for i in y:
    mid = list()
    mid.append(int(i))
    Y.append(mid)
y = Y
test = scale(pd.get_dummies(train)[-6:])
tf_x = tf.placeholder(tf.float32, [None, 14])
tf_y = tf.placeholder(tf.float32, [None, 1])
l1 = tf.layers.dense(tf_x, 40, tf.nn.tanh)
l2 = tf.layers.dense(l1, 20, tf.nn.tanh)
output = tf.layers.dense(l2, 1)
loss = tf.losses.mean_squared_error(tf_y, output)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_op = optimizer.minimize(loss)
sess = tf.Session() 
sess.run(tf.global_variables_initializer()) 
for step in range(500):
    _, l, pred = sess.run([train_op, loss, output], {tf_x: x, tf_y: y})
    if step % 100 == 0:
        print('loss is: ' + str(l))
pred = sess.run(output,{tf_x:test})
result = list()
for i in pred:
    if i > 0.5:
        result.append(1)
    else:
        result.append(0)
R.append(result)
result
---------------------------------------------------------------------------
loss is: 0.44383866
loss is: 0.012355352
loss is: 0.0054020723
loss is: 0.0019608906
loss is: 0.0006009453

[0, 0, 0, 0, 0, 1]

神经网络预测的结果是......《荒野大镖客2》。

XGBoost

XGBoost参考:
https://www.jianshu.com/p/7467e616f227
https://www.cnblogs.com/mfryf/p/6293814.html

import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from xgboost.sklearn import XGBClassifier
from sklearn.model_selection import validation_curve
label = df_train["Awardornot"]
train = sgamedata.iloc[:, 1:-1]
#train.head()
X = pd.get_dummies(train)[:-6]
y = label
X = scale(X.values)
y = y.values
xbg_clf = XGBClassifier()
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2,stratify=y, random_state=42)
train_score,validation_score=validation_curve(xbg_clf,X_train,y_train,param_name='n_estimators',cv=10,param_range=np.arange(1,201,10)) 
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
x_axis=np.linspace(0,200,20)  
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')
my_y_ticks = np.arange(0, 200, 20)
plt.xticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()  
xgboost n_estimators

n_estimators选择为60。

xbg_clf = XGBClassifier(n_estimators=60)
train_score,validation_score=validation_curve(xbg_clf,X_train,y_train,param_name='max_depth',cv=10,param_range=np.arange(1,16,1)) 
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
x_axis=np.linspace(1,16,15)  
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')
my_y_ticks = np.arange(0, 16, 1)
plt.xticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()  
xgboost max_depth
xbg_clf = XGBClassifier(n_estimators=60, max_depth=6)
train_score,validation_score=validation_curve(xbg_clf,X_train,y_train,param_name='gamma',cv=10,param_range=np.arange(0,1,0.1)) 
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
x_axis=np.linspace(0,1,10)  
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')
my_y_ticks = np.arange(0, 1, 0.1)
plt.xticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()  
xgboost gamma

gamma选择0.1

xbg_clf = XGBClassifier(n_estimators=60, max_depth=6,gamma=0.1)
train_score,validation_score=validation_curve(xbg_clf,X_train,y_train,param_name='min_child_weight',cv=10,param_range=np.arange(0,10,1)) 
train_score_mean=np.mean(train_score,1)  
validation_score_mean=np.mean(validation_score,1) 
x_axis=np.linspace(0,10,10)  
plt.grid()  
plt.plot(x_axis,train_score_mean,c='r',label='train score')  
plt.plot(x_axis,validation_score_mean,c='g',label='validation score')
my_y_ticks = np.arange(0, 10, 1)
plt.xticks(my_y_ticks)
plt.legend(loc='best')  
plt.show()  
xgboost min_child_weight

可能因为样本太少,调参时候准确率真是,五花八门......

xbg_clf = XGBClassifier(n_estimators=60, max_depth=6,gamma=0,min_child_weight=1)
xbg_clf.fit(X,y)
test = pd.get_dummies(train)[-6:]
t = scale(test.values)
result = xbg_clf.predict(t)
R.append(result)
result
---------------------------------------------------------------------------
array([0., 0., 0., 0., 1., 1.])

XGBoost投票给了《怪物猎人:世界》以及《荒野大镖客2》。

四、结果

结果统计

votelist = list()
vote = pd.DataFrame(R)
for i in range(vote.shape[1]):
    votelist.append(sum(vote[i]))
test = df_gamedata[-6:]['Name']
test = list(test)
print("Award_Predict")
for i in range(6):
    print(test[i],"------------------", str(round((votelist[i]/sum(votelist))*100,2))+"%")

Award_Predict
Assassin's Creed Odyssey ------------------ 0.0%
Celeste ------------------------------------------- 23.53%
God of War ---------------------------------------0.0%
Marvel’s Spider-Man -------------------------- 0.0%
Monster Hunter: World ----------------------- 23.53%
Red Dead: Redemption 2 -------------------- 52.94%

那么这么看起来大表哥有一半以上的可能拿到这个奖项。《怪物猎人:世界》以及《蔚蓝》各有约四分之一的可能拿到最佳游戏奖。《奥德赛》感觉上大概率是陪跑,以前几届都提名5个,不知道为什么今年提名6个。
《战神》、《蜘蛛侠》几率为0,从游戏素质上看,《战神》也应该是有较高可能获奖的,但是这两个都为0,主要原因应该是PS独占游戏此前没有获得过最佳游戏,如果进一步调整,剔除平台的影响,似乎又不太确切,毕竟看影响了整个游戏业界的一些游戏确实的独占的。

不太确切的分析

《刺客信条:奥德赛》:育碧为这个系列注入了新的活力,从《起源》开始,他们不断尝试新的事物。此前TGA还是VGA的时候,《刺客信条2》、《刺客信条3》都获得过提名,但很难说未来在哪里。
《蔚蓝》:如果独立游戏获奖,应该挺有趣的。
《战神》、《蜘蛛侠》:应该是前几届PS独占游戏没获奖,所以预测成0了,如果今年有了新的变化,那么数据将更丰富一些。
《怪物猎人:世界》:应该是系列最佳吧,晕3D也没在PC上体验过。


《荒野大镖客2》:砸钱就完事了,投入大回报大,质量高,不像国内拍《雷锋的故事》。云的体验应该和玩的体验差别挺大,想试试。首周销售额为7.25亿美元,是整个娱乐媒体史上最成功的首发之一,那不就是50亿R吗。反正国内是不可能有这种游戏。

另外,在用模型的过程中应该也有诸多错误,数据量又少,最后这个结果就这样了。

《异度之刃2》竟然连最佳音乐都没提名。


The Game Awards 2018将于12月6日下午8点30(纽约),北京时间12月7日早上9点30颁奖。等待最终结果吧。

真实结果分析

12月7日,The Game Awards年度游戏公布,最终的获奖游戏是《战神》,这是该游戏系列革新之作,在之前的模型中,该游戏获奖的几率是0,在之前的分析中也提到这和游戏平台可能有很大关系。在去除游戏平台这一特征后,再进行预测,我们发现《战神》获奖的几率依然为0,如果再进一步分析数据,可以发现战神的销量、评分的确都存在劣势。

将今年的结果加入到模型构建中,使用的特征不变,预测的结果为:

Assassin's Creed Odyssey ------------------ 0.0%
Celeste ------------------ 11.11%
God of War ------------------ 44.44%
Marvel’s Spider-Man ------------------ 0.0%
Monster Hunter: World ------------------ 16.67%
Red Dead: Redemption 2 ------------------ 27.78%

模型发生了改变,可能性最高的获奖游戏依然是《战神》和《荒野大镖客2》。但总结而言,不能实现较准确的预测根本原因还是数据量太少,如果获奖游戏的平台、类型分布更加均衡,结果才能更加准确。

你可能感兴趣的:(用一些简单的数据挖掘(机器学习)模型预测2018TGA最佳游戏)