【问题标题】:How to use grid search for the svm?如何对 svm 使用网格搜索?
【发布时间】:2019-08-15 17:19:08
【问题描述】:

我认为机器学习很有趣,我正在研究 scikit learn 文档以获得乐趣。 下面我做了一些数据清理,问题是我想使用网格搜索来找到参数的最佳值。

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn import metrics
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score


cats = ['sci.space','rec.autos','rec.motorcycles']
newsgroups_train = fetch_20newsgroups(subset='train',remove=('headers', 'footers', 'quotes'), categories = cats)
newsgroups_test = fetch_20newsgroups(subset='test',remove=('headers', 'footers', 'quotes'), categories = cats)

vectorizer = TfidfVectorizer( stop_words = "english")


vectors = vectorizer.fit_transform(newsgroups_train.data)
vectors_test = vectorizer.transform(newsgroups_test.data)

clf =  SVC(C=0.4,gamma=1,kernel='linear')

clf.fit(vectors, newsgroups_train.target)
vectors_test = vectorizer.transform(newsgroups_test.data)
pred = clf.predict(vectors_test)
print(accuracy_score(newsgroups_test.target, pred))

准确度为:0.849

我听说过网格搜索是为了找到参数的最佳值,但我不明白如何执行它。你能详细说明一下吗?这是我尝试过的,但不正确。我想学习正确的方法以及一些解释。谢谢

Cs = np.array([0.001, 0.01, 0.1, 1, 10])
gammas = np.array([0.001, 0.01, 0.1, 1])
model = SVC()
grid = GridSearchCV(estimator=model, param_grid=dict(Cs=alphas,gamma=gammas))
grid.fit(newsgroups_train.data, newsgroups_train.target)
print(grid)
# summarize the results of the grid search
print(grid.best_score_)
print(grid.best_estimator_.alpha)

编辑根据收到的答案:

parameters = {'C': [1, 10], 
          'gamma': [0.001, 0.01, 1]}
model = SVC()
grid = GridSearchCV(estimator=model, param_grid=parameters)
grid.fit(vectors, newsgroups_train.target)
print(grid)
# summarize the results of the grid search
print(grid.best_score_)
print(grid.best_estimator_)

它返回:

GridSearchCV(cv='warn', error_score='raise-deprecating',
       estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
  kernel='rbf', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False),
       fit_params=None, iid='warn', n_jobs=None,
       param_grid={'C': [1, 10], 'gamma': [0.001, 0.01, 1]},
       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',
       scoring=None, verbose=0)
0.8532212885154061
SVC(C=10, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma=1, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

我需要澄清这些:

1)What actually is displayed on the results?
2)Does it also take ranges for C as 1 to 10 or either 1 or 10? 
3)Can you suggest anything    to improve accuracy further?  
4)I noticed that the Tfidf made the accuracy worse even though it 
              cleaned the data from words that dont have any value

【问题讨论】:

  • 你几乎明白了,但是param_grid 接受一个字典,其中键是参数作为str,值是列表。所以{'C':np.array([0.001, 0.01, 0.1, 1, 10]), 'gamma':...}

标签: python machine-learning scikit-learn svm


【解决方案1】:

您希望传递参数字典,其中键是模型文档 (1) 中定义的参数名称。这些值应该是您想尝试的值的列表。

然后,网格搜索将调用这些参数的所有可能组合。文档中有一些很好的例子 (2)。

  1. https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html
  2. https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html

对于您的脚本,您还需要确保为网格搜索提供正确的训练数据,在本例中,是“vectors”而不是“newsgroups_test.data”。

见下文:

parameters = {'C': [1, 10], 
          'gamma': [0.001, 0.01, 1]}
model = SVC()
grid = GridSearchCV(estimator=model, param_grid=parameters)
grid.fit(vectors, newsgroups_train.target)
print(grid)
# summarize the results of the grid search
print(grid.best_score_)
print(grid.best_estimator_)

如果有效,请接受答案。祝你好运!

【讨论】:

  • 我在问题中添加了一些说明,作为与您的回答有关的编辑。
【解决方案2】:

为了提高准确性:


所以,由于这是一个文本分类问题,首先我们应该看看文本本身,看看它是否需要任何预处理。数据清理对于 tfidf 非常重要,因为它不考虑单词的上下文。
您可以尝试使大小写与使所有单词小写相同,这样它就不会以不同的方式对待同一个单词。您可以检查 url 和其他对模型无用的内容,并使用正则表达式删除所有内容。在 tfidf 模型中,您可以使用一些变量,如 max_features、ngram_range 等,以查看哪些值范围适用于该用例。

您可以探索许多其他模型。通常我们使用 LSTM、RNN 等来解决文本问题。您应该使用 Keras 探索这些模型。

网格搜索


网格搜索,随机网格搜索可用于尝试各种参数。 它本质上返回从您正在调整的指标中获得的最佳超参数集。它可以取值范围,也可以取值。 使用网格搜索搜索参数是完全随机的。 一个更好的选择是 HyperOpt,它实际上从过去获得的参数中学习一些东西。因此,使用它可以更快地提供最佳参数集。

您可以通过此链接更好地理解:https://medium.com/vantageai/bringing-back-the-time-spent-on-hyperparameter-tuning-with-bayesian-optimisation-2e21a3198afb

【讨论】:

  • 由于问题中的示例是完全可重现的,您可以使用代码来传递您的想法吗?例如,您认为实现最佳精度的最佳预处理是什么?我实际上已经使用了 tfidf 和 max features 和其他参数,但只是出于某种原因降低了准确性。示例将不胜感激。谢谢
猜你喜欢
  • 2012-03-27
  • 1970-01-01
  • 2016-07-18
  • 2015-03-15
  • 2020-04-20
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 2023-02-06
相关资源
最近更新 更多