【问题标题】:How do I make my algo work with KNN text classification?如何使我的算法与 KNN 文本分类一起使用?
【发布时间】:2020-05-16 08:05:25
【问题描述】:

试图让我的分类接受文本(字符串)而不仅仅是数字(数字)。处理数据,携带大量拉取的文章,我希望分类算法显示哪些要继续,哪些要删除。应用一个数字,一切正常,但这不是很直观,尽管我知道该数字代表与我正在使用的两个类之一的关系。

如何更改算法中的逻辑以使其接受文本作为搜索条件,而不仅仅是从“Unique_id”列中挑选的匿名号码?列是,顺便说一句......'标题','摘要','相关','标签','Unique_id'。在算法结束时连接 df 的原因是我想比较结果。最后。应该注意的是 col 'Label' 包含一个关键字列表,所以基本上我希望算法从该 col 中读取。

我确实尝试过,从数据源读取数据,将 'index_col='Unique_id' 更改为 'index_col='Label',但这也没有成功。

我想要的一个例子:

print("\nPrint KNN1")
print(get_closest_neighs1('search word'), "\n")

print("\nPrint KNN2")
print(get_closest_neighs2('search word'), "\n")

print("\nPrint KNN3")
print(get_closest_neighs3('search word'), "\n")

这是完整的代码(查看算法末尾以查看上面运行的示例,使用数字标识最近的邻居):

import pandas as pd

print("\nPerforming Analysis using Text Classification")
data = pd.read_csv('File_1_coltest_demo.csv', sep=';',  encoding="ISO-8859-1").dropna()

data['Unique_id'] = data.groupby(['Title', 'Abstract', 'Relevant']).ngroup()

data.to_csv('File_2_coltest_demo_KNN.csv', sep=';', encoding="ISO-8859-1", index=False)

data1 = pd.read_csv('File_2_coltest_demo_KNN.csv', sep=';', encoding="ISO-8859-1", index_col='Unique_id')

data2 = pd.DataFrame(data1, columns=['Abstract', 'Relevant'])

data2.to_csv('File_3_coltest_demo_KNN_reduced.csv', sep=';', encoding="ISO-8859-1", index=False)

print("\nData top 25 items")
print(data2.head(25))

print("\nData info")
print(data2.info())

print("\nData columns")
print(data2.columns)

from sklearn.feature_extraction.text import CountVectorizer
from nltk.tokenize import RegexpTokenizer

token = RegexpTokenizer(r'[a-zA-Z0-9]+')
cv = CountVectorizer(lowercase=True, stop_words='english', ngram_range=(1, 1), tokenizer=token.tokenize)
text_counts = cv.fit_transform(data2['Abstract'])

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
text_counts, data2['Abstract'], test_size=0.5, random_state=1)

print("\nTF IDF")
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()
text_tf = tf.fit_transform(data2['Abstract'])
print(text_tf)

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
text_tf, data2['Abstract'], test_size=0.3, random_state=123)

from sklearn.neighbors import NearestNeighbors
import pandas as pd

nbrs = NearestNeighbors(n_neighbors=20, metric='euclidean').fit(text_tf)

def get_closest_neighs1(Abstract):
    row = data2.index.get_loc(Abstract)
    distances, indices = nbrs.kneighbors(text_tf.getrow(row))
    names_similar = pd.Series(indices.flatten()).map(data2.reset_index()['Abstract'])
    result = pd.DataFrame({'distance1' : distances.flatten(), 'Abstract' : names_similar}) # 'Unique_id' : names_similar,
    return result

def get_closest_neighs2(Unique_id):
    row = data2.index.get_loc(Unique_id)
    distances, indices = nbrs.kneighbors(text_tf.getrow(row))
    names_similar = pd.Series(indices.flatten()).map(data2.reset_index()['Unique_id'])
    result1 = pd.DataFrame({'Distance' : distances.flatten() / 10, 'Unique_id' : names_similar}) # 'Unique_id' : names_similar,
    return result1

