C1W1.LAB.Preprocessing+Word frequencies+Logistic_regression_model

news2024/11/13 23:33:37

理论课:C1W1.Sentiment Analysis with Logistic Regression

文章目录

  • 预处理
    • 导入包
    • Twitter dataset简介
    • 查看原始文本
    • 处理原始文本
      • 处理超链接、Twitter 标记和样式
      • 分词
      • 去除标点和停用词
      • 词干处理
    • process_tweet()
  • 词频构建与可视化
    • 导入包
    • 加载数据集
    • 字典
      • 字典实例
      • 添加或编辑词条
      • 访问值和查找键
    • 词频字典
    • 词频表格化
  • 逻辑回归模型可视化
    • 导入包
    • 加载推特数据集
    • 加载特征(情感词频)
    • 加载预训练的逻辑回归模型
    • 样本散点图
    • 绘制逻辑回归模型

理论课: C1W1.Sentiment Analysis with Logistic Regression

预处理

主要任务是完成对推文的预处理函数,主要使用NLTK软件包对 Twitter 数据集进行预处理。

导入包

import nltk                                # Python library for NLP
from nltk.corpus import twitter_samples    # sample Twitter dataset from NLTK
import matplotlib.pyplot as plt            # library for visualization
import random                              # pseudo-random number generator

下载twitter_samples可以运行:

nltk.download()

或者

nltk.download('twitter_samples')

如果下载twitter_samples失败,可以到https://www.nltk.org/nltk_data/,手工下载twitter_samples.zip后放corpora目录,不用解压。

Twitter dataset简介

NLTK 的推特样本数据集分为正面推文和负面推文。其中包含 5000 条正面推文和 5000 条负面推文。这些类别之间的精确匹配并非巧合。这样做的目的是为了得到一个平衡的数据集。这并不能反映实时 Twitter 流中正面和负面类别的真实分布(正面大于负面)。这只是因为平衡数据集简化了情感分析所需的大多数计算方法的设计。
下载并导入成功后可以使用以下代码加载数据:

# select the set of positive and negative tweets
all_positive_tweets = twitter_samples.strings('positive_tweets.json')
all_negative_tweets = twitter_samples.strings('negative_tweets.json')

打印正面和负面推文的数量,打印数据集的数据结构:

print('Number of positive tweets: ', len(all_positive_tweets))
print('Number of negative tweets: ', len(all_negative_tweets))

print('\nThe type of all_positive_tweets is: ', type(all_positive_tweets))
print('The type of a tweet entry is: ', type(all_negative_tweets[0]))

在这里插入图片描述
数据类型是列表,列表中的推文是字符串类型,下面使用Matplotlib 的 pyplot 库进行可视化:

# Declare a figure with a custom size
fig = plt.figure(figsize=(5, 5))

# labels for the two classes
labels = 'Positives', 'Negative'

# Sizes for each slide
sizes = [len(all_positive_tweets), len(all_negative_tweets)] 

# Declare pie chart, where the slices will be ordered and plotted counter-clockwise:
plt.pie(sizes, labels=labels, autopct='%1.1f%%',
        shadow=True, startangle=90)

# Equal aspect ratio ensures that pie is drawn as a circle.
plt.axis('equal')  

# Display the chart
plt.show()

在这里插入图片描述

查看原始文本

随机打印一条正面推文和一条负面推文。代码在字符串的开头添加了一个颜色标记,以进一步区分两者(原推文会有脏话):

# print positive in greeen
print('\033[92m' + all_positive_tweets[random.randint(0,5000)])

# print negative in red
print('\033[91m' + all_negative_tweets[random.randint(0,5000)])

处理原始文本

数据预处理是任何机器学习项目的关键步骤之一。它包括在将数据输入机器学习算法之前对数据进行清理和格式化。对于 NLP,预处理步骤通常包括以下任务:
分词
大/小写
删除停顿词和标点符号
词干化
这里只选取一条推文为例,看看每一个预处理步骤是如何转换的。

