【问题标题】:How fit_transform, transform and TfidfVectorizer worksfit_transform、transform 和 TfidfVectorizer 的工作原理
【发布时间】:2020-06-23 19:00:27
【问题描述】:

我正在做一个模糊匹配项目,我发现了一个非常有趣的方法:awesome_cossim_top

我全面理解了定义,但不明白当我们执行 fit_transform 时会发生什么

import pandas as pd
import sqlite3 as sql
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
from scipy.sparse import csr_matrix
import sparse_dot_topn.sparse_dot_topn as ct
import re

def ngrams(string, n=3):
    string = re.sub(r'[,-./]|\sBD',r'', re.sub(' +', ' ',str(string)))
    ngrams = zip(*[string[i:] for i in range(n)])
    return [''.join(ngram) for ngram in ngrams]

def awesome_cossim_top(A, B, ntop, lower_bound=0):
    # force A and B as a CSR matrix.
    # If they have already been CSR, there is no overhead
    A = A.tocsr()
    B = B.tocsr()
    M, _ = A.shape
    _, N = B.shape

    idx_dtype = np.int32

    nnz_max = M*ntop

    indptr = np.zeros(M+1, dtype=idx_dtype)
    indices = np.zeros(nnz_max, dtype=idx_dtype)
    data = np.zeros(nnz_max, dtype=A.dtype)

    ct.sparse_dot_topn(
            M, N, np.asarray(A.indptr, dtype=idx_dtype),
            np.asarray(A.indices, dtype=idx_dtype),
            A.data,
            np.asarray(B.indptr, dtype=idx_dtype),
            np.asarray(B.indices, dtype=idx_dtype),
            B.data,
            ntop,
            lower_bound,
            indptr, indices, data)

    print('ct.sparse_dot_topn: ', ct.sparse_dot_topn)
    return csr_matrix((data,indices,indptr),shape=(M,N))

    def get_matches_df(sparse_matrix, A, B, top=100):
        non_zeros = sparse_matrix.nonzero()

        sparserows = non_zeros[0]
        sparsecols = non_zeros[1]

        if top:
            nr_matches = top
        else:
            nr_matches = sparsecols.size

        left_side = np.empty([nr_matches], dtype=object)
        right_side = np.empty([nr_matches], dtype=object)
        similairity = np.zeros(nr_matches)

        for index in range(0, nr_matches):
            left_side[index] = A[sparserows[index]]
            right_side[index] = B[sparsecols[index]]
            similairity[index] = sparse_matrix.data[index]

        return pd.DataFrame({'left_side': left_side,
                             'right_side': right_side,
                             'similairity': similairity})

这是我遇到困惑的脚本: 为什么我们应该首先使用 fit_transform 然后只使用 SAME 矢量化器进行转换。 我尝试从矢量化器和矩阵打印一些输出,例如 print(vectorizer.get_feature_names()) 但不理解逻辑。

有人可以帮我澄清一下吗?

非常感谢!!

Col_clean = 'fruits_normalized'
Col_dirty = 'fruits'

#read table
data_dirty={f'{Col_dirty}':['I am an apple', 'You are an apple', 'Aple', 'Appls', 'Apples']}
data_clean= {f'{Col_clean}':['apple', 'pear', 'banana', 'apricot', 'pineapple']}

df_clean = pd.DataFrame(data_clean)
df_dirty = pd.DataFrame(data_dirty)

Name_clean = df_clean[f'{Col_clean}'].unique()
Name_dirty= df_dirty[f'{Col_dirty}'].unique()

vectorizer = TfidfVectorizer(min_df=1, analyzer=ngrams)
clean_idf_matrix = vectorizer.fit_transform(Name_clean)
dirty_idf_matrix = vectorizer.transform(Name_dirty)

matches = awesome_cossim_top(dirty_idf_matrix, clean_idf_matrix.transpose(),1,0)
matches_df = get_matches_df(matches, Name_dirty, Name_clean, top = 0)

with pd.option_context('display.max_rows', None, 'display.max_columns', None):
    matches_df.to_excel("output_apple.xlsx")

print('done')

