基于SVM+TensorFlow+Django的酒店评论打分智能推荐系统——机器学习算法应用(含python工程源码)+数据集+模型(二)


在这里插入图片描述

前言

本项目以支持向量机(SVM)技术为核心,利用酒店评论数据集进行了情感分析模型的训练。通过使用Word2Vec生成词向量,该项目实现了一个打分推荐系统,其中服务器端提供数据,而客户端则查询数据。

首先,项目使用了酒店评论数据集,这些评论包括了来自不同用户的对酒店的评价。这些评论被用来训练情感分析模型,该模型能够分析文本并确定评论的情感极性,即正面、负面或中性。

其次,项目使用Word2Vec技术,将文本数据转换为词向量表示。这些词向量捕捉了不同词汇之间的语义关系,从而提高了文本分析的效果。这些词向量可以用于训练模型以进行情感分析。

在服务器端,项目提供了处理和存储酒店评论数据的功能。这意味着评论数据可以在服务器上进行管理、存储和更新。

在客户端,用户可以查询酒店评论数据,并获得关于特定酒店的情感分析结果。例如,用户可以输入酒店名称或位置,并获取该酒店的评论以及评论的情感分数,这有助于用户更好地了解其他人对酒店的评价。

总的来说,本项目基于SVM技术和Word2Vec词向量,提供了一个针对酒店评论情感的分析和打分推荐系统。这个系统可以帮助用户更好地了解酒店的口碑和评价,从而做出更明智的决策。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括Python环境、TensorFlow环境、 安装模块、MySQL数据库。

详见博客

模块实现

本项目包括3个模块:数据预处理、模型训练及保存、模型测试,下面分别给出各模块的功能介绍及相关代码。

1. 数据预处理

详见博客

2. 模型训练及保存

通过训练集训练数据得出模型,使模型进行情感分类。这里,使用训练集和测试集来拟合并保存模型。

1)加载词向量表,并设置训练集和测试集

相关代码如下:

fdir = ''
df = pd.read_csv(fdir + '2000_data.csv')
#导入每一条词向量为x,对应的结果为y
y = df.iloc[:,1].values
x = df.iloc[:,2:].values
#分割训练集和测试集
(x_train,x_test,y_train,y_test)=train_test_split(x,y,test_size=0.2,random_state=1)

2)模型训练并保存

相关代码如下:

#进行模型的训练
clf = svm.SVC(C = 10,kernel='rbf',gamma=0.38,probability = True)#训练
clf.fit(x_train,y_train)
#打印模型在训练集上的准确率
print 'train Accuracy: %.2f'% clf.score(x_train,y_train)
#打印模型在测试集上的准确率
print 'Test Accuracy: %.2f'% clf.score(x_test,y_test)
pred_probas = clf.predict_proba(x)[:,1] #score
fpr,tpr,_ = metrics.roc_curve(y, pred_probas)
roc_auc = metrics.auc(fpr,tpr)
#画出模型的ROC曲线,便于后续分析调整模型
plt.plot(fpr, tpr, label = 'area = %.2f' % roc_auc)
plt.plot([0, 1], [0, 1], 'k--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.legend(loc = 'lower right')
plt.show()
#保存模型
joblib.dump(clf, "my_model_1.m")

3. 模型应用

1)爬取评论

在携程酒店爬取指定酒店ID的评论集。

#爬虫输入网页请求参数,得到相应网页
def getResponse(url,pageindex):
data={"hotelId":1737627,"pageIndex":pageindex,"tagId":0,"pageSize":10,"groupTypeBitMap":2,"needStatisticInfo":0,"order":0,"basicRoomName":"","travelType":1,"head":{"cid":"09031179411625216472","ctok":"","cver":"1.0","lang":"01","sid":"8888","syscode":"09","auth":"","extension":[]}}
    data = json.dumps(data).encode(encoding='utf-8')
    #模拟普通浏览器的方式
     header_dict = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko',"Content-Type": "application/json"}
url_request = request.Request(url=url,data=data,headers=header_dict)
    print("正在采集的是第%d页", %i)
url_response = request.urlopen(url_request)
    return url_response
if __name__ == "__main__":
   #循环爬取所有页数
    for i  in  range(1,434):
    #输入采取网页的地址
		http_response=getResponse("http://m.ctrip.com/restapi/soa2/16765/gethotelcomment?_fxpcqlniredt=09031144211504567945",i)
        data = http_response.read().decode('utf-8')
        dic = json.loads(data) 
        ungz=dic['othersCommentList']
        #网页结构是每页有十条评论
        for k in range(10):
            content=ungz[k]
            comment=content['content']
          #存储到本地文件中
            with open('comment_beiwai.txt', 'a', encoding='UTF-8') as f:
              f.write(json.dumps(comment, ensure_ascii=False) + '\n'+'\n')
#每采集页延迟10s
        time.sleep(10)

