Python 提供了強大的 JSON 解析能力和豐富的機器學習工具。本文示範如何結合這些技術,從 JSON 物件中提取資訊,並應用於情感分析、文書處理和機器學習任務。我們將使用正規表示式提取特定欄位,並利用 Snorkel API 建立標籤函式,為後續的機器學習模型準備資料。接著,我們將探討如何使用多數投票模型和標籤模型進行預測,並分析標籤函式的有效性。最後,我們將以電影評論情感分析為例,示範如何使用邏輯回歸和 K-means 聚類等機器學習方法進行文字分類,並評估模型的效能。

步驟1:解析JSON物件

import json

# 假設response是包含JSON物件的變數
json_data = response['choices']

步驟2:提取所需資訊

# 初始化變數來儲存提取的資訊
name = None
organization = None
location = None
contact_number = None

# 迭代JSON物件中的每個條目
for entry in json_data:
    # 提取text欄位的值
    text = entry.get("text", "")
    
    # 使用字串分割和查詢來提取所需資訊
    lines = text.splitlines()
    for line in lines:
        if line.startswith("Name: "):
            name = line[6:].strip()
        elif line.startswith("Organization: "):
            organization = line[14:].strip()
        elif line.startswith("Geographical location: "):
            location = line[22:].strip()
        elif line.startswith("Contact number: "):
            contact_number = line[16:].strip()

步驟3:驗證和使用提取的資訊

# 驗證是否成功提取了所有所需資訊
if name and organization and location and contact_number:
    print("提取的資訊:")
    print(f"姓名:{name}")
    print(f"組織:{organization}")
    print(f"地理位置:{location}")
    print(f"聯絡號碼:{contact_number}")
else:
    print("未能提取所有所需資訊。")

完整程式碼

import json

def extract_information(response):
    json_data = response['choices']
    name = None
    organization = None
    location = None
    contact_number = None

    for entry in json_data:
        text = entry.get("text", "")
        lines = text.splitlines()
        for line in lines:
            if line.startswith("Name: "):
                name = line[6:].strip()
            elif line.startswith("Organization: "):
                organization = line[14:].strip()
            elif line.startswith("Geographical location: "):
                location = line[22:].strip()
            elif line.startswith("Contact number: "):
                contact_number = line[16:].strip()

    if name and organization and location and contact_number:
        print("提取的資訊:")
        print(f"姓名:{name}")
        print(f"組織:{organization}")
        print(f"地理位置:{location}")
        print(f"聯絡號碼:{contact_number}")
    else:
        print("未能提取所有所需資訊。")

# 假設response是包含JSON物件的變數
response = {
    'choices': [
        {
            "text": "Thank you for your time, and I look forward to hearing from you soon. \n\nName: Sarah Johnson\nOrganization: XYZ Tech Solutions\nGeographical location: Austin, Texas\nContact number: (555) 123-4567",
            "index": 0,
            "finish_reason": "stop",
            "logprobs": None,
            "content_filter_results": {
                "hate": {
                    "filtered": False,
                    "severity": "safe"
                },
                "self_harm": {
                    "filtered": False,
                    "severity": "safe"
                },
                "sexual": {
                    "filtered": False,
                    "severity": "safe"
                },
                "violence": {
                    "filtered": False,
                    "severity": "safe"
                }
            }
        }
    ]
}

extract_information(response)

圖表翻譯:

  flowchart TD
    A[開始] --> B[解析JSON]
    B --> C[提取所需資訊]
    C --> D[驗證和使用提取的資訊]
    D --> E[輸出結果]

在這個流程圖中,我們首先解析JSON物件,然後提取所需的資訊,接著驗證是否成功提取了所有資訊,最後輸出結果。

文書處理和正規表示式

在處理文字資料時,常常需要提取特定的資訊。以下是一個使用 Python 的 split() 方法和正規表示式提取資訊的例子:

