Node.js 如何创建情感分析应用程序

Node.js 如何创建情感分析应用程序

情感分析是一种自然语言处理技术,用于确定文本数据中的情绪。它通常用于了解客户需求、研究用户反馈中的产品情绪、决策等。

情感分析的类型:

  1. 细粒度情感分析: 当我们希望在结果中获得极性精度时使用。在这种类型的分析中,我们将结果分为非常消极、消极、积极、非常积极和中性等极性类别。
  2. 基于情感的情感分析: 此类型的分析检测到不同类型的情感,如快乐、愤怒和悲伤。
  3. 基于方面的情感分析: 如果我们想要知道用户以正面或负面方式提及的特定方面或特征,那么就会使用这种类型的分析。例如,用户评论说这台笔记本电脑非常好,但是电池非常差,所以我们的基于方面的算法将能够确定有关电池的负面意见,而不是整个产品。

方法: 本文中,我们将使用Node.js创建一个情感分析应用程序,该应用程序分析用户反馈中的文本数据,并结合细粒度和基于情感的情感分析方法来获取用户情感。我们将使用AFINN(用于赋予英文单词价值的字典,值为介于负五(负面)到正五(正面)之间的整数),该字典包含在我们将在应用程序中包含为npm软件包的自然语言处理库中。

下面是逐步实施的步骤:

安装Node.js 请访问以下链接下载并安装Node.js下载Node.js。我们将通过执行以下命令来确保我们的系统中安装了Node:

node -v
JavaScript

步骤1: 创建一个单独的文件夹,并使用终端或命令提示符导航到该文件夹并进入该文件夹。

cd <your folder location>
JavaScript

步骤2: 在终端中输入以下命令来创建 package.json:

npm init -y
JavaScript

步骤3: 安装以下依赖项。

  1. Express: Express是一个简洁灵活的Node.js Web应用程序框架,为Web和移动应用程序提供强大的功能集
  2. Natural: 一个支持大多数NLP算法的Node.js软件包
  3. Stopword: 一个允许您从输入文本中删除停用词的Node.js软件包
npm install --save express natural stopword
JavaScript

项目结构: 项目结构将如下所示:

Node.js 如何创建情感分析应用程序

步骤4: 首先,我们将创建一个基本的HTTP服务器。

server.js

// Import packages below 
const express = require("express"); 
const natural = require("natural"); 
const stopword = require("stopword"); 
  
// Port and Host 
const port = 5500; 
const host = "127.0.0.1"; 
  
// Initialise our app 
let app = express(); 
  
// Include Routes 
  
// Listen 
app.listen(port,host,()=>{ 
    console.log("Server is running..."); 
}); 
JavaScript

步骤5: 创建一个新的路由并将其路径设置为 /feedback。 当用户将反馈内容包含在请求体中通过 POST 请求发送到我们的路由时,他们应该收到一个包含其情感分析的响应。

server.js

// Include Routes 
  
app.post("/feedback",(request,response)=>{ 
    const { feedback } = request.body; 
});
JavaScript

步骤6: 我们从用户那里得到的数据充斥着许多错误和噪音,我们需要在分析过程中对其进行过滤。为了提取有意义的情感或信息,我们需要对用户的文本数据进行筛选,这个过程叫做数据过滤。

过滤步骤:

  1. 为了保持数据的结构,我们将所有单词转换为标准形式。例如,You’re -> You are。
  2. 所有文本数据将被转换为小写形式,因为我们希望我们的分析算法将brilliant和BriLLiaNt视为相同单词。
  3. 删除特殊字符和数值标记,因为它们只是噪音元素,对我们的结果的贡献将为零。
  4. 分词是过滤过程中的关键步骤之一,这是将文本拆分为有意义单元的过程。我们将使用我们引入的Natural包中的WordTokenizer。
  5. 删除停用词,因为这些词对用户的情感没有任何贡献,一些停用词的示例包括:but, a, or,等等。
  6. NLP中的单词归一化过程中,预计使用词干算法将单词减少为其根词。例如,“training”,“trained”变为“train”。调用时,Natural库中的Sentiment Analyzer可以提供词干器作为参数。在分析过程中,个别单词将被转换为其根本形式。

    使用Natural进行情感分析: Natural库中的情感分析算法使用了一个评分的英语词汇表AFINN,该词汇表以介于负五(消极)和正五(积极)之间的整数对英语单词进行了评估。算法运作方式是计算一个文本中每个词的极性的总和,并将其与句子长度归一化。如果算法返回一个负值,那意味着情感是消极的,如果返回一个正值,则意味着情感是积极的。零值表示中性情绪。

