我有一个分组df:
id text
100 he loves ice cream
100 she loves ice
100 i hate avocado
我用这个函数提取bigrams,frequency和tfidf得分:
def extractFeatures(groupedDF, textCol):
features = pd.DataFrame()
for id, group in tqdm(groupedDF):
freq = cv.fit_transform(group[textCol])
tfidf = tv.fit_transform(group[textCol])
freq = sum(freq).toarray()[0]
tfidf.todense()
tfidf = tfidf.toarray()[0]
freq = pd.DataFrame(freq, columns=['frequency'])
tfidf = pd.DataFrame(tfidf, columns=['tfidf'])
dfinner = pd.DataFrame(cv.get_feature_names(), columns=['ngram'])
dfinner['id'] = id
dfinner = dfinner.join(freq)
results = dfinner.join(tfidf)
features = features.append(results)
return features
这导致以下df:
id ngram frequency tfidf
100 hate avocado 1 0
100 he loves 1 .3
100 i hate 1 0
100 ice cream 1 .3
100 loves ice 2 .6
100 she loves 1 0
tfidf得分是人为的。因此,该功能正确地找到频率。然后找到分组df的第一行的tfidf分数(包括出现在多行中的二元组。最后,它没有找到第二行和第三行特有的双字母组的tfidf分数。
此外,虽然设计了tfidf分数,但对于在特定文档中具有相同频率的任何二元组,它们确实是相同的。因此,第一行中频率为1的任何二元组都将具有.3 tfidf分数。另一行中频率为1的任何二重奏可能具有.24的tfidf分数。这很奇怪,因为每个二元组的术语频率肯定是不同的。
两个问题:
感谢您对所有人的见解!
print(df)
id text
0 100 he loves ice cream
1 100 she loves ice
2 100 i hate avocado
TF-IDF被计算为单词的重要性,该单词相对于一个文档中的单词的频率与文档的其余部分相比。如果你想计算TF-IDF,我建议使用scikit-learn TfidfVectorizer()
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(smooth_idf=True,
ngram_range = (2,2),
token_pattern='(?u)\\b\\w\\w*\\b'
)
words = vectorizer.fit_transform(df.text)
df2 = pd.DataFrame(words.todense()).rename(columns=dict(zip(vectorizer.vocabulary_.values(),
vectorizer.vocabulary_.keys())))
print(df2)
hate avocado he loves i hate ice cream loves ice she loves
0 0.000000 0.622766 0.000000 0.622766 0.473630 0.000000
1 0.000000 0.000000 0.000000 0.000000 0.605349 0.795961
2 0.707107 0.000000 0.707107 0.000000 0.000000 0.000000
上面的矩阵给出了每个文档中每个单词的相对重要性,如果该单词没有出现在文档中,则它的值为零。
您也可以使用scikit-learn CountVectorizer()
以相同的方式计算频率