我有一个 Books 数据集,我正尝试为此选择最合适的数据集。我尝试使用LinearRegression
,Decisiontree
和Polynomial
之一,但似乎没有一个适合曲线。我已经绘制了3条不同的曲线,其中一个曲线与y_target相对,这是曲线:
曲线_1 :评分数量与书籍评分
所以请告诉我,对于这种类型的曲线,最佳模型是什么?或者我应该通过其他方式进行分析? LinearRegression输出为:
MSE :0.11599130999215618
MAE :0.23
准确性:0.11599130999215622
R2得分:0.08296506346310017
我认为对数是好的,但可能会留下一些数据(数据接近每条曲线的值5)。我是ML的新手,请至少指导一下我。
这是数据集链接:https://www.kaggle.com/jealousleopard/goodreadsbooks
数据集快速查看:
代码如下:
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import PolynomialFeatures
from scipy import stats
df = pd.read_csv("books.csv")
def drop_numerical_outliers(df, z_thresh=3):
# Constrains will contain `True` or `False` depending on if it is a value below the threshold.
constrains = df.select_dtypes(include=[np.number]) \
.apply(lambda x: np.abs(stats.zscore(x)) < z_thresh, reduce=False) \
.all(axis=1)
# Drop (inplace) values set to be rejected
df.drop(df.index[~constrains], inplace=True)
df.drop(['bookID','Unnamed: 10','isbn13','isbn','title','authors'], axis=1, inplace=True)
print(df.columns.values)
print("Shape After dropping columns: ",df.shape)
df.replace(to_replace = 'None', value = '0', inplace=True)
df = df[df['# num_pages'] != '0']
print("Shape After Removing Rows with Num_pages 0: ",df.shape)
drop_numerical_outliers(df)
#print(df['# num_pages'].values[339])
print("Shape After Removing outliers: ",df.shape)
dummy_cols = ['language_code']
df = pd.get_dummies(df, columns=dummy_cols)
print("Shape After Categorizing dataset: ",df.shape)
#df[(np.abs(stats.zscore(df)) < 3).all(axis=1)]
x = df[df.columns.values]
x.drop(['average_rating'], axis=1, inplace=True)
y = df['average_rating']
x = x.apply(pd.to_numeric, errors='coerce')
y = y.apply(pd.to_numeric, errors='coerce')
x.fillna(0, inplace=True)
y.fillna(0, inplace=True)
#print(repr(df['# num_pages']))
#x = StandardScaler().fit_transform(x)
#print(df.head())
plt.scatter(x['# num_pages'],y, color = 'blue')
plt.xlabel("Number of Pages per Book")
plt.ylabel("Ratings")
plt.show()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=4)
regr = LinearRegression()
#regr = DecisionTreeRegressor(random_state=0 )
regr.fit(x_train, y_train)
y_hat = regr.predict(x_test)
print(y_hat)
print(y_test.values)
print("MSE: ", mean_squared_error(y_test, y_hat))
print("Mean absolute error: %.2f" %np.mean(np.absolute(y_hat - y_test)))
print("Accuarcy: ", np.mean((y_hat - y_test)**2))
print('R2 score: ', r2_score(y_test, y_hat))
答案 0 :(得分:2)
首先,在机器学习中,您确实必须牢记选择用于训练的功能。在您的示例中,“每本书的页数”并不能真正为您提供帮助,因为如果一本好书,读者就不会在意页数。 Curve_3进一步巩固了这一事实,因为该数据在3级和5级之间非常密集。因此,您实际上不需要此功能。
回到问题所在,您正在尝试预测一本书的评级。曲线1和2中的曲线表明,一条曲线将无法通过所有点(如果能够通过,则将是过度拟合的模型)。在这种情况下,线性回归将在(y轴上)接近4的值处创建一条直线,因为这是大多数样本所在的位置。
如果您使用不同阶数的多项式回归,它将为您提供该阶数的曲线,但仍然无法传递您想要的所有点,在这种情况下,甚至没有必要。
现在重要的是评估指标。您的MAE非常低,这表明您的模型可以做出良好的预测(低MAE良好结果,高MAE不良结果)。但是您的r2仅为0.082。 r2的范围在0到1之间,1是完美的预测(可能显示过度拟合),0表示非常差的模型,具有不好的预测。 0.082的值表明,在某些测试值中,预测值偏离了目标。因此,总结结果,您的模型可以为您提供高精度的预测,但有时会超出预期。
在这种情况下,我建议收集更多相关特征,然后如果需要更好的模型,则使用神经网络训练模型。
我现在已经分析了该数据集,在这里我要提到几件事。
首先,我在y_test和y_hat(仅用于线性回归的预测值)之间绘制了一个图形:
正如我之前解释的那样,线性回归将在值4附近创建一条直线,您可以看到所有预测都位于该直线附近。因此,对于真实评级为0或5的值,它将产生较高的预测误差。这就是为什么您的r2_score如此之低且如此之低的分数意味着您的特征对于该模型而言不够好。
如果您转到此笔记本: https://www.kaggle.com/bellali/select-which-book-to-enjoy 您会发现功能与您的目标(书评)之间没有相关性或相关性很低。此外,我还运行了不同的算法,但结果很差或非常相似,这进一步巩固了这些功能不能解释您的目标的事实。
这里要提到的另一件事是,该数据集仅用于探索目的,而不用于进行预测。您可以看到用于此数据的几个内核,它们正在进行不同类型的分析,这是该数据集的真正目的。
这是“模型与数据一样好”的典型示例。