# Our selected sample. Complex enough to exemplify each step
tweet = all_positive_tweets[2277]
print(tweet)

结果:
在这里插入图片描述

接下来要下载停用词:

#download the stopwords from NLTK
nltk.download('stopwords')

下载失败后手工安装,下载stopwords.zip后放corpora目录
导入以下库:

import re                                  # library for regular expression operations
import string                              # for string operations

from nltk.corpus import stopwords          # module for stop words that come with NLTK
from nltk.stem import PorterStemmer        # module for stemming
from nltk.tokenize import TweetTokenizer   # module for tokenizing strings

处理超链接、Twitter 标记和样式

使用re库在推特上执行正则表达式操作。我们将定义搜索模式,并使用 sub() 方法用空字符(即 '')替换来移除匹配的字符。

print('\033[92m' + tweet)
print('\033[94m')

# remove old style retweet text "RT"
tweet2 = re.sub(r'^RT[\s]+', '', tweet)

# remove hyperlinks
tweet2 = re.sub(r'https?://[^\s\n\r]+', '', tweet2)

# remove hashtags
# only removing the hash # sign from the word
tweet2 = re.sub(r'#', '', tweet2)

print(tweet2)

结果:
在这里插入图片描述

分词

使用NLTK中的tokenize模块进行操作(中文得用别的分词库):

print()
print('\033[92m' + tweet2)
print('\033[94m')

# instantiate tokenizer class
tokenizer = TweetTokenizer(preserve_case=False, strip_handles=True,
                               reduce_len=True)

# tokenize tweets
tweet_tokens = tokenizer.tokenize(tweet2)

print()
print('Tokenized string:')
print(tweet_tokens)

在这里插入图片描述

去除标点和停用词

这里加载是英文停用词,也有中文专用的停用词

#Import the english stop words list from NLTK
stopwords_english = stopwords.words('english') 

print('Stop words\n')
print(stopwords_english)

print('\nPunctuation\n')
print(string.punctuation)

在这里插入图片描述
可以看到,上面的停用词表包含了一些在某些语境中可能很重要的词。这些词包括 i、not、between、because、won、against 等。在某些应用中,您可能需要自定义停用词列表。在我们的练习中,我们将使用整个列表。

关于标点符号,我们在前面已经提到,在处理推文时应保留某些分组,如"😃 “和”…",因为它们用于表达情绪。而在其他情况下,如医学分析,这些标点符号也应删除。

print()
print('\033[92m')
print(tweet_tokens)
print('\033[94m')

tweets_clean = []

for word in tweet_tokens: # Go through every word in your tokens list
    if (word not in stopwords_english and  # remove stopwords
        word not in string.punctuation):  # remove punctuation
        tweets_clean.append(word)

print('removed stop words and punctuation:')
print(tweets_clean)

在这里插入图片描述

词干处理

词干处理是将一个词转换成其最一般的形式或词干的过程。这有助于减少我们的词汇量。例如:
learn
learning
learned
learnt
所有这些词都是由共同词根 learn 生成的词干。然而,在某些情况下,词干拼写过程中产生的单词并不是词根的正确拼写。例如,happi 和 sunni。这是因为它为相关词选择了最常见的词干。例如,我们可以看看由不同形式的 happy 组成的词组:

happy
happiness
happier
我们可以看到,前缀 happi 更常用。这里不能选择 happ,因为它是 happen 等不相关词的词干。NLTK 有不同的词干处理模块,这里使用 PorterStemmer 模块,该模块使用波特词干处理算法。

print()
print('\033[92m')
print(tweets_clean)
print('\033[94m')

# Instantiate stemming class
stemmer = PorterStemmer() 

# Create an empty list to store the stems
tweets_stem = [] 

for word in tweets_clean:
    stem_word = stemmer.stem(word)  # stemming word
    tweets_stem.append(stem_word)  # append to the list

