- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个代码,使用 Python(和 Scikit Learn)自动对我的银行交易进行分类。目前,我已经对大约 1700 个交易进行了 70 个类别(标签)的分类 - 我总共有大约 3500 行,但并未全部组织起来,这是我的第一次尝试。基本上我导入了一个 CSV 文件:
Description | Value | Label
RSHOP-SABORES DA -25/04 | -30 | Restaurants
RSHOP-MERCATTINO -28/04 | -23 | Bars
RSHOP-HORTISABOR -07/05 | -65 | Supermarket
TBI 3712.06663-9 tokpag | 1.000 | Salary
描述和值是我的功能,标签是我的标签。由于不同的字符等,描述可能会变得有点复杂。所以我了解到我应该使用 Tf-IDF 对描述进行矢量化,并对标签进行 LabelEncode。
<小时/>现在,我有:
# Loads data
data = pd.read_csv('classifications.csv',
encoding='latin1',
error_bad_lines=False,
delimiter=';')
# Assigns features and labels - I chose to use only the description to make it simpler for a first time. I want to use the value later as well.
data.columns = ['desc', 'value', 'label']
data_base = data.values
features_base= data_base[:,[0]]
labels_base = data_base[:,[2]]
# Printing features returns a (1722,1) array - looks good.
print(features_base.shape)
# Printing labels returns a (1722,1) array - looks good.
print(labels_base.shape)
# Encodes labels, printing returns (1722,) - don't know why the "1" is missing on the y.
encoder = LabelEncoder()
label_encoded = encoder.fit_transform((labels_base.astype(str)).ravel())
print(label_encoded.shape)
# Encodes features. Printing returns (1722, 1012) - don't know what's the "1012" on the y axis... the only thing I can think of the number of unique values on the vector, but can't be sure.
vectorizer = TfidfVectorizer()
vectors = vectorizer.fit_transform(features_base.ravel().astype('U'))
print(vectors.shape)
#Test
train_features, train_labels, test_features, test_labels = tts(vectors, label_encoded, test_size=0.2)
<小时/>
然后我尝试了几个估算器,每个估算器都有不同的错误(写在第一条注释行上):
# Random Forest Classifier - returns "ValueError: Unknown label type: 'continuous-multioutput'"
clf1 = RandomForestClassifier()
print("Using", clf1)
clf1.fit(train_features.toarray(), train_labels.toarray())
predictions1 = clf1.predict(test_features)
print( "\nPredictions:", predictions1)
score = 0
for i in range(len(predictions1)):
if predictions[i] == test_labels[i]:
score += 1
print("Accuracy:", (score / len(predictions)) * 100, "%")
# Decision Tree Classifier - returns "ValueError: Unknown label type: 'continuous-multioutput'"
clf2 = tree.DecisionTreeClassifier()
print("Using", clf2)
clf2.fit(train_features.toarray(), train_labels.toarray())
predictions2 = clf2.predict(test_features)
print( "\nPredictions:", predictions2)
score = 0
for i in range(len(predictions2)):
if predictions[i] == test_labels[i]:
score += 1
print("Accuracy:", (score / len(predictions)) * 100, "%")
#SVC Linear - returns "ValueError: bad input shape (345, 1012)"
clf3 = svm.SVC(kernel='linear')
print("Using", clf3)
clf3.fit(train_features, train_labels)
predictions3 = clf3.predict(test_features)
print( "\nPredictions:", predictions3)
score = 0
for i in range(len(predictions1)):
if predictions[i] == test_labels[i]:
score += 1
print("Accuracy:", (score / len(predictions)) * 100, "%")
# SVC Non Linear - returns "ValueError: bad input shape (345, 1012)"
clf4 = svm.SVC()
print("Using", clf4)
clf4.fit(train_features.toarray(), train_labels.toarray())
predictions4 = clf4.predict(test_features)
print( "\nPredictions:", predictions4)
score = 0
for i in range(len(predictions1)):
if predictions[i] == test_labels[i]:
score += 1
print("Accuracy:", (score / len(predictions)) * 100, "%")
<小时/>
最终目标是加载包含描述/金额的 CSV 文件,它会向我建议一个标签(如果知道建议的确定性级别那就太好了)。
总结一下:
非常感谢。
最佳答案
问题在于标签,因为您使用 pandas,所以它们应该作为分类数据传递给分类器。我将在几分钟内发布一些代码。
更新:好的,您的代码存在一些问题。在针对新任务开发 ML 模型时,我建议从简单开始,然后在有了工作原型(prototype)后增加其复杂性。我只为 RandomForestClassifier 实现了代码,您应该能够轻松地将其复制到您感兴趣的其他分类器。这是:
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import RandomForestClassifier
data = pd.read_csv('classifications.csv',
encoding='latin1',
error_bad_lines=False,
delimiter=';')
data.columns = ['desc', 'value', 'label']
data['label'] = data['label'].astype('category')
data.info()
vectorizer = TfidfVectorizer()
vectors = vectorizer.fit_transform(data['desc'])
print('Shape: ',vectors.shape)
clf = RandomForestClassifier(random_state=42)
clf.fit(vectors,data['label'])
print('Score: {}'.format(clf.score(vectors,data['label'])))
clf.predict(vectorizer.transform(data['desc']))
这段代码的输出是:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):
desc 4 non-null object
value 4 non-null float64
label 4 non-null category
dtypes: category(1), float64(1), object(1)
memory usage: 340.0+ bytes
Shape: (4, 14)
Score: 1.0
array(['Restaurants', 'Bars', 'Supermarket', 'Salary'], dtype=object)
一些评论:
1) 如果您使用 pandas,分类标签理想情况下应该是分类数据 (pandas.Categorical)。这降低了分类器将标签解释为有序数据并尝试对其预测进行相应排序的可能性。
2) 如果您要链接 sklearn 中的多个对象,例如向量化器和分类器,最好通过编写来实例化 Pipeline 对象
from sklearn.pipeline import Pipeline
pipeline = Pipeline([('vectorizer',TfidfVectorizer()),
('classifier',RandomForestClassifier())])
这为您节省了在需要向分类器提供新数据时随时将 .transform 或 .fit_transform 方法的输出从向量化器传递到分类器的麻烦,因为管道会自动执行此操作。
3) 为随机分类器设置 random_state,以保证结果的可重复性。
4) 目前尚不清楚为什么您要尝试手动计算分数:分类器的 .score() 方法会自动计算平均准确度分数,并且它可以防止您使用 len(predictions) 等函数犯错误。当在另一种情况下,您尝试预测概率分布而不是单个点预测时,如果您养成了调用 len(predictions) 的习惯,您可能最终会在数组上计算错误的维度,而不会注意到。但是,如果您想要百分比形式的分数,而不是 0 到 1 的范围内的分数,只需将 .score() 方法返回的分数乘以 100 即可。
希望这有帮助。
关于python - 机器学习: autocategorization of strings - "Unknown label type" and "Bad Input Shape",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52251651/
如果您想使用 String.Concat() 连接 5 个或更多字符串,则它会使用 Concat(String[])。 为什么不一直使用 Concat(String[]) 而不再需要 Concat(S
今天在使用 String 时,我遇到了一种我以前不知道的行为。我无法理解内部发生的事情。 public String returnVal(){ return "5";
似乎在我所看到的任何地方,都有一些过时的版本,这些版本不再起作用。 我的问题似乎很简单。我有一个Java类,它映射到derby数据库。我正在使用注释,并且已经成功地在数据库中创建了所有其他表,但是在这
一、string::size_type() 在C++标准库类型 string ,在调用size函数求解string 对象时,返回值为size_type类型,一种类似于unsigned类型的int 数据
我正在尝试将数据保存到我的 plist 文件中,其中包含字符串数组的定义。我的plist - enter image description here 我将数据写入 plist 的代码是 -- let
我有一个带有键/值对的 JavaScript 对象,其中值是字符串数组: var errors = { "Message": ["Error #1", "Error #2"], "Em
例如,为了使用相同的函数迭代 List 和 List> ,我可以编写如下内容: import java.util.*; public class Test{ public static voi
第一个Dictionary就像 Dictionary ParentDict = new Dictionary(); ParentDict.Add("A_1", "1")
这是我的 jsp 文件: 我遇到了错误 The method replace(String, String, String) in the type Functions is not appl
我需要一些帮助。我有一个方法应该输出一个包含列表内容的 txt 文件(每行中的每个项目)。列表项是字符串数组。问题是,当我调用 string.Join 时,它返回文字字符串 "System.Strin
一位同事告诉我,使用以下方法: string url = "SomeURL"; string ext = "SomeExt"; string sub = "SomeSub"; string s
给定类: public class CategoryValuePair { String category; String value; } 还有一个方法: public
我正在尝试合并 Stream>>对象与所有 Streams 中的键一起映射到单个映射中. 例如, final Map someObject; final List>> list = someObjec
在这里使用 IDictionary 的值(value)是什么? 最佳答案 使用接口(interface)的值(value)始终相同:切换到另一个后端实现时,您不必更改客户端代码。 请考虑稍后分析您的代
我可以知道这两个字典声明之间的区别吗? var places = [String: String]() var places = [Dictionary()] 为什么当我尝试以这种方式附加声明时,只有
在 .NET 4.0 及更高版本中存在 string.IsNullOrWhiteSpace(string) 时,在检查字符串时使用 string.IsNullOrEmpty(string) 是否被视为
这个名字背后的原因是什么? SS64在 PowerShell 中解释此处的字符串如下: A here string is a single-quoted or double-quoted string
我打算离开 this 文章,尝试编写一个接受字符串和 &str 的函数,但我遇到了问题。我有以下功能: pub fn new(t_num: S) -> BigNum where S: Into {
我有一个结构为 [String: [String: String]] 的多维数组。我可以使用 for 循环到达 [String: String] 位,但我不知道如何访问主键(这个位 [String:
我正在尝试使用 sarama(管理员模式)创建主题。没有 ConfigEntries 工作正常。但我需要定义一些配置。 我设置了主题配置(这里发生了错误): tConfigs := map[s
我是一名优秀的程序员,十分优秀!