text = "Name: Sarah Johnson\nOrganization: XYZ Tech Solutions\nGeographical location: Austin, Texas\nContact number: (555) 123-4567"

name = text.split("Name:")[1].split("\n")[0].strip()
organization = text.split("Organization:")[1].split("\n")[0].strip()
location = text.split("Geographical location:")[1].split("\n")[0].strip()
contact_number = text.split("Contact number:")[1].split("\n")[0].strip()

print("Name:", name)
print("Organization:", organization)
print("Location:", location)
print("Contact Number:", contact_number)

這個例子使用 split() 方法分割文字,然後使用索引提取所需的資訊。

情感分析

情感分析是一種自然語言處理(NLP)技術,用於評估文字中表達的情感。以下是一個使用 Python 的 gpt3.5 部署進行情感分析的例子:

engine = "gpt3.5"
prompt = "Conduct aspect-based sentiment analysis on the following product reviews:\n Provide an overall sentiment score between 0 and 5 for each review.\n Assign a sentiment polarity score between 0 and 5 for each aspect mentioned. \n Identify the top positive and negative aspects, if any. \n Review 1: \n I recently purchased this smartphone, and it has exceeded my expectations! The camera quality is superb, capturing vivid and detailed photos. The battery life is impressive, easily lasting a full day with regular use. The sleek design adds a premium feel to the device. However, the speaker quality could be improved. Overall sentiment score: 4.8 \nAspects with sentiment polarity score: \n - Camera: 5 \n - Battery Life: 5 \n - Design: 5 \n - Speaker: 3 \n \n Top positive aspect: Camera \n Top negative aspect: Speaker \n \n Review 2: \n This laptop offers powerful performance and a sleek design. The keyboard is comfortable for extended typing sessions, and the display is vibrant with accurate colors. However, the trackpad responsiveness can be inconsistent at times."

response = engine(prompt)
print(response.choices[0].text.strip())

這個例子使用 gpt3.5 部署進行情感分析,評估產品評價中的情感,並提供整體情感評分和各個方面的情感極性評分。

Snorkel API

Snorkel API 是一個開源的資料標記和訓練平臺,用於生成標記資料。以下是一個使用 Snorkel API 進行文字資料標記的例子:

import pandas as pd

# 安裝 Snorkel
!pip install snorkel

# 匯入必要的庫
from snorkel.labeling import labeling_function

# 定義標記函式
@labeling_function()
def label_positive(x):
    if "good" in x:
        return 1
    else:
        return 0

@labeling_function()
def label_negative(x):
    if "bad" in x:
        return -1
    else:
        return 0

# 建立資料框
df = pd.DataFrame({"text": ["This is a good product.", "This is a bad product."]})

# 應用標記函式
df["label"] = df["text"].apply(label_positive)
df["label"] = df["text"].apply(label_negative)

# 顯示結果
print(df)

這個例子使用 Snorkel API 定義標記函式,然後將其應用於文字資料框,生成標記資料。

定義常數與資料集

在進行電影評論情感分析時,首先需要定義一些常數來代表不同的情感類別,例如正面(POS)、負面(NEG)和棄權(ABSTAIN)。接著,我們會建立一個包含更多資料的DataFrame,包括評論的ID和內容。

import pandas as pd
import numpy as np

# 定義常數
ABSTAIN = -1  # 棄權
POS = 0  # 正面
NEG = 1  # 負面

# 建立一個包含更多資料的DataFrame
df = pd.DataFrame({
    'id': [1, 2, 3, 4, 5, 6, 7, 8],
    'review': [
        "這部電影非常精彩!",
        "這部電影很糟糕,很無聊。",
        "我對這部電影有混合的感覺。",
        "我對這部電影沒有意見。",
        "這部電影非常棒,很刺激!",
        "我不喜歡這部電影,它太慢了。",
        "這部電影還可以,不太好也不太壞。",
        "這部電影很混亂,很無趣。"
    ]
})