print('stemmed words:')
print(tweets_stem)

在这里插入图片描述

process_tweet()

将以上步骤合起来就可以得到process_tweet函数,将其写作utils.py中

import re
import string
import numpy as np

from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
from nltk.tokenize import TweetTokenizer


def process_tweet(tweet):
    """Process tweet function.
    Input:
        tweet: a string containing a tweet
    Output:
        tweets_clean: a list of words containing the processed tweet

    """
    stemmer = PorterStemmer()
    stopwords_english = stopwords.words('english')
    # remove stock market tickers like $GE
    tweet = re.sub(r'\$\w*', '', tweet)
    # remove old style retweet text "RT"
    tweet = re.sub(r'^RT[\s]+', '', tweet)
    # remove hyperlinks    
    tweet = re.sub(r'https?://[^\s\n\r]+', '', tweet)
    # remove hashtags
    # only removing the hash # sign from the word
    tweet = re.sub(r'#', '', tweet)
    # tokenize tweets
    tokenizer = TweetTokenizer(preserve_case=False, strip_handles=True,
                               reduce_len=True)
    tweet_tokens = tokenizer.tokenize(tweet)

    tweets_clean = []
    for word in tweet_tokens:
        if (word not in stopwords_english and  # remove stopwords
                word not in string.punctuation):  # remove punctuation
            # tweets_clean.append(word)
            stem_word = stemmer.stem(word)  # stemming word
            tweets_clean.append(stem_word)

    return tweets_clean

下面是调用示例:

from utils import process_tweet # Import the process_tweet function

# choose the same tweet
tweet = all_positive_tweets[2277]

print()
print('\033[92m')
print(tweet)
print('\033[94m')

# call the imported function
tweets_stem = process_tweet(tweet); # Preprocess a given tweet

print('preprocessed tweet:')
print(tweets_stem) # Print the result

在这里插入图片描述

词频构建与可视化

导入包

import nltk                                  # Python library for NLP
from nltk.corpus import twitter_samples      # sample Twitter dataset from NLTK
import matplotlib.pyplot as plt              # visualization library
import numpy as np                           # library for scientific computing and matrix operations
# import our convenience functions
from utils import process_tweet, build_freqs

process_tweet函数上节已经讲过,这里直接导入了build_freqs,其目的是构建一个频率字典,该字典将每个(单词,情感)对映射到其出现的频率。具体看后面

加载数据集

加载Twitter dataset

# select the lists of positive and negative tweets
all_positive_tweets = twitter_samples.strings('positive_tweets.json')
all_negative_tweets = twitter_samples.strings('negative_tweets.json')

# concatenate the lists, 1st part is the positive tweets followed by the negative
tweets = all_positive_tweets + all_negative_tweets

# let's see how many tweets we have
print("Number of tweets: ", len(tweets))

结果:
Number of tweets: 10000
我们将建立一个标签数组,与推文的情绪标签相匹配。其工作原理与普通列表类似,但针对计算和操作进行了优化。标签数组将由 10000 个元素组成。前 5000 个元素将填入表示正面情绪的 1 标签,后 5000 个元素将填入表示反面情绪的 0 标签。
np.ones() - 创建一个 1 的数组
np.zeros() - 创建 0 的数组
np.append() - 连接数组

# make a numpy array representing labels of the tweets
labels = np.append(np.ones((len(all_positive_tweets))), np.zeros((len(all_negative_tweets))))

字典

在 Python 中,字典是一个可变的索引集合。它以键值对的形式存储条目,并使用哈希表来实现查找(查找时间与数量大小基本无关)。在 NLP 中,字典是必不可少的,因为它可以快速检索项目或进行包含检查,即使集合中有成千上万的条目。

字典实例

dictionary = {'key1': 1, 'key2': 2}

以上代码定义了一个有两个条目的字典。键和值几乎可以是任何类型(对键有一些限制),在本例中,我们使用了字符串。我们还可以使用浮点数、整数、元组等。

