我想在20_newsgroup
数据集上计算信息增益
。
我使用这里的代码(我也将代码复制在问题下方)。
如你所见,算法的输入是X,y
。我感到困惑的是,X
将是一个矩阵
,其中行是文档
,列是特征
。(根据20_newsgroup的数据,如果只考虑1000个特征,它是11314行,1000列)。
但是,根据信息增益的概念,它应该为每个特征
计算信息增益。
(所以我期待看到代码以某种方式遍历每个特征,使得函数的输入是一个矩阵,其中行是特征,列是类别)
但在这里,X不是特征,X代表文档,我在代码中看不到处理这部分的部分!(我的意思是考虑每个文档,然后遍历该文档的每个特征;就像遍历行,但同时也遍历列,因为特征存储在列中)。
我阅读了这个和这个以及许多类似的提问,但它们在输入矩阵形状方面并不清楚。
这是读取20_newsgroup的代码:
newsgroup_train = fetch_20newsgroups(subset='train')X,y = newsgroup_train.data,newsgroup_train.targetcv = CountVectorizer(max_df=0.99,min_df=0.001, max_features=1000,stop_words='english',lowercase=True,analyzer='word')X_vec = cv.fit_transform(X)
(X_vec.shape)
是 (11314,1000),这并不是20_newsgroup数据集中的特征。我在想,我是否以错误的方式计算信息增益?
这是信息增益
的代码:
def information_gain(X, y): def _calIg(): entropy_x_set = 0 entropy_x_not_set = 0 for c in classCnt: probs = classCnt[c] / float(featureTot) entropy_x_set = entropy_x_set - probs * np.log(probs) probs = (classTotCnt[c] - classCnt[c]) / float(tot - featureTot) entropy_x_not_set = entropy_x_not_set - probs * np.log(probs) for c in classTotCnt: if c not in classCnt: probs = classTotCnt[c] / float(tot - featureTot) entropy_x_not_set = entropy_x_not_set - probs * np.log(probs) return entropy_before - ((featureTot / float(tot)) * entropy_x_set + ((tot - featureTot) / float(tot)) * entropy_x_not_set) tot = X.shape[0] classTotCnt = {} entropy_before = 0 for i in y: if i not in classTotCnt: classTotCnt[i] = 1 else: classTotCnt[i] = classTotCnt[i] + 1 for c in classTotCnt: probs = classTotCnt[c] / float(tot) entropy_before = entropy_before - probs * np.log(probs) nz = X.T.nonzero() pre = 0 classCnt = {} featureTot = 0 information_gain = [] for i in range(0, len(nz[0])): if (i != 0 and nz[0][i] != pre): for notappear in range(pre+1, nz[0][i]): information_gain.append(0) ig = _calIg() information_gain.append(ig) pre = nz[0][i] classCnt = {} featureTot = 0 featureTot = featureTot + 1 yclass = y[nz[1][i]] if yclass not in classCnt: classCnt[yclass] = 1 else: classCnt[yclass] = classCnt[yclass] + 1 ig = _calIg() information_gain.append(ig) return np.asarray(information_gain)
回答:
好吧,在详细研究了代码之后,我对X.T.nonzero()
有了更多的了解。
实际上,信息增益确实需要遍历特征。同时,scikit-learn
在这里提供的矩阵确实是基于文档-特征
的。
但是:
代码中使用了X.T.nonzero()
,它技术上将所有非零值转换为数组。然后在下一行循环遍历该数组的长度range(0, len(X.T.nonzero()[0])
。
总的来说,这部分X.T.nonzero()[0]返回了所有非零特征给我们 🙂