【问题标题】:How can I increase the accuracy of my Linear Regression model?(machine learning with python)如何提高线性回归模型的准确性?(使用 python 进行机器学习)
【发布时间】:2018-05-14 14:26:05
【问题描述】:

我有一个使用 scikit-learn 库的 Python 机器学习项目。我有两个单独的数据集用于训练和测试,我尝试进行线性回归。我使用如下所示的代码块:

import numpy as np
import pandas as pd
import scipy
import matplotlib.pyplot as plt
from pylab import rcParams
import urllib
import sklearn
from sklearn.linear_model import LinearRegression
df =pd.read_csv("TrainingData.csv")
df2=pd.read_csv("TestingData.csv")

df['Development_platform']= ["".join("%03d" % ord(c) for c in s) for s in df['Development_platform']]
df['Language_Type']= ["".join("%03d" % ord(c) for c in s) for s in df['Language_Type']]


df2['Development_platform']= ["".join("%03d" % ord(c) for c in s) for s in df2['Development_platform']]
df2['Language_Type']= ["".join("%03d" % ord(c) for c in s) for s in df2['Language_Type']]

X_train = df[['AFP','Development_platform','Language_Type','Resource_Level']]
Y_train = df['Effort']

X_test=df2[['AFP','Development_platform','Language_Type','Resource_Level']]
Y_test=df2['Effort']
lr = LinearRegression().fit(X_train, Y_train)
print("lr.coef_: {}".format(lr.coef_))
print("lr.intercept_: {}".format(lr.intercept_))
print("Training set score: {:.2f}".format(lr.score(X_train, Y_train)))
print("Test set score: {:.7f}".format(lr.score(X_test, Y_test)))

我的结果是: lr.coef_: [ 2.32088001e+00 2.07441948e-12 -4.73338567e-05 6.79658129e+02]
lr.intercept_:2166.186033098048
训练集得分:0.63
测试集得分:0.5732999

你有什么建议?我怎样才能提高我的准确性? (添加代码、参数等) 我的数据集在这里:https://yadi.sk/d/JJmhzfj-3QCV4V

【问题讨论】:

  • 使用正则化。除此之外:它太宽泛了,而且总是依赖于没有给出的数据!
  • 如果您提供 csv 文件,人们可以进行具体改进。
  • 我添加了数据集

标签: python machine-learning scikit-learn


【解决方案1】:

我将通过一些示例详细说明@GeorgiKaradjov 的答案。您的问题非常广泛,并且有多种方法可以获得改进。最后,拥有领域知识(上下文)将为您提供获得改进的最佳机会。

  1. 规范化您的数据,即将它的平均值为零,散布为 1 个标准差
  2. 通过例如 OneHotEncoding 将分类数据转换为变量
  3. 做特征工程:
    • 我的特征是否共线?
    • 我的任何特征是否有交叉词/高阶词?
  4. 对特征进行正则化以减少可能的过拟合
  5. 根据项目的基本特征和目标查看替代模型

1) 标准化数据

from sklearn.preprocessing import StandardScaler
std = StandardScaler()
afp = np.append(X_train['AFP'].values, X_test['AFP'].values)
std.fit(afp)

X_train[['AFP']] = std.transform(X_train['AFP'])
X_test[['AFP']] = std.transform(X_test['AFP'])

给予

0    0.752395
1    0.008489
2   -0.381637
3   -0.020588
4    0.171446
Name: AFP, dtype: float64

2) 分类特征编码

def feature_engineering(df):

    dev_plat = pd.get_dummies(df['Development_platform'], prefix='dev_plat')
    df[dev_plat.columns] = dev_plat
    df = df.drop('Development_platform', axis=1)

    lang_type = pd.get_dummies(df['Language_Type'], prefix='lang_type')
    df[lang_type.columns] = lang_type
    df = df.drop('Language_Type', axis=1)

    resource_level = pd.get_dummies(df['Resource_Level'], prefix='resource_level')
    df[resource_level.columns] = resource_level
    df = df.drop('Resource_Level', axis=1)

    return df