添加或编辑词条

可以使用方括号在字典中插入新条目。如果字典中已包含指定的键,则其值将被覆盖。

# Add a new entry
dictionary['key3'] = -5

# Overwrite the value of key1
dictionary['key1'] = 0

print(dictionary)

结果:
{‘key1’: 0, ‘key2’: 2, ‘key3’: -5}

访问值和查找键

执行字典查询和检索是 NLP 中的常见任务。有两种方法可以做到这一点:

  1. 使用方括号符号: 如果查找键在字典中,则允许使用这种形式。否则会产生错误。
  2. 使用 get() 方法: 如果字典键不存在,我们可以使用这种方法设置默认值。
# Square bracket lookup when the key exist
print(dictionary['key2'])

使用方括号的时候如果访问不存在的键则会产生error,因此,需要在访问前加上if判断,或者使用get方法,并给出访问不存在键值的返回值:

# This prints a value
if 'key1' in dictionary:
    print("item found: ", dictionary['key1'])
else:
    print('key1 is not defined')

# Same as what you get with get
print("item found: ", dictionary.get('key1', -1))

词频字典

def build_freqs(tweets, ys):
    """Build frequencies.
    Input:
        tweets: a list of tweets
        ys: an m x 1 array with the sentiment label of each tweet
            (either 0 or 1)
    Output:
        freqs: a dictionary mapping each (word, sentiment) pair to its
        frequency
    """
    # 将numpy数组转换为列表,因为zip函数需要可迭代的对象。
    # 使用squeeze函数确保ys是一个一维数组,如果ys已经是列表,这个操作没有影响。
    yslist = np.squeeze(ys).tolist()

    # 初始化一个空字典,用于存储单词和情感标签的频率。
    freqs = {}

    # 遍历每个情感标签和对应的推文。
    for y, tweet in zip(yslist, tweets):
        # 对每个推文进行处理,得到单词列表。
        for word in process_tweet(tweet):
            # 创建一个单词和情感标签的元组。
            pair = (word, y)
            # 如果这个元组已经在字典中,就增加其计数。
            if pair in freqs:
                freqs[pair] += 1
            # 如果这个元组不在字典中,就将其添加到字典中,并设置计数为1。
            else:
                freqs[pair] = 1

    # 返回构建好的频率字典。
    return freqs

以上代码对元组是否在字典中的判断部分可以修改为get函数:

    for y, tweet in zip(yslist, tweets):
        for word in process_tweet(tweet):
            pair = (word, y)
            freqs[pair] = freqs.get(pair, 0) + 1

从上面代码可以看到,字典的每个键都是一个包含两个元素的元组,其中包含一个(word, y)对。word 是已处理推文中的一个元素,而 y 则是代表语料库的一个整数: 1 代表正面推文,0 代表负面推文。与该键相关的值是该词在指定语料库中出现的次数。例如

# "followfriday" appears 25 times in the positive tweets
('followfriday', 1.0): 25

# "shame" appears 19 times in the negative tweets
('shame', 0.0): 19 

根据推文数据创建词频字典,并打印出字典的数据类型和长度:

# create frequency dictionary
freqs = build_freqs(tweets, labels)

# check data type
print(f'type(freqs) = {type(freqs)}')

# check length of the dictionary
print(f'len(freqs) = {len(freqs)}')

结果:
type(freqs) = <class ‘dict’>
len(freqs) = 13234

词频表格化

选择一小部分需要可视化的词:

# select some words to appear in the report. we will assume that each word is unique (i.e. no duplicates)
keys = ['happi', 'merri', 'nice', 'good', 'bad', 'sad', 'mad', 'best', 'pretti',
        '❤', ':)', ':(', '😒', '😬', '😄', '😍', '♛',
        'song', 'idea', 'power', 'play', 'magnific']