# 將DataFrame分割成訓練集和測試集
df_train = df.iloc[:6]  # 前6筆記錄用於訓練
df_test = df.iloc[6:]  # 其餘記錄用於測試

# 定義測試集的真實標籤
Y_test = [ABSTAIN, NEG]  # 將其替換為實際標籤

# 將Y_test轉換為NumPy陣列
Y_test = np.array(Y_test)

定義根據規則的標籤函式

接下來,我們將定義根據規則的標籤函式,使用正規表示式來判斷評論的情感傾向。這些函式將根據評論內容傳回相應的情感類別。

# 定義根據規則的標籤函式,使用正規表示式
def lf_positive_review(x):
    """判斷評論是否為正面"""
    return POS if '精彩' in x['review'] or '棒' in x['review'] else ABSTAIN

def lf_negative_review(x):
    """判斷評論是否為負面"""
    return NEG if '糟糕' in x['review'] or '無聊' in x['review'] or '慢' in x['review'] or '混亂' in x['review'] else ABSTAIN

def lf_neutral_review(x):
    """判斷評論是否為中立"""
    return POS if '還可以' in x['review'] else ABSTAIN

內容解密:

上述程式碼中,我們首先定義了三個常數:ABSTAINPOSNEG,分別代表棄權、正面和負面的情感類別。然後,我們建立了一個包含8筆評論的DataFrame,並將其分割成訓練集和測試集。接著,我們定義了測試集的真實標籤,並將其轉換為NumPy陣列。

在定義根據規則的標籤函式時,我們使用了正規表示式來判斷評論的情感傾向。函式lf_positive_review判斷評論是否包含正面詞彙,如“精彩”或“棒”,如果包含則傳回POS,否則傳回ABSTAIN。函式lf_negative_review判斷評論是否包含負面詞彙,如“糟糕”、“無聊”、“慢”或“混亂”,如果包含則傳回NEG,否則傳回ABSTAIN。函式lf_neutral_review判斷評論是否為中立,如果評論包含“還可以”則傳回POS,否則傳回ABSTAIN

圖表翻譯:

  flowchart TD
    A[評論內容] --> B{包含正面詞彙?}
    B -->|是| C[傳回 POS]
    B -->|否| D{包含負面詞彙?}
    D -->|是| E[傳回 NEG]
    D -->|否| F[傳回 ABSTAIN]

上述流程圖描述了根據規則的標籤函式的邏輯。首先,根據評論內容判斷是否包含正面詞彙,如果包含則傳回POS。如果不包含正面詞彙,則進一步判斷是否包含負面詞彙,如果包含則傳回NEG,否則傳回ABSTAIN

大多數投票模型的應用

在這個章節中,我們將探討如何使用大多數投票模型(MajorityLabelVoter)來預測標籤。首先,我們需要定義一個函式,該函式根據評論的內容傳回一個標籤。這個函式被稱為標籤函式(labeling function)。

def lf_neutral_review(x):
    return 0 if 'mixed feelings' in x.review or \
                  'no opinion' in x.review or 'okay' in x.review \
           else 0

這個函式檢查評論中是否包含特定的詞彙,如「mixed feelings」、「no opinion」或「okay」。如果包含,則傳回0,否則傳回0。

標籤函式的應用

接下來,我們需要將這些標籤函式應用到訓練集和測試集上。為此,我們使用了PandasLFApplier類別。

lfs = [lf_positive_review, lf_negative_review, 
       lf_neutral_review]

applier = PandasLFApplier(lfs=lfs)

L_train = applier.apply(df=df_train)

L_test = applier.apply(df=df_test)

這段程式碼建立了一個標籤函式列表,並將其應用到訓練集和測試集上。結果儲存在L_train和L_test變數中。

大多數投票模型的建立

現在,我們可以使用大多數投票模型來預測標籤。

from snorkel.labeling.model import MajorityLabelVoter, LabelModel

majority_model = MajorityLabelVoter()

這段程式碼建立了一個大多數投票模型的例項。

