【笔记】第四章:从线性回归到逻辑回归-Mastering Machine Learning With scikit-learn

标签: | 发表时间:2017-11-15 20:47 | 作者:
出处:http://www.phantask.net

 

(这章起换用Markdown)
《Mastering Machine Learning With scikit-learn》是一本非常实用的机器学习实战书籍,它使用通俗易懂的语言和适度的理论知识来帮助python开发者使用scikit-learn机器学习工具包实现机器学习相关算法的应用。早些时候我拜读了这本书,记了些笔记和重要的知识点,今天重新温习了遍,仍有收获,顺便张贴到博客上,一起学习交流。

第四章:从线性回归到逻辑回归

广义线性回归是一种灵活的框架,比普通线性回归要求更少的假设。这一章,我们讨论广义线性回归模型的具体形式的另一种形式,逻辑回归(logistic regression)。

和前面讨论的模型不同,逻辑回归是用来做分类任务的。

分类任务的目标是找一个函数,把观测值匹配到相关的类和标签上。学习算法必须用成对的特征向量和对应的标签来估计匹配函数的参数,从而实现更好的分类效果。

在二元分类(binary classification)中,分类算法必须把一个实例配置两个类别。多元分类中,分类算法需要为每个实例都分类一组标签。

逻辑回归处理二元分类

普通的线性回归假设响应变量呈正态分布,也称为 高斯分布(Gaussian distribution)钟形曲线(bell curve)。正态分布数据是对称的,且均值,中位数和众数(mode)是一样的。

很多自然现象都服从正态分布。比如,人类的身高就服从正态分布,姚明那样的高度极少,在99%之外了。 在某些问题里,响应变量不是正态分布的。比如,掷一个硬币获取正反两面的概率分布是 伯努利分布(Bernoulli distribution),又称两点分布或者0-1分布。表示一个事件发生的概率是P,不发生的概率是1-P,概率在{0,1}之间。 线性回归假设解释变量值的变化会引起响应变量值的变化,如果响应变量的值是概率的,这条假设就不满足了。广义线性回归去掉了这条假设,用一个 联连函数(link function)来描述解释变量与响应变量的关系。

在逻辑回归里,响应变量描述了类似于掷一个硬币结果为正面的概率。如果响应变量等于或超过了指定的临界值,预测结果就是正面,否则预测结果就是反面。响应变量是一个像线性回归中的解释变量构成的函数表示,称为 逻辑函数(logistic function)

一个值在{0,1}之间的逻辑函数如下所示:

$$F\left(t\right)=\frac{1}{1+e^{-t}}$$

下面是在{-6,6}的图形:

      %matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\msyh.ttc", size=10)
import numpy as np
plt.figure()
plt.axis([-6, 6, 0, 1])
plt.grid(True)
X = np.arange(-6,6,0.1)
y = 1 / (1 + np.e ** (-X))
plt.plot(X, y, 'b-')

在逻辑回归中, 是解释变量的线性组合,公式如下:

$$F\left(t\right)=\frac{1}{1+e^{-(\beta_{0}+\beta_{x})}}$$

对数函数(logit function)是逻辑函数的逆运算:

$$g\left(x\right)=\ln\frac{F\left(x\right)}{1-F\left(x\right)}=\beta_{0}+\beta_{x}$$

垃圾邮件分类

经典的二元分类问题就是 垃圾邮件分类(spam classification)。 这里,我们分类垃圾短信。我们用第三章介绍的TF-IDF算法来抽取短信的特征向量,然后用逻辑回归分类。

首先,我们还是用Pandas做一些描述性统计:

      import pandas as pd
df = pd.read_csv('mlslpic/SMSSpamCollection', delimiter='\t', header=None
) print(df.head())
print('含spam短信数量:', df[df[0] == 'spam'][0].count())
print('含ham短信数量:', df[df[0] == 'ham'][0].count())  

#    0                                             1
# 0  ham    Go until jurong point, crazy.. Available only ...
# 1  ham    Ok lar... Joking wif u oni...
# 2  spam   Free entry in 2 a wkly comp to win FA Cup fina...
# 3  ham    U dun say so early hor... U c already then say...
# 4  ham    Nah I don't think he goes to usf, he lives aro...
# 含spam短信数量: 7
# 含ham短信数量: 4825