# list representing our table of word counts.
# each element consist of a sublist with this pattern: [<word>, <positive_count>, <negative_count>]
data = []

# loop through our selected words
for word in keys:
    
    # initialize positive and negative counts
    pos = 0
    neg = 0
    
    # retrieve number of positive counts
    if (word, 1) in freqs:
        pos = freqs[(word, 1)]
        
    # retrieve number of negative counts
    if (word, 0) in freqs:
        neg = freqs[(word, 0)]
        
    # append the word counts to the table
    data.append([word, pos, neg])
    
data

在这里插入图片描述
然后,我们可以使用散点图来直观地查看该表。我们将不绘制原始计数,而是绘制对数刻度,以考虑原始计数之间的巨大差异(例如☺在正区域有 3691 个计数,而在负区域只有 2 个计数)。红线是正负区域的分界线。靠近红线的词可归类为中性词。

fig, ax = plt.subplots(figsize = (8, 8))

# convert positive raw counts to logarithmic scale. we add 1 to avoid log(0)
x = np.log([x[1] + 1 for x in data])  

# do the same for the negative counts
y = np.log([x[2] + 1 for x in data]) 

# Plot a dot for each pair of words
ax.scatter(x, y)  

# assign axis labels
plt.xlabel("Log Positive count")
plt.ylabel("Log Negative count")

# Add the word as the label at the same position as you added the points just before
for i in range(0, len(data)):
    ax.annotate(data[i][0], (x[i], y[i]), fontsize=12)

ax.plot([0, 9], [0, 9], color = 'red') # Plot the red line that divides the 2 areas.
plt.show()

在这里插入图片描述
从图中够可以看到,最能表现情感的两个数据是笑脸和哭脸,因此对于情感分析来说,这些标点最好是保留。

逻辑回归模型可视化

导入包

import nltk                         # NLP toolbox
from os import getcwd
import pandas as pd                 # Library for Dataframes 
from nltk.corpus import twitter_samples 
import matplotlib.pyplot as plt     # Library for visualization
import numpy as np                  # Library for math functions

from utils import process_tweet, build_freqs # Our functions for NLP

加载推特数据集

# select the set of positive and negative tweets
all_positive_tweets = twitter_samples.strings('positive_tweets.json')
all_negative_tweets = twitter_samples.strings('negative_tweets.json')

tweets = all_positive_tweets + all_negative_tweets ## Concatenate the lists. 
labels = np.append(np.ones((len(all_positive_tweets),1)), np.zeros((len(all_negative_tweets),1)), axis = 0)

# split the data into two pieces, one for training and one for testing (validation set) 
train_pos  = all_positive_tweets[:4000]
train_neg  = all_negative_tweets[:4000]

train_x = train_pos + train_neg 

print("Number of tweets: ", len(train_x))

加载特征(情感词频)

将每个推文的词频特征保存在logistic_features.csv中,直接加载即可:
推文的词频特征计算方式看这里:C1W1.Sentiment Analysis with Logistic Regression

data = pd.read_csv('./data/logistic_features.csv'); # Load a 3 columns csv file using pandas function
data.head(10) # Print the first 10 data entries

在这里插入图片描述
接下来去掉dataframe,保留np数组:

# Each feature is labeled as bias, positive and negative
X = data[['bias', 'positive', 'negative']].values # Get only the numerical values of the dataframe
Y = data['sentiment'].values; # Put in Y the corresponding labels or sentiments

print(X.shape) # Print the shape of the X part
print(X) # Print some rows of X

加载预训练的逻辑回归模型

其实就是三个参数 θ \theta θ

theta = [6.03518871e-08, 5.38184972e-04, -5.58300168e-04]

样本散点图