#将爬取的评论写入数据库中,使用longtext存储,为节省空间只存储了前一百个字符
def into(path,string):
#连接数据库
    conn = mysql.connector.connect(user='root', password='password', database='grades', use_unicode=True)
    cursor = conn.cursor()
    f = codecs.open(path, 'r', encoding='utf-8')
    f=f.read()
    #删去评论里的换行符,节省存储空间
    f=filter_emoji(f,restr='')
    f=f.replace('\r','')
    f=f.replace('\n','')
    f=f.replace('"',"")
    f=f[0:100]
    print(f)
    
def filter_emoji(desstr,restr=""):
    #过滤表情
    try:
        co = re.compile(u'[\U00010000-\U0010ffff]')
    except re.error:
        co = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF]')
    return co.sub(restr, desstr)
    try:  
        print(string)
        print(f)
#插入酒店和分数到数据库
  cursor.execute('insert into grades (hotel,date) values(%s,%s)',[string,f]) conn.commit()  
    except:  
#插入不成功回滚,并且报错
        conn.rollback()
        print("fail")

2)酒店打分

将爬取的评论用模型训练时处理数据的方式进行同样的处理,相关代码如下:

import warnings
warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')  #忽略警告
import logging
import os.path
import codecs,sys
import numpy as np
import pandas as pd
import gensim
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn import svm
from sklearn import metrics
from sklearn.externals import joblib
import collections
import mysql.connector
import jieba
import jieba.analyse
import string,re
def prepareData(sourceFile,targetFile):
    f = open(sourceFile, 'r', encoding='utf-8')
    target = ""
    print( 'open source file: '+ sourceFile)
    print ('open target file: '+ targetFile)
    lineNum = 1
    line = f.readline()
    while line:
        print( '---processing ',lineNum,' article---')
        line = clearTxt(line)
        seg_line = sent2word(line)
        target.writelines(seg_line + '\n')       
        lineNum = lineNum + 1
        line = f.readline()
    f.close()
	return target
#清洗文本
def clearTxt(line): 
        if line != '':
          line = line.strip()
          pun_num = string.punctuation + string.digits
          intab = pun_num
          outtab = " "*len(pun_num)
          #去除所有标点和数字
          trantab = str.maketrans(intab, outtab)
          line = line.translate(trantab)
          #去除文本中的英文和数字
          line = re.sub("[a-zA-Z0-9]", "", line)
          #去除文本中的中文符号和英文符号
          line = re.sub("[\s+\.\!\/_,$%^*(+\"\';:“”.]+|[+——!==°【】,÷。??、~@#¥%……&*()]+", "", line)
        return line
#文本切割
def sent2word(line):
    segList = jieba.cut(line,cut_all=False)    
    segSentence = ''
    for word in segList:
        if word != '\t':
            segSentence += word + " "
    return segSentence.strip()
def stopWord(source,stopkey):
    sourcef = source
    lineNum = 1
    line = sourcef.readline()
	target=""
    while line:
        print ('---processing ',lineNum,' article---')
        sentence = delstopword(line,stopkey)
        #print sentence
        target.writelines(sentence + '\n')       
        lineNum = lineNum + 1
        line = sourcef.readline()
   return target
#构建特征词向量
def getWordVecs(wordList,model):
    vecs = []
    for word in wordList:
        word = word.replace('\n','')
        #print word
        try:
            vecs.append(model[word])
        except KeyError:
            continue
    return np.array(vecs, dtype='float')
    #构建文档词向量 
def buildVecs(input,model):
    fileVecs = []
    with codecs.open(filename, 'rb', encoding='utf-8') as contents:
        for line in contents:
            logger.info("Start line: " + line)
            wordList = line.split(' ')
            vecs = getWordVecs(wordList,model)
            #print vecs
            #sys.exit()
            #for each sentence, the mean vector of all its vectors is used to represent this sentence
            if len(vecs) >0:
                vecsArray = sum(np.array(vecs))/len(vecs) # mean
                #print vecsArray
                #sys.exit()
                fileVecs.append(vecsArray)
    return fileVecs   
if __name__ == '__main__':   
    sourceFile = '../comment.txt'
	#分词
    result1=prepareData(sourceFile)
	stopkey = [w.strip() for w in result1.readlines()]
	#去除停用词
	result2=stopWord(source,stopkey)
	program = os.path.basename(sys.argv[0])
    logger = logging.getLogger(program)    logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s',level=logging.INFO)
    logger.info("running %s" % ' '.join(sys.argv))
	#加载模型
    fdir = 'E:\word2vec\word2vec_from_weixin\word2vec'
    inp = fdir + '\word2vec_wx'
    model = gensim.models.Word2Vec.load(inp)
    fdir1 = 'C:\Users\zhoua\\test_a_review'
	#开始构建词向量表
    output = buildVecs(result2,model)
    Y = np.ones(len(posInput))
    X = output[:]
    X = np.array(X)
    df_x = pd.DataFrame(X)
    df_y = pd.DataFrame(Y)
    data = pd.concat([df_y,df_x],axis = 1)
    data.to_csv(fdir1 + '\\comment_data.csv')
