让我们从头开始编写机器学习中的简单线性回归算法
线性回归是机器学习的基础。几乎每一种主要的机器学习算法都使用它,因此理解它将帮助您为大多数主要的机器学习算法打下基础。对于我们这些狂热的人来说,理解线性回归和一般的线性代数是写你自己的自定义机器学习算法和扩展到机器学习的边缘的第一步。随着处理的改进和硬件体系结构的变化,用于机器学习的方法也发生了变化。最近神经网络的兴起与通用图形处理单元有很大关系。想知道人工神经网络的核心是什么吗?你猜对了:线性回归。
让我们开始编码,我们都知道,首先要做的是导入
from statistics import mean
import numpy as np
import pandas as pd
顺便说一下,statistics是一个预构建的python包。现在,我们可能还记得,计算斜率的公式是
现在,让我们使用数据集,
data = pd.read_csv('Salary_data.csv')
data.head()
现在让我们检查数据的头部(这意味着检查数据集的前5行)。它看起来像这样
现在,让我们对函数进行编程,找出最佳拟合线
def best_fit_slope(x,y):
m = (((mean(x)*mean(y)) - mean(x*y)) /
((mean(x)**2) - mean(x*x)))
return m
m = best_fit_slope(data['YearsExperience'], data['Salary'])
print(m)
## result -> 9449.96
现在,我们可以看到,在python中,我们已经写出了求最佳拟合直线斜率的完全相同的公式。简单线性回归仅仅是y = mx + c,我们知道x和y,但是我们需要算出m和c(斜率和常数)。运行上面的函数,我们会发现,结果是9449.96,也就是直线的斜率。现在,我们需要算出常数c,这并不难,如果y = mx + c,那么c = y - mx,很简单。但要记住的是,我们不使用一个点的数据,而是用一个完整的数据集,而不是x和y,我们会用x和y的均值,所以,我们也要把它编码出来。
def best_fit_slope_and_intercept(x ,y):
m = (((mean(x)*mean(y)) - mean(x*y)) /
((mean(x)*mean(x)) - mean(x*x)))
c = mean(y) - m*mean(x)
return m, c
m, c = best_fit_slope_and_intercept(data['YearsExperience'], data['Salary'])
print(m,c)
# result -> 9449.96232146 25792.2001987
其中m为9449.96232146,c为25792.2001987。在这之前,我们先画出数据,看看我们是怎么做的。
import matplotlib.pyplot as plt
from matplotlib import style
style.use('ggplot')
plt.scatter(data['YearsExperience'], data['Salary'])
plt.title('Salary vs Experience')
plt.show()
这里,style用于使用matplotlib的内置样式之一。因此,我们看到数据可视化,我们的数据看起来像这样。
所以,既然我们已经找到了答案,那么m和c现在可以让它们发挥作用并且绘制我们的回归线。
regression_line = [(m*x)+c for x in data['YearsExperience']]
所以,我们运行一个循环,对于x中的所有值,然后找出y并进行回归。让我们来画这个,看看我们怎么样。
## ...Continuing
plt.scatter(data['YearsExperience'], data['Salary'],color='blue')
plt.plot(data['YearsExperience'], regression_line, label='regression_line')
plt.title('Salary vs Experience')
plt.legend()
plt.show()
而且,这就是我们的数据看起来像,
在这里,我们可以看到,这条线对数据有多完美。现在来谈谈预测价值的线性回归的核心。
predict_x = data['Salary']
predict_y = [((m*x) + c) for x in predict_x]
print(predict_x, predict_y)
数据很像这样 -
你可以看到,我们的预测值非常接近实际值。这就是我们编码的线性回归模型。现在,唯一需要做的是,我们需要弄清楚,这是最合适的线,还是其他线可能是最合适的线。所以,要做到这一点,我们需要使用最小二乘法,我们现在就这样做。
R-square method
我们最近刚刚创建了一个可用的线性回归模型,现在我们想知道下一个是什么。现在,我们可以轻松地查看数据,并在一定程度上确定回归线的“准确性”。然而,当你的线性回归模型应用于神经网络中的20个hierarchical layers 时,会发生什么呢?不仅如此,您的模型还可以在每次100个数据点的步骤或窗口中工作,在一个包含500万个数据池的数据集中。你需要一种自动的方式来发现你的最佳拟合线到底有多好。
现在,我们刚建立的模型对这样的数据是有好处的
但对于像这样的数据没有多大意义 -
我们来编写r-squared程序
def squared_error(y_orig, y_line):
return sum((y_line - y_orig) * (y_line - y_orig))
这个函数,只返回数据点的平方误差。我们可以用这种语法来表示回归线和y的均值。也就是说,平方误差只是决定系数的一部分,我们来建立这个函数。因为平方误差函数只有一条直线,你可以选择它只是确定函数的系数中的一条直线,但是平方误差是你可以在这个函数之外使用的,所以我会选择把它作为它自己的函数。For r squared:
def coefficient_of_determination(y_orig, y_line):
y_mean_line = [mean(y_orig) for y in y_orig]
squared_error_regr = squared_error(y_orig, y_line)
squared_error_y_mean = squared_error(y_orig, y_mean_line)
return 1 - (squared_error_regr/squared_error_y_mean)
我们在这里所做的就是计算y的均值线,然后计算y均值和回归线的平方误差用上面的公式。现在,我们要做的就是计算r的平方值,也就是1减去回归直线的平方误差除以y平均线的平方误差。我们返回值,就完成了!这就是我们的代码现在的样子。
from statistics import mean
import numpy as np
import pandas as pd
data = pd.read_csv('Salary_data.csv')
def best_fit_slope_and_intercept(x ,y):
m = (((mean(x)*mean(y)) - mean(x*y)) /
((mean(x)*mean(x)) - mean(x*x)))
c = mean(y) - m*mean(x)
return m, c
def squared_error(y_orig, y_line):
return sum((y_line - y_orig) * (y_line - y_orig))
def coefficient_of_determination(y_orig, y_line):
y_mean_line = [mean(y_orig) for y in y_orig]
squared_error_regr = squared_error(y_orig, y_line)
squared_error_y_mean = squared_error(y_orig, y_mean_line)
return 1 - (squared_error_regr/squared_error_y_mean)
m, c = best_fit_slope_and_intercept(data['YearsExperience'], data['Salary'])
regression_line = [(m*x)+c for x in data['YearsExperience']]
predict_x = data['Salary']
predict_y = [((m*x) + c) for x in predict_x]
r_squared = coefficient_of_determination(data['Salary'] ,regression_line)
print(r_squared)
## result -> 0.9569
## For Visualization
# import matplotlib.pyplot as plt
# from matplotlib import style
# style.use('ggplot')
# plt.scatter(data['YearsExperience'], data['Salary'],color='blue')
# plt.plot(data['YearsExperience'], regression_line, label='regression_line')
# plt.title('Salary vs Experience')
# plt.legend()
# plt.show()
这是一个很低的值,实际上根据这个测量,我们的最佳拟合线并不是很好。在这种情况下r的平方是一个很好的度量吗?这可能取决于你的目标是什么。在大多数情况下,如果你关心预测准确的未来值,r的平方确实非常有用。如果你对运动/方向感兴趣,那么到目前为止,我们的最佳拟合线是相当不错的,而且r的平方不应该有那么大的权重。看看我们实际的数据集。我们坚持用低的整数。从值到值的方差在某些点是20-50%这是一个很大的方差。使用这个简单的数据集,我们的最佳拟合线仍然不是对实际数据的描述,这并不奇怪。
然而,我们刚才描述的是一个假设。你知道他们怎么说“假定”!我希望我们都能在逻辑上同意这个假设,但我们需要找到一种方法来检验这个假设。到目前为止所涉及的算法都是非常基本的,我们这里只有几个层,所以没有太多的错误空间,但是,以后,很可能会有一层一层的。不仅要考虑算法本身的层次化层,而且算法还会受到很多算法层的影响。在可能的情况下,我们需要对这些算法进行测试,以确保我们对这些算法应该如何操作的假设是正确的