向量 Theta 代表一个平面,它将我们的特征空间分成两个部分。位于该平面上方的样本被视为正样本,位于该平面下方的样本被视为负样本。结果一个 3D 特征空间,也就是说,每条推文都是由三个值组成的向量: 偏置、正求和、负求和]",其中 “偏置 = 1”。
如果忽略偏置项,我们就可以用 "正和值 "和 "负和值 "在笛卡尔平面上绘制每条推文。积极的推文为绿色,消极的推文为红色。

# Plot the samples using columns 1 and 2 of the matrix
fig, ax = plt.subplots(figsize = (8, 8))

colors = ['red', 'green']

# Color based on the sentiment Y
ax.scatter(X[:,1], X[:,2], c=[colors[int(k)] for k in Y], s = 0.1)  # Plot a dot for each pair of words
plt.xlabel("Positive")
plt.ylabel("Negative")

在这里插入图片描述

绘制逻辑回归模型

从上图可以看到正负样本分界非常明显,我们将画一条灰线来表示正负区域的分界线:
z = θ ∗ x = 0. z = \theta * x = 0. z=θx=0.
要画出这条线,我们必须用其中一个自变量来求解上述方程。
z = θ ∗ x = 0 z = \theta * x = 0 z=θx=0
x = [ 1 , p o s , n e g ] x = [1, pos, neg] x=[1,pos,neg]
z ( θ , x ) = θ 0 + θ 1 ∗ p o s + θ 2 ∗ n e g = 0 z(\theta, x) = \theta_0+ \theta_1 * pos + \theta_2 * neg = 0 z(θ,x)=θ0+θ1pos+θ2neg=0
n e g = ( − θ 0 − θ 1 ∗ p o s ) / θ 2 neg = (-\theta_0 - \theta_1 * pos) / \theta_2 neg=(θ0θ1pos)/θ2
指向相应情感方向的红线和绿线是用一条垂直于前面公式中计算出的分离线(负函数)的线来计算的。它必须与 Logit 函数的导数指向相同的方向,但大小可能不同。这只是为了直观地表示模型。
d i r e c t i o n = p o s ∗ θ 2 / θ 1 direction = pos * \theta_2 / \theta_1 direction=posθ2/θ1
代码如下:

# Equation for the separation plane
# It give a value in the negative axe as a function of a positive value
# f(pos, neg, W) = w0 + w1 * pos + w2 * neg = 0
# s(pos, W) = (-w0 - w1 * pos) / w2
def neg(theta, pos):
    return (-theta[0] - pos * theta[1]) / theta[2]

# Equation for the direction of the sentiments change
# We don't care about the magnitude of the change. We are only interested 
# in the direction. So this direction is just a perpendicular function to the 
# separation plane
# df(pos, W) = pos * w2 / w1
def direction(theta, pos):
    return    pos * theta[2] / theta[1]
# Plot the samples using columns 1 and 2 of the matrix
fig, ax = plt.subplots(figsize = (8, 8))

colors = ['red', 'green']

# Color base on the sentiment Y
ax.scatter(X[:,1], X[:,2], c=[colors[int(k)] for k in Y], s = 0.1)  # Plot a dot for each pair of words
plt.xlabel("Positive")
plt.ylabel("Negative")

# Now lets represent the logistic regression model in this chart. 
maxpos = np.max(X[:,1])

offset = 5000 # The pos value for the direction vectors origin

# Plot a gray line that divides the 2 areas.
ax.plot([0,  maxpos], [neg(theta, 0),   neg(theta, maxpos)], color = 'gray') 

# Plot a green line pointing to the positive direction
ax.arrow(offset, neg(theta, offset), offset, direction(theta, offset), head_width=500, head_length=500, fc='g', ec='g')
# Plot a red line pointing to the negative direction
ax.arrow(offset, neg(theta, offset), -offset, -direction(theta, offset), head_width=500, head_length=500, fc='r', ec='r')

plt.show()

在这里插入图片描述

图中绿线指向 z > 0 的方向,红线指向 z < 0 的方向。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1927020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cesium 实现地图环境功能 - 雨,雪,雾特效

