计算大熊猫的Tf-Idf分数?

时间:2018-08-02 10:58:27

标签: python python-3.x pandas tf-idf tfidfvectorizer

我想从下面的文件中分别计算tf和idf。我正在使用python和pandas。

import pandas as pd
df = pd.DataFrame({'docId': [1,2,3], 
               'sent': ['This is the first sentence','This is the second sentence', 'This is the third sentence']})

我想使用Tf-Idf的公式而不使用Sklearn库进行计算。

标记化后,我已将其用于TF计算:

tf = df.sent.apply(pd.value_counts).fillna(0) 

但这给了我一个数字,但我希望比率为(count/total number of words)

对于IDf: df[df['sent'] > 0] / (1 + len(df['sent'])

但是它似乎不起作用。 我希望Tf和Idf都作为熊猫系列格式。

编辑

对于令牌化,我使用了df['sent'] = df['sent'].apply(word_tokenize) 我的IDF得分是:

tfidf = TfidfVectorizer()
feature_array = tfidf.fit_transform(df['sent'])
d=(dict(zip(tfidf.get_feature_names(), tfidf.idf_)))

我如何分别获得tf分数?

3 个答案:

答案 0 :(得分:1)

这是我的解决方法:

第一次标记化,为了方便起见在单独的列中

df['tokens'] = [x.lower().split() for x in df.sent.values] 

然后像您一样执行TF,但要使用normalize参数(出于技术原因,您需要使用lambda函数):

tf = df.tokens.apply(lambda x: pd.Series(x).value_counts(normalize=True)).fillna(0)

然后是IDF(词汇中的每个单词一个):

idf = pd.Series([np.log10(float(df.shape[0])/len([x for x in df.tokens.values if token in x])) for token in tf.columns])
idf.index = tf.columns

然后,如果您需要TFIDF:

tfidf = tf.copy()
for col in tfidf.columns:
    tfidf[col] = tfidf[col]*idf[col]

答案 1 :(得分:1)

您需要做更多的工作来计算这个。

import numpy as np

df = pd.DataFrame({'docId': [1,2,3], 
               'sent': ['This is the first sentence', 
                        'This is the second sentence',
                        'This is the third sentence']})

# Tokenize and generate count vectors
word_vec = df.sent.apply(str.split).apply(pd.value_counts).fillna(0)

# Compute term frequencies
tf = word_vec.divide(np.sum(word_vec, axis=1), axis=0)

# Compute inverse document frequencies
idf = np.log10(len(tf) / word_vec[word_vec > 0].count()) 

# Compute TF-IDF vectors
tfidf = np.multiply(tf, idf.to_frame().T)

print(tfidf)

    is  the     first  This  sentence    second     third
0  0.0  0.0  0.095424   0.0       0.0  0.000000  0.000000
1  0.0  0.0  0.000000   0.0       0.0  0.095424  0.000000
2  0.0  0.0  0.000000   0.0       0.0  0.000000  0.095424

根据您的情况,您可能需要标准化:

# L2 (Euclidean) normalization
l2_norm = np.sum(np.sqrt(tfidf), axis=1)

# Normalized TF-IDF vectors
tfidf_norm = (tfidf.T / l2_norm).T

print(tfidf_norm)

    is  the     first  This  sentence    second     third
0  0.0  0.0  0.308908   0.0       0.0  0.000000  0.000000
1  0.0  0.0  0.000000   0.0       0.0  0.308908  0.000000
2  0.0  0.0  0.000000   0.0       0.0  0.000000  0.308908

答案 2 :(得分:0)

我想我和你有同样的问题。

我想使用TfIdfVectorizer,但默认的tf-idf定义不是标准的(tf-idf = tf + tf*idf而不是常规的tf-idf = tf*idf

TF =术语“频率”通常用于表示计数。为此,您可以使用sklearn中的CountVectorizer()。 需要进行日志转换并在需要时进行规范化。

使用numpy的选项的处理时间更长(慢50倍以上)。