用TensorFlow机器学习框架构建学校学科成绩的线性模型

TensorFlow机器学习框架

TensorFlow是Google开源的一个机器学习框架,它可以在Python环境下运行,我昨天认识和接触它。

模型构建方法&事情经过

昨天我用Excel尝试绘制了我们学校高二年级的各个学科——物理散点图,然后用Excel绘制了三次方回归曲线,我发现不论是哪个学科与物理,拟合优度 R2R^2 都很低,这代表它们之间的的关系并不明显,几乎是随机的。

因此我就想,如果一个量映射到另一个量的关系不明显,那我几个量映射到一个量可能就会有比较强的关系了。但是想要找到这个关系,似乎非常困难,我尝试把各个学科与物理的三次方回归曲线以它的拟合优度 R2R^2 为权重线性混合起来,结果得到了一个不三不四的方程,处理极其困难,误差也很大。

刚好昨天认识了TensorFlow(后面简称TF),于是打算下载使用TF训练出我想要的模型,但是在安装TF的过程中遇到了很多坑,这里我就不细说了。

在使用TF前,我简单的看了几个别人写的Demo,然后我就开始构建学校学科成绩的线性模型,步骤基本分为下面几个。

1,构建模型

我将物理成绩构建成一个线性模型,满足下面这个式子: a×+b×+c×+d×+e×+s {\begin{aligned} 物理成绩 &\approx a \times 语文成绩 \\\\ &+ b \times 数学成绩 \\\\ &+ c \times 英语成绩 \\\\ &+ d \times 化学成绩 \\\\ &+ e \times 生物成绩 \\\\ &+ s \end{aligned}} 我们只需要使用TF,把上式的各个系数优化到最贴近真实,使得我把一个真实的成绩代入上式后能得到一个较为精确的值。

2,找数据,然后把数据转换成csv格式

我找到了我们高二年级这次期末统考成绩的表格,用Excel打开它,然后提取所需要的数据,另存为csv格式。

3,用Python写一个读取csv的程序

要注意csv文件的编码!其它我就不细说了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import csv

csv_file = csv.reader(open('cj.csv', encoding='utf-8'))

x_data = []
y_data = []

for data in csv_file:
x_s = data[3]
y_s = data[5]
if not len(x_s) * len(y_s) == 0:
x_data.append(float(x_s))
y_data.append(float(y_s))

print(x_data)

4,用Python写TS的模型训练程序

运行下面的这个程序,训练一千万次来优化系数。具体不细说了,下面是这个工程的全部源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import tensorflow as tf
import numpy as np
import csv

csv_file = csv.reader(open('cj.csv', encoding='utf-8'))

a_data = []
b_data = []
c_data = []
d_data = []
e_data = []
y_data = []

for data in csv_file:
a_s = data[0]
b_s = data[1]
c_s = data[2]
d_s = data[3]
e_s = data[4]
y_s = data[5]
if not len(a_s)*len(b_s)*len(c_s)*len(d_s)*len(e_s)*len(y_s) == 0:
a_data.append(float(a_s))
b_data.append(float(b_s))
c_data.append(float(c_s))
d_data.append(float(d_s))
e_data.append(float(e_s))
y_data.append(float(y_s))


# 构造一个线性模型

a = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
c = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
d = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
e = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
s = tf.Variable(tf.random_uniform([1], -1.0, 1.0))

y = a*a_data + b*b_data + c*c_data + d*d_data + e*e_data + s


# 最小化方差

loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.00001)
train = optimizer.minimize(loss)


# 初始化变量

init = tf.global_variables_initializer()


# 启动图 (graph)

sess = tf.Session()
sess.run(init)


# 拟合

for step in range(10000001):
sess.run(train)
if step % 1000000 == 0:
print(step, sess.run(a), sess.run(b), sess.run(c), sess.run(d), sess.run(e), sess.run(s))

while True :
a1 = float(input("语文成绩:"))
b1 = float(input("数学成绩:"))
c1 = float(input("英语成绩:"))
d1 = float(input("化学成绩:"))
e1 = float(input("生物成绩:"))
v = sess.run(a)*a1 + sess.run(b)*b1 + sess.run(c)*c1 + sess.run(d)*d1 + sess.run(e)*e1 + sess.run(s)
print("你的物理成绩大概是:", v[0])

成果

0.04158394×+0.37960723×+0.18630792×+0.48215818×+0.28883076×26.1632100 {\begin{aligned} 物理成绩 \approx &-0.04158394 \times 语文成绩 \\\\ &+ 0.37960723 \times 数学成绩 \\\\ &+ 0.18630792 \times 英语成绩 \\\\ &+ 0.48215818 \times 化学成绩 \\\\ &+ 0.28883076 \times 生物成绩 \\\\ &- 26.1632100 \end{aligned}}

猜想和总结

上面的一个模型,使用范围是有限的,因为我的数据仅仅只是我们学校高二年级在2019年的期末统考数据。精度也是有限的,因为我的数据只有1000多个,并且我使用的是线性模型,所以一般来说误差会在10以内,比较好的情况下误差不超过2。

如果把模型构建成二次方,三次方,甚至更多,那么所得到的模型就越贴近真实,但是训练次数也要更多,模型的表达式也会很复杂。

上面式子每个成绩前面的系数,就是这个学科成绩对物理成绩的影响大小,可以发现化学成绩前的系数最大,这代表着大部分化学成绩优秀的学生,物理成绩也不会太差。我们还可以发现语文成绩前面的系数竟然是负值!这说明,物理成绩较好的学生,语文往往拖他后退。

两张散点图

化学——物理

语文——物理

用TensorFlow机器学习框架构建学校学科成绩的线性模型

https://hk-shao.github.io/p/eedb.html

作者

烧风

发布于

2019-01-31

更新于

2021-07-12

许可协议

评论