需求背景解决效果Codeindex.vuefogEffect.tsrain.glslsnow.glslfog.glsl 需求背景 需要实现天气模拟&#xff0c;日照模拟功能&#xff0c;提高三维实景效果 解决效果 Code 注意&#xff1a;我以下glsl文件时基于 webgl1.0&#xff0c;即cesium&#xff0c;创建球的时候&…

ES的使用示例

1.安装 ES的安装对springboot的版本配置要求很高&#xff0c;需要根据如下的目录下载对应的版本。 查看自己项目所使用的springboot和spring的版本&#xff0c;对应下载文件。 下载链接地址&#xff1a;https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-…

微软GraphRAG原理介绍(附带部分源码)

我们前几天写了一篇文章&#xff0c;简单跑了一下GraphRAG看了下效果&#xff0c;没看过这篇文章的可以看下https://www.luxinfeng.top/article/动手实操微软开源的GraphRAG。今天我们介绍一下GraphRAG的实现原理&#xff0c;关于实验对比的内容&#xff0c;我会在下一篇文章中…

48V电源架构解析

48V电源架构解析 48V系统的诞生 汽车在1918年引入蓄电池&#xff0c;到1920年逐渐普及&#xff0c;当时的电池电压是6V。后来&#xff0c;随着内燃机排量的增加以及高压缩比内燃机的出现&#xff0c;6V系统已经不能满足需求&#xff0c;于是在1950年引入了12V系统。大多数汽车…

【python学习】标准库之数学相关math库的定义、功能、使用场景、代码示例和第三方数学相关库NumPy

引言 math模块是Python标准库的一部分&#xff0c;它提供了一系列基本的数学函数和常数。这些函数和常数对于日常的数学运算非常有用&#xff0c;例如计算平方根、计算余弦值等。 文章目录 引言一、math的定义二、math的功能2.1 基本的数学运算2.2 数学常数2.3 随机数 三、math…

八臂-聚乙二醇-生物素;8ARM-PEG-Biotin

一、基本信息 名称&#xff1a;八臂PEG生物素、八臂-聚乙二醇-生物素、Octa-arm PEG Biotin、8ARM-PEG-Biotin 结构&#xff1a;具有八个分支的PEG链&#xff0c;每个分支末端连接生物素分子 状态&#xff1a;固体/粉末/溶液&#xff0c;具体取决于产品规格和存储条件 纯度&…

论文去AI痕秘籍:轻松几步,守护你的学术原创性

如何有效降低AIGC论文的重复率&#xff0c;也就是我们说的aigc如何降重&#xff1f;AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文&#xff0c;就一定要在交稿之前做一下AIGC降重的检查。一般来说&#xff0c;如果论文的AIGC超过30%&#xff0c;很可能会被判定…

Qt|QTreewidget类下函数qt助手详解说明示例(二)

上篇&#xff1a;Qt|QTreewidget类下函数qt助手详解说明示例&#xff08;一&#xff09; 该系列持续更新&#xff0c;喜欢请一键三连&#xff0c;一起学习进步&#xff0c;升职加薪&#xff0c;感谢各位大佬。 QT5.14.2 参考官方QT助手 Kimi辅助说明 文章目录 insertTopLevelI…

浅学三次握手

数据要完成传输&#xff0c;必须要建立连接。由于建立TCP连接的过程需要来回3次&#xff0c;所以&#xff0c;将这个过程形象的叫做三次握手。 结合上面的图来看更清楚。 先说三次握手吧&#xff0c;连接是后续数据传输的基础。就像我们打电话一样&#xff0c;必须保证我和对方…

工作是为了什么

如果经常和总监及以上的领导聊天&#xff0c;就会发现他们与咱们一线程序员的最大不同&#xff0c;并不是编程技能多高深精通&#xff0c;而是分析问题、认知世界的方式。 程序员只关注工作领域的“一亩三分地”&#xff0c;实质上是放弃了自己成长的机会&#xff0c;在工作的…