模型的評估

最後,我們可以使用這個模型來預測測試集的標籤,並計算模型的準確度。

  flowchart TD
    A[訓練集] --> B[標籤函式]
    B --> C[大多數投票模型]
    C --> D[預測]
    D --> E[評估]

圖表翻譯:

這個流程圖描述瞭如何使用大多數投票模型來預測標籤。首先,訓練集被輸入到標籤函式中,然後標籤函式的輸出被用來訓練大多數投票模型。接下來,大多數投票模型被用來預測測試集的標籤。最後,模型的預測結果被評估,以計算其準確度。

內容解密:

在這個章節中,我們學習瞭如何使用大多數投票模型來預測標籤。首先,我們定義了一個標籤函式,該函式根據評論的內容傳回一個標籤。然後,我們將這個標籤函式應用到訓練集和測試集上。接下來,我們使用大多數投票模型來預測測試集的標籤。最後,我們評估了模型的準確度。這個過程可以幫助我們提高模型的準確度,並更好地理解資料的特點。

執行多數投票模型和標籤模型

在這個步驟中,我們將使用多數投票模型和標籤模型來預測標籤。首先,我們建立了一個多數投票模型,並使用它來預測訓練集的標籤。

# 執行多數投票模型
majority_model.predict(L=L_train)
majority_acc = majority_model.score(L=L_test, Y=Y_test, tie_break_policy="random")["accuracy"]
print(majority_acc)

輸出結果為 1.0,表示多數投票模型在測試集上的準確率為 100%。

接下來,我們使用多數投票模型來預測訓練集的標籤,並將結果印出。

# 預測訓練集的標籤
preds_train = majority_model.predict(L=L_train)
print(preds_train)

輸出結果為 [ 0 1 -1 -1 0 1],這是多數投票模型對訓練集的預測結果。

執行標籤模型

在這個步驟中,我們建立了一個標籤模型,並使用它來預測標籤。首先,我們建立了一個標籤模型,設定其基數為 2(代表兩個標籤:正面和負面)。

# 建立標籤模型
label_model = LabelModel(cardinality=2, verbose=True)

接下來,我們使用標籤模型來預測測試集的標籤,並計算其準確率。

# 執行標籤模型
label_model.fit(L_train=L_train, n_epochs=500, log_freq=100, seed=123)
label_model_acc = label_model.score(L=L_test, Y=Y_test, tie_break_policy="random")["accuracy"]
print(label_model_acc)

輸出結果為標籤模型在測試集上的準確率。

最後,我們使用標籤模型來預測訓練集的標籤,並將結果印出。

# 預測訓練集的標籤
Y_train_pred = label_model.predict(L=L_train)
print(Y_train_pred)

輸出結果為 [ 0 1 -1 -1 0 1],這是標籤模型對訓練集的預測結果。

分析標籤函式

在這個步驟中,我們使用 LFAnalysis 類別來分析標籤函式。首先,我們建立了一個 LFAnalysis 物件,並使用其 lf_summary() 方法來獲得標籤函式的概覽。

# 分析標籤函式
lf_analysis = LFAnalysis(L=L, lfs=lfs)
lf_summary = lf_analysis.lf_summary()
print(lf_summary)

輸出結果為標籤函式的概覽,包括其覆蓋率等資訊。

文字標記與分析

文字標記是自然語言處理(NLP)中的一個重要步驟,涉及將文字分類為預先定義的類別或情感。這個過程可以使用各種機器學習演算法來完成,包括邏輯回歸(Logistic Regression)。

文字預處理

在進行文字標記之前,需要對文字進行預處理。這包括以下步驟:

  • 分詞(Tokenization):將文字分割成個別的詞彙或符號。
  • 停用詞(Stopwords)移除:移除常見的詞彙,如「the」、「and」等。
  • 詞彙化(Lemmatization):將詞彙還原為其基本形式。

邏輯回歸(Logistic Regression)

