sklearn classifier get ValueError: bad input shape
Asked Answered
R

2

15

I have a csv, struct is CAT1,CAT2,TITLE,URL,CONTENT, CAT1, CAT2, TITLE ,CONTENT are in chinese.

I want train LinearSVC or MultinomialNB with X(TITLE) and feature(CAT1,CAT2), both get this error. below is my code:

PS: I write below code through this example scikit-learn text_analytics

import numpy as np
import csv
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline

label_list = []

def label_map_target(label):
    ''' map chinese feature name to integer  '''
    try:
        idx = label_list.index(label)
    except ValueError:
        idx = len(label_list)
        label_list.append(label)

    return idx


c1_list = []
c2_list = []
title_list = []
with open(csv_file, 'r') as f:
    # row_from_csv is for shorting this example
    for row in row_from_csv(f):
        c1_list.append(label_map_target(row[0])
        c2_list.append(label_map_target(row[1])
        title_list.append(row[2])

data = np.array(title_list)
target = np.array([c1_list, c2_list])
print target.shape
# (2, 4405)
target = target.reshape(4405,2)
print target.shape
# (4405, 2)

docs_train, docs_test, y_train, y_test = train_test_split(
   data, target, test_size=0.25, random_state=None)

# vect = TfidfVectorizer(tokenizer=jieba_tokenizer, min_df=3, max_df=0.95)
# use custom chinese tokenizer get same error
vect = TfidfVectorizer(min_df=3, max_df=0.95)
docs_train= vect.fit_transform(docs_train)

clf = LinearSVC()
clf.fit(docs_train, y_train)

error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-24-904eb9af02cd> in <module>()
      1 clf = LinearSVC()
----> 2 clf.fit(docs_train, y_train)

C:\Python27\lib\site-packages\sklearn\svm\classes.pyc in fit(self, X, y)
    198 
    199         X, y = check_X_y(X, y, accept_sparse='csr',
--> 200                          dtype=np.float64, order="C")
    201         self.classes_ = np.unique(y)
    202 

C:\Python27\lib\site-packages\sklearn\utils\validation.pyc in check_X_y(X, y, accept_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, multi_output, ensure_min_samples, ensure_min_features, y_numeric)
    447                         dtype=None)
    448     else:
--> 449         y = column_or_1d(y, warn=True)
    450         _assert_all_finite(y)
    451     if y_numeric and y.dtype.kind == 'O':

C:\Python27\lib\site-packages\sklearn\utils\validation.pyc in column_or_1d(y, warn)
    483         return np.ravel(y)
    484 
--> 485     raise ValueError("bad input shape {0}".format(shape))
    486 
    487 

ValueError: bad input shape (3303, 2)
Ruff answered 9/7, 2015 at 0:59 Comment(10)
x_train, You didn't assign value in your code.Clueless
@Clueless please refresh the page, I paste wrong code at first.Ruff
Why target has 2 columns, there only should be 1 target value.Clueless
@Clueless isn't it one title has two features(CAT1,CAT2) ? I am new to sklearn, If I misunderstand it, please point that out.Ruff
In you code, data is feature vector, target is target value. I think you are mixing up two thingsClueless
@Clueless Thank you for your tip, I got it. TfidfVectorizer process data to [data, feature] , and each data should map to just one target (C1 or C2). If I want to predict two type targets, I need two Classifiers.Is that right?Ruff
If you have two distinct targets, then you need two classifier, but normally we only have one target.Clueless
Please don't put [SOLVED] in the title - StackOverflow is not a forum. If you found an answer - you can answer your own question and then accept your answer - which marks the question as closed.Plenary
@Burhan Khalid my problem had solved by meelo's comment.Today I think I should mark it, that's why I put [solved]. So what should I do?Ruff
You can answer it yourself; (just write an answer) and you can refer to @melo's comment and how you integrated it. Then, after a while, you'll be able to click the hollow checkmark next to your answer in order to accept it. This way, others will know the question is resolved.Plenary
R
9

Thanks to @meelo, I solved this problem. As he said: in my code, data is a feature vector, target is target value. I mixed up two things.

I learned that TfidfVectorizer processes data to [data, feature], and each data should map to just one target.

If I want to predict two type targets, I need two distinct targets:

  1. target_C1 with all C1 value
  2. target_C2 with all C2 value.

Then use the two targets and original data to train two classifier for each target.

Ruff answered 3/8, 2015 at 5:32 Comment(0)
Z
7

I had the same issue.

So if you are facing the same problem you should check the shape of clf.fit(X,y)parameters:

X : Training vector {array-like, sparse matrix}, shape (n_samples, n_features).

y : Target vector relative to X array-like, shape (n_samples,).

as you can see the y width should be 1, to make sure your target vector is shaped correctly try command

y.shape

should be (n_samples,)

In my case, for my training vector I was concatenating 3 separate vectors from 3 different vectorizers to use all as my final training vector. The problem was that each vector had the ['Label'] column in it so the final training vector contained 3 ['Label'] columns. Then when I used final_trainingVect['Label'] as my Target vector it's shape was n_samples,3).

Zambrano answered 21/5, 2018 at 8:48 Comment(1)
As correctly said by @eslam samy you need an encoder which will make sure the shape of target valriable as (row,). For that (if using MultinomialNB) use labelEncoder as follows: from sklearn.preprocessing import LabelEncoder le=LabelEncoder() y_train_array=le.fit_transform(ytrain)Gig

© 2022 - 2024 — McMap. All rights reserved.