每条信息的前面已经被打上了标签。共5574条短信里面,4827条是ham,747条是spam。ham短信用0标记,spam短信用1标记。观察数据会看到更多建模时需要的信息。下面的几条信息体现两种类型的特征:

      Spam: Free entry in 2 a wkly comp to win FA Cup final tkts 21st May
Text FA to 87121 to receive entry question(std txt rate)T&C's apply 08452810075over18's
Spam: WINNER!! As a valued network customer you have been selected to receivea £900
prize reward! To claim call 09061701461. Claim code KL341. Valid 12 hours only.
Ham: Sorry my roommates took forever, it ok if I come by now?
Ham: Finished class where are you.

让我们用 LogisticRegression类来预测:

      import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model.logistic import LogisticRegression
from sklearn.cross_validation import train_test_split

首先,用 pandas加载数据.csv文件,然后用 train_test_split分成训练集(75%)和测试集(25%):

      df = pd.read_csv('mlslpic/SMSSpamCollection', delimiter='\t', header=None) 
X_train_raw, X_test_raw, y_train, y_test =train_test_split(df[1],df[0])

然后,我们建一个 TfidfVectorizer实例来计算TF-IDF权重:

      vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(X_train_raw)
X_test = vectorizer.transform(X_test_raw)

最后,我们建一个 LogisticRegression实例来训练模型。和 LinearRegression类似, LogisticRegression同样实现 fit()predict()方法。最后把结果打印出来看看:

      classifier = LogisticRegression()
classifier.fit(X_train, y_train)
predictions = classifier.predict(X_test)  
for i, prediction in enumerate(predictions[-5:]):
    print('预测类型:%s. 信息:%s' % (prediction, X_test_raw.iloc[i]))  

# 预测类型:ham. 信息:Are u coming to the funeral home
# 预测类型:ham. 信息:Love isn't a decision, it's a feeling. If we could decide who to love, then, life would be much simpler, but then less magical
# 预测类型:ham. 信息:Dont think so. It turns off like randomlly within 5min of opening
# 预测类型:spam. 信息:Hey happy birthday...
# 预测类型:ham. 信息:None of that's happening til you get here though

二元分类效果评估方法

二元分类的效果评估方法有很多,常见的包括第一章里介绍的肿瘤预测使用的 准确率(accuracy)精确率(precision)召回率(recall)三项指标,以及 综合评价指标(F1 measure)ROC,AUC值(Receiver Operating Characteristic ROC,Area Under Curve,AUC)。这些指标评价的样本分类是 真阳性(true positives)真阴性(true negatives)假阳性(false positives)假阴性(false negatives)。阳性和阴性指分类,真和假指预测的正确与否。

混淆矩阵(Confusion matrix),也称 列联表分析(Contingency table)可以用来描述真假与阴阳的关系。矩阵的行表示实际类型,列表示预测类型。

      from sklearn.metrics import confusion_matrix #引入混淆矩阵
import matplotlib.pyplot as plt
y_test = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
y_pred = [0, 1, 0, 0, 0, 0, 0, 1, 1, 1]
confusion_matrix = confusion_matrix(y_test, y_pred)
print(confusion_matrix)
plt.matshow(confusion_matrix)
plt.title('混淆矩阵',fontproperties=font)
plt.colorbar()
plt.ylabel('实际类型',fontproperties=font)
plt.xlabel('预测类型',fontproperties=font)
plt.show()  

# [[4 1]
# [2 3]]

准确率

准确率是分类器预测正确性的评估指标。 scikit-learn提供了 accuracy_score来计算:

      from sklearn.metrics import accuracy_score
y_pred, y_true = [0, 1, 1, 0], [1, 1, 1, 1]
print(accuracy_score(y_true, y_pred))  

# 0.5

LogisticRegression.score()用来计算模型预测的准确率:

      import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model.logistic import LogisticRegression
from sklearn.cross_validation import train_test_split, cross_val_score
df = pd.read_csv('mlslpic/sms.csv')
X_train_raw, X_test_raw, y_train, y_test = train_test_split(df['message'], df['label'])
vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(X_train_raw)
X_test = vectorizer.transform(X_test_raw)
classifier = LogisticRegression()
classifier.fit(X_train, y_train)
scores = cross_val_score(classifier, X_train, y_train, cv=5)
print('准确率:',np.mean(scores), scores)  

