我尝试在python中执行线性回归模型的示例。目的是在我的数据集中找到两个特征之间的线性关系,这些特征是“年”和“肥胖度(%)”。我想训练我的模型来预测世界肥胖的未来趋势。问题是我的MSE太高而R2太低。如何改善我的模型?
这是我在其中找到数据集的link;肥胖清理.csv
CODE
#Analysis of obesity by country
import pandas as pd
import seaborn as sb
import matplotlib.pyplot as plt
import numpy as np
import sklearn
from sklearn import metrics
from sklearn.linear_model import LinearRegression
from sklearn import preprocessing
address = 'C:/Users/Andre/Desktop/Python/firstMN/obesity-cleaned.csv'
dt = pd.read_csv(address)
#eliminate superfluos data
dt.drop(dt['Obesity (%)'][dt['Obesity (%)'].values == 'No data'].index, inplace=True)
for i in range(len(dt)):
dt['Obesity (%)'].values[i] = float(dt['Obesity (%)'].values[i].split()[0])
obMean = dt['Obesity (%)'].mean()
print('%0.3f' %obMean, '\n')
dt['Obesity (%)'] = dt['Obesity (%)'].astype(float) #converto il tipo in float
group = dt.groupby('Country')
print(group[['Year', 'Obesity (%)']].mean(), '\n')
dt1 = dt[dt['Sex'] == 'Both sexes']
print(dt1[dt1['Obesity (%)'] == dt1['Obesity (%)'].max()], '\n')
sb.lmplot('Year', 'Obesity (%)', dt1)
plt.show()
#linear regression predictions
group1 = dt1.groupby('Year')
x = np.array(np.linspace(1975, 2016, 2016-1975+1)).tolist()
y = np.array([group1['Obesity (%)'].mean()]).tolist()[0]
x1 = np.array([1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 , 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 ]).reshape((-1, 1))
y1 = np.array([group1['Obesity (%)'].mean()]).reshape(-1, 1)
lr = LinearRegression(fit_intercept=False)
lr.fit(x1, y1)
plt.plot(x, y)
plt.show()
print('Coefficients: ', lr.coef_)
print("Intercept: ", lr.intercept_ )
y_hat = lr.predict(x1)
print('MSE: ', sklearn.metrics.mean_squared_error(y_hat, y1))
print('R^2: ', lr.score(x1, y1) )
print('var: ', y1.var())
输出
Coefficients: [[0.00626604]]
Intercept: 0.0
MSE: 15.09451970012738
R^2: 0.03779706109503678
var: 15.687459567838905
Correlation among years and obesity (%) is: (0.9960492544111168, 1.0885274634054143e-43)
强制fit_intercept=False
是模型的huge约束,在确定要执行此操作之前,应确保确切了解自己在做什么。
在简单线性回归中不进行截距拟合实际上意味着,当我们的单个特征X为0时,响应Y也应为0;在这里,它表示在“ 0年”(可能意味着什么)中,肥胖也应为0。鉴于此,报告的不良结果并不令人惊讶(ML不是魔术,并且肯定暗示我们这样做了)在我们的模型中包括现实的假设)。
这里尚不清楚您为什么决定这样做,但我高度怀疑这是您打算要做的。您应该从模型中删除此不必要的约束。
删除代码中的fit_intercept=False
。如果真实模型截距确实为零,则截距项将近似为零,从而无需将fit_intercept
设置为False
。据我所知,您实际上是在没有任何理由的情况下约束模型(如果我错了,请纠正我)。
从scikit-learn documentation on the linear regression:
是否计算此模型的截距。如果设置为False,则在计算中将不使用截距(即期望数据居中)。
我没有看到您将数据居中的任何地方。因此,您的结果是有缺陷的。要解决这种情况,只需删除fit_intercept=False
,因为默认情况下它是True
。希望对您有所帮助。