Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
們對150萬條語音進行了情感分析 ~
原標題 | Sentiment Analysis of 1.5 Million Audible Reviews
作 者 | Toby Manders
翻 譯 | 廖穎、had_in、Jonathan-huang、david95、黛娜?卡特琳
編 輯 | Pita
在這個項目的第一部分中,我們收集和研究了一個數據集,其中包括asin、評級數量和每個單獨的有聲英語課程的URL。
我們將通過使用這些字段來盡可能多地獲取文本評論和附帶的評級,從而找到我們離開的地方。然后我們將訓練一些LSTM神經網絡,將評論分類為正負兩種。
查看遍歷筆記:https://github.com/tobymanders/Data_Analysis/blob/master/audible_eda/audible_reviews_scraper.ipynb
查看數據預處理和情緒分析筆記:https://github.com/tobymanders/Data_Analysis/blob/master/audible_eda/audible_review_classifier.ipynb
下載所有評論的數據集,可訪問:https://drive.google.com/file/d/1Wka-rYvEykaG4fGR71zDis5d1NOFZlLX/view?usp=sharing
我們以前研究過音頻目錄中的分級分布,注意到頂部選擇的少數節目的分級的極端集中(標題等級日志和評論數量日志之間的大致線性關系)。
我們今天將利用這種偏斜的優勢,以最大限度地提高每小時可獲取的評論數量。假設每個標題的書面評論數量與每個標題的評級數量成比例,我們可以預計大約50%的網站評論集中在我們數據集中的前1%的程序中。
從HTML中刪除這些評論有一個障礙。大多數最受歡迎的標題的評論都隱藏在“查看更多”按鈕下面。
當點擊那個顯示答案的按鈕時,我們要檢查網絡請求。我們發現一個指向我們剛剛評論過的文章url鏈接。通過在這個鏈接向后閱讀到末尾,我們能夠收集對于給出項目的所有評論。由于這里的頁面下載非常快(也因為我們正在使用多線程工作),在一段合理的時間內,我們可以從項目的前6%(26,101)中搜刮到高達80%的評論。
在遍歷期間,我們有機會去做少量的家務活。我們將會使用評論內容去訓練一個把評論分類成有幫助的(4~5顆星)和無用的(1~3顆星)的機器學習模型。如果在我們先前閱讀過的文章中有留下標題和作者,我們的模型很有可能會‘記住它’,也就是說,那個項目有很高的評分了。這意味著對泛化能力有不好的影響,所以我們希望把作者和標題從評論中移除。這樣做我們就不需要為每篇評論都儲存信息了。
統一都用<unk>,簡稱‘未知’來代替單詞的步驟叫做‘unking’。除了從每篇評論中‘unking’作者和標題外,我們還會用“停止”這個詞來代替句號,去掉所有其他標點符號,并將所有文章內容改為小寫。這減少了我們數據集中的“單詞”數量。
幾個小時后,我們會有超過150萬的評論。
當我們為每篇評論收集評分時,‘overall’、‘story’和‘表現performance’中,我們會以‘overall’列作為標簽。另外兩列我們將會保存下來用作未來的分析。
為了把數據和目標轉換成我們訓練模型所需要的形式,我們需要完成接下來的準備工作:
1. 在詞匯類型做參數的假設函數中,我們要根據使用頻率從高頻詞匯數據中創建一個詞匯表。
2.‘Unk' ——即用‘unk’代替所有數據集存在但詞匯表中缺失的詞匯。
3. 填補或刪減所有條目去統一長度、序列長度和假設函數中的參數。
4. Tokenize(也就是整合)數據集中所有的單詞。
5. 從‘overall’列中創建二進制標簽。
我們的目標是把數據中的X數組整合成(評論總數 * 序列長度)的形式 和 把矢量y整合成評論總數的長度。
這是前面的部分條目。已經把內容標準化,移除了作者和標題。
為了決定截斷更長或更短,讓我們看看下面的分類情況。
上面的長度-頻率圖看起來像是指數圖像。96.4%的評論都小于250個單詞。我們將把250個單詞作為序列長度。
那評論長度下限是什么呢?左邊的圖表向我們展示了數據集中剩下的絕大多數評論(>98%)都是多于10個單詞。我們用10作為評論長度的下限。
按照字符長度排序,我們可以看到超過10個“單詞”的最短評論。
大于10個單詞的最短的評論。請注意,“單詞”是空格之間的所有內容。
我們的下一步工作是根據所有的評論構建一個詞匯表。我們將構建一個字典用來統計數據集中每個單詞出現的頻率,然后我們將使用平率最高的10,000個單詞來構建詞匯表,并且用“unk”來編碼我們的數據集——如用“unk”替換評論中我們詞匯表中沒有的單詞。同時我們還將數據集編碼為數字數組——如“tokens”——我們可以在同一個函數中完成這兩項任務。
在一些示例文本上測試我們的功能如下:
sample=‘i really loved dfalkjf especially the introduction’
...
print(tokenize_text(sample))
Unk ID: 24
[4, 56, 79, 24, 301, 1, 1190]
注意到,未識別的“dfalkjf”被替換為“unk”,編碼為24。其余的單詞編碼為對應于詞匯表中單詞的索引。
經過填充、截斷和編碼之后,我們的數據如下:
array([[ 24, 0, 0, ..., 24, 24, 24],
[ 24, 9, 11, ..., 24, 24, 24],
[ 149, 149, 149, ..., 24, 24, 24],
...,
[ 131, 32, 873, ..., 24, 24, 24],
[ 5, 3312, 368, ..., 24, 24, 24],
[ 172, 195, 1, ..., 24, 24, 24]])
注意到每一行末尾的24,這就是用'unk'進行填充得到的。
最后,我們根據“overall”評級創建了二進制標簽,并發現大約79%的評論獲得了4星或5星評級。這個數字很重要,因為它意味著即使是最簡單的模型(總是預測1)也能獲得79%的準確率,這是必須要超過的數字。
3.訓練模型
現在預處理步驟已經完成,我們可以訓練我們的模型了。利用TensorFlow和Keras層,我們可以嘗試網絡結構以及不同的參數。我們所有的模型均將嵌入層作為網絡第一層,嵌入層每個單詞轉換成固定長度的向量,這個長度也是一個超參數。
我們所有的模型都將至少有一個RNN層(特別是長短期記憶單元或稱為LSTM層)。這一層將用于向前和向后傳播。在每種情況下,LSTM層都將輸入一個具有relu激活函數的全連接層和輸出一個具有sigmoid激活函數的輸出層,后者將得到一個介于0和1之間的值,該值將被閾值化以進行類別預測。
對于其他層,我們加入Dropout層以減少過擬合,其中包括一種特殊類型的Dropout層,該Dropout層接在嵌入層之后,,隨機丟棄一維特征圖而不是單個單詞,以及一個一維卷積層,該卷積層將學習一組濾波器,以提取相鄰的詞之間的關系特征,我們還將嘗試堆疊兩層LSTMs。
我們將使用二分類交叉熵損失函數,Adam優化器,并使用early stopping回調函數,當驗證集損失開始增加時,該回調函數將停止訓練。
我們的最佳模型之一的訓練集和驗證集的準確性。驗證損失在第5個epoch達到最低點,訓練提前停止。
4.結果
表現最好的模型確實是最復雜的——在一組未知的測試集上有93.8%的準確率,這個測試集包含大約155,000個評論。然而,值得注意的是,最簡單的模型達到了93.1%的準確率。
我們最簡單的模型只包含三個隱藏層:嵌入長度只有8的嵌入層、只有8個單元的LSTM層以及一個16個單元的全連接層。網絡總共有81k的參數,訓練耗時53分鐘。
model=tf.keras.Sequential([
tf.keras.layers.Embedding(vocab_size, 8),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(8)),
tf.keras.layers.Dense(16, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
我們最復雜的模型,也是最終的贏家,除了LSTM層,還有7個隱藏層,包括dropout層、卷積層和pooling層:
對于二分類,受試者工作特征 (ROC)曲線很好地反映了模型的區分能力。它反映了這樣一個事實:當您降低最終概率輸出的閾值時,您會獲得更高的真正率 ,但也會導致更高的誤報率 。一個完美的模型會將更高的概率分配給正的樣本,而不是負的樣本,因此降低閾值將得到更多的正樣本而不是更多的負樣本。這樣,曲線就會緊靠左上角。AUC相當于測量ROC曲線下的面積(越接近1越好) 。這里我們的模型在測試數據上的AUC為0.975.
讓我們使用一些例子來測試一下我們的模型。我們會給它四個句子。分數小于0.5代表著負樣本(消極情緒),大于0.5代表著正樣本(積極情緒)。
這本糟糕的書真讓人討厭,真的,它讓真讓人難受。
我們的模型正確的給它打了0.01分(盡可能接近0)
我愛這本書,它很杰出、幽默而且新奇。
這一句得到0.99分。如果有歧義的句子會怎么樣呢:
這本書很不錯,但是它讓我覺得難過。
0.52分,我們的模型要被我們玩哭了。那如果積極的詞和消極的詞同時出現呢:
這個故事真的很棒,但是解說員有點可怕。
0.72,模型給了“真的很棒”更多的權重。可能如果我們重新訓練模型,能得到不同的結果。
最終,讓我們觀察一下我們的模型學習到的詞嵌入向量。學到的我們字典里每一個單詞的向量代表著關于這個單詞的信息,這些信息用于預測詞是正向的還是負向的。為了更直觀的表示他們的空間關系,有助于我們理解,我們需要將這些詞向量降維。
主成分分析(PCA)是一個將含有豐富信息的多維數據(比如包含很多變量)轉化為坐標軸對齊(比如數據的第一維)的方法。我們會使用PCA將我們的128維的嵌入向量轉化為2維數據,然后我們就可以將單詞關系可視化:
如圖,一個2D圖表,從我們學到的詞嵌入向量中選取了兩個最主要的維度。
使用主成分分析法將詞語表中61個常見詞語轉化為兩維數據生成了上圖。主要分為褒義詞,比如“迷人的”、“卓越的”,標為藍色;貶義詞像“糟糕的”和“無聊的”,標為紅色;還有中性詞,比如“行為”和“書本”,標為黑色。
詞嵌入清楚地反映了這次詞語的詞性,甚至可以看出更細致的關系。比如,我們直覺地感知近義詞的關系:“單調的”和“單調”、“更糟”和“最差”、“乏味”和“厭倦”、“聲音”和“敘述者”、“音頻”和“質量”等等。
通過對整個詞語表重復這個過程,只看最主要的成分,可以找到最積極和最消極的詞語。分數最高的詞語是“充分利用”,而分數最低的詞語呢,就是“Refund(退款)”。
最后,我們在整個訓練集上進行預測,來找“最差”和“最好”的評論。
“最差”評論:
浪費,浪費,浪費,買這本書就是浪費,省點錢吧。
什么可以使<標題>更好呢?
沒有什么可以使這本書更好了。溫馨提醒,這本書不像有些人說的那么有趣,誰會買一本有趣的吸血鬼的書呢?
你認為下一個會聽到什么呢?
不確定,讀者會對吸血鬼或天啟發表評論,而不是對作者或書籍朗讀者。
你為什么不喜歡<朗讀者>的的表現呢?
因為她的音色,她讀每一個角色感覺都是一樣的。
你不喜歡這本書,但它有沒有什么優點呢?
沒有...甚至更糟糕,因為它是數字媒體而不是實體書,我都不能把它拷貝下來回顧。我之前讀/聽過比這本書好太多的產品。
還有什么補充的嗎?
我是對任意題材吸血鬼和天啟故事的真愛粉,這本書就不該寫出來更別說...
“最好”評論:
太棒了
太棒了太棒了太棒了太棒了太棒了太棒了...(此處省略N個“太棒了”)太棒了太棒了太棒了太棒了太棒了太棒了太棒了
via https://towardsdatascience.com/scraping-and-sentiment-analysis-of-1-5-million-audible-reviews-3502fa6bc86c
封面圖來源:https://pixabay.com/zh/photos/%E4%B8%8D%E5%BF%AB%E4%B9%90-%E7%94%B7%E5%AD%90-%E9%9D%A2%E5%85%B7-%E4%BC%A4%E5%BF%83-%E8%84%B8-389944/
語義化的標簽,旨在讓標簽有自己的含義。
<title>:頁面主體內容。
<h>:h1~h6,分級標題,<h1> 與 <title> 協調有利于搜索引擎優化。
<ul>:無序列表。
<li>:有序列表。
<header>:頁眉通常包括網站標志、主導航、全站鏈接以及搜索框。
<nav>:標記導航,僅對文檔中重要的鏈接群使用。
<main>:頁面主要內容,一個頁面只能使用一次。如果是web應用,則包圍其主要功能。
<article>:定義外部的內容,其中的內容獨立于文檔的其余部分。
<section>:定義文檔中的節(section、區段)。比如章節、頁眉、頁腳或文檔中的其他部分。
<aside>:定義其所處內容之外的內容。如側欄、文章的一組鏈接、廣告、友情鏈接、相關產品列表等。
<footer>:頁腳,只有當父級是body時,才是整個頁面的頁腳。
<small>:呈現小號字體效果,指定細則,輸入免責聲明、注解、署名、版權。
<strong>:和 em 標簽一樣,用于強調文本,但它強調的程度更強一些。
<em>:將其中的文本表示為強調的內容,表現為斜體。
<mark>:使用黃色突出顯示部分文本。
<figure>:規定獨立的流內容(圖像、圖表、照片、代碼等等)(默認有40px左右margin)。
<figcaption>:定義 figure 元素的標題,應該被置于 figure 元素的第一個或最后一個子元素的位置。
<cite>:表示所包含的文本對某個參考文獻的引用,比如書籍或者雜志的標題。
<blockquoto>:長引用,塊引用擁有它們自己的空間。
<q>:短引用(跨瀏覽器問題,盡量避免使用)。
<time>:datetime屬性遵循特定格式,如果忽略此屬性,文本內容必須是合法的日期或者時間格式。
<address>:作者、相關人士或組織的聯系信息(電子郵件地址、指向聯系信息頁的鏈接)。
<del>:移除的內容。
<meter>:定義已知范圍或分數值內的標量測量。(Internet Explorer 不支持 meter 標簽)
<!-- hgroup 標題用來為標題分組,可以將一組相關的標題同時放入到hgroup中 -->
<hgroup>
<h1>回鄉偶書</h1>
<h2>其二</h2>
</hgroup>
<!-- p標簽 表示頁面中一個段落 也是塊元素 -->
<p>在p標簽的內容 表示為一個段落</p>
<!--
em標簽 表示語調語氣加重
行內元素 :不會獨占一行的元素
-->
<p>今天天氣<em>真</em>不錯</p>
<!-- strong 表示強調,重要內容 -->
<p>你今天必須要<strong>完成作業</strong></p>
魯迅說
<!-- blockquote 表示 引用長引用 塊元素 -->
<blockquote>
我說過很多話 但我都不記得了
</blockquote>
<!-- q標簽 表示短引用 為行內元素 -->
子曰<q>溫故而知新</q>
</body>
(部分標簽)效果圖
關聯面試題:請簡述下你對HTML語義化的理解?知道的可以在評論區留言![送心]
內容首發于工粽號:程序員大澈,每日分享一段優質代碼片段,歡迎關注和投稿!
大家好,我是大澈!
本文約 1100+ 字,整篇閱讀約需 2 分鐘。
今天分享一段優質 CSS 代碼片段,應用灰度效果,讓頁面變成黑白顯示。
老規矩,先閱讀代碼片段并思考,再看代碼解析再思考,最后評論區留下你的見解!
body {
filter: grayscale(1); // 1相當于100%
}
分享原因
這段代碼展示了如何使用 CSS 濾鏡來將整個網頁變為灰度效果。
在特殊的日子里,網頁有整體變灰色的需求,可以使用這段代碼,這個需求很有必要。
再就是做一些老照片或黑白電影的效果,也可以使用這段代碼。
代碼解析
1. 選擇器 body
這一部分選擇了 HTML 文檔的 <body> 元素,即整個網頁的主體。
CSS 的 filter 屬性通常用于圖像,但也可以應用到其他任何 HTML 元素上。
2. grayscale(1);
grayscale 濾鏡將元素的顏色變成灰度效果。
參數 1 表示 100% 灰度,參數 0 表示無灰度效果。
3. filter 所有屬性值 大盤點!
CSS 的 filter 屬性提供了多種圖形效果,且這些屬性值可以組合用起來,且可以應用于任何元素。
以下是 filter 屬性的所有值及其詳細解釋:
blur()
功能:應用模糊效果。
參數:接受一個長度值(如 px、em),默認值是 0。
示例:filter: blur(5px);
brightness()
功能:調整圖像的亮度。
參數:接受一個數值,1 為原始亮度。值小于 1 會降低亮度,值大于 1 會增加亮度。
示例:filter: brightness(0.5);
contrast()
功能:調整圖像的對比度。
參數:接受一個數值,1 為原始對比度。值小于 1 會降低對比度,值大于 1 會增加對比度。
示例:filter: contrast(200%);
drop-shadow()
功能:應用陰影效果。
參數:類似于 box-shadow,包括偏移量、模糊半徑和顏色。
示例:filter: drop-shadow(10px 10px 10px #000);
grayscale()
功能:將圖像變為灰度。
參數:接受一個 0 到 1 之間的數值,0 為無灰度,1 為完全灰度。
示例:filter: grayscale(1);
hue-rotate()
功能:旋轉圖像的色相。
參數:接受一個角度值,單位為度(deg)。
示例:filter: hue-rotate(90deg);
invert()
功能:反轉圖像的顏色。
參數:接受一個 0 到 1 之間的數值,0 為無效果,1 為完全反轉。
示例:filter: invert(1);
opacity()
功能:調整圖像的透明度。
參數:接受一個 0 到 1 之間的數值,0 為完全透明,1 為完全不透明。
示例:filter: opacity(0.5);
saturate()
功能:調整圖像的飽和度。
參數:接受一個數值,1 為原始飽和度。值小于 1 會降低飽和度,值大于 1 會增加飽和度。
示例:filter: saturate(2);
sepia()
功能:將圖像變為棕褐色。
參數:接受一個 0 到 1 之間的數值,0 為無效果,1 為完全棕褐色。
示例:filter: sepia(1);
url()
功能:引用 SVG 濾鏡。
參數:接受一個 URL,指向一個包含 SVG 濾鏡的文件。
示例:filter: url(#filter-id);
- end -
*請認真填寫需求信息,我們會在24小時內與您取得聯系。