# 准确率: 0.958373205742 [ 0.96291866 0.95334928 0.95813397 0.96172249 0.95574163]

准确率是分类器预测正确性的比例,但是并不能分辨出假阳性错误和假阴性错误。

有时准确率并非一个有效的衡量指标,如果分类的比例在样本中严重失调。

精确率和召回率

在本章的垃圾短信分类器中,精确率是指分类器预测出的垃圾短信中真的是垃圾短信的比例:

$$ P=\frac{TP}{TP+FP} $$

召回率在医学领域也叫做 灵敏度(sensitivity),在本例中是指所有真的垃圾短信被分类器正确找出来的比例。

$$ R=\frac{TP}{TP+FN} $$

精确率和召回率各自含有的信息都很少,它们对分类器效果的观察角度不同。精确率和召回率都不能从表现差的一种分类器中区分出好的分类器。

scikit-learn结合真实类型数据,提供了一个函数来计算一组预测值的精确率和召回率。

      import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model.logistic import LogisticRegression
from sklearn.cross_validation import train_test_split, cross_val_score
df = pd.read_csv('mlslpic/sms.csv')
X_train_raw, X_test_raw, y_train, y_test = train_test_split(df['message']
, df['label'])
vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(X_train_raw)
X_test = vectorizer.transform(X_test_raw)
classifier = LogisticRegression()
classifier.fit(X_train, y_train)
precisions = cross_val_score(classifier, X_train, y_train, cv=5, scoring='precision')
print('精确率:', np.mean(precisions), precisions)
recalls = cross_val_score(classifier, X_train, y_train, cv=5, scoring='recall')
print('召回率:', np.mean(recalls), recalls)  

# 精确率: 0.99217372134 [ 0.9875 0.98571429 1. 1. 0.98765432]
# 召回率: 0.672121212121 [ 0.71171171 0.62162162 0.66363636 0.63636364 0.72727273]

我们的分类器精确率99.2%,分类器预测出的垃圾短信中99.2%都是真的垃圾短信。召回率比较低67.2%,就是说真实的垃圾短信中,32.8%被当作正常短信了,没有被识别出来。这些数据会不断变化,因为训练集和测试集是随机抽取的。

计算综合评价指标

综合评价指标(F1 measure)是精确率和召回率的 调和均值(harmonic mean),或加权平均值,也称为 F-measureF-score

$$ \frac{1}{F1}+\frac{1}{F1}=\frac{1}{P}+\frac{1}{R} $$

$$ F1=2\frac{PR}{P+R} $$

综合评价指标平衡了精确率和召回率。一个二元分类模型,精确率和召回率为1,那么综合评价指标为1。如果精确率或召回率为0,那么综合评价指标为0。 scikit-learn也提供了计算综合评价指标的函数。

      f1s = cross_val_score(classifier, X_train, y_train, cv=5, scoring='f1')
print('综合评价指标:', np.mean(f1s), f1s)  

# 综合评价指标: 0.800588878125 [ 0.82722513 0.76243094 0.7978142 1 0.77777778 0.83769634]

本例的综合评价指标是80%。由于精确率和召回率的差异比较小,所以综合评价指标的罚值也比较小。有时也会用F0.5和F2,表示精确率权重大于召回率,或召回率权重大于精确率。

ROC AUC

ROC曲线(Receiver Operating Characteristic,ROC curve)可以用来可视化分类器的效果。和准确率不同,ROC曲线对分类比例不平衡的数据集不敏感,ROC曲线显示的是对超过限定阈值的所有预测结果的分类器效果。ROC曲线画的是分类器的召回率与误警率(fall-out)的曲线。误警率也称假阳性率,是所有阴性样本中分类器识别为阳性的样本所占比例:

$$ F=\frac{FP}{TN+FP} $$

AUC是ROC曲线下方的面积,它把ROC曲线变成一个值,表示分类器随机预测的效果。 scikit-learn提供了计算ROC和AUC指标的函数:

      import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model.logistic import LogisticRegression
