TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0] while using RF classifier?
TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0] while using RF classifier?
我正在学习 scikit learn 中的随机森林,作为示例,我想使用随机森林分类器和我自己的数据集进行文本分类。所以首先我用 tfidf 对文本进行矢量化并进行分类:
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(X_train, y_train)
prediction = classifier.predict(X_test)
当我运行分类时我得到了这个:
TypeError: A sparse matrix was passed, but dense data is required. Use X.toarray() to convert to a dense numpy array.
然后我将 .toarray()
用于 X_train
,我得到了以下结果:
TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0]
根据我之前的 question 理解,我需要减少 numpy 数组的维数,所以我也这样做了:
from sklearn.decomposition.truncated_svd import TruncatedSVD
pca = TruncatedSVD(n_components=300)
X_reduced_train = pca.fit_transform(X_train)
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(X_reduced_train, y_train)
prediction = classifier.predict(X_testing)
然后我得到了这个异常:
File "/usr/local/lib/python2.7/site-packages/sklearn/ensemble/forest.py", line 419, in predict
n_samples = len(X)
File "/usr/local/lib/python2.7/site-packages/scipy/sparse/base.py", line 192, in __len__
raise TypeError("sparse matrix length is ambiguous; use getnnz()"
TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0]
我尝试了以下方法:
prediction = classifier.predict(X_train.getnnz())
得到这个:
File "/usr/local/lib/python2.7/site-packages/sklearn/ensemble/forest.py", line 419, in predict
n_samples = len(X)
TypeError: object of type 'int' has no len()
由此提出了两个问题:如何使用随机森林进行正确分类? X_train
发生了什么?
然后我尝试了以下方法:
df = pd.read_csv('/path/file.csv',
header=0, sep=',', names=['id', 'text', 'label'])
X = tfidf_vect.fit_transform(df['text'].values)
y = df['label'].values
from sklearn.decomposition.truncated_svd import TruncatedSVD
pca = TruncatedSVD(n_components=2)
X = pca.fit_transform(X)
a_train, a_test, b_train, b_test = train_test_split(X, y, test_size=0.33, random_state=42)
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(a_train, b_train)
prediction = classifier.predict(a_test)
from sklearn.metrics.metrics import precision_score, recall_score, confusion_matrix, classification_report
print '\nscore:', classifier.score(a_train, b_test)
print '\nprecision:', precision_score(b_test, prediction)
print '\nrecall:', recall_score(b_test, prediction)
print '\n confussion matrix:\n',confusion_matrix(b_test, prediction)
print '\n clasification report:\n', classification_report(b_test, prediction)
有点不清楚您是否将相同的数据结构(类型和形状)传递给分类器的 fit
方法和 predict
方法。随机森林需要很长时间才能 运行 具有大量特征,因此建议将 post 中的维数降低 link 到。
您应该将 SVD 应用于训练数据和测试数据,以便分类器在与您希望预测的数据相同形状的输入上进行训练。检查拟合的输入,和预测方法的输入具有相同数量的特征,并且都是数组而不是稀疏矩阵。
更新示例:
已更新为使用数据框
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vect= TfidfVectorizer( use_idf=True, smooth_idf=True, sublinear_tf=False)
from sklearn.cross_validation import train_test_split
df= pd.DataFrame({'text':['cat on the','angel eyes has','blue red angel','one two blue','blue whales eat','hot tin roof','angel eyes has','have a cat']\
,'class': [0,0,0,1,1,1,0,3]})
X = tfidf_vect.fit_transform(df['text'].values)
y = df['class'].values
from sklearn.decomposition.truncated_svd import TruncatedSVD
pca = TruncatedSVD(n_components=2)
X_reduced_train = pca.fit_transform(X)
a_train, a_test, b_train, b_test = train_test_split(X, y, test_size=0.33, random_state=42)
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(a_train.toarray(), b_train)
prediction = classifier.predict(a_test.toarray())
注意 SVD 发生在拆分成训练集和测试集之前,因此传递给预测器的数组与调用 fit
方法的数组具有相同的 n
。
我对 sklearn
了解不多,但我依稀记得一些较早的问题是由切换到使用稀疏矩阵引发的。在内部,一些矩阵必须替换为 m.toarray()
或 m.todense()
.
但为了让您了解错误消息的内容,请考虑
In [907]: A=np.array([[0,1],[3,4]])
In [908]: M=sparse.coo_matrix(A)
In [909]: len(A)
Out[909]: 2
In [910]: len(M)
...
TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0]
In [911]: A.shape[0]
Out[911]: 2
In [912]: M.shape[0]
Out[912]: 2
len()
通常用在 Python 中来计算列表中第一级术语的数量。当应用于二维数组时,它是行数。但是 A.shape[0]
是计算行数的更好方法。和 M.shape[0]
是一样的。在这种情况下,您对 .getnnz
不感兴趣,它是稀疏矩阵的非零项数。 A
没有此方法,但可以从 A.nonzero()
.
派生
我正在学习 scikit learn 中的随机森林,作为示例,我想使用随机森林分类器和我自己的数据集进行文本分类。所以首先我用 tfidf 对文本进行矢量化并进行分类:
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(X_train, y_train)
prediction = classifier.predict(X_test)
当我运行分类时我得到了这个:
TypeError: A sparse matrix was passed, but dense data is required. Use X.toarray() to convert to a dense numpy array.
然后我将 .toarray()
用于 X_train
,我得到了以下结果:
TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0]
根据我之前的 question 理解,我需要减少 numpy 数组的维数,所以我也这样做了:
from sklearn.decomposition.truncated_svd import TruncatedSVD
pca = TruncatedSVD(n_components=300)
X_reduced_train = pca.fit_transform(X_train)
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(X_reduced_train, y_train)
prediction = classifier.predict(X_testing)
然后我得到了这个异常:
File "/usr/local/lib/python2.7/site-packages/sklearn/ensemble/forest.py", line 419, in predict
n_samples = len(X)
File "/usr/local/lib/python2.7/site-packages/scipy/sparse/base.py", line 192, in __len__
raise TypeError("sparse matrix length is ambiguous; use getnnz()"
TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0]
我尝试了以下方法:
prediction = classifier.predict(X_train.getnnz())
得到这个:
File "/usr/local/lib/python2.7/site-packages/sklearn/ensemble/forest.py", line 419, in predict
n_samples = len(X)
TypeError: object of type 'int' has no len()
由此提出了两个问题:如何使用随机森林进行正确分类? X_train
发生了什么?
然后我尝试了以下方法:
df = pd.read_csv('/path/file.csv',
header=0, sep=',', names=['id', 'text', 'label'])
X = tfidf_vect.fit_transform(df['text'].values)
y = df['label'].values
from sklearn.decomposition.truncated_svd import TruncatedSVD
pca = TruncatedSVD(n_components=2)
X = pca.fit_transform(X)
a_train, a_test, b_train, b_test = train_test_split(X, y, test_size=0.33, random_state=42)
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(a_train, b_train)
prediction = classifier.predict(a_test)
from sklearn.metrics.metrics import precision_score, recall_score, confusion_matrix, classification_report
print '\nscore:', classifier.score(a_train, b_test)
print '\nprecision:', precision_score(b_test, prediction)
print '\nrecall:', recall_score(b_test, prediction)
print '\n confussion matrix:\n',confusion_matrix(b_test, prediction)
print '\n clasification report:\n', classification_report(b_test, prediction)
有点不清楚您是否将相同的数据结构(类型和形状)传递给分类器的 fit
方法和 predict
方法。随机森林需要很长时间才能 运行 具有大量特征,因此建议将 post 中的维数降低 link 到。
您应该将 SVD 应用于训练数据和测试数据,以便分类器在与您希望预测的数据相同形状的输入上进行训练。检查拟合的输入,和预测方法的输入具有相同数量的特征,并且都是数组而不是稀疏矩阵。
更新示例: 已更新为使用数据框
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vect= TfidfVectorizer( use_idf=True, smooth_idf=True, sublinear_tf=False)
from sklearn.cross_validation import train_test_split
df= pd.DataFrame({'text':['cat on the','angel eyes has','blue red angel','one two blue','blue whales eat','hot tin roof','angel eyes has','have a cat']\
,'class': [0,0,0,1,1,1,0,3]})
X = tfidf_vect.fit_transform(df['text'].values)
y = df['class'].values
from sklearn.decomposition.truncated_svd import TruncatedSVD
pca = TruncatedSVD(n_components=2)
X_reduced_train = pca.fit_transform(X)
a_train, a_test, b_train, b_test = train_test_split(X, y, test_size=0.33, random_state=42)
from sklearn.ensemble import RandomForestClassifier
classifier=RandomForestClassifier(n_estimators=10)
classifier.fit(a_train.toarray(), b_train)
prediction = classifier.predict(a_test.toarray())
注意 SVD 发生在拆分成训练集和测试集之前,因此传递给预测器的数组与调用 fit
方法的数组具有相同的 n
。
我对 sklearn
了解不多,但我依稀记得一些较早的问题是由切换到使用稀疏矩阵引发的。在内部,一些矩阵必须替换为 m.toarray()
或 m.todense()
.
但为了让您了解错误消息的内容,请考虑
In [907]: A=np.array([[0,1],[3,4]])
In [908]: M=sparse.coo_matrix(A)
In [909]: len(A)
Out[909]: 2
In [910]: len(M)
...
TypeError: sparse matrix length is ambiguous; use getnnz() or shape[0]
In [911]: A.shape[0]
Out[911]: 2
In [912]: M.shape[0]
Out[912]: 2
len()
通常用在 Python 中来计算列表中第一级术语的数量。当应用于二维数组时,它是行数。但是 A.shape[0]
是计算行数的更好方法。和 M.shape[0]
是一样的。在这种情况下,您对 .getnnz
不感兴趣,它是稀疏矩阵的非零项数。 A
没有此方法,但可以从 A.nonzero()
.