软件测试——非功能测试

工作职责&#xff1a; 1.负责产品系统测试&#xff0c;包括功能测试、性能测试、稳定性测试、用户场景测试、可靠性测试等。 2.负责测试相关文档的编写&#xff0c;包括测试计划、测试用例、测试报告等。 3.负责自动化测试框架、用例的维护。 岗位要求&#xff1a; 1.熟练…

解决mysql,Navicat for MySQL,IntelliJ IDEA之间中文乱码

使用软件版本 jdk-8u171-windows-x64 ideaIU-2021.1.3 mysql-essential-5.0.87-win32 navicat8_mysql_cs 这个问题我调试了好久&#xff0c;网上的方法基本上都试过了&#xff0c;终于是解决了。 三个地方结果都不一样。 方法一 首先大家可以尝试下面这种方法&#xff1a…

53 传输层

作用&#xff1a;负责数据能够从发送端传输接收端 再谈端口号 端口号&#xff08;port&#xff09;标识了一个主机上进行通信的不同的应用程序 在TCP/IP协议中&#xff0c;用“源IP”&#xff0c;“源端口号”&#xff0c;“目的IP”&#xff0c;“目的端口号”&#xff0c…

陶晶驰串口屏与arduino uno通信,远程控制arduino 2560上的LED

一 材料清单 arduino uno 1个 arduino 2560 1个 nrf24l01 2个 陶晶驰串口屏 1个 二 本文目的 通过串口屏触摸按键远程控制arduino 2560上的LED 点亮。 三 硬件接线 3.1 发射端接线 3.1.1uno和发射模块接线 nRF24L01 与Arduino UNO接线如…

你也想做一个Elemen-ui吧!!!——Blueの前端路

目录 前言 diglog组件 准备工作&#xff1a; 在diglog.vue中模仿element-ui搭建diglog框架 该组件需要完成的任务&#xff1a; title diglog.vue代码&#xff1a; App.vue代码&#xff1a; 效果&#xff1a; 自定义dialog的宽度和距离顶部的 App.vue代码&#xff1a;…

Windows 下 VMamba 安装教程(无需更改base环境中的cuda版本且可加速)

导航 Mamba 及 Vim 安装问题参看本人之前博客&#xff1a;Mamba 环境安装踩坑问题汇总及解决方法Windows 下 Mamba 的安装参看本人之前博客&#xff1a;Window 下Mamba 环境安装踩坑问题汇总及解决方法 &#xff08;无需绕过selective_scan_cuda&#xff09;Linux 下VMamba 安…

前端面试题(JS篇三)

一、|| 和 && 操作符的返回值&#xff1f; || 和 && 首先会对第一个操作数执行条件判断&#xff0c;如果其不是布尔值就先进行 ToBoolean 强制类型转换&#xff0c;然后再执行条件判断。 对于 || 来说&#xff0c;如果条件判断结果为 true 就返回第一个操作数的…

磁环编码器原理

目录 概述 1 编码器介绍 2 实现原理介绍 2.1 磁环功能分析 2.2 硬件实现方式 3 编码器参数 3.1 编码器精度 3.2 影响编码器精度的因素 4 角度计算方法 4.1 单对极编码器 4.2 磁游标编码器 4.2.1 游标方案实现原理 4.2.2 一个实例磁环分析 5 磁刻线编码器 概述 本…

算法题-二叉树

二叉树 二叉树的理论知识 二叉树的种类 满二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为0的节点和度为2的节点&#xff0c;并且度为0的节点在同一层&#xff0c;则此二叉树为满二叉树&#xff08;深度为k&#xff0c;有2^k-1个节点的二叉树&#xff09;。 完全二叉…

PostgreSQL 中如何解决因长事务阻塞导致的其他事务等待问题?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何解决因长事务阻塞导致的其他事务等待问题&#xff1f;一、了解长事务阻塞的原因&…