from sklearn.cross_validation import train_test_split, cross_val_score
from sklearn.metrics import roc_curve, auc
df = pd.read_csv('mlslpic/sms.csv')
X_train_raw, X_test_raw, y_train, y_test = train_test_split(df['message'], df['label'])
vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(X_train_raw)
X_test = vectorizer.transform(X_test_raw)
classifier = LogisticRegression()
classifier.fit(X_train, y_train)
predictions = classifier.predict_proba(X_test) #输出的是概率
false_positive_rate, recall, thresholds = roc_curve(y_test, predictions[:, 1])
roc_auc = auc(false_positive_rate, recall)
plt.title('Receiver Operating Characteristic')
plt.plot(false_positive_rate, recall, 'b', label='AUC = %0.2f' % roc_auc)
plt.legend(loc='lower right')
plt.plot([0, 1], [0, 1], 'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.ylabel('Recall')
plt.xlabel('Fall-out')
plt.show()

 

 

网格搜索

在第二章我们曾经提到过超参数,是需要手动调节的参数,模型无法学习。比如,在我们的垃圾短信分类模型中,超参数出现在TF-IDF中,用来移除太频繁和太稀缺单词的频率阈值,目前函数正则化的权重值。

scikit-learn里面,超参数是在模型建立时设置的。

网格搜索(Grid search)就是用来确定最优超参数的方法。其原理就是选取可能的参数不断运行模型获取最佳效果。网格搜索用的是穷举法,其缺点在于即使每个超参数的取值范围都很小,计算量也是巨大的。不过这是一个并行问题,参数与参数彼此独立,计算过程不需要同步,所有很多方法都可以解决这个问题。

scikit-learnGridSearchCV()函数解决这个问题:

      import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model.logistic import LogisticRegression
from sklearn.grid_search import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.cross_validation import train_test_split
from sklearn.metrics import precision_score, recall_score, accuracy_score
pipeline = Pipeline([
('vect', TfidfVectorizer(stop_words='english')),
('clf', LogisticRegression())
])
parameters = {
'vect__max_df': (0.25, 0.5, 0.75),
'vect__stop_words': ('english', None),
'vect__max_features': (2500, 5000, 10000, None),
'vect__ngram_range': ((1, 1), (1, 2)),
'vect__use_idf': (True, False),
'vect__norm': ('l1', 'l2'),
'clf__penalty': ('l1', 'l2'),
'clf__C': (0.01, 0.1, 1, 10),
} grid_search =
GridSearchCV(pipeline, parameters, n_jobs=-1, verbose=1, sc
oring='accuracy', cv=3)
df = pd.read_csv('mlslpic/sms.csv')
X, y, = df['message'], df['label']
X_train, X_test, y_train, y_test = train_test_split(X, y)
grid_search.fit(X_train, y_train)
print('最佳效果:%0.3f' % grid_search.best_score_)
print('最优参数组合:')
best_parameters = grid_search.best_estimator_.get_params()  
for param_name in sorted(parameters.keys()):
    print('\t%s: %r' % (param_name, best_parameters[param_name]))
predictions = grid_search.predict(X_test)
print('准确率:', accuracy_score(y_test, predictions))
print('精确率:', precision_score(y_test, predictions))
print('召回率:', recall_score(y_test, predictions))  

# [Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.8s
# [Parallel(n_jobs=-1)]: Done 50 jobs | elapsed: 10.1s
# [Parallel(n_jobs=-1)]: Done 200 jobs | elapsed: 27.4s
# [Parallel(n_jobs=-1)]: Done 450 jobs | elapsed: 54.2s
# [Parallel(n_jobs=-1)]: Done 800 jobs | elapsed: 1.6min
# [Parallel(n_jobs=-1)]: Done 1250 jobs | elapsed: 2.4min
# [Parallel(n_jobs=-1)]: Done 1800 jobs | elapsed: 3.4min
# [Parallel(n_jobs=-1)]: Done 2450 jobs | elapsed: 4.6min
# [Parallel(n_jobs=-1)]: Done 3200 jobs | elapsed: 6.0min  
# [Parallel(n_jobs=-1)]: Done 4050 jobs | elapsed: 10.6min
# [Parallel(n_jobs=-1)]: Done 4608 out of 4608 | elapsed: 11.7min
# finished  

# Fitting 3 folds for each of 1536 candidates, totalling 4608 fits
# 最佳效果:0.982
# 最优参数组合:
# clf__C: 10
# clf__penalty: 'l2'
# vect__max_df: 0.25
# vect__max_features: 2500
# vect__ngram_range: (1, 2)
# vect__norm: 'l2'
# vect__stop_words: None
# vect__use_idf: True
# 准确率: 0.989956958393
# 精确率: 0.994252873563
# 召回率: 0.930107526882

GridSearchCV()函数的参数有待评估模型 pipeline,超参数词典 parameters和效果评价指标 scoringn_jobs是指并发进程最大数量,设置为-1表示使用所有CPU核心进程。在Python3.4中,可以写一个Python的脚本,让 fit()函数可以在 main()函数里调用,也可以在Python自带命令行,IPython命令行和IPython Notebook运行。经过网格计算后的超参数在训练集中取得了很好的效果。

多类分类

现实中有很多问题不只是分成两类,许多问题都需要分成多个类,成为 多类分类问题(Multi-class classification)

scikit-learn用one-vs.-all或one-vs.-the-rest方法实现多类分类,就是把多类中的每个类都作为二元分类处理。分类器预测样本不同类型,将具有最大置信水平的类型作为样本类型。

LogisticRegression()通过one-vs.-all策略支持多类分类。

我们利用烂番茄(Rotten Tomatoes)网站影评短语数据对电影进行评价。

每个影评可以归入下面5个类项:不给力(negative),不太给力(somewhat negative),中等(neutral),有点给力(somewhat positive), 给力(positive)。

      import zipfile
# 压缩节省空间
z = zipfile.ZipFile('mlslpic/train.zip')
df = pd.read_csv(z.open(z.namelist()[0]), header=0, delimiter='\t')  
df.head()  
df.count()  

# PhraseId 156060
# SentenceId 156060
# Phrase 156060
# Sentiment 156060
# dtype: int64  

df.Phrase.head(10)

# 0 A series of escapades demonstrating the adage ...
# 1 A series of escapades demonstrating the adage ...
# 2 A series
# 3 A
# 4 series
# 5 of escapades demonstrating the adage that what...
# 6 of
# 7 escapades demonstrating the adage that what is...
# 8 escapades
# 9 demonstrating the adage that what is good for ...
# Name: Phrase, dtype: object  

df.Sentiment.describe()  

# count 156060.000000
# mean 2.063578
# std 0.893832
# min 0.000000
# 25% 2.000000
# 50% 2.000000
# 75% 3.000000
# max 4.000000
# Name: Sentiment, dtype: float64

df.Sentiment.value_counts()

# 2 79582
# 3 32927
# 1 27273
# 4 9206
# 0 7072
# dtype: int64 

df.Sentiment.value_counts()/df.Sentiment.count()  

# 2 0.509945
# 3 0.210989
# 1 0.174760
# 4 0.058990
# 0 0.045316
# dtype: float64

scikit-learn来训练分类器:

      import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model.logistic import LogisticRegression
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report, accuracy_score, confusion_matrix
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV
import zipfile
pipeline = Pipeline([
('vect', TfidfVectorizer(stop_words='english')),
('clf', LogisticRegression())
])
parameters = {
'vect__max_df': (0.25, 0.5),
'vect__ngram_range': ((1, 1), (1, 2)),
'vect__use_idf': (True, False),
'clf__C': (0.1, 1, 10),
}
z = zipfile.ZipFile('mlslpic/train.zip')
df = pd.read_csv(z.open(z.namelist()[0]), header=0, delimiter='\t')
X, y = df['Phrase'], df['Sentiment'].as_matrix()
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5)
grid_search = GridSearchCV(pipeline, parameters, n_jobs=3, verbose=1, scoring='accuracy')  
grid_search.fit(X_train, y_train)
print('最佳效果:%0.3f' % grid_search.best_score_)
print('最优参数组合:')
best_parameters = grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
    print('\t%s: %r' % (param_name, best_parameters[param_name]))

