冬奥会智能分析与预测可视化平台-随机森林预测国家奖牌(四)

一 前言

此项目为冬奥会智能分析与预测可视化平台,这个项目是用于参加中国大学生计算机设计大赛-信息可视化设计赛道的项目,最终获得国赛三等奖的成绩。现在主要介绍一下本项目的使用随机森林算法预测国家下一届获得的奖牌。

本项目对于下届冬奥会各个国家获得奖牌的预测是重点难点,经过翻阅大量的资料与阅读各种预测的论文之后,最终选择使用随机森林方法去预测下届冬奥会各国家获得的金牌、银牌和铜牌,在预测过程中,我们考虑了9种因素可能对预测奖牌产生影响,下面我们将详细的介绍预测算法。

预测因素文件和预测结果文件可以在博主所上传的文件资源上找到。

二 随机森林介绍

随机森林是一个包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定。

学习算法

根据下列算法而建造每棵树 [1] :

  1. 用N来表示训练用例(样本)的个数,M表示特征数目。
  2. 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
  3. 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
  4. 对于每一个节点,随机选择m个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。
  5. 每棵树都会完整成长而不会剪枝,这有可能在建完一棵正常树状分类器后会被采用)。

为什么使用随机森林:

  • 1)对于很多种资料,它可以产生高准确度的分类器;
  • 2)它可以处理大量的输入变数;
  • 3)它可以在决定类别时,评估变数的重要性;
  • 4)在建造森林时,它可以在内部对于一般化后的误差产生不偏差的估计;
  • 5)它包含一个好方法可以估计遗失的资料,如果有很大一部分的资料遗失,仍可以维持准确度;
  • 6)它提供一个实验方法,可以去侦测variable interactions;
  • 7)对于不平衡的分类资料集来说,它可以平衡误差;
  • 8)它计算各例中的亲近度,对于数据挖掘、侦测离群点(outlier)和将资料视觉化非常有用;
  • 9)使用上述。它可被延伸应用在未标记的资料上,这类资料通常是使用非监督式聚类。也可侦测偏离者和观看资料;
  • 10)学习过程是很快速的。

随机森林构建

决策树相当于一个大师,通过自己在数据集中学到的知识对于新的数据进行分类。但是俗话说得好,一个诸葛亮,玩不过三个臭皮匠。随机森林就是希望构建多个臭皮匠,希望最终的分类效果能够超过单个大师的一种算法。
那随机森林具体如何构建呢?有两个方面:数据的随机性选取,以及待选特征的随机选取。

1.数据的随机选取:

首先,从原始的数据集中采取有放回的抽样,构造子数据集,子数据集的数据量是和原始数据集相同的。不同子数据集的元素可以重复,同一个子数据集中的元素也可以重复。第二,利用子数据集来构建子决策树,将这个数据放到每个子决策树中,每个子决策树输出一个结果。最后,如果有了新的数据需要通过随机森林得到分类结果,就可以通过对子决策树的判断结果的投票,得到随机森林的输出结果了。如下图,假设随机森林中有3棵子决策树,2棵子树的分类结果是A类,1棵子树的分类结果是B类,那么随机森林的分类结果就是A类。

在这里插入图片描述

2.待选特征的随机选取

与数据集的随机选取类似,随机森林中的子树的每一个分裂过程并未用到所有的待选特征,而是从所有的待选特征中随机选取一定的特征,之后再在随机选取的特征中选取最优的特征。这样能够使得随机森林中的决策树都能够彼此不同,提升系统的多样性,从而提升分类性能。

下图中,蓝色的方块代表所有可以被选择的特征,也就是待选特征。黄色的方块是分裂特征。左边是一棵决策树的特征选取过程,通过在待选特征中选取最优的分裂特征,完成分裂。右边是一个随机森林中的子树的特征选取过程。

在这里插入图片描述

三 预测算法建立

预测因素文件和预测结果文件在博主资源自取

1.因素考虑:

预测模型建立时考虑了9种可能对预测产生影响的因素,分别为(1).参加冬奥会男子数(2).参加冬奥会女子数(3).是否为主办方(4).国家人均gdp(5).国家总gdp(6).国家人口总数 (7).国家社会制度 (8).获得奖牌排行 (9).获得奖牌占总奖牌数的比率。

下面为部分数据的展示:
在这里插入图片描述

2.方法:

首先用RandomForestRegressor按照不同的权重对9种因素进行模型训练,然后使用同种方法对每一种因素进行训练,并预测出2026年的值,再将2026年的数据带入总的预测模型,并得出2026年冬奥会各个国家获得的奖牌,并将2022年的奖牌进行数据检验,最后将获得的数据进行保存。

3.模型检验:

金牌预测结果准确率达到92.88%,银牌预测结果准确率达到93.01%,铜牌预测结果准确率达到92.19%,预测结果满足预期。

下面为预测结果部分数据的展示:
在这里插入图片描述

四 代码编写

预测因素数据采用mysql数据库进行存储,数据提取采用Django的ORM,预测算法使用的是随机森林回归算法,预测结果打印出来保存到excel表格并导入到数据库中,在前端页面进行展示。

为什么使用Django的ORM进行数据提取,因为本项目一开始使用Django进行搭建,后又用Gin进行项目重写,所以预测算法还继续采用Python进行编写代码。

# 奖牌预测
def predict_process(request):
    data_total = CountryHuman.objects.all()
    data_dict1 = {}
    for k in data_total:
        data_dict1.update({k.country: k.id})
    list1 = []
    list2 = []
    list3 = []
    for a, b in data_dict1.items():
        data_list = []
        country_data1 = CountryHuman.objects.filter(id=b).first()
        country_name = country_data1.country
        message = Predict.objects.filter(name=country_name).all()
        message_count = message.count()
        data_dict = {"country_name": country_name}
        if message:
            for medal in ['gold', 'silver', 'bronze']:
                x_train = []
                y_train = []
                data1 = []
                rank1 = medal + '_rank'
                percent1 = medal + '_percent'
                count1 = medal + '_count'
                element = ['men', 'women', 'is_home', 'human_gdp', 'gdp', 'human_total', 'social_system', rank1,
                           percent1]
                tip2 = 0
                for index in message:
                    data3 = index.__dict__
                    x_train.append(
                        [index.men, index.women, index.is_home, index.human_gdp, index.gdp, index.human_total,
                         index.social_system, data3[rank1], data3[percent1]])
                    y_train.append(data3[count1])
                x_train = np.reshape(x_train, (message_count, 9))
                y_train1 = y_train
                y_train = np.array(y_train)
                if len(y_train) < 2:
                    tip2 = 1
                    continue
                X_train, X_test, Y_train, Y_test = train_test_split(x_train, y_train, test_size=0.3, random_state=666)
                if len(Y_test) < 2:
                    tip2 = 1
                    continue
                regr = ensemble.RandomForestRegressor(random_state=666, n_estimators=500)
                regr.fit(x_train, y_train)
                for tip1 in element:
                    x_train1 = []
                    y_train1 = []
                    for data2 in message:
                        x_train1.append(data2.year)
                        y_train1.append(data2.__dict__[tip1])
                    x_train1 = np.reshape(x_train1, (message_count, 1))
                    y_train1 = np.array(y_train1)
                    regr1 = ensemble.RandomForestRegressor(random_state=666, n_estimators=500)
                    regr1.fit(x_train1, y_train1)
                    # score1 = regr.score(x_train, y_train)
                    # print(medal + " " + tip1 + " Traing Score:%f" % score1)
                    result1 = regr1.predict(np.array(2026).reshape(1, -1))
                    data1.append(result1)
                score = regr.score(X_test, Y_test)
                if score > 0.5:
                    print(str(data_dict['country_name']) + " - " + medal + " Traing Score: %f" % score)
                if medal == 'gold' and not np.isnan(score) and y_train1[0] and float(score) > 0.50:
                    list1.append(score)
                elif medal == 'silver' and not np.isnan(score) and y_train1[0] and float(score) > 0.50:
                    list2.append(score)
                elif medal == 'bronze' and not np.isnan(score) and y_train1[0] and float(score) > 0.50:
                    list3.append(score)
                result1 = regr.predict(np.array(data1).reshape(1, -1))
                data_dict.update({medal + '_count': round(float(result1))})
            if tip2 != 1:
                data_list.append(data_dict)
                msg = str(data_list[0]['country_name'])
                gold = str(data_list[0]['gold_count'])
                silver = str(data_list[0]['silver_count'])
                bronze = str(data_list[0]['bronze_count'])
                print(msg + ' 金牌: ' + gold + ' 银牌: ' + silver + ' 铜牌: ' + bronze)
    gold_score = np.mean(list1)
    silver_score = np.mean(list2)
    bronze_score = np.mean(list3)
    print("金牌平均准确率:" + str(gold_score))
    print("银牌平均准确率:" + str(silver_score))
    print("铜牌平均准确率:" + str(bronze_score))

