【问题标题】:Need help understanding Python linear regression model code issue (sklearn)需要帮助理解 Python 线性回归模型代码问题(sklearn)
【发布时间】:2020-12-25 05:36:38
【问题描述】:

我正在使用 Tech with Tim 视频 (https://www.youtube.com/watch?v=45ryDIPHdGg) 编写我的第一个线性回归代码,但遇到了障碍。我正在使用来自这里的 UCI 学生数据:https://archive.ics.uci.edu/ml/datasets/Student+Performance

我的初始模型代码运行良好。然后我迭代找到了一个最佳精度模型,这很好。它开始偏离轨道的地方是我试图将这些最优系数注入一个新模型,然后运行两个预测:

  1. 第一个模型(预优化循环)

  2. 优化后的模型

针对相同的 x_test1 数据集。为了比较两者,我简单地将预测和实际 y 值之间的平方差相加。然后我还记录了两个模型的最终准确率。

我做错了,因为我的新“优化”模型的准确度与第一个模型相同或更低,并且差异值也非常相似。我希望优化后的模型具有更少的错误和更高的准确度。

有人可以帮我看看错误吗?我怀疑错误出现在代码的情节部分之后。提前致谢,代码如下。

# Import libraries
import pandas as pd
import numpy as np
import sklearn
import pickle
import matplotlib.pyplot as plt
from sklearn import linear_model
from math import sqrt
from sklearn.linear_model import LinearRegression
from matplotlib import style

# from sklearn.utils import shuffle

# Read in Data
data = pd.read_csv("student-mat.csv", sep=";")

# Slice data to include only desired headings
data = data[["G1", "G2", "G3", "studytime", "failures", "absences"]]

# Define the attribute we are trying to predict; called "label".
# Others are "features" and used to predict label
predict = "G3"

# Create array of features and label
X = np.array(data.drop([predict], 1))
y = np.array(data[predict])

# Split data into training and testing data.  90% used for training, 10% testing
# Test size 0.1 = 10% of array size
x_train1, x_test1, y_train1, y_test1 = sklearn.model_selection.train_test_split(X, y, test_size=0.1)

# Create 1st linear model and fit
linear = linear_model.LinearRegression()
linear.fit(x_train1, y_train1)

# Compute accuracy of model
acc = linear.score(x_test1, y_test1)

# Iterate for a given number of times (max_iter) to find an optimal accuracy value and record best coefficients
loop_num = 1
max_iter = 1000
best_acc = acc
best_coef = linear.coef_
best_int = linear.intercept_
acc_counter = [acc]

print("\nInitial Accuracy: %4.3f" % acc)

while loop_num < max_iter + 1:
    x_train, x_test, y_train, y_test = sklearn.model_selection.train_test_split(X, y, test_size=0.1)
    linear2 = linear_model.LinearRegression()
    linear2.fit(x_train, y_train)
    acc = linear2.score(x_test, y_test)
    acc_counter.append(acc)
    print("\nAccuracy of run " + str(loop_num) + " is: %4.3f" % acc)
    if acc > best_acc:
        print("\n\tBetter accuracy found.")
        best_acc = acc
        best_coef = linear2.coef_
        best_int = linear2.intercept_
        print("Co: \n", linear2.coef_)
        print("Intercept: \n", linear2.intercept_)
    else:
        print("\n\tFit Discarded.")
    loop_num += 1

print("\nBest Acccuracy: \n%4.3f" % best_acc)
print("\nBest Coefficients: \n", best_coef)
print("\nBest Intercept: \n", best_int)

# Plot Accuracy over time
x_scale = []
for x in range(max_iter + 1):
    x_scale.append(x)

plt.plot(x_scale, acc_counter, color='green', linestyle='dashed', linewidth=3, marker='o',
         markerfacecolor='blue', markersize=5)

ymax = max(acc_counter)
ymin = min(acc_counter)
xpos = acc_counter.index(ymax)
xmax = x_scale[xpos]
annot_max_acc = str(ymax)
plt.annotate('Max Accuracy = ' + annot_max_acc[0:4], xy=(xmax, ymax), xycoords='data', xytext=(.8, .95),
             textcoords='axes fraction',
             arrowprops=dict(facecolor='black', shrink=0.05), horizontalalignment='right', verticalalignment='top')
plt.ylim(ymin, 1.0)
plt.xlabel('Run Number')
plt.ylabel('Accuracy')
plt.title('Prediction Accuracy over Time')
plt.show()

# Create model with best coefficients from above
new_model = linear_model.LinearRegression()
new_model.intercept_ = best_int
new_model.coef_ = best_coef

# Predict y values for 1st model (not best) then compute difference between predictions and actual values
print("\n\n\nBREAK")
comp = []
predictions = linear.predict(x_test1)
for x in range(len(predictions)):
    print(predictions[x], x_test1[x], y_test1[x])
    diff = sqrt((predictions[x] - y_test1[x])**2)
    print("\tDifference is ", diff)
    comp.append(diff)
print("\n\n\nBREAK")
print(comp)
print("\nSum of errors is ", sum(comp))

# Predict y values of best model (with optimal coefficients from above) using same x_test1 values as 1st model
# then compute difference between predictions and actual values
print("\n\n\nBREAK")
comp2 = []
predictions_new_model = new_model.predict(x_test1)
for x in range(len(predictions_new_model)):
    print(predictions_new_model[x], x_test1[x], y_test1[x])
    diff2 = sqrt((predictions_new_model[x] - y_test1[x])**2)
    print("\tDifference is ", diff2)
    comp2.append(diff2)

print("\n\n\nBREAK")
print(comp2)
print("\nSum of errors is ", sum(comp2))

print("\n\n\nFirst model fit difference: ", sum(comp))
print("\nSecond model fit difference ", sum(comp2))

print('\n1st model score: ',linear.score(x_train1, y_train1))

print('\nBest model score: ',new_model.score(x_train1, y_train1))

【问题讨论】:

    标签: python machine-learning scikit-learn


    【解决方案1】:

    查看您的代码,我刚刚意识到您使用的是相同的模型 (LinearRegression),并且在任何运行中都没有更改任何超参数,因此实际上没有任何改进,不同之处在于您已经拆分了数据两次(并且你没有给它任何随机种子)所以细微的差别就来自于此。要改进模型,您必须更改估计器的超参数。在此处查看更多信息:hyperparameter tuning

    【讨论】:

    • 精彩的回答和解释,非常感谢您花时间帮助我!我要看看你的另一篇文章,我会按照你的建议修复我的代码。你指出的逻辑谬误对我来说也很有意义。再次感谢!
    • 另一个问题 - 我理解您关于使用相同指标的观点。但我确实打印出来并将第一次运行与“最佳”运行 R^2 分数进行比较,它们通常非常相似。如果我做的所有事情都正确,它们不应该有所不同吗,因为那将是相同的指标?
    • 您能否改为使用均方误差进行优化和评估并发布结果?
    • 我按照您的要求对 MSE 进行了优化,但保留 R^2 值仅供参考。这就是我得到的:1st model score: 0.8590411253845174 1st model MSE: 2.942428408301564 Best model score: 0.8591956695723348 Best model MSE: 2.9392023949709936
    • 比较部分代码,末尾:new_model = linear_model.LinearRegression() new_model.intercept_ = best_int new_model.coef_ = best_coef predictions_new_model = new_model.predict(x_test1) print('\n1st model score: ', comp_acc) print('\n1st model MSE: ', comp_error) # Print out R^2 accuracy and MSE using optimized model on same dataset as first run, for fair comparison new_model_error = mean_squared_error(y_test1, predictions_new_model) print('\nBest model score: ',new_model.score(x_test1, y_test1)) print('\nBest model MSE: ', new_model_error)
    猜你喜欢
    • 2019-03-07
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多