多类分类效果评估

二元分类里,混淆矩阵可以用来可视化不同分类错误的数据。每种类型的精确率,召回率和综合评价指标(F1 score)可以计算,所有预测的准确率也可以计算。

      predictions = grid_search.predict(X_test)
print('准确率:', accuracy_score(y_test, predictions))
print('混淆矩阵:', confusion_matrix(y_test, predictions))
print('分类报告:', classification_report(y_test, predictions))  

# 准确率: 0.635024990388
# 混淆矩阵: [[ 1178 1701 616 71 4]
# [ 990 5993 6030 563 30]
# [ 227 3231 32668 3520 143]
# [ 37 401 6642 8089 1305]
# [ 7 30 534 2397 1623]]
# 分类报告: precision     recall     f1-score     support
# 0                 0.48             0.33         0.39         3570
# 1                 0.53             0.44         0.48         13606
# 2                 0.70             0.82         0.76         39789
# 3                 0.55             0.49         0.52         16474
# 4                 0.52             0.35         0.42         4591
# avg / total    0.62             0.64         0.62         78030

我们通过网格搜索获得了最佳参数组合,最终的分类器是通过对开始的分类器不断优化得到的

多标签分类和问题转换

前面我们讨论了二元分类,多类分类,还有一种分类问题是 多标签分类(multi-label classification)

