目录
0引言
看了一天多的美赛C题,打算这两天从编程手的角度更新一些美赛的思路以及代码资料(R语言
)。
更新完
注意:本文的代码及思路仅供参考,切勿照抄,比赛期间勿私聊 … … 。
1、赛题要求
1.1翻译后的要求:
– 1、讨论这种害虫随着时间的推移而传播是否可以被预测,传播的特点是什么。
– 2、很多报道的目击事件都将其他黄蜂误认为是野黄蜂。使用提供的数据集文件和文件提供的图像视频文件来创建模型,并分析和预测错误分类的概率。
– 3、使用建立的模型讨论您的分类标准如何导致优先调查最有可能是阳性(野黄蜂)的目击报告。
– 4、随着时间的推移如何使用模型更新出新报告,预测发生的频率。
– 5、使用你的模型,什么时候可以说明华盛顿州已经消灭了这种害虫?
1.2赛题小结
前两问是本次问题建模的核心。分别是:
1、根据时间和空间的经纬度关系分析出该黄蜂的传播特点以及生存特性
。
2、结合给出的每次目击报告的文件信息:图像数据、文本评论数据作为协变量数据、识别结果:阳性阴性作为相应遍量建立可预测的回归模型
。
后面三问都是对前两问中的一个模型应用
以及模型稳健分析
。
2、问题一模型思路
2.1数据读入合并
为了更好了构建模型,分析数据先读取数据进行预处理和可视化。
两个Excel数据可去链接免费下载:2021美赛excel数据
读入数据,分析字段
> str(GlobalID)
Classes ‘data.table’ and 'data.frame': 3305 obs. of 3 variables:
$ FileName: chr "ATT1_DSCN9647.jpg" "ATT10_67EAF187-B59C-4F5F-BAAC-9F76E06A96D6.jpg" "ATT100_inbound241937372812029587.jpg" "ATT1000_A5A50BAB-A6EF-4576-A1F8-A07862AADE3A.jpg" ...
$ GlobalID: chr "{5AC8034E-5B46-4294-85F0-5B13117EBEFE}" "{C4F44511-EA53-4FCF-9422-E1C57703720D}" "{43506835-18B8-46B2-A2CB-586AF9C8ECE6}" "{E0AE2F2A-38A5-463C-97B5-9F84A477F9AE}" ...
$ FileType: chr "image/jpg" "image/jpg" "image/jpg" "image/jpg" ...
- attr(*, ".internal.selfref")=<externalptr>
> str(DataSet)
Classes ‘data.table’ and 'data.frame': 4440 obs. of 8 variables:
$ GlobalID : chr "{7D0E73B4-EB54-4CA5-B6B0-F36CC41EBFBC}" "{55C3DF05-0FC3-4737-98CE-2AECFA6C21DB}" "{29CAD9B0-977C-4947-BD62-5CA381CEEA33}" "{DFA7F66D-8DCB-43D7-93EC-3F2E42602600}" ...
$ Detection Date : POSIXct, format: "2020-01-21" "2020-01-22" ...
$ Notes : chr "Definitive orange color....1.5-1.75\" long...very large body....this is the same report I turned in last night,"| __truncated__ "Looked like a yellow jacket on steroids was over an inch long I stepped on it to kill my wife scooped up with s"| __truncated__ "Big and nasty" "I killed this hornet with a bug zapper it took about 30 to 40 mins to kill every time I hit it it came back wit"| __truncated__ ...
$ Lab Status : chr "Unverified" "Unverified" "Unverified" "Unverified" ...
$ Lab Comments : chr "If you see it again, please submit a picture with your next reported sighting." NA NA NA ...
$ Submission Date: POSIXct, format: "2020-07-07" "2020-05-05" ...
$ Latitude : num 47.4 47.4 47.5 48.1 45.6 ...
$ Longitude : num -119 -122 -122 -122 -123 ...
- attr(*, ".internal.selfref")=<externalptr>
为了后面的容易处理,用DataSet
做主表,对GlobalID
做左连接合成一个表。
并提取年份和月份。记为变量y和m
维度:5618行13列
> str(r)
Classes ‘data.table’ and 'data.frame': 5618 obs. of 13 variables:
$ FileName : chr NA NA NA NA ...
$ GlobalID : chr "{7D0E73B4-EB54-4CA5-B6B0-F36CC41EBFBC}" "{55C3DF05-0FC3-4737-98CE-2AECFA6C21DB}" "{29CAD9B0-977C-4947-BD62-5CA381CEEA33}" "{DFA7F66D-8DCB-43D7-93EC-3F2E42602600}" ...
$ FileType : chr NA NA NA NA ...
$ DetectionDate : POSIXct, format: "2020-01-21" "2020-01-22" ...
$ Notes : chr "Definitive orange color....1.5-1.75\" long...very large body....this is the same report I turned in last night,"| __truncated__ "Looked like a yellow jacket on steroids was over an inch long I stepped on it to kill my wife scooped up with s"| __truncated__ "Big and nasty" "I killed this hornet with a bug zapper it took about 30 to 40 mins to kill every time I hit it it came back wit"| __truncated__ ...
$ LabStatus : chr "Unverified" "Unverified" "Unverified" "Unverified" ...
$ LabComments : chr "If you see it again, please submit a picture with your next reported sighting." NA NA NA ...
$ SubmissionDate: POSIXct, format: "2020-07-07" "2020-05-05" ...
$ Latitude : num 47.4 47.4 47.5 48.1 45.6 ...
$ Longitude : num -119 -122 -122 -122 -123 ...
$ y : num 2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 ...
$ m : num 1 1 1 1 1 1 1 1 1 1 ...
$ m : num 1 1 1 1 1 1 1 1 1 1 ...
- attr(*, ".internal.selfref")=<externalptr>
2.2可视化
赛题给了我们经纬度,先看一下具体的位置在哪里:
我找到了地图当底盘,画了散点图。左边是美国所有州的地图,我们看到只有左上角的华盛顿州有记录。所以我们调整图片的范围得到右图。但是这样画到一起看不出任何的信息,通过R语言glpot2分面
的技术得到下面的图。
假设点不重叠,从点的数目上可以看出黄蜂从2017年开始有苗头2018-2019增长期,2020年份数目骤增。接下来我们还想知道该物种是否具有季性。故加下来以2020年为例分月份我们画出了下面两幅图形。
上面那一幅图的是2020年不同月份发现的黄蜂报告数目,可以看出报告多集中在夏季前后。下面的幅图是每个月份做出的具体统计与可视化。有了这些关于黄蜂的数据特点我们下面选回归模型
、时间序列的分解模型
和生长季模型
来量化黄蜂生长的时间特点。
2.2回归模型
统计每年的报告数据做回归模型:
我们看到这个模型的效果不是很好无论是R2还是拟合曲线,还是曲线的方差,原因就在于这个数据在2020年有一个突增。
2.3时间序列模型
在时间序列模型中我们选择从2010年到2020年11年的时间,并细化到月份。
2.3.1 重塑数据
> Ts
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2010 0 1 0 1 0 0 0 0 1 0 0 0
2011 1 0 0 1 1 0 1 2 1 0 0 0
2012 0 0 0 0 0 2 2 1 0 0 0 0
2013 0 0 0 0 0 0 2 2 0 0 0 0
2014 0 0 0 1 0 0 0 0 0 0 0 0
2015 0 0 0 2 1 1 1 2 0 0 0 0
2016 0 0 0 0 0 1 3 2 0 0 0 0
2017 3 0 0 0 0 2 0 0 1 0 0 0
2018 0 1 0 1 5 7 9 3 1 0 0 0
2019 2 0 1 1 11 18 39 50 26 7 3 2
2020 12 7 25 205 649 435 1296 1719 811 227 3 1
从统计数据中我们可以看到一定的季节性,和周期性。下面我们通过建模进行提取关键信息。
2.3.2 选择模型
qq图
告诉我们这幅图不是纯随机的图也不是正态图。从时序图
中我们看到该序列具有明显趋势,故不平稳。从acf、pacf
中可以看出,虽然有截尾特征,但是他的不满足平稳时间序列的前提,所以不能够建立ARMA
模型。可以考虑ARIMA以及SARIMA
,就这个题目而言SARIMA
比较贴切。
这里我们用加法模型
来拟合数据,因为乘法模型对数据突变的数据处理总是不好。
季节指数图:
上图是1-12月份的季节指数,可以看出5月份季节指数最高。3月份达到低谷。
最后我们给出分解模型的三个组成部分:
第一行是原始的时间序列图,第二行是长期的趋势,第三行是模型的周期性,第四行是模型的随机因素。如果想具体到几月份达到峰值,周期长度是多少,骤变结点是哪一个,可以直接处理数据的数据,篇幅原因就不把每个模型的数据输出了。
当然我个人不是和喜欢这个图的风格,想改的下面的代码可以实现。
function (x, ...)
{
xx <- x$x
if (is.null(xx))
xx <- with(x, if (type == "additive")
random + trend + seasonal
else random * trend * seasonal)
plot(cbind(observed = xx, trend = x$trend, seasonal = x$seasonal,
random = x$random), main = paste("Decomposition of",
x$type, "time series"), ...)
}
2.4生长季模型
生长季模型是一类模型常用来处理植被的时空变化的NDVI(生长指数)值。这节通过不同时间节点的报告数,并计算黄蜂的频率指数。建立生长季模型,最终计算出不同年份中黄蜂的快速增长点,快速下降点,以及出现的时间长度。
本文建模的代码方法参考的包phenofit
,给出他的代码示例网站链接。
左图是20210-2020的昆虫的报告情况。右图是2020年的的一个情况。(AG方法的例子)
> myfit(df[241:264,]) # 2020
flag origin TRS2.sos TRS2.eos TRS5.sos TRS5.eos TRS6.sos TRS6.eos DER.sos DER.pop
1: 2020_1 2020-01-01 124 276 160 260 170 256 171 229
DER.eos UD SD DD RD Greenup Maturity Senescence Dormancy
1: 255 113 209 238 282 94 214 290 NA
可以看到TRS2
方法的生长季(sos: start of season)
节的开始是这年的第124天,结束(eos)
是这年的276天,持续存在了153天。
模型的参数和形式,这是对称的模型曲线。
$fFIT
$fFIT$AG
formula: mn + (mx - mn) * exp(-((t0 - t) * rsp)^a3)
formula: mn + (mx - mn) * exp(-((t - t0) * rau)^a5)
pars:
t0 mn mx rsp a3 rau a5
nlminb 7533.309 0.03075173 5.477063 0.01217213 2 0.02732946 2
3、问题二的模型思路(图像)
整题想法:第二问是想把整个题目做成一个回归的任务。因为响应变量是离散的,所以考虑的是分类变量。把数据按着评论、时间、空间、图片信息
的思路进行整理。如下图:是我代码中整理变量生成代码的含义:
这里图片处理运用的是SVD
的压缩图像的技术,不过后来因为数据规模大,运行不动就改用了pac(主成分)
提取最大特征值的方法进行压缩。得到相应的协变量。
最后回归的方法用了:
– 高斯的回归分析
– 基于逻辑回归和MCP结合的变量选择方法
– lda判别分析方法
– 当然还有其他诸如:支持向量机、决策树、随机森林、神经网络等回归方法。
下面具体介绍数据的整理思路。
3.1评论文本的词频统计及词云图
下面是每次报告评论的词频及词云图
> word(ls)
Encoding of stop words file: ascii
ls3
wasp hornet sawfly digger golden horntail wood asian
967 676 537 472 469 375 273 260
cicada bee killer giant dead yellow female don
243 240 239 207 166 162 158 150
bald kill faced native urocerus inches insect beetle
146 144 142 138 133 132 129 128
picture bees orange wa bug ground yard hornets
120 119 115 113 111 111 104 103
inch flying black stinger elm photo murder fly
102 99 98 98 95 95 94 89
garden june bumble killed house hard nest head
89 88 85 81 80 78 78 76
harmless alive flew genus huge looked jacket ten
73 72 72 72 72 72 71 70
body size lined county jar western siricid pictures
69 69 68 66 65 62 61 59
caught negative larger 1.5 pool sp landed didn
57 57 56 54 54 53 52 49
coloring front photos captured paper cimbex trapped species
48 47 47 46 46 45 45 44
3.2 数据和图片数据整理
这部分介绍图片的初步处理思路。每层.jpg
的文件是长*宽*3
的一个rgb
储存彩色的形式。根据R语言——基于SVD的人脸识别所采用的方法,使用0.299、0.587、0.114
三个比例对R、G、B
进行加权。得到灰色模型。
效果图如下:
转换为灰色的好处可以图片降维,方便后面的特征提取,或者svd
降维,接下就是根据整体思路那里介绍的整理变量。
我是用的特征值的方法提取的变量,选择了前10个特征值。他从3000+
个特征值中的占比是90+%
效果还OK。
下面是处理exel和图像(jpg and png)
得到的可用回归数据。3208次观测,15个变量。
> str(Data)
Classes ‘data.table’ and 'data.frame': 3208 obs. of 15 variables:
$ y : num 1 0 0 0 0 0 0 0 0 0 ...
$ m : num 12 2 5 7 7 7 7 7 7 7 ...
$ LoN : int 55 203 199 161 54 20 95 160 160 47 ...
$ LoC : int NA 63 23 111 14 19 14 44 44 14 ...
$ EorW: logi FALSE FALSE TRUE FALSE TRUE TRUE ...
$ V1 : num -0.00781 -0.01773 -0.01358 -0.01322 -0.01536 ...
$ V2 : num 0.0412 -0.01795 -0.02085 -0.00677 0.01333 ...
$ V3 : num -0.01361 -0.01934 -0.01963 -0.00894 -0.00205 ...
$ V4 : num -0.025232 0.007893 -0.019865 0.000805 0.000668 ...
$ V5 : num -0.01894 -0.02135 0.00768 -0.00718 0.00487 ...
$ V6 : num -0.04329 -0.02533 -0.00857 -0.01218 0.02815 ...
$ V7 : num -0.05079 0.00663 -0.03299 0.0076 -0.00403 ...
$ V8 : num -0.03732 0.000421 -0.002197 -0.010853 0.020643 ...
$ V9 : num 0.00528 0.01741 -0.00041 0.00631 -0.00956 ...
$ V10 : num 0.00461 -0.0378 -0.01417 -0.00889 0.0164 ...
- attr(*, ".internal.selfref")=<externalptr>
3.3模型部分
3.3.1 多元线性回归
Call:
lm(formula = y ~ ., data = data.frame(Data))
Residuals:
Min 1Q Median 3Q Max
-0.02587 -0.00918 -0.00516 -0.00032 1.00818
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.385e-03 8.110e-03 0.417 0.6765
m 2.898e-03 9.061e-04 3.198 0.0014 **
LoN -9.833e-06 1.539e-05 -0.639 0.5230
LoC -1.746e-04 3.909e-05 -4.467 8.21e-06 ***
EorW -6.545e-03 2.860e-03 -2.288 0.0222 *
V1 4.083e-01 2.181e-01 1.872 0.0613 .
V2 7.267e-02 6.577e-02 1.105 0.2693
V3 -1.273e-01 6.576e-02 -1.936 0.0530 .
V4 6.573e-02 6.865e-02 0.957 0.3385
V5 3.408e-02 6.583e-02 0.518 0.6046
V6 -2.894e-02 6.577e-02 -0.440 0.6600
V7 1.594e-02 6.585e-02 0.242 0.8087
V8 -4.848e-02 6.579e-02 -0.737 0.4612
V9 1.494e-03 6.576e-02 0.023 0.9819
V10 3.594e-02 6.575e-02 0.547 0.5846
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.06571 on 3186 degrees of freedom
Multiple R-squared: 0.01295, Adjusted R-squared: 0.008608
F-statistic: 2.985 on 14 and 3186 DF, p-value: 0.0001435
模型显著,系数部分显著,R2很小。故不使用这种方法,而且因变量也是0-1分类变量。
3.3.2 带有乘法参数的逻辑回归
这种方法可以进行变量选择。达到稀疏变量的目的。
下面是估计的参数:
> coef(fit.lig.MCP, lambda=0.0005)
(Intercept) m LoN LoC EorW
-6.113203492 0.677398271 -0.002840932 -0.066402244 -6.821828149
V1 V2 V3 V4 V5
56.055622642 7.208752701 -28.064207606 9.196576772 8.205828280
V6 V7 V8 V9 V10
0.000000000 8.893824094 0.000000000 0.000000000 9.115290756
可以看出图片的V6到V9被稀疏掉了。下面是选择变量的路径:
给出混淆矩阵和预测精度:
> tab_mcp
y
x 0 1
0 3187 11
1 0 3
> erro_mcp <- 1-sum(diag(prop.table(tab_mcp)))
> paste0(round(erro_mcp*100,5), "%")
[1] "0.34364%"
3.3.3判别分析(lda)
下面是lda
的模型信息。
> str(fit.lda)
List of 10
$ prior : Named num [1:2] 0.99563 0.00437
..- attr(*, "names")= chr [1:2] "0" "1"
$ counts : Named int [1:2] 3187 14
..- attr(*, "names")= chr [1:2] "0" "1"
$ means : num [1:2, 1:14] 7.49 8.5 90.59 64.71 65.54 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:2] "0" "1"
.. ..$ : chr [1:14] "m" "LoN" "LoC" "EorW" ...
$ scaling: num [1:14, 1] 0.38837 -0.00132 -0.0234 -0.87709 54.71993 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:14] "m" "LoN" "LoC" "EorW" ...
.. ..$ : chr "LD1"
$ lev : chr [1:2] "0" "1"
$ svd : num 6.48
$ N : int 3201
$ call : language lda(formula = y ~ ., data = data.frame(Data))
$ terms :Classes 'terms', 'formula' language y ~ m + LoN + LoC + EorW + V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 + V10
.. ..- attr(*, "variables")= language list(y, m, LoN, LoC, EorW, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10)
.. ..- attr(*, "factors")= int [1:15, 1:14] 0 1 0 0 0 0 0 0 0 0 ...
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : chr [1:15] "y" "m" "LoN" "LoC" ...
.. .. .. ..$ : chr [1:14] "m" "LoN" "LoC" "EorW" ...
.. ..- attr(*, "term.labels")= chr [1:14] "m" "LoN" "LoC" "EorW" ...
.. ..- attr(*, "order")= int [1:14] 1 1 1 1 1 1 1 1 1 1 ...
.. ..- attr(*, "intercept")= int 1
.. ..- attr(*, "response")= int 1
.. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
.. ..- attr(*, "predvars")= language list(y, m, LoN, LoC, EorW, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10)
.. ..- attr(*, "dataClasses")= Named chr [1:15] "numeric" "numeric" "numeric" "numeric" ...
.. .. ..- attr(*, "names")= chr [1:15] "y" "m" "LoN" "LoC" ...
$ xlevels: Named list()
- attr(*, "class")= chr "lda"
同样分类方法给出混淆矩阵:
> tab_lda
newGroup
0 1
0 3187 0
1 13 1
> erro_lda <- 1-sum(diag(prop.table(tab_lda)))
> paste0(round(erro_lda*100,5), "%")
[1] "0.40612%"
3.3.4总结
上面说过,根据3.3.1
的数据整理之后的数据是一个标准的分类回归的任务,如果大家感觉上述三个模型的精度不够,可以自行换自己熟悉的统计学习方方法训练模型。
我把数据存了一个class.csv
的文件出去,方法含义在整体思路
有总结,下面是具体的形式:
4、本文涉及代码
每一题目(只更新前两问)在发布完思路后,统一发布合集链接,更新中 … …
会陆续发布思路代码,感兴趣的下面链接自取。
4.1第一问代码
注意:代码在安装包之后可正常运行,不需要改动参数,但是这是R语言的代码,没有R语言基础的同学不推荐购买下载。
第一问代码链接。
4.2第二问代码
注意:代码在安装包之后可正常运行,不需要改动参数,但是这是R语言的代码,没有R语言基础的同学不推荐购买下载。
第二问代码链接。
第二问的参考代码文件有点多,下面截图介绍一下。
4.3代码合集链接
考虑到有的同学想要两个同时下载。后续会出一个前两问模型的套餐。是4.1和4.2
的合集。
2021美赛C题前两问思路合集
写在最后的建议
比赛期间合理安排作息,注意休息。O奖冲呀!!!