X_train = feature_engineering(X_train)
X_train.head(5)

给予

AFP dev_plat_077070 dev_plat_077082 dev_plat_077117108116105    dev_plat_080067 lang_type_051071076 lang_type_052071076 lang_type_065112071 resource_level_1    resource_level_2    resource_level_4
0   0.752395    1   0   0   0   1   0   0   1   0   0
1   0.008489    0   0   1   0   0   1   0   1   0   0
2   -0.381637   0   0   1   0   0   1   0   1   0   0
3   -0.020588   0   0   1   0   1   0   0   1   0   0

3) 特征工程;共线性

import seaborn as sns
corr = X_train.corr()
sns.heatmap(corr, mask=np.zeros_like(corr, dtype=np.bool), cmap=sns.diverging_palette(220, 10, as_cmap=True), square=True)

您想要y=x 的红线,因为值应该与它们自身相关。但是,任何红色或蓝色列都表明存在强相关/反相关,需要进行更多调查。例如,Resource=1、Resource=4,在某种意义上可能是高度相关的,如果人们有 1,那么有 4 的机会就会更小,等等。回归假设使用的参数相互独立。

3) 特征工程;高阶项

也许你的模型太简单了,你可以考虑添加高阶和交叉项:

from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(2, interaction_only=True)
output_nparray = poly.fit_transform(df)
target_feature_names = ['x'.join(['{}^{}'.format(pair[0],pair[1]) for pair in tuple if pair[1]!=0]) for tuple in [zip(df.columns, p) for p in poly.powers_]]
output_df = pd.DataFrame(output_nparray, columns=target_feature_names)

我对此进行了快速尝试,我认为高阶项没有多大帮助。您的数据也有可能是非线性、快速的logarithm 或 Y 输出的拟合效果更差,表明它是线性的。你也可以看看实际的,但我太懒了......

4) 正则化

尝试使用 sklearn 的 RidgeRegressor 并使用 alpha:

lr = RidgeCV(alphas=np.arange(70,100,0.1), fit_intercept=True)

5) 替代模型

有时线性回归并不总是合适的。例如,随机森林回归器的性能非常好,并且通常对标准化数据和分类/连续数据不敏感。其他模型包括 XGBoost 和 Lasso(L1 正则化线性回归)。

lr = RandomForestRegressor(n_estimators=100)

把它们放在一起

我得意忘形并开始查看您的问题,但在不了解所有功能上下文的情况下无法对其进行太多改进:

import numpy as np
import pandas as pd
import scipy
import matplotlib.pyplot as plt
from pylab import rcParams
import urllib
import sklearn
from sklearn.linear_model import RidgeCV, LinearRegression, Lasso
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.model_selection import GridSearchCV

def feature_engineering(df):

    dev_plat = pd.get_dummies(df['Development_platform'], prefix='dev_plat')
    df[dev_plat.columns] = dev_plat
    df = df.drop('Development_platform', axis=1)

    lang_type = pd.get_dummies(df['Language_Type'], prefix='lang_type')
    df[lang_type.columns] = lang_type
    df = df.drop('Language_Type', axis=1)

    resource_level = pd.get_dummies(df['Resource_Level'], prefix='resource_level')
    df[resource_level.columns] = resource_level
    df = df.drop('Resource_Level', axis=1)

    return df

df = pd.read_csv("TrainingData.csv")
df2 = pd.read_csv("TestingData.csv")

df['Development_platform']= ["".join("%03d" % ord(c) for c in s) for s in df['Development_platform']]
df['Language_Type']= ["".join("%03d" % ord(c) for c in s) for s in df['Language_Type']]

df2['Development_platform']= ["".join("%03d" % ord(c) for c in s) for s in df2['Development_platform']]
df2['Language_Type']= ["".join("%03d" % ord(c) for c in s) for s in df2['Language_Type']]

