Python 如何使用机器学习为数据分配标签/分数

Python 如何使用机器学习为数据分配标签/分数,python,pandas,machine-learning,sentiment-analysis,Python,Pandas,Machine Learning,Sentiment Analysis,我有一个由许多行组成的数据框,其中包括tweets。我想用有监督或无监督的机器学习技术对它们进行分类。 由于数据集未标记,我想选择几行50%手动标记+1 pos,-1 neg,0 neutral,然后使用机器学习将标签分配给其他行。 为了做到这一点,我做了如下工作: Date ID Tweet PosNegNeu 01/20/2020 4141 The cat is o

我有一个由许多行组成的数据框,其中包括tweets。我想用有监督或无监督的机器学习技术对它们进行分类。 由于数据集未标记,我想选择几行50%手动标记+1 pos,-1 neg,0 neutral,然后使用机器学习将标签分配给其他行。 为了做到这一点,我做了如下工作:

Date                   ID        Tweet                          PosNegNeu
 01/20/2020           4141    The cat is on the table               0
 01/20/2020           4142    The weather is bad today              -1
 01/20/2020           53      What a wonderful day                  1
 ...
 05/12/2020           532     In this extraordinary circumstance we are together   1
 05/13/2020           12      It was a very bad decision            -1
 05/22/2020           565     I know you are the best               1
原始数据集

Date                   ID        Tweet                         
01/20/2020           4141    The cat is on the table               
01/20/2020           4142    The sky is blue                       
01/20/2020           53      What a wonderful day                  
...
05/12/2020           532     In this extraordinary circumstance we are together   
05/13/2020           12      It was a very bad decision            
05/22/2020           565     I know you are the best              
将数据集分为50%的训练和50%的测试。我手动标记了50%的数据,如下所示:

Date                   ID        Tweet                          PosNegNeu
 01/20/2020           4141    The cat is on the table               0
 01/20/2020           4142    The weather is bad today              -1
 01/20/2020           53      What a wonderful day                  1
 ...
 05/12/2020           532     In this extraordinary circumstance we are together   1
 05/13/2020           12      It was a very bad decision            -1
 05/22/2020           565     I know you are the best               1
然后在删除停止词后提取单词的频率:

               Frequency
 bad               2
 circumstance      1
 best              1
 day               1
 today             1
 wonderful         1

我想尝试根据以下内容为其他数据指定标签:

频率表中的单词,例如,如果tweet包含bad than assign-1;如果一条tweet包含1,即我应该创建一个字符串列表和一条规则; 基于句子相似性,例如使用Levenshtein距离。 我知道有几种方法可以做到这一点,甚至更好,但我在为数据分类/分配标签方面遇到了一些问题,我无法手动完成

我的预期输出,例如使用以下测试数据集

Date                   ID        Tweet                                   
06/12/2020           43       My cat 'Sylvester' is on the table            
07/02/2020           75       Laura's pen is black                                                
07/02/2020           763      It is such a wonderful day                                    
...
11/06/2020           1415    No matter what you need to do                  
05/15/2020           64      I disagree with you: I think it is a very bad decision           
12/27/2020           565     I know you can improve                         
应该是

Date                   ID        Tweet                                   PosNegNeu
06/12/2020           43       My cat 'Sylvester' is on the table            0
07/02/2020           75       Laura's pen is black                          0                       
07/02/2020           763      It is such a wonderful day                    1                
...
11/06/2020           1415    No matter what you need to do                  0  
05/15/2020           64      I disagree with you: I think it is a very bad decision  -1          
12/27/2020           565     I know you can improve                         0   

也许更好的方法应该考虑N-gram,而不是单字或建立语料库/词汇来分配分数,然后是情感。任何建议都将不胜感激,因为这是我关于机器学习的第一次练习。我认为k-means聚类也可以应用,试图得到更多相似的句子。


如果您能为我提供一个完整的示例,说明我的数据将非常好,但同时说明其他数据也可以,我将不胜感激。

