【零基础成为 AI 解梦大师秘笈】Day27 - 周易解梦之人工智慧(8)

人工智慧8

前言

系列文章简介

大家好,我们是 AI . FREE Team - 人工智慧自由团队,这一次的铁人赛,自由团队将从0到1 手把手教各位读者学会 (1)Python基础语法 (2)Python Web 网页开发框架 – Django (3)Python网页爬虫 – 周易解梦网 (4)Tensorflow AI语言模型基础与训练 – LSTM (5)实际部属AI解梦模型到Web框架上。

为什麽技术要从零开始写起

自由团队的成立宗旨为开发AI/新科技的学习资源,提供各领域的学习者能够跨域学习资料科学,并透过自主学习发展协杠职涯,结合智能应用到各式领域,无论是文、法、商、管、医领域的朋友,都可以自由的学习AI技术。

资源

AI . FREE Team 读者专属福利 → Python Basics 免费学习资源

实作part-1

今天将带大家实作NLP前段,处理资料的部分

资料集

一开始先下载资料集

!git clone https://github.com/ken19980727/emoji.git

输出

Cloning into 'emoji'...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.

下载好後,应该会在左边的side bar

在解压缩

!unzip /content/emoji/data.zip

在检查side bar

这就是我们的资料集,虽然说很多个资料,但是我们只会用到两个

下载&导入套件

这个套件是将符号变成实际的表情符号,待会会有实际的操作和详细说明

!pip install emoji 
Collecting emoji
  Downloading https://files.pythonhosted.org/packages/ff/1c/1f1457fe52d0b30cbeebfd578483cedb3e3619108d2d5a21380dfecf8ffd/emoji-0.6.0.tar.gz (51kB)
     |████████████████████████████████| 51kB 1.8MB/s 
Building wheels for collected packages: emoji
  Building wheel for emoji (setup.py) ... done
  Created wheel for emoji: filename=emoji-0.6.0-cp36-none-any.whl size=49716 sha256=b0cb86566420299a4f4558c19a9ac6f00d33c57c3647d8e08188f7932f2f3af7
  Stored in directory: /root/.cache/pip/wheels/46/2c/8b/9dcf5216ca68e14e0320e283692dce8ae321cdc01e73e17796
Successfully built emoji
Installing collected packages: emoji
Successfully installed emoji-0.6.0

其他套件

import numpy as np
import emoji
import matplotlib.pyplot as plt
import pandas as pd
import emoji
from sklearn.metrics import confusion_matrix
from emoji import emojize

除了emoji之外其他的大家一定都不陌生

再来,我们利用pd.read_csv将csv资料读进来

data = pd.read_csv('/content/data/emojify_data.csv',names = ['sentences','labels',3,4])
data_dev = pd.read_csv('/content/data/tesss.csv',names = ['sentences','labels'])

我们读进两笔data,第一个为train用,第二个valid用,而括号的第一栏是路径,第二个是蓝为名称

输出

data_dev

读取资料集的长度

X_train = [i for i in data['sentences']]
y_train = [i for i in data['labels']]
X_valid = [i[:-1] for i in data_dev['sentences']] # clean the data
y_valid = [i for i in data_dev['labels']]
print(f'X_train length : {len(X_train)}.')
print(f'y_train length : {len(y_train)}.')
print(f'X_valid length : {len(X_valid)}.')
print(f'y_valid length : {len(y_valid)}.')

可以发现X_valid我取每个句子并去掉最後一个字元,原因是因为这笔资料保留的\t跳脱字元,但我们不需要,所以去除(可以自己print出来)

输出

X_train length : 183.
y_train length : 183.
X_valid length : 56.
y_valid length : 56.

表情符号

前面有提到emoji,他是可以将str转成可视的表情符号

emoji_dictionary = {"0": "\u2764\uFE0F",    # :heart: prints a black instead of red heart depending on the font
                    "1": ":baseball:",
                    "2": ":smile:",
                    "3": ":disappointed:",
                    "4": ":fork_and_knife:"}

def label_to_emoji(label):
    return emoji.emojize(emoji_dictionary[str(label)])
idx = 3
print(f'before emoji convert : \n{X_train[idx]} {y_train[idx]}')
print('')
print(f'after emoji convert : \n{X_train[idx]} {label_to_emoji(y_train[idx])}')

输出

before emoji convert : 
throw the ball 1

after emoji convert : 
throw the ball ⚾

想不到hackmd也有表情符号XD,我原本打算用截图的

差点忘记介绍,可以发现我们总共有5类的答案

print(emoji.emojize('\u2764\uFE0F'))
print(emoji.emojize(':baseball:'))
print(emoji.emojize(':smile:', use_aliases=True))
print(emoji.emojize(":disappointed:", use_aliases=True))
print(emoji.emojize(':fork_and_knife:'))
❤️
⚾
?
?
?

当初资料集的说明是这样的(大家可以自己打开csv来看)

来看一下每个句子(大家可以调整idx)

idx = 2
print(f'before emoji convert : \n{X_train[idx]} {y_train[idx]}')
print('')
print(f'after emoji convert : \n{X_train[idx]} {label_to_emoji(y_train[idx])}')

输出

before emoji convert : 
I am upset 3

after emoji convert : 
I am upset ?

one hot encoding