X_train = df[['AFP','Development_platform','Language_Type','Resource_Level']]
Y_train = df['Effort']

X_test = df2[['AFP','Development_platform','Language_Type','Resource_Level']]
Y_test = df2['Effort']

std = StandardScaler()
afp = np.append(X_train['AFP'].values, X_test['AFP'].values)
std.fit(afp)

X_train[['AFP']] = std.transform(X_train['AFP'])
X_test[['AFP']] = std.transform(X_test['AFP'])

X_train = feature_engineering(X_train)
X_test = feature_engineering(X_test)

lr = RandomForestRegressor(n_estimators=50)
lr.fit(X_train, Y_train)

print("Training set score: {:.2f}".format(lr.score(X_train, Y_train)))
print("Test set score: {:.2f}".format(lr.score(X_test, Y_test)))

fig = plt.figure()
ax = fig.add_subplot(111)

ax.errorbar(Y_test, y_pred, fmt='o')
ax.errorbar([1, Y_test.max()], [1, Y_test.max()])

导致:

Training set score: 0.90
Test set score: 0.61

可以看变量的重要性(值越高,越重要)。

Importance
AFP                         0.882295
dev_plat_077070             0.020817
dev_plat_077082             0.001162
dev_plat_077117108116105    0.016334
dev_plat_080067             0.004077
lang_type_051071076         0.012458
lang_type_052071076         0.021195
lang_type_065112071         0.001118
resource_level_1            0.012644
resource_level_2            0.006673
resource_level_4            0.021227

您也可以开始查看超参数以对此进行改进:http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV

【讨论】:

  • 你能帮我解决这个问题吗? stackoverflow.com/questions/47800688/…
  • 一个关于缩放的问题afp = np.append(X_train['AFP'].values, X_test['AFP'].values) 缩放器可以看到训练和测试数据。它不应该只在 X_train 上吗?
【解决方案2】:

这里有一些提示:

数据准备(探索)是机器学习项目中最重要的步骤之一,您需要从它开始。

您是否清理过数据?如果不从那一步开始!

正如this tutorial 所说:

数据探索没有捷径可走。如果您处于以下状态 请注意,机器学习可以让你远离每一次数据风暴, 相信我,不会的。过了一段时间,你会意识到你 正在努力提高模型的准确性。在这种情况下,数据 探索技术将助您一臂之力。

这是数据探索的一些步骤:

  • 缺失值处理,

  • 异常值去除

  • 特征工程

  • 然后尝试使用您的特征执行单变量和双变量分析。

  • 使用one hot 编码将分类特征转换为数字特征。

这就是你所需要的,根据我们在 cmets 中讨论的内容。

here 是关于如何处理分类变量的教程,来自 sklearn learn 的 one-hot encoding 是解决您问题的最佳技术。

使用 ASCII 表示不是处理分类特征的最佳实践

您可以在here 中找到有关数据探索的更多信息 遵循我给你的建议,稍后感谢我。

【讨论】:

  • 我删除了缺失值并将非数字值转换为数字值,除了这些值我还能做什么?
  • 我删除了包含空值的行
  • 并将非数字值转换为数字值?
  • 是的,我取了它们的 ASCII 值,而且我在两种方式上都给了它们数值结果是相同的
  • 这是您的第一个问题,正如我的回答中所建议的那样,尝试执行一次热编码
【解决方案3】:
  1. 规范化您的数据
  2. 根据输入特征的类型,您可以从中提取不同的特征(也可以进行特征组合)
  3. 如果您的数据不是线性可分的,您将无法很好地预测它。您可能需要使用其他模型 - Logistic 回归、SVR、NN / 任何其他模型

【讨论】:

  • 线性可分是什么意思?我们不是在谈论回归吗?
猜你喜欢
  • 2021-04-09
  • 2019-04-17
  • 1970-01-01
  • 2019-08-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多