预测结果展示

1. 中国2026届冬奥会奖牌预测结果

在这里插入图片描述

2. 俄罗斯2026届冬奥会奖牌预测结果在这里插入图片描述
3. 挪威2026届冬奥会奖牌预测结果

在这里插入图片描述

4. 美国2026届冬奥会奖牌预测结果

在这里插入图片描述

5. 俄罗斯2026届冬奥会奖牌预测结果在这里插入图片描述

五 总结

以上就是冬奥会智能分析与预测可视化平台使用随机森林算法预测国家下一届获得的奖牌的全部内容啦,在进行预测时可能会有一些不足,请大家多多批评指正。

博主还会更新更多使用到的技术的具体用法,请大家收藏观看不迷路。

本专栏还会继续的更新,希望大家能够多多关注博主的文章,感谢大家的观看。

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
以下是一个示例代码,实现了上述要求: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LEN 20 // 国家名最大长度 #define NUM_COUNTRIES 10 // 国家数量 // 国家结构体 typedef struct { char name[MAX_NAME_LEN]; // 国家名 int gold; // 金牌数 int silver; // 银牌数 int bronze; // 铜牌数 } Country; // 比较函数,按金牌数从大到小排序 int cmp(const void* a, const void* b) { return ((Country*)b)->gold - ((Country*)a)->gold; } int main() { // 建立国家数组 Country countries[NUM_COUNTRIES]; // 输入各个国家奖牌数量并存入文件 FILE* fp = fopen("national.txt", "w"); for (int i = 0; i < NUM_COUNTRIES; i++) { printf("请输入第%d个国家的名称和奖牌数量(金牌 银牌 铜牌):", i+1); scanf("%s %d %d %d", countries[i].name, &countries[i].gold, &countries[i].silver, &countries[i].bronze); fprintf(fp, "%s %d %d %d\n", countries[i].name, countries[i].gold, countries[i].silver, countries[i].bronze); } fclose(fp); // 从文件中读取数据 fp = fopen("national.txt", "r"); for (int i = 0; i < NUM_COUNTRIES; i++) { fscanf(fp, "%s %d %d %d", countries[i].name, &countries[i].gold, &countries[i].silver, &countries[i].bronze); } fclose(fp); // 按金牌数排序 qsort(countries, NUM_COUNTRIES, sizeof(Country), cmp); // 将排序后的结果存入新文件 fp = fopen("national_sort.txt", "w"); for (int i = 0; i < NUM_COUNTRIES; i++) { fprintf(fp, "%s %d %d %d\n", countries[i].name, countries[i].gold, countries[i].silver, countries[i].bronze); } fclose(fp); // 输出结果 printf("排序后的结果:\n"); for (int i = 0; i < NUM_COUNTRIES; i++) { printf("%s %d %d %d\n", countries[i].name, countries[i].gold, countries[i].silver, countries[i].bronze); } return 0; } ``` 注意,上述代码中的排序算法使用了 C 标准库中的 `qsort` 函数,需要包含头文件 `stdlib.h`。另外,为了方便起见,本示例中所有数据都是手动输入的,实际应用中可以根据实际情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏沫の梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值