自然语言处理入门

  自然语言处理NLP( natural language process)是这几年越来越火了,kaggle上的比赛有关NLP的也日渐多起来了.
  
  NLP的应用场景很多,情感分析,邮件过滤,ai客服,机器翻译等等等等,就像这几年越来越火有成为BAT之后第四极的今日头条,为什么能够为每个人推送不同的感兴趣的内容,这里少不了机器学习的功能,当然也包括NLP.
  
  想入门NLP,上网一搜,搜到的多是些具体算法的讲解,或者某些框架的使用,要么就是上来就一顿推荐看某某书某某论文或者讲义.从个人经验的角度来讲,这种方法其实不适合大多数人,因为在初期,学的东西枯燥无味又过于细节,又没有即时的反馈,学习热情很容易就消减了.
  
  初期的时候对要学习的东西的整体概况,框架全貌,基本流程,有个基本了解,然后快速上手,再慢慢地去填充细节.这里强推数学之美,google一下蛮容易下载到的.即便你对机器学习都一无所知,这本书的大部分内容应该也能看懂.这本书会让你对机器学习,自然语言处理的一些基础原理有个大概的了解.
  
  说回NLP,早期的时候发展的其实并不好.最早的时候分为两个派别,一派是语法语义分析派,一派是统计学派.
  
  举个简单的例子,以分析"我爱北京天安门"为例
  
  前者的思路是分析出"这是一个主谓宾结构,主语是‘我’,谓语是‘爱’,宾语是‘北京天安门’",我知道‘爱’是什么意思,知道‘北京天安门’是个地名.那么这句表达的意思也就知道了.
  
  后者的思路是从大量的文本中找出相似的句子,比如我事先人工搜集了1000个文本,我们人工分析出“我爱xxx,我喜欢xxx,去北京天安门”等等类似的文本,人工标注这些文本,知道这种句子表达的是一种正面的情绪,表达喜欢某个人/地点/事物等. 那么我通过比较,就知道了“我爱北京天安门”表达的意思大概率也是我喜欢某个地方,这个地方叫天安门.
  
  早期的时候语法分析派发展的比较好,但是很快就遇到了瓶颈,因为语法太TM复杂了,词的二义性也很多,根本分析不明白.统计学派发展的不好,很好理解,以这种思路来做NLP,势必要对语料库(也就是上面例子里的那1000个文本)的数量有要求,数量越多越好,早期的时候是没有这种条件的.随着计算机的发展,数据量的增长,统计学派越来越体现出其优势,这就是我们今天的NLP处理的思路:根据大量的已有的文本(语料库),基于统计学,基于概率,去推测待预测文本的最大可能的含义.
  
  如果上面这个"我爱天安门"的例子让你困惑,不要怀疑自己,一定是我的例子举得还不够好,再一次建议去看看数学之美.可以看看第二章:从规则到统计.
  
  书归正传:
  
  NLP笼统地说:可以分为4个部分
  
  文本清洗
  
  分词
  
  word2vec
  
  上算法对文本做分析
  
  拿到一个文本,首先要做清洗,比如你用爬虫爬一个电影评论,你爬下来的内容是html格式的,其中你真正要的可能就是评论的部分,那你可能会用到beatifulsoup这个库,用python写过爬虫的应该很熟悉了.
  
  好,现在我们拿到干净的文本了,我们要把词分割出来,比如"我爱北京天安门",要分割出我,爱,北京,天安门这几个词.英文的分词好分一点,因为词和词之间有空格.这一步我们通常也是用现成的工具,英文就nltk,中文就结巴分词.都挺有名的.
  
  好,现在我们已经拿到一堆一堆的词了,我们要把这些词转换成相应的向量,用向量表示出来.我们用一个例子来说明这一步做的是什么.
  
  >>> from sklearn.feature_extraction.text import CountVectorizer
  
  >>> corpus = [
  
  ...     'This is the first document.',
  
  ...     'This document is the second document.',
  
  ...     'And this is the third one.',
  
  ...     'Is this the first document?',
  
  ... ]
  
  >>> vectorizer = CountVectorizer()
  
  >>> X = vectorizer.fit_transform(corpus)
  
  >>> print(vectorizer.get_feature_names())
  
  ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
  
  >>> print(X.toarray())
  
  [[0 1 1 1 0 0 1 0 1]
  
  [0 2 0 1 0 1 1 0 1]
  
  [1 0 0 1 1 0 1 1 1]
  
  [0 1 1 1 0 0 1 0 1]]
  
  可以看到我们先统计出文本中有几种词,比如上面例子.corpus中一共涉及到  ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']这9种词,那么我们就把每一句话都转化为一个9个特征的样本,其中特征的值就是该特征出现的次数.比如第二句中document出现了两次,is一次,second一次.....,那么第二句的向量化表示就是[0 2 0 1 0 1 1 0 1]。这就是所谓的词频TF:Term Frequency.
  
  但是,问题来了!
  
  考虑这样一个句子:"我想你,我喜欢你,我爱你,我要向你求婚!",分完词以后,得到我/你/爱/喜欢/想/求婚.  ‘我’,‘你’出现了很多次,但你能说这句话的重点在‘我’‘你’吗?这句的重点明显在‘爱’‘求婚’.
  
  知识点来了:TF-IDF是Term Frequency -  Inverse Document Frequency的缩写,即“词频-逆文本频率”
  
  概括来讲, IDF用来反映词的重要性.IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低。比如上面例子里,‘我’‘你’重复了太多遍,你可以理解为表白的人废话有点多.所以‘我’,‘你’的IDF就低,‘求婚’的IDF更高.
  
  下面给出IDF和TF-IDF的计算公式:
  
  IDF(x)=logN+1N(x)+1+1
  
  IDF(x)=logN+1N(x)+1+1
  
  TF−IDF(x)=TF(x)∗IDF(x)
  
  TF−IDF(x)=TF(x)∗IDF(x)
  
  其中,N代表语料库中文本的总数,而N(x)代表语料库中包含词xx的文本总数。TF(x)指词xx在当前文本中的词频.
  
  stackoverflow上关于sklean中具体计算tf-idf的过程的回答详情请戳这里.   sklearn的官方文档戳这里  以上两个link有兴趣可以看看.
  
  好,到了这一步,文本数据就已经被我们转换为M*N的矩阵了.代表M个文本. 下面就该上什么算法就上什么算法吧.
  
  说了这么多,来实战看看吧.完整代码戳这里.
  
  关于kaggle上这个比赛的描述及数据下载具体见这里. 这边我简单介绍一下,labeledTrainData.tsv里记录了各种电影评论,已经标明了是正面的评价还是负面的,testData.tsv里记录了各种评论,我们需要根据这些评论去判断这是一个正面的还是负面的评价.
  
  1.文本清洗,分词
  
  复制代码
  
  import re
  
  from bs4 import BeautifulSoup
  
  def review_to_wordlist(review):
  
  '''
  
  Meant for converting each of the IMDB reviews into a list of words.
  
  '''
  
  # First remove the HTML.
  
  review_text = BeautifulSoup(review).get_text()
  
  # Use regular expressions to only include words.
  
  review_text = re.sub("[^a-zA-Z]"," ", review_text)
  
  # Convert words to lower case and split them into separate words.
  
  words = review_text.lower(www.gouyiflb.cn).split()
  
  # Return a list of words
  
  return(words)
  
  traindata = []
  
  for i in range(0,len(train['review'])):
  
  traindata.append(" ".join(review_www.mcyllpt.com_wordlist(train['review'][i])))
  
  testdata = []
  
  for i in range(0,len(test['review'])):
  
  testdata.append(" ".join(review_www.thd178.com to_wordlist(test['review'][i])))
  
  复制代码
  
  2.词的向量化word2vec
  
  这里,我们没有使用大名鼎鼎的google的word2vec库,我们就用sklearn中的TfidfVectorizer
  
  复制代码
  
  from sklearn.feature_extraction.text import TfidfVectorizer
  
  tfv = TfidfVectorizer(stop_words = 'english')
  
  X_all = traindata + testdata
  
  tfv.fit(X_all)
  
  X_all = tfv.transform(X_all)
  
  复制代码
  
  这里涉及到一个stopwords的概念,即有些词我们认为对我们理解语义是无关紧要的,比如英文里的the,to 中文里的的地得...这种词我们就叫做stopwords,在做向量化的时候我们不管这些词.
  
  3.采用逻辑回归 做模型训练
  
  复制代码
  
  from sklearn.linear_model import LogisticRegression
  
  log_reg = LogisticRegression()
  
  log_reg.fit(X_train,y_train)
  
  predict_result = log_reg.predict(X_test)
  
  result_df = pd.DataFrame(data= www.tygj178.com{"www.michenggw.com id":test["id"], "sentiment":predict_result})
  
  result_df.to_csv("log_reg.csv",index=False)
  
  复制代码
  
  最终我们取得了0.88的准确率.
  
  总结一下:
  
  你需要一个学习环境.  建议直接安装anaconda。已经帮你装好了大部分你可能用到的机器学习包.
  
  python   python语法需要有基本了解.不会的话就搜一搜吧,网上教程大把.对于有编程基础的朋友,入门很容易.
  
  pandas/numpy用法要有个基本了解.可以跟着https://www.kaggle.com/learn/overview学习.
  
  sklearn  在刚开始的时候可以先不用太注重各种算法背后的原理.先学着用起来.等能入门了以后,再不断深化自己对各种算法的理解,这样才能更好地选择合适的算法,合适的参数.
  
  去kaggle找些比赛动起手来,实战起来.
  
  以上就是机器学习快速入门的学习路径,结合本文说的内容,也就算是nlp的快速入门的内容了,希望能帮到大家.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值