每个样本可以拥有全部类型的一部分类型。这样的例子太普遍了,比如统计班上同学一周7天里哪天有空。每个同学都会在周一到周日这7天里,根据自己的情况分别打勾。再比如常见的博客文章分类标签,一篇文章一般都有好几个标签等等。

多标签分类问题一般有两种解决方法

问题转化方法(Problem transformation)可以将多标签问题转化成单标签问题。 第一种转换方法是训练集里面每个样本通过幂运算转换成单标签。比如下面数据里面每篇文章都带有若干标签。

转换方法就是用幂运算将多个类合并成一个类,比如样本1有Local和US类,新建一个标签为Local^US类,这样多标签就变成单标签了。

这样原来5个标签现在变成了7个标签。这种幂运算虽然直观,但是并不实用,因为这样做多出来的标签只有一小部分样本会用到。而且,这些标签只能在训练集里面学习这些类似,在测试集中依然无法使用。

另外一种问题转换方法就是每个标签都用二元分类处理。每个标签的分类器都预测样本是否属于该标签。我们的例子中需要5个二元分类器,第一个分类器预测样本是否应该被归入Local类,第二个分类器预测样本是否应该被归入US类,以此类推。预测最后一步就是把这些分类结果求并集,如下图所示:

这个问题确保了单标签问题和多标签问题有同样的训练集,只是忽略了标签之间的关联关系。

多标签分类效果评估

多标签分类效果评估最常用的手段是 汉明损失函数(Hamming loss)杰卡德相似度(Jaccard similarity)

汉明损失函数表示错误标签的平均比例,是一个函数,当预测全部正确,即没有错误标签时,值为0。

杰卡德相似度或杰卡德相指数(Jaccard index),是预测标签和真实标签的交集数量除以预测标签和真实标签的并集数量。其值在{0,1}之间,公式如下:

$$ J\left(Predicted, True\right)=\frac{|Predicted \bigcap True|}{|Predicted \bigcup True|} $$

      import numpy as np
from sklearn.metrics import hamming_loss, jaccard_similarity_score
print(hamming_loss(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[0.0, 1.0], [1.0, 1.0]])))
print(hamming_loss(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [1.0, 1.0]])))
print(hamming_loss(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [0.0, 1.0]])))
print(jaccard_similarity_score(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[0.0, 1.0], [1.0, 1.0]])))
print(jaccard_similarity_score(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [1.0, 1.0]])))
print(jaccard_similarity_score(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [0.0, 1.0]]))  

# 0.0
# 0.25
# 0.5
# 1.0
# 0.75
# 0.

 

 

 

相关 [笔记 线性回归 逻辑回归] 推荐:

【笔记】第四章:从线性回归到逻辑回归-Mastering Machine Learning With scikit-learn

- -
(这章起换用Markdown). 《Mastering Machine Learning With scikit-learn》是一本非常实用的机器学习实战书籍,它使用通俗易懂的语言和适度的理论知识来帮助python开发者使用scikit-learn机器学习工具包实现机器学习相关算法的应用. 早些时候我拜读了这本书,记了些笔记和重要的知识点,今天重新温习了遍,仍有收获,顺便张贴到博客上,一起学习交流.

线性回归与逻辑回归 - CSDN博客

