我在使用sklearn进行自然语言处理的向量化,使用的是tf-idf Vectorizer对象。这个对象可以通过关键字”token_pattern”来构建。
我想避免使用标签(#foobar)、数字(以及以数字开头的字符串,例如10mg)、任何以’RT’(转发)开头的行,或者”Deleted tweet”这样的行。
此外,我想忽略Unicode字符。
我想保留URL(不包括’http://’部分),并将它们中的任何单词(仅限[A-Za-z]+)标记化。
我对正则表达式有一定的经验,但直到现在才需要更复杂的模式。
下面是我对所有内容的尝试…显然这不是调查的最佳方式,但它确实总结了我目前对正则表达式规则的思考方式。
注意:skearn文档这里显示了默认的”token_pattern”使用了字符串上的Unicode标志,我不明白为什么…这可能是一个单独的问题。
pat2 = r"(?im)([A-Z]+)(?<!^@)([A-Z]+)(?<!^#)([A-Z]+)(?<!^(RT))([A-Z]+)(?<!^Deleted)(?<=^(http://))([A-Z]+)"
我的分解:
(?im) # '多行'和'不区分大小写'的标志([A-Z]+)(?<!^@) # 负向回顾,仅当不以'@'开头时匹配[A-Z]+。(?<=^(http://))([A-Z]+) # 正向预查,仅当存在'以"http://"开头'时匹配[A-Z]+。
我觉得这不是一个优雅的解决方案,即使它被调整到可以工作…
提前感谢!
更新:原始数据示例:
如果知道有帮助的话,我正在使用pandas数据框来加载数据。我对pandas还不熟,可能错过了基于pandas的解决方案。
从这些原始数据中,我只想从文本中提取单词和URL。这个例子很糟糕…请进一步评论以帮助我更好地定义…谢谢!
原始数据:
http://foxsportswisconsin.ning.com/profiles/blogs/simvastatin-20-mg-pas-cher-sur-internet-acheter-du-simvastatin-20
标记化后:
[foxsportswisconsin, ning, com, profiles, blogs, simvastatin, mg, pas, cher, sur, internet, acheter, du, simvastatin]
回答:
tl;dr: 如果你写的regex
超过20个字符,你做错了什么,但这可能是一个可以接受的临时解决方案。如果你写的regex
超过50个字符,你需要立即停止。
让我先说清楚,这绝不应该通过正则表达式来解决。
你描述的大多数步骤应该在预处理或后处理中处理。你不应该试图设计一个regex
来过滤以Deleted tweet
或RT
开头的东西,你应该在预处理中忽略这些行。
忽略unicode
?那么可能值得离开互联网,因为互联网上的一切,以及notepad之外的一切都是unicode。如果你想删除所有无法用ascii表示的unicode字符(我假设你指的是这个?),那么在编码步骤中解决这个问题是值得的:
<string>.encode('ascii', 'ignore')
至于忽略http
,你应该将其设置为停用词。这可以作为另一个参数传递给您使用的向量化器。
一旦完成,使用的标记正则表达式(可能仍然不是使用正则表达式的理由,但这是sklearn提供的接口)实际上非常简单:
'\b[a-zA-Z]\w+\b'
这里唯一需要实现的变化是忽略上面提到的像10mg
这样的数字。
值得注意的是,这种程度的标记删除将对你试图进行的任何分析产生负面影响。如果你有一个体量适中的语料库,你不应该删除任何标记,如果语料库较小,删除停用词并使用词干提取器或词形还原器是一个不错的选择,但这种标记删除是糟糕的做法,会导致过拟合。