我们将创建一个名为/feedback的路由,用于收集用户的反馈并实现我们的分析。名为convertToStandard的函数将把我们的所有数据转换为标准形式。convertTolowerCase函数将把我们的所有数据转换为小写形式。removeNonAlpha函数将删除非字母字符。接下来,我们将使用stopword npm包对我们的数据进行分词和删除停用词。在进行所有这些数据过滤的代码之后,我们将使用Natural包中的SentimentAnalyzer创建一个情感评分。最后,我们将根据我们的分析将这个情感评分作为回应发送给我们的用户。

server.js文件

// Include npm packages 
const express = require("express"); 
const natural = require("natural"); 
const stopword = require("stopword"); 
  
// For conversion of contractions to standard lexicon 
const wordDict = { 
    "aren't": "are not", 
    "can't": "cannot", 
    "couldn't": "could not", 
    "didn't": "did not", 
    "doesn't": "does not", 
    "don't": "do not", 
    "hadn't": "had not", 
    "hasn't": "has not", 
    "haven't": "have not", 
    "he'd": "he would", 
    "he'll": "he will", 
    "he's": "he is", 
    "i'd": "I would", 
    "i'd": "I had", 
    "i'll": "I will", 
    "i'm": "I am", 
    "isn't": "is not", 
    "it's": "it is", 
    "it'll": "it will", 
    "i've": "I have", 
    "let's": "let us", 
    "mightn't": "might not", 
    "mustn't": "must not", 
    "shan't": "shall not", 
    "she'd": "she would", 
    "she'll": "she will", 
    "she's": "she is", 
    "shouldn't": "should not", 
    "that's": "that is", 
    "there's": "there is", 
    "they'd": "they would", 
    "they'll": "they will", 
    "they're": "they are", 
    "they've": "they have", 
    "we'd": "we would", 
    "we're": "we are", 
    "weren't": "were not", 
    "we've": "we have", 
    "what'll": "what will", 
    "what're": "what are", 
    "what's": "what is", 
    "what've": "what have", 
    "where's": "where is", 
    "who'd": "who would", 
    "who'll": "who will", 
    "who're": "who are", 
    "who's": "who is", 
    "who've": "who have", 
    "won't": "will not", 
    "wouldn't": "would not", 
    "you'd": "you would", 
    "you'll": "you will", 
    "you're": "you are", 
    "you've": "you have", 
    "'re": " are", 
    "wasn't": "was not", 
    "we'll": " will", 
    "didn't": "did not"
} 
  
const port = 5500; 
const host = "127.0.0.1"; 
  
let app = express(); 
  
app.use(express.json()); 
app.use(express.urlencoded({ extended: false })); 
app.use("/",express.static(__dirname + "/public")); 
  
  
// Contractions to standard lexicons Conversion 
const convertToStandard = text => { 
    const data = text.split(' '); 
    data.forEach((word, index) => { 
        Object.keys(wordDict).forEach(key => { 
            if (key === word.toLowerCase()) { 
                data[index] = wordDict[key] 
            }; 
        }); 
    }); 
  
    return data.join(' '); 
} 
  
// LowerCase Conversion 
const convertTolowerCase = text => { 
    return text.toLowerCase(); 
} 
  
// Pure Alphabets extraction 
const removeNonAlpha = text => { 
  
    // This specific Regex means that replace all 
    //non alphabets with empty string. 
    return text.replace(/[^a-zA-Z\s]+/g, ''); 
} 
  