再用one hot之前,先介绍np.eye()这个funciton

np.eye(5)
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

这个function可以产生一个对称的n*n的矩阵

因此利用其特性来做one hot encoding,方法有很多种,大家可以来brainstorm一下

def convert_to_one_hot(Y, C):
    Y_oh = [np.eye(C)[i] for i in Y]
    return Y_oh
y_oh_train = convert_to_one_hot(y_train, C = 5)
y_oh_valid = convert_to_one_hot(y_valid, C = 5)
idx = 7
print(f'train : {y_train[idx]} is converted into one hot : {y_oh_train[idx]}')
print(f'valid : {y_valid[idx]} is converted into one hot : {y_oh_valid[idx]}')

输出

train : 3 is converted into one hot : [0. 0. 0. 1. 0.]
valid : 2 is converted into one hot : [0. 0. 1. 0. 0.]

这样就算转换完成了

文字转数字

之前有提到说,文字也要转成index(索引)

我们先建立一个words来存入全部的字(不重复)

words = []
for i in X_train:
  for j in i.split():
    if j not in words:
      words.append(j)
words.append('unk')
words.append('pad')
len(words)
335

可以看到总共有333+2个字,至於unkpad待会儿会用到

建立一个字典,让每个字都有对应的indexword2idx,每个index也有对应的字idx2word,方便查表

word2idx = {w: i for i, w in enumerate(words)}
idx2word = {i: w for i, w in enumerate(words)}
word2idx['unk']
idx = 24
print(f'before split : {X_train[idx]}')
print('')
print(f'after split : {[word2idx[j] for j in X_train[idx].split()]}')

输出

before split : family is all I have

after split : [68, 2, 69, 7, 47]

建立字典後,可以将全部的句子转换了

X_train_int = [[word2idx[j] for j in i.split()] for i in X_train]
X_valid_int = []
for i in X_valid:
  x_val_ = []
  for j in i.split():
    if j in words:
      x_val_.append(word2idx[j])
    else:
      x_val_.append(word2idx['unk'])
  X_valid_int.append(x_val_)

这里可以看到X_train_int没有复杂的判断式,但为何X_valid_int要呢,因为当初在建字典和辞库时,是以X_train的为主,所以X_valid_int可能会有字典和辞库没有的字,遇到这种字一律使用unk

这时候就会有热心的读者好奇,变unk会不会影响training的结果

其实不太大,就算你把X_valid的词也丢进字典,但是在训练时,其实不会training到这类的资料,所以是一样的

填充句子

之前有说过,如果要用gpu加速的话,就要将资料全部转成长度一致的矩阵

因此我们来看一下最长的句子长度

tr_maxLen = len(max(X_train_int, key=len))
print(f'train max length : {tr_maxLen}')
va_maxLen = len(max(X_valid_int, key=len))
print(f'valid max length : {va_maxLen}')

输出

train max length : 10
valid max length : 8

最长的句子长度为10

def padding(X,maxlen):
  for i in X:
    for pad in range(maxlen-len(i)):
      i.append(word2idx['pad'])
  return X
  
X_train_int = padding(X_train_int,tr_maxLen)
X_valid_int = padding(X_valid_int,tr_maxLen)

我们将最长的长度设为tr_maxLen,让tr_maxLen减去每个句子的长度,之间的差就是要填充的长度,我们再将word2idx['pad']填入

print(f'train max length : {len(max(X_train_int, key=len))}')
print(f'valid max length : {len(max(X_valid_int, key=len))}')

这时应该每个句子长度都一致

train max length : 10
valid max length : 10

先介绍到这里,NLP的资料处理是非常复杂且多元的,基本上资料处理到这就可以丢进模型了,剩下的我们下篇介绍

想更深入认识 AI . FREE Team ?

自由团队 官方网站:https://aifreeblog.herokuapp.com/
自由团队 Github:https://github.com/AI-FREE-Team/
自由团队 粉丝专页:https://www.facebook.com/AI.Free.Team/
自由团队 IG:https://www.instagram.com/aifreeteam/
自由团队 Youtube:https://www.youtube.com/channel/UCjw6Kuw3kwM_il39NTBJVTg/

文章同步发布於:自由团队部落格
(想看更多文章?学习更多AI知识?敬请锁定自由团队的频道!)


<<:  [Day0] 参赛初衷

>>:  【Day27】建立一个 QA Bot

Day 15 -资料查询语言 INNER JOIN!

INNER JOIN (内部连接) 为等值连接,必需指定等值连接的条件,而查询结果只会返回符合连接条...

Day06 Flutter 启动流程

首先我们先来看看Flutter 启动流程以及Flutter 和 Native 通信的原理 参考:Fl...

自动化测试,让你上班拥有一杯咖啡的时间 | Day 15 - 设定环境变量

此系列文章会同步发文到个人部落格,有兴趣的读者可以前往观看喔。 在测试时,当要测试的环境有许多种,...

Day 07:大人更要懂选择-BootstrapVue 部分引入

上篇透过简单的 vue add 指令就完成了 BootstrapVue 安装和引入,其引入 boot...

Day 5. 怎麽开始Vue起来

Vue 的官网提供了三种不同的方式供我们使用,我们可以依照自己需求选择不同的方式开始我的与vue的旅...