IIUC,您已标记了数据的百分比,并且需要标记剩余数据。我建议你读一些关于半监督机器学习的书

半监督学习是一种机器学习方法,它在训练过程中将少量标记数据与大量未标记数据相结合。半监督学习介于没有标记训练数据的无监督学习和只有标记训练数据的监督学习之间

Sklearn提供了大量的算法来帮助实现这一点。一定要退房

如果你需要对这个话题有更多的了解,我强烈建议你也来看看

下面是一个iris数据集的示例-

import numpy as np
from sklearn import datasets
from sklearn.semi_supervised import LabelPropagation

#Init
label_prop_model = LabelPropagation()
iris = datasets.load_iris()

#Randomly create unlabelled samples
rng = np.random.RandomState(42)
random_unlabeled_points = rng.rand(len(iris.target)) < 0.3
labels = np.copy(iris.target)
labels[random_unlabeled_points] = -1

#propogate labels over remaining unlabelled data
label_prop_model.fit(iris.data, labels)


IIUC,您已标记了一定百分比的数据,并要求标记剩余数据。我建议你读一些关于半监督机器学习的书

半监督学习是一种机器学习方法,它在训练过程中将少量标记数据与大量未标记数据相结合。半监督学习介于没有标记训练数据的无监督学习和只有标记训练数据的监督学习之间

Sklearn提供了大量的算法来帮助实现这一点。一定要退房

如果你需要对这个话题有更多的了解,我强烈建议你也来看看

下面是一个iris数据集的示例-

import numpy as np
from sklearn import datasets
from sklearn.semi_supervised import LabelPropagation

#Init
label_prop_model = LabelPropagation()
iris = datasets.load_iris()

#Randomly create unlabelled samples
rng = np.random.RandomState(42)
random_unlabeled_points = rng.rand(len(iris.target)) < 0.3
labels = np.copy(iris.target)
labels[random_unlabeled_points] = -1

#propogate labels over remaining unlabelled data
label_prop_model.fit(iris.data, labels)


我建议在这种情况下对句子或tweet进行极性分析。这可以使用textblob库完成。它可以作为pip安装-U textblob安装。一旦发现文本数据极性,就可以在数据框中将其指定为单独的列。随后,可以使用句子的极性进行进一步分析

初始代码

中间结果

从上面输出的情绪栏中,我们可以看到情绪栏分为两极和主观性

极性是[-1.0到1.0]范围内的浮点值,其中0 表示中性,+1表示非常积极的情绪,-1 代表一种非常消极的情绪

主观性是[0.0到1.0]范围内的浮点值,其中0.0 非常客观,1.0非常主观。主观句 表达一些个人的感情、观点、信仰、观点, 指控、欲望、信念、怀疑和猜测 客观句是事实句

注意,情绪列是一个元组。所以我们可以把它分成两列,像df1=pd.DataFramedf['emotation'].tolist,index=df.index。现在,我们可以创建一个新的dataframe,我将在其中附加拆分列,如图所示

df_new = df
df_new['polarity'] = df1['polarity']
df_new.polarity = df1.polarity.astype(float)
df_new['subjectivity'] = df1['subjectivity']
df_new.subjectivity = df1.polarity.astype(float)
最后,根据前面发现的句子极性,我们现在可以在数据帧中添加一个标签,它将指示tweet是正的、负的还是中性的

import numpy as np
conditionList = [
    df_new['polarity'] == 0,
    df_new['polarity'] > 0,
    df_new['polarity'] < 0]
choiceList = ['neutral', 'positive', 'negative']
df_new['label'] = np.select(conditionList, choiceList, default='no_label')
print(df_new)
资料

完整代码


我建议在这种情况下对句子或tweet进行极性分析。这可以使用textblob库完成。它可以作为pip安装-U textblob安装。一旦发现文本数据极性,就可以在数据框中将其指定为单独的列。随后,可以使用句子的极性进行进一步分析