// Analysis Route 
app.post("/feedback", (request, response) => { 
    console.log(request.body); 
  
    // NLP Logic 
    // Convert all data to its standard form 
    const lexData = convertToStandard(request.body.feedback); 
    console.log("Lexed Data: ",lexData); 
  
    // Convert all data to lowercase 
    const lowerCaseData = convertTolowerCase(lexData); 
    console.log("LowerCase Format: ",lowerCaseData); 
  
    // Remove non alphabets and special characters 
    const onlyAlpha = removeNonAlpha(lowerCaseData); 
    console.log("OnlyAlpha: ",onlyAlpha); 
  
    // Tokenization 
    const tokenConstructor = new natural.WordTokenizer(); 
    const tokenizedData = tokenConstructor.tokenize(onlyAlpha); 
    console.log("Tokenized Data: ",tokenizedData); 
  
    // Remove Stopwords 
    const filteredData = stopword.removeStopwords(tokenizedData); 
    console.log("After removing stopwords: ",filteredData); 
  
    // Stemming 
    const Sentianalyzer = 
    new natural.SentimentAnalyzer('English', natural.PorterStemmer, 'afinn'); 
    const analysis_score = Sentianalyzer.getSentiment(filteredData); 
    console.log("Sentiment Score: ",analysis_score); 
  
  
    response.status(200).json({ 
        message: "Data received", 
        sentiment_score: analysis_score 
    }) 
}); 
  
app.listen(port, host, () => { 
    console.log('Server is running...'); 
});
JavaScript

步骤7: 为了将前端与我们的服务器连接起来,我们需要在我们的server.js文件中添加一行代码,这意味着我们的所有静态HTML,CSS和JS文件将被提供在/路由下。

server.js

app.use("/",express.static(__dirname + "/public"));
JavaScript

现在,我们将创建一个名为index.html的HTML文件,该文件将成为我们的前端页面。

index.html

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <meta http-equiv="X-UA-Compatible"
          content="IE=edge"> 
    <meta name="viewport" 
          content="width=device-width, initial-scale=1.0"> 
  
    <!-- Font CDN -->
    <link rel="preconnect" 
          href="https://fonts.googleapis.com"> 
    <link rel="preconnect" 
          href="https://fonts.gstatic.com" crossorigin> 
    <link href= 
"https://fonts.googleapis.com/css2?family=Open+Sans&family=Outfit&family=M+PLUS+1+Code&display=swap" 
          rel="stylesheet">   
  
    <title>Event Feedback Application</title> 
</head> 
<style> 
    *{ 
        margin: 0; 
        padding: 0; 
    } 
  
    .feedback{ 
        transition: all .3s; 
        background-size: cover; 
        min-height: 100vh; 
    } 
  
    .feedback.active{ 
        filter: blur(8px); 
    } 
  
    .container{ 
        display: flex; 
        justify-content: center; 
        flex-direction: column; 
        align-items: center; 
    } 
  
    .container .form{ 
        margin-top: 10%; 
        background: #f1f5f3; 
        padding: 1em 2.5em 1.7em 2.5em; 
  
        display: flex; 
        justify-content: center; 
        align-items: center; 
        flex-direction: column; 
    } 
  
    .form > div{ 
        font-family: 'Open Sans',sans-serif; 
        margin-top: 8%; 
    } 
  
    textarea{ 
        font-family: 'Open Sans',sans-serif; 
        padding: .8em; 
        border: none; 
        outline: none; 
  
        resize: none; 
    } 
  
    button{ 
        padding: .7em; 
        cursor: pointer; 
        outline: none; 
        font-family: 'Open Sans',sans-serif; 
        background: #000; 
        border: 1px solid #222; 
        color: #f1f5f3; 
    } 
  
    .results{ 
        position: absolute; 
        top: 40%; 
        left: 50%; 
        transform: translate(-50%,-50%); 
        z-index: 999999; 
  
        transition: all .5s; 
        opacity: 0; 
        pointer-events: none; 
    } 
  
    .results.active{ 
        opacity: 1; 
        pointer-events: visible; 
    } 
  
  
  
    .results .result-box{ 
        background: #f1f5f3; 
        padding: 2em 4em; 
    } 
  
    .result-box > div{ 
        display: flex; 
        justify-content: center; 
  
        margin-top: 15%; 
    } 
  
    .sentiment p{ 
        font-family:'M PLUS 1 Code',sans-serif; 
    } 
  
    .close-button button{ 
        width: 100%; 
        margin-top: 20%; 
        background: rgb(255, 63, 102); 
    } 
  
  
