背景
最近在学 MIT 的线代课,教授讲的极好,但用的是英文教材,无奈我英文太烂,有些概念看不太懂,于是便想做个词频分析,方便熟悉概念和记忆数学高频词。
首先下载 pdf 文件,链接: https://pan.baidu.com/s/1qYEgcEw 密码: 3fby。然后把需要把 pdf 转为 txt,Linux 下有个小工具 python-pdfminer,可用sudo apt-get install python-pdfminer
下载。
分析
下载之后,转格式:
pdf2txt Gilbert_Strang_Introduction_to_Linear_Algebra__2009.pdf > MathLinearBook.txt
然后再下载一个 Python 词频分析工具
git clone https://github.com/Enaunimes/freeq.git
进入文件夹,把 txt 文件放进去,分析词频
cd Documents/freeq
mv ~/MathLinearBook.txt ./
./Documents/freeq/freeq.py -i MathLinearBook.txt -o MathLinearBookFreq.txt
查看下文件:
less MathLinearBookFreq.csv
10066 the
9994 a
5411 be
4030 and
2817 to
2370 in
2173 matrix
1801 are
1497 by
1451 row
1421 that
1278 this
1263 have
1207 column
1128 vector
1051 for
1037 we
843 at
排版很舒服,但有两个问题,左列是右对齐,右列是左对齐,行首存在多个空格,不便于进一步分析;另外有大量高频词太简单了,如 the/a 等。
数据清理
考虑用 < filename | tr -s ' ' > newfile
做空格压缩,但压缩后,行首还是有空格,于是可以考虑 tr
的加强版 sed
直接删除行首多个空格,同时在首行插入列名。
sed -i 's/^ *//g' MathLinearBookFreq.csv # 第一个`/`后面是需替换内容,第二个`/`为空,表示删除,`-i` 表示替换原文件
sed -i 's/ /,/g' MathLinearBookFreq.csv # 后面的空格替换成`,`
sed -i '1i/Frequency,Word' head.csv # 插入列名
剔除熟悉词汇
那么如何去除一些太简单的高频词呢?这个时候就需要 R 语言或 Python 来做匹配了,结合 COCA 的 5000 词频表,链接: https://pan.baidu.com/s/1migyoYG 密码: vv5x。
先创建一个 WordFreq
目录存放需处理的文件,把所需文件移动到这个目录。
➜ ~ ls WordFreq
COCA_top5000.csv MathLinearBookFreq.csv
Gilbert_Strang_Introduction_to_Linear_Algebra__2009.pdf
底下是 R 代码
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(readr)
导入词汇表。
df <- read_csv('~/WordFreq/COCA_top5000.csv')
df1 <- select(df, Word) # 选择 word 这一列
df2 <- read_csv('~/WordFreq/MathLinearBookFreq.csv')
df2
#> # A tibble: 2,086 x 2
#> Frequency Word
#> <int> <chr>
#> 1 10066 the
#> 2 9994 a
#> 3 5411 be
#> 4 4030 and
#> 5 2817 to
#> 6 2370 in
#> 7 2173 matrix
#> 8 1801 are
#> 9 1497 by
#> 10 1451 row
#> # ... with 2,076 more rows
采用 dplyr 里的anti_join 函数把 df2 里面不匹配 df1 前 1000 的单词挑出来,大白话就是把你不怎么认识的词挑出来
df3 <- anti_join(df2, df1[0:1000,], by = 'Word') %>%
arrange(desc(Frequency))
df3
#> # A tibble: 1,438 x 2
#> Frequency Word
#> <int> <chr>
#> 1 2173 matrix
#> 2 1801 are
#> 3 1451 row
#> 4 1207 column
#> 5 1128 vector
#> 6 659 solution
#> 7 589 equation
#> 8 577 zero
#> 9 547 ion
#> 10 485 pivot
#> # ... with 1,428 more rows
summary(df3)
#> Frequency Word
#> Min. : 1.00 Length:1438
#> 1st Qu.: 1.00 Class :character
#> Median : 3.00 Mode :character
#> Mean : 21.47
#> 3rd Qu.: 9.00
#> Max. :2173.00
但还有个问题,数学书里面有太多两位数的符号,属于无效单词,也可删除
df4 <- filter(df3, nchar(Word) > 2)
summary(df4)
#> Frequency Word
#> Min. : 1.00 Length:1399
#> 1st Qu.: 1.00 Class :character
#> Median : 3.00 Mode :character
#> Mean : 20.58
#> 3rd Qu.: 8.00
#> Max. :2173.00
df4
#> # A tibble: 1,399 x 2
#> Frequency Word
#> <int> <chr>
#> 1 2173 matrix
#> 2 1801 are
#> 3 1451 row
#> 4 1207 column
#> 5 1128 vector
#> 6 659 solution
#> 7 589 equation
#> 8 577 zero
#> 9 547 ion
#> 10 485 pivot
#> # ... with 1,389 more rows
大功告成,写入文件,即可
write_csv(df4, '~/WordFreq/LA_MIT_freq.csv')
写了一个 Python 版的,分析了下 Python 机器学习 这本书。