#加载模型,统计模型的0与1占比,根据一定规则进行打分,并且将分数存入数据库
clf = joblib.load("my_model_1.m")
def countgrades(filename):
    df = pd.read_csv(filename)
    x = df.iloc[:,2:]
    predict=clf.predict(x)
    pred_probas = clf.predict_proba(x)
    x=collections.Counter(predict)
    #统计0和1 的比例,并给出分数
    x0=x[0]
    x1=x[1]
    grades=100*x1/(x1+x0)
    return grades
if __name__=="__main__":
    #存入数据库
    conn = mysql.connector.connect(user='root', password='zhou19990806', database='grades', use_unicode=True)
    cursor = conn.cursor()
    filename1="comment_data.csv"
    grades1=countgrades(filename1)
    cursor.execute('insert into grades grades=%s where hotel=%s', (int(grades1),'南京全季酒店'))
    print '南京全季酒店的分数是: %.2f'% grades1
    filename2="comment_bupt_data.csv"
    grades2=countgrades(filename2)
    cursor.execute('insert into grades grades=%s where hotel=%s', (int(grades2),'北邮科技酒店'))
    print '北邮科技酒店的分数是: %.2f'% grades2
    filename3="comment_pku_data.csv"
    grades3=countgrades(filename3)
    cursor.execute('insert into grades grades=%s where hotel=%s', (int(grades3),'北大博雅酒店'))
    print '北大博雅酒店的分数是: %.2f'% grades3
    filename4="comment_beiwai_data.csv"
    grades4=countgrades(filename4)
    cursor.execute('insert into grades grades=%s where hotel=%s', (int(grades4),'鹤佳酒店'))
    print '鹤佳酒店的分数是: %.2f'% grades4
    filename5="comment_beijiao_data.csv"
    grades5=countgrades(filename5)
    cursor.execute('insert into grades grades=%s where hotel=%s', (int(grades5),'乐家服务酒店'))
    print '乐家服务酒店的分数是: %.2f'% grades5
    conn.commit()
    cursor.close()

3)界面设置

本部分输入指定名称,在数据库中搜索数据,调出酒店分数和排名。生成Django项目,包括hello.htmlview.pysettings.pyurls.py

(1)创建Django项目

进入命令行环境,输入命令,生成helloworld项目:

django-admin startproject HelloWorld

在HelloWorld目录下创建templates,并建立hello.html文件。本部分包括界面文件和处理提交数据,从数据库中搜索给出相关信息。

(2)html布局文件

相关代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>酒店分数查询</title>
<style type="text/css">
<!—表单的样式-->
 #bg{
       width:700px;
       height:400px;
	   margin:0 auto;
   }
   .bordered {
            border-style:solid;
            width:600px;
            height:300px;
        }
</style>
</head>
<body>
<!—查询框-->
<body align="center"/>
<body style="color:black"/>
<br/><br/><br/><br/> &nbsp;&nbsp;&nbsp;&nbsp;
<div id="bg" class="bordered">
<fieldset>
<legend><h1 align="center" >查询页面</h1></legend>
    <form action="/search-post" method="post">
	        {% csrf_token %}
       <p> <strong>酒店名</strong>&nbsp;<input type="text" name="q"></p>
	    <br/>
        <p><input type="submit"value="查询"style="width:70px;height:30px" ></p>
    </form>
	<!—预留内容,展示输出内容-->
 </fieldset>
    <p id="view">{{ rlt1 }}</p>
	<p id="view">{{ rlt2 }}</p>
<div>
</body>
</html>
(3)后台调用数据库

相关代码如下:

import mysql.connector
#接收POST请求数据
def search_post(request):
#连接数据库
	conn = mysql.connector.connect(user='root', password='password', database='grades', use_unicode=True)
	cursor = conn.cursor()
	ctx ={}
	if request.POST:
        #获取表单中填入内容
		res=request.POST['q']
        #在数据库中搜索并展示结果
		sql="SELECT * FROM grades WHERE hotel=%s"
		cursor.execute(sql,(res,))
		results = cursor.fetchall()
		results=results[0]
		grade=results[1]
		data=results[2]
        #展示该酒店的打分
		ctx['rlt1'] = "分数:"+str(grade)
        #展示该酒店的评论
		ctx['rlt2']="评论:"+str(data)+"......"
		cursor.close()
         #返回响应内容
	return render(request, "hello.html", ctx)
(4)Django项目中其余两个重要文件

相关代码如下:

#Django中自动生成的urls.py文件,将提交动作与后台响应函数绑定
from django.conf.urls import url
from . import view
urlpatterns = [
    url(r'^search-post$', view.search_post),
]
#Django中自动生成的settings.py文件
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = '_$&5uv^$+5@$*&&%9c+0+-c7v8%dmsj(ycnq=sh34a_)s+7n=p'
DEBUG = True
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'HelloWorld.urls'
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR+"/templates",],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
WSGI_APPLICATION = 'HelloWorld.wsgi.application'
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'

相关其它博客

基于SVM+TensorFlow+Django的酒店评论打分智能推荐系统——机器学习算法应用(含python工程源码)+数据集+模型(一)

基于SVM+TensorFlow+Django的酒店评论打分智能推荐系统——机器学习算法应用(含python工程源码)+数据集+模型(三)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡说人工智能

谢谢老板打赏,祝您天天好心情!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值