</style> 
<body> 
    <!-- Toast Box -->
    <div class="results"> 
        <div class="result-box"> 
            <div class="emoji"> 
            </div> 
            <div class="sentiment"> 
            </div> 
            <div class="close-button"> 
                <button class="close"></button> 
            </div> 
        </div> 
    </div> 
  
      
    <section class="feedback"> 
  
        <div class="container"> 
            <div class="form"> 
                <div class="title"> 
                    <h2>Event Feedback ????</h2> 
                </div> 
                <div> 
                    <textarea cols="20" 
                              rows="5" 
                              id="feedbacktext" 
                              placeholder="Write..."> 
                    </textarea> 
                </div> 
                <div> 
                    <button id="submit">Submit</button> 
                </div> 
            </div> 
        </div> 
  
    </section> 
</body> 
<script src="main.js"></script> 
</html>
JavaScript

步骤8:

现在在/public文件夹中,让我们创建一个名为main.js的文件,在其中我们将添加一些用于进行API调用的函数。获取所有的HTML元素。所以我们的逻辑是,当用户填写反馈表单后,在点击提交按钮后,应该调用一个函数并向我们的node js服务器发出API调用。我们将在按钮上添加一个点击事件,在点击时,我们将向服务器发出API调用,并根据我们的反馈获取响应。根据我们的情感评分,我们将用表情符号显示结果。

main.js

// Grab all HTML Elements  
  
// All containers 
const feedback = document.getElementById("feedbacktext"); 
const wholeContainer = document.querySelector(".feedback"); 
const resultContainer = document.querySelector(".results"); 
  
// All controls 
const submit_button = document.getElementById("submit"); 
const closeButton = document.querySelector(".close"); 
  
// Results 
const emoji = document.querySelector(".emoji"); 
const sentiment = document.querySelector(".sentiment"); 
  
// Add event listener to submit button, send feedback and  
// name to our node js server application  
submit_button.addEventListener("click",()=>{ 
    console.log("Feedback: ",feedback.value); 
  
    // Send POST request to our server 
    const options = { 
        method : "POST", 
        body : JSON.stringify({ 
            feedback : feedback.value 
        }), 
        headers : new Headers({ 
            'Content-Type' : "application/json"
        }) 
    } 
  
    // Use fetch to request server 
    fetch("/feedback",options) 
        .then(res=>res.json()) 
        .then((response)=>{ 
            console.log(response.sentiment_score); 
  
            const score = response.sentiment_score; 
  
            // Separate responses according to sentiment_score 
            if(score > 0){ 
                emoji.innerHTML = "<p>😄</p>"; 
                sentiment.innerHTML = "<p>➕ Positive</p>"; 
            }else if(score === 0){ 
                emoji.innerHTML = "<p>😐</p>"; 
                sentiment.innerHTML = "<p>Neutral</p>"; 
            }else{ 
                emoji.innerHTML = "<p>😡</p>"; 
                sentiment.innerHTML = "<p>➖ Negative</p>"; 
            } 
  
            // Result Box should appear  
            resultContainer.classList.add("active"); 
            wholeContainer.classList.add("active"); 
  
        }) 
        .catch(err=>console.error("Error: ",err)); 
  
    // Clear all inputs after operation 
    feedback.value = ""; 
}); 
  
// Close Button 
  
closeButton.addEventListener("click",()=>{ 
    wholeContainer.classList.remove("active"); 
    resultContainer.classList.remove("active"); 
})
JavaScript

运行该应用的步骤: 要启动此应用程序,请在命令提示符上执行以下命令:

node server.js
JavaScript

输出:

Navigate to

http://localhost:5500/

Node.js 如何创建情感分析应用程序

服务器日志:

Node.js 如何创建情感分析应用程序

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册