我正在尝试使用各种技术(如SMR、逻辑回归等)创建一个ML模型(回归)。使用所有这些技术,我无法获得超过35%的效率。以下是我正在做的事情:
X_data = [X_data_distance]X_data = np.vstack(X_data).astype(np.float64)X_data = X_data.Ty_data = X_data_orders#print(X_data.shape)#print(y_data.shape)#(10000, 1)#(10000,)X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.33, random_state=42)svr_rbf = SVC(kernel= 'rbf', C= 1.0)svr_rbf.fit(X_train, y_train)plt.plot(X_data_distance, svr_rbf.predict(X_data), color= 'red', label= 'RBF model')
我尝试了各种参数调整,改变参数C、gamma,甚至尝试了不同的内核,但都没有改变准确性。甚至尝试了SVR、逻辑回归来代替SVC,但都没有帮助。我尝试了不同的训练输入数据缩放方法,如StandardScalar()
和scale()
。
我使用这个作为参考
我应该怎么做?
回答:
作为经验法则,我们通常遵循以下惯例:
- 对于少量特征,使用
Logistic Regression
。 - 对于大量特征但数据量不大,使用
SVM
。 - 对于大量特征和大量数据,使用
Neural Network
。
因为你的数据集有10000个案例,最好使用Logistic Regression
,因为SVM
会花费很长时间才能完成!
尽管如此,因为你的数据集包含了很多类别,你的实现中可能存在类别不平衡的问题。因此,我尝试通过使用StratifiedKFold来解决这个问题,而不是使用train_test_split
,后者不能保证分割中的类别平衡。
此外,我使用了GridSearchCV和StratifiedKFold来执行交叉验证,以便调整参数并尝试所有不同的优化器!
所以完整的实现如下:
import pandas as pdfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_scorefrom sklearn.model_selection import GridSearchCV, StratifiedKFold, StratifiedShuffleSplitimport numpy as npdef getDataset(path, x_attr, y_attr): """ 从CSV文件中提取数据集 :param path: CSV文件的位置 :param x_attr: 特征名称列表 :param y_attr: CSV文件中的Y头名称 :return: 元组,(X, Y) """ df = pd.read_csv(path) X = X = np.array(df[x_attr]).reshape(len(df), len(x_attr)) Y = np.array(df[y_attr]) return X, Ydef stratifiedSplit(X, Y): sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=0) train_index, test_index = next(sss.split(X, Y)) X_train, X_test = X[train_index], X[test_index] Y_train, Y_test = Y[train_index], Y[test_index] return X_train, X_test, Y_train, Y_testdef run(X_data, Y_data): X_train, X_test, Y_train, Y_test = stratifiedSplit(X_data, Y_data) param_grid = {'C': [0.01, 0.1, 1, 10, 100, 1000], 'penalty': ['l1', 'l2'], 'solver':['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga']} model = LogisticRegression(random_state=0) clf = GridSearchCV(model, param_grid, cv=StratifiedKFold(n_splits=10)) clf.fit(X_train, Y_train) print(accuracy_score(Y_train, clf.best_estimator_.predict(X_train))) print(accuracy_score(Y_test, clf.best_estimator_.predict(X_test)))X_data, Y_data = getDataset("data - Sheet1.csv", ['distance'], 'orders')run(X_data, Y_data)
尽管尝试了所有不同的算法,准确率没有超过36%!
为什么会这样?
如果你想让一个人通过T恤的颜色来识别/分类另一个人,你不能说:嘿,如果是红色的,那就是约翰,如果是红色的,那就是彼得,但如果是红色的,那就是艾斯琳!他会说“真的,有什么区别”?!
这就是你的数据集中存在的情况!
简单来说,运行print(len(np.unique(X_data)))
和print(len(np.unique(Y_data)))
,你会发现这些数字非常奇怪,简而言之,你有:
案例数:10000 !!类别数:118 !!唯一输入(即特征)数:66 !!
所有类别共享了大量信息,这使得即使达到36%的准确率也令人印象深刻!
换句话说,你没有信息丰富的特征,导致每个类别模型的独特性不足!
该怎么做?我认为你不被允许删除一些类别,所以你只有两个解决方案:
-
要么接受这个非常有效的结果。
-
要么添加更多信息丰富的特征。
更新
你提供的相同数据集但增加了更多特征(即完整的特征集),现在情况不同了。
我建议你做以下几件事:
-
预处理你的数据集(即通过填补缺失值或删除包含缺失值的行,转换日期为某些唯一值(示例)…等来准备数据)。
-
检查哪些特征对
Orders
类别最重要,你可以通过使用Forests of Trees
来评估特征的重要性。这里是一个在Scikit-Learn
中如何做的完整且简单的示例。 -
创建数据集的新版本,但这次将
Orders
作为Y
响应变量,将上述发现的特征作为X
变量。 -
按照我在上面的实现中展示的相同
GridSearchCV
和StratifiedKFold
程序进行操作。
提示
正如Vivek Kumar在下面的评论中提到的那样,stratify
参数已在Scikit-learn
更新中添加到train_test_split函数中。
它的工作原理是传递数组状的真实标签,因此你不需要我在stratifiedSplit(X, Y)
函数中的解决方案。