上面做了数据基础分析,其实用SQL语句也都能很好实现,现在我们要去实现一下SQL做不了的事情,去预测一下中国在下届奥运会的奖牌情况。
同样先是基础数据处理,找到我们认为和最后能夺得奖牌相关的数据,先根据经验去除相关没用的字段,这里我保留了Age,Height,Weight,TEAM,Games, Year, Event,和Medal字段,我们用这些属性字段预测奖牌的情况,这样可以合理的选择最合适的年龄,身高,体重的选手参加比赛。
athlete_data = athlete[athlete.Season=="Summer"] athlete_data = athlete_data[["Age","Height","Weight","Team","Year","Sport","Medal"]] print (athlete_data.head(5)) |
处理数据后打印出来,你会发现很多数据是不全的,这样大量NaN在训练时会导致无法收敛,程序在处理时选择用平均值去填充。
这里我们要预测的能获得金牌概率,当然你还可以改为获得奖牌的概率,但在训练时需要将数据转换为机器可以读懂的格式,这里我们采用One-Hot格式
athlete_data['Gold'] = pd.get_dummies(athlete_data.Medal == 'Gold',drop_first=True) |
这里还要将剩下的字符串字段进行处理,我们使用LabelEncoder
#对不连续数据进行编码,将国家这种字符型字段转换为数字格式 le = preprocessing.LabelEncoder() athlete_data.Team = le.fit_transform(athlete_data.Team) athlete_data.Sport = le.fit_transform(athlete_data.Sport) |
处理后的数据变为,可以看到除了Medal字段其它都以整理完毕。
分割训练集与数据集
x = athlete_data[["Age","Height","Weight","Team","Year","Sport"]] y = athlete_data["Gold"]
x_train, x_test, y_train, y_test = train_test_split(x,y, random_state=101, test_size=0.30) |
训练时我采用的是大名鼎鼎的XGBoost方法,该方法的好处是简单准确,在分类问题上采用提升树的方式,通过打分投票决定出最优结果
x_train, x_test, y_train, y_test = train_test_split(x,y, random_state=101, test_size=0.30) eval_set = [(x_test,y_test)] #这里只论是否获得金牌,所以是个二分类问题 model = XGBClassifier() model.fit(x_train, y_train, early_stopping_rounds=10, eval_metric="logloss", eval_set=eval_set, verbose=True) y_pred = model.predict(x_test) predictions = [round(value) for value in y_pred] accuracy = accuracy_score(y_test, predictions) print("Accuracy: %.2f%%" % (accuracy * 100.0)) |
最终输出:94.93%,这个结果也真是厉害,毕竟我们没有调整任何参数,这里再把哪些属性是最终奖牌影响的权重列出来,可以看出还是哪个国家最重要,而体重不是那么重要,还可以去调整一下参数比如Max_depth=10,准确率能上升到95%,但这么多参数如何才能得到最佳参数能,这里引入交叉验证,去打印出最好的参数值,这里用到是学习率和深度。
learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3] max_depth = [4,5,6,8,10] param_grid = dict(learning_rate=learning_rate,max_depth = max_depth)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=7) grid_search = GridSearchCV(model,param_grid,scoring="neg_log_loss") grid_result = grid_search.fit(x_train, y_train) print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_)) |
输出:
Best: -0.138945 using {'max_depth': 10, 'learning_rate': 0.2}
再次根据最优参数再执行一次:
得到最有准确率95.72%和最佳属性权重比