def get_closest_neighs3(Relevant):
    row = data2.index.get_loc(Relevant)
    distances, indices = nbrs.kneighbors(text_tf.getrow(row))
    names_similar = pd.Series(indices.flatten()).map(data2.reset_index()['Relevant'])
    result2 = pd.DataFrame({'distance2' : distances.flatten(), 'Relevant' : names_similar}) # 'Unique_id' : names_similar,
    return result2

print("\nPrint KNN1")
print(get_closest_neighs1(114), "\n")

print("\nPrint KNN2")
print(get_closest_neighs2(114), "\n")

print("\nPrint KNN3")
print(get_closest_neighs3(114), "\n")

data3 = pd.DataFrame(get_closest_neighs1(114))
data4 = pd.DataFrame(get_closest_neighs2(114))
data5 = pd.DataFrame(get_closest_neighs3(114))

del data5['distance2']

data6 = pd.concat([data3, data4, data5], axis=1).reindex(data3.index)

del data6['distance1']

data6.to_csv('File_4_coltest_demo_KNN_results.csv', sep=';', encoding="ISO-8859-1", index=False)

【问题讨论】:

  • 您能否提供第一个 CSV 的简短摘录?

标签: python-3.x nlp knn text-classification


【解决方案1】:

如果我理解正确,您正在尝试这样做:

  • 您已通过“摘要”字段对所有文档进行矢量化处理。因此,具有相似词分布的摘要的文档应该在 TFIDF 空间附近。
  • 您想要找到与包含搜索关键字的文档最近的邻居。
  • 因此,您需要在原始语料库中搜索包含该关键字的第一个或所有文档
  • 然后找到那个/那些文档的索引,然后找到它们的邻居。
  • 如果有多个文档使用该关键字,则需要对索引列表进行排序,并以某种方式将整体结果与一些权重合并。

如果这是真的,那么关键字搜索/查找并不是真正“在”模型“内部”,它只是从语料库中预先选择了一个文档。获得文档索引后,您可以(重复)执行 KNN。

我对 Pandas 不是很熟悉,但我以前“手动”做过这种事情,例如通过将文档标题保存在单独的数组中,并带有索引的映射。

我想您需要用对“标签”列值的迭代替换您的 data2.index.get_loc() 调用,并对每个调用进行简单的字符串搜索。还是 Pandas 提供语料库内的搜索功能?

例如https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html#pandas.DataFrame.query

【讨论】:

  • 嗨 scipilot,感谢您对我的问题的回应,您对我的问题的看法非常正确...;o) 您是否建议不需要整个文本分析部分,那我应该直接在原始语料库中搜索吗?我猜想执行 TF-IDF 之类的预处理的真正原因是利用直觉,如果一个单词在文档中出现多次,那么我在语料库中选择的文档或任何其他文档的相关性是被提升。我可能弄错了,尝试更改一些代码,即 get_loc 到 .query
  • 你能想出一个例子来说明我应该如何应用你的建议吗? - 谢谢
  • 实际上,我确实尝试从 col 'Label' 中创建一个索引,然后指向 col 'Abstract' 中的相应项目。我确定我犯了一个愚蠢的错误,但我无法找出错误隐藏在哪里...;o/...;o)
  • 这取决于您要达到的目标。如果您想在标签文件附近找到未标签文件(即您不信任原始标签),那么最好利用 TFIDF 邻居。但是,如果您认为标签一开始是正确的,那么您可以只通过标签列搜索原始语料库,甚至不必费心将它们矢量化。
  • 我认为 2k+ 文本字符串的列表(即不同的科学摘要)是未标记的数据,这也是我执行 TF-IDF 的原因
猜你喜欢
  • 2017-01-17
  • 2013-05-17
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 2014-11-14
  • 2020-01-14
  • 2019-07-26
相关资源
最近更新 更多