### 1.数据预处理模型

(1)导包

```import re
import numpy as np
import pandas as pd
import warnings
from bs4 import BeautifulSoup
from gensim.models.word2vec import Word2Vec
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.linear_model import LogisticRegression
import nltk
import matplotlib.pyplot as plt
import itertools
from tqdm import tqdm```

#### (2)读取数据

```# 用pandas读入训练数据
print('Number of reviews: {}'.format(len(df)))
print(df)```

(3)数据预处理

```# 1.去掉HTML标签的数据,获取review这一列的100行数据
example = BeautifulSoup(df['review'][1000], 'html.parser').get_text()
# 2.去掉标点符号
example_letters = re.sub(r'[^a-zA-Z]', ' ', example)
words = example_letters.lower().split()
# 3.获取停用词
stopwords = {}.fromkeys([ line.rstrip() for line in open('../movie_data/stopwords.txt')])
# 获得停用词之后,使用set集合去重复
eng_stopwords = set(stopwords)
# 4.去除停用词
words_nostop = [w for w in words if w not in stopwords]```

#### (4)清洗数据

```# 这个清洗数据的函数其实就是去标点，去停用词，大写变小写
def clean_text(text):
text = BeautifulSoup(text, 'html.parser').get_text()
text = re.sub(r'[^a-zA-Z]', ' ', text)
words = text.lower().split()
words = [w for w in words if w not in eng_stopwords]
return ' '.join(words)
# 清洗数据
words=clean_text(df['review'][1000])
# 清洗数据添加到dataframe里
df['clean_review'] = df.review.apply(clean_text)```

（5）分词

```# 建立分词器
warnings.filterwarnings("ignore")
# 获取df中清洗过的一行新数据
review_part = df['clean_review']
# 显示添加clean_review之后的表格样子
# 使用nltk进行分词
def split_sentences(review):
raw_sentences = tokenizer.tokenize(review.strip())
sentences = [clean_text(s) for s in raw_sentences if s]
return sentences
sentences = sum(review_part.apply(split_sentences), [])
print('{} reviews -> {} sentences'.format(len(review_part), len(sentences)))
print（sentence）```

（6）将分词后的句子中的词语全部单个的添加到一个list中

```sentences_list = []
for line in sentences:
sentences_list.append(nltk.word_tokenize(line))
print(sentences_list)```

### 2.word2vec模型模块

#### （1）设置模型需要的参数

```# 设定词向量训练的参数
'''
sentences：可以是一个list
sg： 用于设置训练算法，默认为0，对应CBOW算法；sg=1则采用skip-gram算法。
size：是指特征向量的维度，默认为100。大的size需要更多的训练数据,但是效果会更好. 推荐值为几十到几百。
window：表示当前词与预测词在一个句子中的最大距离是多少
alpha: 是学习速率
seed：用于随机数发生器。与初始化词向量有关。
min_count: 可以对字典做截断. 词频少于min_count次数的单词会被丢弃掉, 默认值为5
max_vocab_size: 设置词向量构建期间的RAM限制。如果所有独立单词个数超过这个，则就消除掉其中最不频繁的一个。每一千万个单词需要大约1GB的RAM。设置成None则没有限制。
workers参数控制训练的并行数。
hs: 如果为1则会采用hierarchica·softmax技巧。如果设置为0（defau·t），则negative sampling会被使用。
negative: 如果>0,则会采用negativesamp·ing，用于设置多少个noise words
iter： 迭代次数，默认为5
'''
num_features = 300    # Word vector dimensionality
min_word_count = 40   # Minimum word count
num_workers = 4       # Number of threads to run in parallel
context = 10          # Context window size
model_name = '{}features_{}minwords_{}context.model'.format(num_features, min_word_count, context)```

#### （2）训练模型

```# 9.训练模型
model=Word2Vec(sentences_list,workers=num_workers,vector_size=num_features, min_count = min_word_count, window = context)
model.init_sims(replace=True)
# 保存模型
model.save("F:\python\word2vect\model\demo3_model")
# 测试
# 计算这几个词的相似度,把最不相关的返回出来
print(model.wv.doesnt_match(['man','woman','child','kitchen']))
# 计算boy 相关的词
print(model.wv.most_similar("boy"))```

### 3.将trian，test数据转换成向量

```# 定义一个数据清洗函数清洗我们需要用来训练的数据
def to_review_vector(review):
global word_vec
review = clean_text(review, remove_stopwords=True)
# words = nltk.word_tokenize(review)
word_vec = np.zeros((1, 300))
for word in review:
# word_vec = np.zeros((1,300))
if word in list(model.wv.key_to_index):
word_vec += np.array([model.wv[word]])
# print (word_vec.mean(axis = 0))
# 把300维的向量挨个挨个的放到其中,并且标记上序号
return pd.Series(word_vec.mean(axis=0))
# 下面这句话是pandas的一个特殊的函数,将review这个一列的数据循环放到to_review_vector中
train_data_features = df.review.apply(to_review_vector)
print("输出叠加之后的词向量")

`X_train, X_test, y_train, y_test = train_test_split(train_data_features,df.sentiment,test_size = 0.2, random_state = 0)`

### 4.线性回归模块

```# 获得逻辑回归模型
LR_model = LogisticRegression()
# 将训练集放到模型中训练
LR_model = LR_model.fit(X_train, y_train)
# 将测试数据放到其中测试
y_pred = LR_model.predict(X_test)
# 将真实值和预测值放到其中得到一个混淆矩阵
cnf_matrix = confusion_matrix(y_test,y_pred```

### 5.可视化数据结果

```def plot_confusion_matrix(cm, classes,
title='Confusion matrix',
cmap=plt.cm.Blues):
"""
This function prints and plots the confusion matrix.
"""
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=0)
plt.yticks(tick_marks, classes)
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, cm[i, j],
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label')
# Plot non-normalized confusion matrix
class_names = [0,1]
plt.figure()
plot_confusion_matrix(cnf_matrix, classes=class_names,title='Confusion matrix')
plt.show()```

### 评估模型

TP：(实际为正例，预测也为正例) 实际为男生，预测为男生；

FP：(实际为负例，预测为正例) 实际为女生，预测为男生；

FN：(实际为正例，预测为负例) 实际为男生，预测为女生；

TN：(实际为负例，预测也为负例) 实际为女生，预测为女生；

F1=(2 x precision x recall)/(precision+recoall)

F1值是召回率和精确度的一个平均计算方式

```print("accuracy(test): ", (cnf_matrix[1,1]+cnf_matrix[0,0])/(cnf_matrix[0,0]+cnf_matrix[1,1]+cnf_matrix[1,0]+cnf_matrix[0,1]))
print("precision:",(cnf_matrix[0,0])/(cnf_matrix[0,0]+cnf_matrix[1,0]))
print("Recall metric in the testing dataset: ", cnf_matrix[1,1]/(cnf_matrix[1,0]+cnf_matrix[1,1]))```

```accuracy(test):  0.861
precision: 0.8773930753564155
Recall :  0.8772430668841762```