- -
七月在线4月机器学习算法班课程笔记——No.5.   回归算法是一种通过最小化预测值与实际结果值之间的差距,而得到输入特征之间的最佳组合方式的一类算法. 对于连续值预测有线性回归等,而对于离散值/类别预测,我们也可以把逻辑回归等也视作回归算法的一种.   线性回归与逻辑回归是机器学习中比较基础又很常用的内容.

Python实现逻辑回归(Logistic Regression in Python)

- - 神刀安全网
Logistic Regression in Python ,作了中文翻译,并相应补充了一些内容. 本文并不研究逻辑回归具体算法实现,而是使用了一些算法库,旨在帮助需要用Python来做逻辑回归的训练和预测的读者快速上手. 逻辑回归是一项可用于预测二分类结果(binary outcome)的统计技术,广泛应用于金融、医学、犯罪学和其他社会科学中.

Python实现逻辑回归(Logistic Regression in Python)_给力星

- -
Logistic Regression in Python,作了中文翻译,并相应补充了一些内容. 本文并不研究逻辑回归具体算法实现,而是使用了一些算法库,旨在帮助需要用Python来做逻辑回归的训练和预测的读者快速上手. 逻辑回归是一项可用于预测二分类结果(binary outcome)的统计技术,广泛应用于金融、医学、犯罪学和其他社会科学中.

从零开始使用TensorFlow建立简单的逻辑回归模型

- - SegmentFault 最新的文章
TensorFlow 是一个基于 python 的机器学习框架. 在 Coursera 上学习了逻辑回归的课程内容后,想把在 MATLAB 中实现了的内容用 TensorFlow 重新实现一遍,当做学习 Python 和框架的敲门砖. 知道逻辑回归是什么,懂一点 Python,听说过 TensorFlow.

从逻辑回归到深度学习,点击率预测技术面面观

- -
预测物品的点击率在计算广告、推荐系统等不同业务系统中都有一定需求,因此业界在这方面进行了不少研究. 然而在机器学习领域,书籍出版远远落后于业界知识更新,这就要求每个从业者阅读大量资料和论文才能跟上知识更新的步伐,而这又需要耗费大量的时间和精力. 本文是作者对阅读过的大量相关研究文献的小结,作者尝试结合文献与工作实践梳理广告点击率预测、推荐方面相关的技术脉络,希望能对大家有所帮助.

使用Tensorflow训练线性回归模型并进行预测

- - 蓝鲸的网站分析笔记
Tensorflow是Google开发的开源机器学习库. 本篇文章我们将使用Tensorflow对线性回归模型进行训练,并使用模型对数据进行预测. 首先导入所需的库文件,包括tensorflow,numpy和matplotlib. Tensorflow用于创建和训练线性回归模型,numpy用于提取数据和计算均方误差MSE,matplotlib用于绘制成本函数变化图.

对线性回归,logistic回归和一般回归的认识 - JerryLead - 博客园

- -
     【转载时请注明来源】:.      2011年2月27日.      作为一个机器学习初学者,认识有限,表述也多有错误,望大家多多批评指正.       本报告是在学习斯坦福大学机器学习课程前四节加上配套的讲义后的总结与认识. 前四节主要讲述了回归问题,回归属于有监督学习中的一种方法. 该方法的核心思想是从连续型统计数据中得到数学模型,然后将该数学模型用于预测或者分类.

笔记

- 毛毛 - 游戏人生
我关于写代码的一些琐碎的看法. 之前没有把 Paul Graham 的 <黑客与画家> 一书读完, 上周就从同事那里把书带回家, 也一直没读, 到这周才有时间读完. 很久没有更新了 (一看时间, 整整 5 个月), 顺便把这篇写了几个月的感想放出来.. 这本书前面 8 章讲述的内容, 大多是我并不太感兴趣的, 比如财富, 比如创业.

Textmate笔记

- Sean Lee - Reborn
过去在Windows上还真的没有怎么太在意文本编辑器(也跟自己不是职业程序员有点关系吧. ),近来常在Mac上使用Textmate,真觉得一款好的文本编辑器实在非常必要. Textmate售价$58,很多人觉得贵,不过它真的不错. 为Finder加上“Open in textmate”按钮. 作者Henrik的主页上有详细的介绍.