初始代码

安葬 后期结果

从上面输出的情绪栏中,我们可以看到情绪栏分为两极和主观性

极性是[-1.0到1.0]范围内的浮点值,其中0 表示中性,+1表示非常积极的情绪,-1 代表一种非常消极的情绪

主观性是[0.0到1.0]范围内的浮点值,其中0.0 非常客观,1.0非常主观。主观句 表达一些个人的感情、观点、信仰、观点, 指控、欲望、信念、怀疑和猜测 客观句是事实句

注意,情绪列是一个元组。所以我们可以把它分成两列,像df1=pd.DataFramedf['emotation'].tolist,index=df.index。现在,我们可以创建一个新的dataframe,我将在其中附加拆分列,如图所示

df_new = df
df_new['polarity'] = df1['polarity']
df_new.polarity = df1.polarity.astype(float)
df_new['subjectivity'] = df1['subjectivity']
df_new.subjectivity = df1.polarity.astype(float)
最后,根据前面发现的句子极性,我们现在可以在数据帧中添加一个标签,它将指示tweet是正的、负的还是中性的

import numpy as np
conditionList = [
    df_new['polarity'] == 0,
    df_new['polarity'] > 0,
    df_new['polarity'] < 0]
choiceList = ['neutral', 'positive', 'negative']
df_new['label'] = np.select(conditionList, choiceList, default='no_label')
print(df_new)
资料

完整代码


非常感谢你的回答,维利索。我会尽快给你颁发赏金奖possible@LucaDiMauro我很高兴它对你有用。我期待着获得赏金奖。干杯,非常感谢你的回答,维利索。我会尽快给你颁发赏金奖possible@LucaDiMauro我很高兴它对你有用。我期待着获得赏金奖。干杯。我建议你使用你自己的标记数据微调一个预先训练好的模型,然后使用这个模型预测其余推文的类别。@luca di mauro温柔地提醒赏金奖。看来你忘记分配赏金了。我以前的用户名是villisSO。上周我把它改成了maverick。当我回答你的问题时,我认为这不应该成为奖励我的威慑。非常感谢你留下来。我以为我已经分配好了!谢谢你这么特立独行!“我建议你使用自己标记的数据对一个预先训练好的模型进行微调,然后使用这个模型来预测其余推文的类别。”卢卡·迪·毛罗《赏金奖温柔提示》。看来你忘记分配赏金了。我以前的用户名是villisSO。上周我把它改成了maverick。当我回答你的问题时,我认为这不应该成为奖励我的威慑。非常感谢你留下来。我以为我已经分配好了!谢谢你这么特立独行!
# create some dummy data
import pandas as pd
import numpy as np

# create a dictionary
data = {"Date":["1/1/2020","2/1/2020","3/2/2020","4/2/2020","5/2/2020"],
        "ID":[1,2,3,4,5],
        "Tweet":["the weather is sunny",
                 "tom likes harry", "the sky is blue",
                 "the weather is bad","i love apples"]}
# convert data to dataframe
df = pd.DataFrame(data)

from textblob import TextBlob
df['sentiment'] = df['Tweet'].apply(lambda Tweet: TextBlob(Tweet).sentiment)
print(df)

# split the sentiment column into two
df1=pd.DataFrame(df['sentiment'].tolist(), index= df.index)

# append cols to original dataframe
df_new = df
df_new['polarity'] = df1['polarity']
df_new.polarity = df1.polarity.astype(float)
df_new['subjectivity'] = df1['subjectivity']
df_new.subjectivity = df1.polarity.astype(float)
print(df_new)

# add label to dataframe based on condition
conditionList = [
    df_new['polarity'] == 0,
    df_new['polarity'] > 0,
    df_new['polarity'] < 0]
choiceList = ['neutral', 'positive', 'negative']
df_new['label'] = np.select(conditionList, choiceList, default='no_label')
print(df_new)