代码之家  ›  专栏  ›  技术社区  ›  Christopher

W2V变压器:仅使用一个字作为输入?

  •  -1
  • Christopher  · 技术社区  · 7 年前

    W2VTransformer gensim中的包装器:

    import numpy as np
    import pandas as pd
    from sklearn.linear_model import LogisticRegression
    from sklearn.pipeline import Pipeline
    from gensim.sklearn_api import W2VTransformer
    from gensim.utils import simple_preprocess
    
    # Load synthetic data
    data = pd.read_csv('https://pastebin.com/raw/EPCmabvN')
    data = data.head(10)
    
    # Set random seed
    np.random.seed(0)
    
    # Tokenize text
    X_train = data.apply(lambda r: simple_preprocess(r['text'], min_len=2), axis=1)
    # Get labels
    y_train = data.label
    
    train_input = [x[0] for x in X_train]
    
    # Train W2V Model
    model = W2VTransformer(size=10, min_count=1)
    model.fit(X_train)
    
    clf = LogisticRegression(penalty='l2', C=0.1)
    clf.fit(model.transform(train_input), y_train)
    
    text_w2v = Pipeline(
        [('features', model),
         ('classifier', clf)])
    
    score = text_w2v.score(train_input, y_train)
    score
    

    0.80000000000000004

    这个脚本的问题是 只有 工作时 train_input = [x[0] for x in X_train] ,它本质上总是第一个单词。 一旦换成 train_input = X_train (或 train_input X_train ),脚本返回:

    ValueError:无法将大小为10的数组重塑为形状(10,10)

    如何解决这个问题,即分类器如何处理多个输入字?

    显然,与D2V相比,W2V包装器无法处理可变长度的列车输入。这是一个工作的D2V版本:

    import numpy as np
    import pandas as pd
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import cross_val_score
    from sklearn.metrics import accuracy_score, classification_report
    from sklearn.pipeline import Pipeline
    from gensim.utils import simple_preprocess, lemmatize
    from gensim.sklearn_api import D2VTransformer
    
    data = pd.read_csv('https://pastebin.com/raw/bSGWiBfs')
    
    np.random.seed(0)
    
    X_train = data.apply(lambda r: simple_preprocess(r['text'], min_len=2), axis=1)
    y_train = data.label
    
    model = D2VTransformer(dm=1, size=50, min_count=2, iter=10, seed=0)
    model.fit(X_train)
    
    clf = LogisticRegression(penalty='l2', C=0.1, random_state=0)
    clf.fit(model.transform(X_train), y_train)
    
    pipeline = Pipeline([
            ('vec', model),
            ('clf', clf)
        ])
    
    y_pred = pipeline.predict(X_train)
    score = accuracy_score(y_train,y_pred)
    print(score)
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Vivek Kumar    7 年前

    这在技术上不是一个答案,但不能写在评论中,所以在这里。这里有多个问题:

    • LogisticRegression 类(以及大多数其他scikit学习模型)使用二维数据 (n_samples, n_features) .

      这意味着它需要一组1-d数组(每行一个(示例),其中数组元素包含特征值)。

      在您的数据中,单个单词将是一维数组,这意味着单个句子(示例)将是二维数组。这意味着完整的数据(这里的句子集合)将是一个二维数组的集合。即使如此,由于每个句子可以有不同的字数,它也不能组合成一个单一的三维数组。

    • W2VTransformer fit() , fit_transform() 和 transform() 不兼容 使用scikit学习 Pipeline .

      fit() fit_变换() 它们是不同的。

      • fit() :

        X(str的可数可数) 输入语料库。

        X可以简单地是令牌列表,但是对于更大的语料库,考虑一个可直接从句子中流出来的迭代。 磁盘/网络。请参见word2vec中的BrownCorpus、Text8Corpus或Line句子 这些例子的模块。

      • fit_transform() :

        X(形状的numpy数组[n个样本,n个特征])

    如果您想使用scikit learn,则需要具有二维形状。您需要“以某种方式合并”单个句子的词向量,以形成该句子的一维数组。这意味着您需要通过以下操作形成一种句子向量:

    • 单个单词的平均值
    • 基于频率、tf idf等对单个单词进行加权平均。
    • 使用其他技术,如sent2vec、paragraph2vec、doc2vec等。

    :-我现在注意到 you were doing this thing based on D2VTransformer . 如果您想使用sklearn,这应该是正确的方法。

    该问题中的问题是这一行(因为该问题现已删除):

    X_train = vectorizer.fit_transform(X_train)
    

    在这里,您可以覆盖您的原始文件 X_train (单词列表)具有已计算的单词向量,因此存在该错误。

    或者,您可以使用其他工具/库(keras、tensorflow),这些工具/库允许按顺序输入可变大小的数据。例如,可以在此处配置LSTM,以获取变量输入和结束标记,以标记句子结束(示例)。

    使现代化 :

    model = D2VTransformer(dm=1, size=50, min_count=2, iter=10, seed=0)
    model.fit(X_train)
    
    clf = LogisticRegression(penalty='l2', C=0.1, random_state=0)
    clf.fit(model.transform(X_train), y_train)
    
    pipeline = Pipeline([
            ('vec', model),
            ('clf', clf)
        ])
    
    y_pred = pipeline.predict(X_train)
    

    具有

    pipeline = Pipeline([
            ('vec', model),
            ('clf', clf)
        ])
    
    pipeline.fit(X_train, y_train)
    y_pred = pipeline.predict(X_train)
    

    pipeline.fit() 将自动执行此操作。

    推荐文章