【问题讨论】:

    标签: python machine-learning scikit-learn sparse-matrix fuzzy-logic


    【解决方案1】:

    TfidfVectorizer.fit_transform 用于从训练数据集创建词汇表,TfidfVectorizer.transform 用于将该词汇表映射到测试数据集,以便测试数据中的特征数量保持与训练数据相同。下面的例子可能会有所帮助:

    import pandas as pd
    from sklearn.feature_extraction.text import TfidfVectorizer
    

    创建一个虚拟训练数据:

    train = pd.DataFrame({'Text' :['I am a data scientist','Cricket is my favorite sport', 'I work on Python regularly', 'Python is very fast for data mining', 'I love playing cricket'],
                          'Category' :['Data_Science','Cricket','Data_Science','Data_Science','Cricket']})
    

    还有一个小测试数据:

    test = pd.DataFrame({'Text' :['I am new to data science field', 'I play cricket on weekends', 'I like writing Python codes'],
                             'Category' :['Data_Science','Cricket','Data_Science']})
    

    创建一个名为 vectorizerTfidfVectorizer() 对象

    vectorizer = TfidfVectorizer()
    

    将它拟合到火车数据上

    X_train = vectorizer.fit_transform(train['Text'])
    print(vectorizer.get_feature_names())
    
    #['am', 'cricket', 'data', 'fast', 'favorite', 'for', 'is', 'love', 'mining', 'my', 'on', 'playing', 'python', 'regularly', 'scientist', 'sport', 'very', 'work']
    
    feature_names = vectorizer.get_feature_names()
    df= pd.DataFrame(X.toarray(),columns=feature_names)
    

    现在看看如果你在测试数据集上做同样的事情会发生什么:

    vectorizer_test = TfidfVectorizer()
    X_test = vectorizer_test.fit_transform(test['Text'])
    print(vectorizer_test.get_feature_names())
    
    #['am', 'codes', 'cricket', 'data', 'field', 'like', 'new', 'on', 'play', 'python', 'science', 'to', 'weekends', 'writing']
    feature_names_test = vectorizer_test.get_feature_names()
    df_test= pd.DataFrame(X_test.toarray(),columns = feature_names_test)
    

    它使用测试数据集创建了另一个词汇表,与来自训练数据的 18 个单词(列)相比,它有 14 个唯一词(列)。

    现在,如果您在 text-classification 的训练数据上训练机器学习算法并尝试根据测试数据对矩阵进行预测,它将失败并生成一个错误,即训练数据和测试数据之间的特征不同。

    为了克服这个错误,我们在text-classification 中做了这样的事情:

    X_test_from_train = vectorizer.transform(test['Text'])
    feature_names_test_from_train = vectorizer.get_feature_names()
    df_test_from_train = pd.DataFrame(X_test_from_train.toarray(),columns = feature_names_test_from_train)
    

    在这里你会注意到我们没有使用fit_transform命令,而是我们在测试数据上使用transform,原因相同,在对测试数据进行预测时,我们只想使用那些特征训练数据和测试数据相似,因此我们不会出现特征不匹配错误。

    希望这会有所帮助!

    【讨论】:

    • 非常感谢 Manojk !它很有教育意义,现在看起来更清晰了。我只想了解一件事:我们如何从那开始:['我是一名数据科学家','板球是我最喜欢的运动','我经常使用 Python','Python 非常快速进行数据挖掘', '我喜欢打板球'] 对此:#['am', 'cricket', 'data', 'fast', 'favorite', 'for', '是','爱','采矿','我的','on','玩','python','经常','科学家','运动','非常','工作'] 例如,为什么我们不再找到 "I""a" 了?
    • 虽然我不确定,但我认为它们不包含在矩阵中,因为它们是非常常见的词,您可以在几乎所有文档中找到它们,因此它们在预测类别时没有任何意义,还应删除诸如 am、for、my、is、on 等词,因为它们是停用词且信息量较少,停用词通常在 NLP 中被删除,因为它们不会在文本分类中增加任何价值。
    猜你喜欢
    • 2021-12-10
    • 2022-08-20
    • 2021-03-11
    • 2021-02-18
    • 2020-11-05
    • 1970-01-01
    • 2014-07-13
    • 2016-08-25
    • 2016-12-06
    相关资源
    最近更新 更多