【问题标题】:Using GridSearchCV best_params_ gives poor results使用 GridSearchCV best_params_ 的结果很差
【发布时间】:2022-01-13 01:02:27
【问题描述】:

我正在尝试在一个非常小的数据集(Kaggle Leaf 大约有 990 行)上调整 KNN 的超参数:

def knnTuning(self, x_train, t_train):
    
    params = {
        'n_neighbors': [1, 2, 3, 4, 5, 7, 9],
        'weights': ['uniform', 'distance'],
        'leaf_size': [5,10, 15, 20]
    }
    grid = GridSearchCV(KNeighborsClassifier(), params)
    grid.fit(x_train, t_train)
    
    print(grid.best_params_)
    print(grid.best_score_)
    
    return knn.KNN(neighbors=grid.best_params_["n_neighbors"], 
                   weight = grid.best_params_["weights"],
                   leafSize = grid.best_params_["leaf_size"])

打印:
{'leaf_size': 5, 'n_neighbors': 1, 'weights': 'uniform'}
0.9119999999999999

然后我返回这个分类器

class KNN:

def __init__(self, neighbors=1, weight = 'uniform', leafSize = 10):
    
    self.clf = KNeighborsClassifier(n_neighbors = neighbors,
                                    weights = weight, leaf_size = leafSize)

def train(self, X, t):
    self.clf.fit(X, t)

def predict(self, x):
    return self.clf.predict(x)

def global_accuracy(self, X, t):
    predicted = self.predict(X)
    accuracy = (predicted == t).mean()
    
    return accuracy

我用 700 行训练和 200 行验证运行了几次,它们是通过随机排列选择的。

然后我得到了从 0.01(经常)到 0.4(很少)的全局精度结果。

我知道我没有比较两个相同的指标,但我仍然无法理解结果之间的巨大差异。

【问题讨论】:

    标签: python machine-learning scikit-learn knn gridsearchcv


    【解决方案1】:

    不太确定您是如何训练模型或如何完成预处理的。 leaf dataset 有大约 100 个标签(物种),因此您必须小心拆分测试和训练以确保样本的平均拆分。奇怪的准确性的一个原因可能是您的样本分裂不均匀。

    您还需要扩展功能:

    from sklearn.preprocessing import LabelEncoder, StandardScaler
    from sklearn.model_selection import GridSearchCV, StratifiedShuffleSplit
    
    df = pd.read_csv("https://raw.githubusercontent.com/WenjinTao/Leaf-Classification--Kaggle/master/train.csv")
    
    le = LabelEncoder()
    scaler = StandardScaler()
    X = df.drop(['id','species'],axis=1)
    X = scaler.fit_transform(X)
    y = le.fit_transform(df['species'])
    
    strat = StratifiedShuffleSplit(n_splits=1, test_size=0.3, random_state=0).split(X,y)
    x_train, y_train, x_test, y_test = [[X.iloc[train,:],t[train],X.iloc[test,:],t[test]] for train,test in strat][0]
    

    如果我们进行培训,我会小心包括 n_neighbors = 1 :

    params = {
        'n_neighbors': [2, 3, 4],
        'weights': ['uniform', 'distance'],
        'leaf_size': [5,10, 15, 20]
    }
    
    sss = StratifiedShuffleSplit(n_splits=10, test_size=0.2, random_state=0)
    grid = GridSearchCV(KNeighborsClassifier(), params, cv=sss)
    grid.fit(x_train, y_train)
    
    print(grid.best_params_)
    print(grid.best_score_)
    
    {'leaf_size': 5, 'n_neighbors': 2, 'weights': 'distance'}
    0.9676258992805755
    

    然后你可以检查你的测试:

    pred = grid.predict(x_test)
    (y_test == pred).mean()
    
    0.9831649831649831
    

    【讨论】:

    • 嘿,可以用x_train, t_train, x_test, t_test = [[X.iloc[train,:],t[train],X.iloc[test,:],t[test]] for train,test in strat][0] 修改你的答案吗?我刚刚在 X 上添加了 iloc 以使其工作!
    猜你喜欢
    • 2018-05-31
    • 2020-07-02
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2021-02-20
    • 2019-03-29
    • 2019-08-14
    • 2021-09-09
    相关资源
    最近更新 更多