Мультиклассу SVM не удалось использовать набор данных 20 News Group

1

Я пытаюсь использовать мультиклассовый SVM-код от Mblondel Multiclass SVM, я прочитал его статью, и он использовал набор данных из sklearn 20newsgroup, но когда я попытался использовать это, код не работает должным образом.

Я попытался изменить код в соответствии с набором данных 20newsgroup. но я застрял в этой ошибке..

Traceback (последний вызов был последним):

Файл "F:\env\chatbotstripped\CSSVM.py", строка 157, в

clf.fit(X, y)

Файл "F:\env\chatbotstripped\CSSVM.py", строка 106, вписывается

v = self._violation (г, у, я)

Файл "F:\env\chatbotstripped\CSSVM.py", строка 50, в _violation

elif k! = y [i] и self.dual_coef_ [k, i]> = 0:

IndexError: индекс 20 выходит за пределы оси 0 с размером 20

это основной код:

from sklearn.datasets import fetch_20newsgroups
news_train = fetch_20newsgroups(subset='train')
X, y = news_train.data[:100], news_train.target[:100]

clf = MulticlassSVM(C=0.1, tol=0.01, max_iter=100, random_state=0, verbose=1)
X = TfidfVectorizer().fit_transform(X)
clf.fit(X, y)
print(clf.score(X, y))

это подходящий код:

def fit(self, X, y):
    n_samples, n_features = X.shape

    self._label_encoder = LabelEncoder()
    y = self._label_encoder.fit_transform(y)

    n_classes = len(self._label_encoder.classes_)
    self.dual_coef_ = np.zeros((n_classes, n_samples), dtype=np.float64)
    self.coef_ = np.zeros((n_classes, n_features))

    norms = np.sqrt(np.sum(X.power(2), axis=1)) # i changed this code

    rs = check_random_state(self.random_state)
    ind = np.arange(n_samples)
    rs.shuffle(ind)

    # i added this sparse
    sparse = sp.isspmatrix(X)
    if sparse:
        X = np.asarray(X.data, dtype=np.float64, order='C')

    for it in range(self.max_iter):
        violation_sum = 0
        for ii in range(n_samples):
            i = ind[ii]

            if norms[i] == 0:
                continue

            g = self._partial_gradient(X, y, i)
            v = self._violation(g, y, i)
            violation_sum += v

            if v < 1e-12:
                continue

            delta = self._solve_subproblem(g, y, norms, i)
            self.coef_ += (delta * X[i][:, np.newaxis]).T
            self.dual_coef_[:, i] += delta

        if it == 0:
            violation_init = violation_sum

        vratio = violation_sum / violation_init

        if self.verbose >= 1:
            print("iter", it + 1, "violation", vratio)

        if vratio < self.tol:
            if self.verbose >= 1:
                print("Converged")
            break
    return self

и код нарушения:

def _violation(self, g, y, i):
    smallest = np.inf
    for k in range(g.shape[0]):
        if k == y[i] and self.dual_coef_[k, i] >= self.C:
            continue
        elif k != y[i] and self.dual_coef_[k, i] >= 0:
            continue

        smallest = min(smallest, g[k].all()) # and i added .all()
    return g.max() - smallest

Я знаю, что с индексом что-то не так, я не уверен, как это исправить, и я не хочу портить код, потому что я не совсем понимаю, как работает этот код.

Теги:
svm

1 ответ

0

Вы должны преобразовать вывод разреженной матрицы векторизатора tfidf в плотную матрицу, а затем сделать его двумерным массивом. Попробуй это!

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
news_train = fetch_20newsgroups(subset='train')
text, y = news_train.data[:1000], news_train.target[:1000]

clf = MulticlassSVM(C=0.1, tol=0.01, max_iter=100, random_state=0, verbose=1)
vectorizer= TfidfVectorizer(min_df=20,stop_words='english')
X = np.asarray(vectorizer.fit_transform(text).todense())
clf.fit(X, y)
print(clf.score(X, y))

Выход:

iter 1 violation 1.0
iter 2 violation 0.07075102408683964
iter 3 violation 0.018288133735158228
iter 4 violation 0.009149083942255389
Converged
0.953
  • 0
    Спасибо, это работает! затем я хочу попытаться предсказать, используя мои собственные предложения, шаги: 1. предварительная обработка входного текста, 2. преобразование входного текста в tfidf 3. прогнозирование и получение категории как числа, верно? и я должен использовать обратный кодировщик меток, чтобы получить название категории?
  • 0
    да, вы получите только категорию в виде числа. Вы должны использовать декодирование, чтобы получить название вашей категории

Ещё вопросы

Сообщество Overcoder
Наверх
Меню