邏輯回歸是一種常用的機器學習演算法,尤其適合於二元分類問題。它的工作原理是根據輸入的特徵預測輸出的機率。

實作文字標記

以下是使用邏輯回歸進行文字標記的步驟:

  1. 匯入必要的庫和模組:包括NLTK、scikit-learn等。
  2. 下載必要的NLTK資料:包括電影評論資料集和其他必要的NLTK資料。
  3. 初始化情感分析器和獲取電影評論ID:初始化一個情感分析器並獲取電影評論的ID。
  4. 預處理設定:設定預處理工具,包括一個詞彙化器和英語停用詞列表。
  5. 定義預處理函式:定義一個預處理函式,該函式對文字進行分詞、停用詞移除和詞彙化。
  6. 訓練邏輯回歸模型:使用預處理後的文字資料訓練一個邏輯回歸模型。
  7. 評估模型:評估模型的效能,包括準確率、精確率、召回率等指標。

程式碼實作

以下是使用Python和scikit-learn實作文字標記的程式碼示例:

from nltk.stem import WordNetLemmatizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import nltk
from nltk.sentiment import SentimentAnalyzer
from nltk.classify import NaiveBayesClassifier

# 下載必要的NLTK資料
nltk.download('movie_reviews')
nltk.download('wordnet')
nltk.download('omw-1.4')
nltk.download('punkt')

# 初始化情感分析器和獲取電影評論ID
sentiment_analyzer = SentimentAnalyzer()
ids = movie_reviews.fileids()

# 預處理設定
lemmatizer = WordNetLemmatizer()
stop_words = set(stopwords.words('english'))

def preprocess(document):
    words = word_tokenize(document)
    words = [word for word in words if word not in stop_words]
    words = [lemmatizer.lemmatize(word) for word in words]
    return ' '.join(words)

# 載入文字資料
train_data = [preprocess(movie_reviews.raw(fileid)) for fileid in ids]

# 標記文字資料
labels = [1 if fileid.startswith('pos') else 0 for fileid in ids]

# 切分訓練和測試資料
X_train, X_test, y_train, y_test = train_test_split(train_data, labels, test_size=0.2, random_state=42)

# 訓練邏輯回歸模型
vectorizer = TfidfVectorizer()
X_train_vectorized = vectorizer.fit_transform(X_train)
model = LogisticRegression()
model.fit(X_train_vectorized, y_train)

# 評估模型
X_test_vectorized = vectorizer.transform(X_test)
y_pred = model.predict(X_test_vectorized)
print('準確率:', accuracy_score(y_test, y_pred))

文字分類:邏輯回歸與K-means聚類

從技術架構視角來看,本文探討了從非結構化文字資料中提取關鍵資訊、進行情感分析和標記,以及使用多數投票模型和標籤模型進行預測的技術方法。文章涵蓋了JSON物件解析、正規表示式、Snorkel API、根據規則的標籤函式、多數投票模型、標籤模型以及文字分類等多個技術層面。透過例項程式碼和流程圖,深入淺出地展示了這些技術的應用方法和流程。然而,根據規則的標籤函式的準確性受限於規則的覆蓋範圍,而多數投票模型和標籤模型的效能則取決於標籤函式的品質和數量。此外,文章中提到的情感分析方法缺乏對複雜情感的處理能力,例如諷刺、反諷等。

展望未來,深度學習模型,例如根據Transformer的模型,在文字分類和情感分析任務中展現出巨大的潛力。這些模型能夠學習更複雜的語義關係,並有效處理更具挑戰性的文字資料。同時,弱監督學習方法,例如Snorkel,也將持續發展,提供更高效的資料標記方案,降低人工標記成本。對於重視資料分析和洞察的企業,整合這些先進技術將是提升文字資料處理能力的關鍵。玄貓認為,隨著技術的發展和成熟,自動化文字分析工具將在各個領域發揮越來越重要的作用,釋放資料的潛在價值。