我有这份文件
这不是普通的文字
这是科学术语的文本
这些文件的正文是这样的
RepID,Txt
1,K9G3P9 4H477 -Q207KL41 98464 ... Q207KL41
2,D84T8X4 -D9W4S2 -D9W4S2 8E8E65 ... D9W4S2
3,-05L8NJ38 K2DD949 0W28DZ48 207441 ... K2D28K84
我可以使用 BOW 算法构建功能集
这是我的代码
def BOW(df):
CountVec = CountVectorizer() # to use only bigrams ngram_range=(2,2)
Count_data = CountVec.fit_transform(df)
Count_data = Count_data.astype(np.uint8)
cv_dataframe=pd.DataFrame(Count_data.toarray(), columns=CountVec.get_feature_names_out(), index=df.index) # <- HERE
return cv_dataframe.astype(np.uint8)
df_reps = pd.read_csv("c:\\file.csv")
df = BOW(df_reps["Txt"])
结果将是“Txt”列中的字数。
RepID K9G3P9 4H477 -Q207KL41 98464 ... Q207KL41
1 2 8 3 2 ... 1
2 0 1 2 4 ... 2
这里我需要帮助的技巧是,其中一些术语前面有一个-,这应该算作负值
因此,如果文本具有这些值
Q207KL41 -Q207KL41 -Q207KL41
在这种情况下,以 - 开头的项应计为负数,因此
Q207KL41
的 BOW 为 -1
而不是具有
Q207KL41
和 -Q207KL41
的功能
它们都计入同一个术语Q207KL41
,但具有正和-负
所以 BOW 之后的数据集将如下所示
RepID K9G3P9 4H477 Q207KL41 98464 ...
1 2 8 -2 2 ...
2 0 1 0 4 ...
如何做到这一点?
这可能与普通的词袋矢量化有很大不同,您最好编写自己的矢量化器。这是我能想到的最简单的方法。
代码:
import io
import pandas as pd
import numpy as np
from collections import defaultdict
s = """
RepID,Txt
1,K9G3P9 4H477 -Q207KL41 98464 Q207KL41
2,D84T8X4 -D9W4S2 -D9W4S2 8E8E65 D9W4S2
3,-05L8NJ38 K2DD949 0W28DZ48 207441 K2D28K84"""
df_reps = pd.read_csv(io.StringIO(s))
def BOW(documents):
ret = []
vocabulary = defaultdict()
vocabulary.default_factory = vocabulary.__len__
for document in documents:
feature_counter = defaultdict(int)
for token in document.split():
sign = 1
if token[0] == "-":
token = token[1:]
sign = -1
feature_idx = vocabulary[token]
feature_counter[feature_idx] += sign
ret.append(feature_counter)
df = pd.DataFrame.from_records(ret)
df = df.fillna(0)
df.columns = vocabulary.keys()
df = df.astype(np.int8)
return df
print(BOW(df_reps["Txt"]))
输出:
K9G3P9 4H477 Q207KL41 98464 D84T8X4 D9W4S2 8E8E65 05L8NJ38 K2DD949 0W28DZ48 207441 K2D28K84
0 1 1 0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 1 -1 1 0 0 0 0 0
2 0 0 0 0 0 0 0 -1 1 1 1 1